config.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. <?php
  2. /**
  3. * ownCloud
  4. *
  5. * @author Michael Gapczynski
  6. * @copyright 2012 Michael Gapczynski mtgap@owncloud.com
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  10. * License as published by the Free Software Foundation; either
  11. * version 3 of the License, or any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public
  19. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. /**
  22. * Class to configure the config/mount.php and data/$user/mount.php files
  23. */
  24. class OC_Mount_Config {
  25. const MOUNT_TYPE_GLOBAL = 'global';
  26. const MOUNT_TYPE_GROUP = 'group';
  27. const MOUNT_TYPE_USER = 'user';
  28. /**
  29. * Get details on each of the external storage backends, used for the mount config UI
  30. * If a custom UI is needed, add the key 'custom' and a javascript file with that name will be loaded
  31. * If the configuration parameter should be secret, add a '*' to the beginning of the value
  32. * If the configuration parameter is a boolean, add a '!' to the beginning of the value
  33. * If the configuration parameter is optional, add a '&' to the beginning of the value
  34. * If the configuration parameter is hidden, add a '#' to the beginning of the value
  35. * @return array
  36. */
  37. public static function getBackends() {
  38. $backends['\OC\Files\Storage\Local']=array(
  39. 'backend' => 'Local',
  40. 'configuration' => array(
  41. 'datadir' => 'Location'));
  42. $backends['\OC\Files\Storage\AmazonS3']=array(
  43. 'backend' => 'Amazon S3',
  44. 'configuration' => array(
  45. 'key' => 'Access Key',
  46. 'secret' => '*Secret Key',
  47. 'bucket' => 'Bucket',
  48. 'hostname' => 'Hostname (optional)',
  49. 'port' => 'Port (optional)',
  50. 'region' => 'Region (optional)',
  51. 'use_ssl' => '!Enable SSL',
  52. 'use_path_style' => '!Enable Path Style'));
  53. $backends['\OC\Files\Storage\Dropbox']=array(
  54. 'backend' => 'Dropbox',
  55. 'configuration' => array(
  56. 'configured' => '#configured',
  57. 'app_key' => 'App key',
  58. 'app_secret' => 'App secret',
  59. 'token' => '#token',
  60. 'token_secret' => '#token_secret'),
  61. 'custom' => 'dropbox');
  62. if(OC_Mount_Config::checkphpftp()) $backends['\OC\Files\Storage\FTP']=array(
  63. 'backend' => 'FTP',
  64. 'configuration' => array(
  65. 'host' => 'URL',
  66. 'user' => 'Username',
  67. 'password' => '*Password',
  68. 'root' => '&Root',
  69. 'secure' => '!Secure ftps://'));
  70. if(OC_Mount_Config::checkcurl()) $backends['\OC\Files\Storage\Google']=array(
  71. 'backend' => 'Google Drive',
  72. 'configuration' => array(
  73. 'configured' => '#configured',
  74. 'client_id' => 'Client ID',
  75. 'client_secret' => 'Client secret',
  76. 'token' => '#token'),
  77. 'custom' => 'google');
  78. $backends['\OC\Files\Storage\SWIFT']=array(
  79. 'backend' => 'OpenStack Swift',
  80. 'configuration' => array(
  81. 'host' => 'URL',
  82. 'user' => 'Username',
  83. 'token' => '*Token',
  84. 'root' => '&Root',
  85. 'secure' => '!Secure ftps://'));
  86. if(OC_Mount_Config::checksmbclient()) $backends['\OC\Files\Storage\SMB']=array(
  87. 'backend' => 'SMB / CIFS',
  88. 'configuration' => array(
  89. 'host' => 'URL',
  90. 'user' => 'Username',
  91. 'password' => '*Password',
  92. 'share' => 'Share',
  93. 'root' => '&Root'));
  94. if(OC_Mount_Config::checkcurl()) $backends['\OC\Files\Storage\DAV']=array(
  95. 'backend' => 'ownCloud / WebDAV',
  96. 'configuration' => array(
  97. 'host' => 'URL',
  98. 'user' => 'Username',
  99. 'password' => '*Password',
  100. 'root' => '&Root',
  101. 'secure' => '!Secure https://'));
  102. $backends['\OC\Files\Storage\SFTP']=array(
  103. 'backend' => 'SFTP',
  104. 'configuration' => array(
  105. 'host' => 'URL',
  106. 'user' => 'Username',
  107. 'password' => '*Password',
  108. 'root' => '&Root'));
  109. $backends['\OC\Files\Storage\iRODS']=array(
  110. 'backend' => 'iRODS',
  111. 'configuration' => array(
  112. 'host' => 'Host',
  113. 'port' => 'Port',
  114. 'use_logon_credentials' => '!Use ownCloud login',
  115. 'user' => 'Username',
  116. 'password' => '*Password',
  117. 'auth_mode' => 'Authentication Mode',
  118. 'zone' => 'Zone'));
  119. return($backends);
  120. }
  121. /**
  122. * Get the system mount points
  123. * The returned array is not in the same format as getUserMountPoints()
  124. * @return array
  125. */
  126. public static function getSystemMountPoints() {
  127. $mountPoints = self::readData(false);
  128. $backends = self::getBackends();
  129. $system = array();
  130. if (isset($mountPoints[self::MOUNT_TYPE_GROUP])) {
  131. foreach ($mountPoints[self::MOUNT_TYPE_GROUP] as $group => $mounts) {
  132. foreach ($mounts as $mountPoint => $mount) {
  133. // Update old classes to new namespace
  134. if (strpos($mount['class'], 'OC_Filestorage_') !== false) {
  135. $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15);
  136. }
  137. // Remove '/$user/files/' from mount point
  138. $mountPoint = substr($mountPoint, 13);
  139. // Merge the mount point into the current mount points
  140. if (isset($system[$mountPoint]) && $system[$mountPoint]['configuration'] == $mount['options']) {
  141. $system[$mountPoint]['applicable']['groups']
  142. = array_merge($system[$mountPoint]['applicable']['groups'], array($group));
  143. } else {
  144. $system[$mountPoint] = array(
  145. 'class' => $mount['class'],
  146. 'backend' => $backends[$mount['class']]['backend'],
  147. 'configuration' => $mount['options'],
  148. 'applicable' => array('groups' => array($group), 'users' => array()),
  149. 'status' => self::getBackendStatus($mount['class'], $mount['options'])
  150. );
  151. }
  152. }
  153. }
  154. }
  155. if (isset($mountPoints[self::MOUNT_TYPE_USER])) {
  156. foreach ($mountPoints[self::MOUNT_TYPE_USER] as $user => $mounts) {
  157. foreach ($mounts as $mountPoint => $mount) {
  158. // Update old classes to new namespace
  159. if (strpos($mount['class'], 'OC_Filestorage_') !== false) {
  160. $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15);
  161. }
  162. // Remove '/$user/files/' from mount point
  163. $mountPoint = substr($mountPoint, 13);
  164. // Merge the mount point into the current mount points
  165. if (isset($system[$mountPoint]) && $system[$mountPoint]['configuration'] == $mount['options']) {
  166. $system[$mountPoint]['applicable']['users']
  167. = array_merge($system[$mountPoint]['applicable']['users'], array($user));
  168. } else {
  169. $system[$mountPoint] = array(
  170. 'class' => $mount['class'],
  171. 'backend' => $backends[$mount['class']]['backend'],
  172. 'configuration' => $mount['options'],
  173. 'applicable' => array('groups' => array(), 'users' => array($user)),
  174. 'status' => self::getBackendStatus($mount['class'], $mount['options'])
  175. );
  176. }
  177. }
  178. }
  179. }
  180. return $system;
  181. }
  182. /**
  183. * Get the personal mount points of the current user
  184. * The returned array is not in the same format as getUserMountPoints()
  185. * @return array
  186. */
  187. public static function getPersonalMountPoints() {
  188. $mountPoints = self::readData(true);
  189. $backends = self::getBackends();
  190. $uid = OCP\User::getUser();
  191. $personal = array();
  192. if (isset($mountPoints[self::MOUNT_TYPE_USER][$uid])) {
  193. foreach ($mountPoints[self::MOUNT_TYPE_USER][$uid] as $mountPoint => $mount) {
  194. // Update old classes to new namespace
  195. if (strpos($mount['class'], 'OC_Filestorage_') !== false) {
  196. $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15);
  197. }
  198. // Remove '/uid/files/' from mount point
  199. $personal[substr($mountPoint, strlen($uid) + 8)] = array(
  200. 'class' => $mount['class'],
  201. 'backend' => $backends[$mount['class']]['backend'],
  202. 'configuration' => $mount['options'],
  203. 'status' => self::getBackendStatus($mount['class'], $mount['options'])
  204. );
  205. }
  206. }
  207. return $personal;
  208. }
  209. private static function getBackendStatus($class, $options) {
  210. foreach ($options as &$option) {
  211. $option = str_replace('$user', OCP\User::getUser(), $option);
  212. }
  213. if (class_exists($class)) {
  214. try {
  215. $storage = new $class($options);
  216. return $storage->test();
  217. } catch (Exception $exception) {
  218. return false;
  219. }
  220. }
  221. return false;
  222. }
  223. /**
  224. * Add a mount point to the filesystem
  225. * @param string Mount point
  226. * @param string Backend class
  227. * @param array Backend parameters for the class
  228. * @param string MOUNT_TYPE_GROUP | MOUNT_TYPE_USER
  229. * @param string User or group to apply mount to
  230. * @param bool Personal or system mount point i.e. is this being called from the personal or admin page
  231. * @return bool
  232. */
  233. public static function addMountPoint($mountPoint,
  234. $class,
  235. $classOptions,
  236. $mountType,
  237. $applicable,
  238. $isPersonal = false) {
  239. if ($isPersonal) {
  240. // Verify that the mount point applies for the current user
  241. // Prevent non-admin users from mounting local storage
  242. if ($applicable != OCP\User::getUser() || $class == '\OC\Files\Storage\Local') {
  243. return false;
  244. }
  245. $mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/');
  246. } else {
  247. $mountPoint = '/$user/files/'.ltrim($mountPoint, '/');
  248. }
  249. $mount = array($applicable => array($mountPoint => array('class' => $class, 'options' => $classOptions)));
  250. $mountPoints = self::readData($isPersonal);
  251. // Merge the new mount point into the current mount points
  252. if (isset($mountPoints[$mountType])) {
  253. if (isset($mountPoints[$mountType][$applicable])) {
  254. $mountPoints[$mountType][$applicable]
  255. = array_merge($mountPoints[$mountType][$applicable], $mount[$applicable]);
  256. } else {
  257. $mountPoints[$mountType] = array_merge($mountPoints[$mountType], $mount);
  258. }
  259. } else {
  260. $mountPoints[$mountType] = $mount;
  261. }
  262. self::writeData($isPersonal, $mountPoints);
  263. return self::getBackendStatus($class, $classOptions);
  264. }
  265. /**
  266. *
  267. * @param string Mount point
  268. * @param string MOUNT_TYPE_GROUP | MOUNT_TYPE_USER
  269. * @param string User or group to remove mount from
  270. * @param bool Personal or system mount point
  271. * @return bool
  272. */
  273. public static function removeMountPoint($mountPoint, $mountType, $applicable, $isPersonal = false) {
  274. // Verify that the mount point applies for the current user
  275. if ($isPersonal) {
  276. if ($applicable != OCP\User::getUser()) {
  277. return false;
  278. }
  279. $mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/');
  280. } else {
  281. $mountPoint = '/$user/files/'.ltrim($mountPoint, '/');
  282. }
  283. $mountPoints = self::readData($isPersonal);
  284. // Remove mount point
  285. unset($mountPoints[$mountType][$applicable][$mountPoint]);
  286. // Unset parent arrays if empty
  287. if (empty($mountPoints[$mountType][$applicable])) {
  288. unset($mountPoints[$mountType][$applicable]);
  289. if (empty($mountPoints[$mountType])) {
  290. unset($mountPoints[$mountType]);
  291. }
  292. }
  293. self::writeData($isPersonal, $mountPoints);
  294. return true;
  295. }
  296. /**
  297. * Read the mount points in the config file into an array
  298. * @param bool Personal or system config file
  299. * @return array
  300. */
  301. private static function readData($isPersonal) {
  302. $parser = new \OC\ArrayParser();
  303. if ($isPersonal) {
  304. $phpFile = OC_User::getHome(OCP\User::getUser()).'/mount.php';
  305. $jsonFile = OC_User::getHome(OCP\User::getUser()).'/mount.json';
  306. } else {
  307. $datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data");
  308. $phpFile = OC::$SERVERROOT.'/config/mount.php';
  309. $jsonFile = $datadir . '/mount.json';
  310. }
  311. if (is_file($jsonFile)) {
  312. $mountPoints = json_decode(file_get_contents($jsonFile), true);
  313. if (is_array($mountPoints)) {
  314. return $mountPoints;
  315. }
  316. } elseif (is_file($phpFile)) {
  317. $mountPoints = $parser->parsePHP(file_get_contents($phpFile));
  318. if (is_array($mountPoints)) {
  319. return $mountPoints;
  320. }
  321. }
  322. return array();
  323. }
  324. /**
  325. * Write the mount points to the config file
  326. * @param bool Personal or system config file
  327. * @param array Mount points
  328. */
  329. private static function writeData($isPersonal, $data) {
  330. if ($isPersonal) {
  331. $file = OC_User::getHome(OCP\User::getUser()).'/mount.json';
  332. } else {
  333. $datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data");
  334. $file = $datadir . '/mount.json';
  335. }
  336. $content = json_encode($data);
  337. @file_put_contents($file, $content);
  338. @chmod($file, 0640);
  339. }
  340. /**
  341. * Returns all user uploaded ssl root certificates
  342. * @return array
  343. */
  344. public static function getCertificates() {
  345. $view = \OCP\Files::getStorage('files_external');
  346. $path=\OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath("").'uploads/';
  347. \OCP\Util::writeLog('files_external', 'checking path '.$path, \OCP\Util::INFO);
  348. if ( ! is_dir($path)) {
  349. //path might not exist (e.g. non-standard OC_User::getHome() value)
  350. //in this case create full path using 3rd (recursive=true) parameter.
  351. mkdir($path, 0777, true);
  352. }
  353. $result = array();
  354. $handle = opendir($path);
  355. if ( ! $handle) {
  356. return array();
  357. }
  358. while (false !== ($file = readdir($handle))) {
  359. if ($file != '.' && $file != '..') $result[] = $file;
  360. }
  361. return $result;
  362. }
  363. /**
  364. * creates certificate bundle
  365. */
  366. public static function createCertificateBundle() {
  367. $view = \OCP\Files::getStorage("files_external");
  368. $path = \OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath("");
  369. $certs = OC_Mount_Config::getCertificates();
  370. $fh_certs = fopen($path."/rootcerts.crt", 'w');
  371. foreach ($certs as $cert) {
  372. $file=$path.'/uploads/'.$cert;
  373. $fh = fopen($file, "r");
  374. $data = fread($fh, filesize($file));
  375. fclose($fh);
  376. if (strpos($data, 'BEGIN CERTIFICATE')) {
  377. fwrite($fh_certs, $data);
  378. fwrite($fh_certs, "\r\n");
  379. }
  380. }
  381. fclose($fh_certs);
  382. return true;
  383. }
  384. /**
  385. * check if smbclient is installed
  386. */
  387. public static function checksmbclient() {
  388. if(function_exists('shell_exec')) {
  389. $output=shell_exec('which smbclient');
  390. return (empty($output)?false:true);
  391. }else{
  392. return(false);
  393. }
  394. }
  395. /**
  396. * check if php-ftp is installed
  397. */
  398. public static function checkphpftp() {
  399. if(function_exists('ftp_login')) {
  400. return(true);
  401. }else{
  402. return(false);
  403. }
  404. }
  405. /**
  406. * check if curl is installed
  407. */
  408. public static function checkcurl() {
  409. return (function_exists('curl_init'));
  410. }
  411. /**
  412. * check dependencies
  413. */
  414. public static function checkDependencies() {
  415. $l= new OC_L10N('files_external');
  416. $txt='';
  417. if(!OC_Mount_Config::checksmbclient()) {
  418. $txt.=$l->t('<b>Warning:</b> "smbclient" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it.').'<br />';
  419. }
  420. if(!OC_Mount_Config::checkphpftp()) {
  421. $txt.=$l->t('<b>Warning:</b> The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it.').'<br />';
  422. }
  423. if(!OC_Mount_Config::checkcurl()) {
  424. $txt.=$l->t('<b>Warning:</b> The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it.').'<br />';
  425. }
  426. return($txt);
  427. }
  428. }