2012-09-07 16:09:41 +04:00
< ? php
/**
* ownCloud
*
* @ author Michael Gapczynski
* @ copyright 2012 Michael Gapczynski mtgap @ owncloud . com
2014-03-19 00:15:11 +04:00
* @ copyright 2014 Vincent Petry < pvince81 @ owncloud . com >
2014-03-21 18:22:48 +04:00
* @ copyright 2014 Robin McCorkell < rmccorkell @ karoshi . org . uk >
2012-09-07 16:09:41 +04:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation ; either
* version 3 of the License , or any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details .
*
* You should have received a copy of the GNU Affero General Public
* License along with this library . If not , see < http :// www . gnu . org / licenses />.
*/
2014-03-19 00:15:11 +04:00
set_include_path (
get_include_path () . PATH_SEPARATOR .
\OC_App :: getAppPath ( 'files_external' ) . '/3rdparty/phpseclib/phpseclib'
);
2012-09-07 16:09:41 +04:00
/**
2014-03-19 15:20:48 +04:00
* Class to configure mount . json globally and for users
2014-03-19 00:15:11 +04:00
*/
2012-09-07 16:09:41 +04:00
class OC_Mount_Config {
2014-03-19 15:20:48 +04:00
// TODO: make this class non-static and give it a proper namespace
2012-09-07 16:09:41 +04:00
const MOUNT_TYPE_GLOBAL = 'global' ;
const MOUNT_TYPE_GROUP = 'group' ;
const MOUNT_TYPE_USER = 'user' ;
2014-03-18 21:29:08 +04:00
// whether to skip backend test (for unit tests, as this static class is not mockable)
public static $skipTest = false ;
2012-09-07 16:09:41 +04:00
/**
* Get details on each of the external storage backends , used for the mount config UI
* If a custom UI is needed , add the key 'custom' and a javascript file with that name will be loaded
* If the configuration parameter should be secret , add a '*' to the beginning of the value
* If the configuration parameter is a boolean , add a '!' to the beginning of the value
* If the configuration parameter is optional , add a '&' to the beginning of the value
2013-04-19 00:20:52 +04:00
* If the configuration parameter is hidden , add a '#' to the beginning of the value
2014-02-06 19:30:58 +04:00
* @ return string
2012-09-07 16:09:41 +04:00
*/
public static function getBackends () {
2013-02-22 20:21:57 +04:00
2014-03-19 20:56:36 +04:00
// FIXME: do not rely on php key order for the options order in the UI
2012-12-15 05:21:26 +04:00
$backends [ '\OC\Files\Storage\Local' ] = array (
2012-11-30 19:27:11 +04:00
'backend' => 'Local' ,
'configuration' => array (
2012-12-11 00:44:43 +04:00
'datadir' => 'Location' ));
2012-12-15 05:21:26 +04:00
$backends [ '\OC\Files\Storage\AmazonS3' ] = array (
2014-03-04 15:38:56 +04:00
'backend' => 'Amazon S3 and compliant' ,
2012-12-11 00:44:43 +04:00
'configuration' => array (
2013-07-03 19:58:44 +04:00
'key' => 'Access Key' ,
'secret' => '*Secret Key' ,
'bucket' => 'Bucket' ,
2013-12-02 19:55:43 +04:00
'hostname' => '&Hostname (optional)' ,
'port' => '&Port (optional)' ,
'region' => '&Region (optional)' ,
2013-07-03 19:58:44 +04:00
'use_ssl' => '!Enable SSL' ,
'use_path_style' => '!Enable Path Style' ));
2012-12-11 00:44:43 +04:00
2012-12-15 05:21:26 +04:00
$backends [ '\OC\Files\Storage\Dropbox' ] = array (
2012-12-11 00:44:43 +04:00
'backend' => 'Dropbox' ,
'configuration' => array (
'configured' => '#configured' ,
'app_key' => 'App key' ,
2014-02-07 21:12:01 +04:00
'app_secret' => '*App secret' ,
2012-12-11 00:44:43 +04:00
'token' => '#token' ,
'token_secret' => '#token_secret' ),
'custom' => 'dropbox' );
2012-12-15 05:21:26 +04:00
if ( OC_Mount_Config :: checkphpftp ()) $backends [ '\OC\Files\Storage\FTP' ] = array (
2012-12-11 00:44:43 +04:00
'backend' => 'FTP' ,
'configuration' => array (
2014-02-12 21:18:09 +04:00
'host' => 'Hostname' ,
2012-12-11 00:44:43 +04:00
'user' => 'Username' ,
'password' => '*Password' ,
'root' => '&Root' ,
'secure' => '!Secure ftps://' ));
2013-04-23 14:36:30 +04:00
if ( OC_Mount_Config :: checkcurl ()) $backends [ '\OC\Files\Storage\Google' ] = array (
2012-12-11 00:44:43 +04:00
'backend' => 'Google Drive' ,
'configuration' => array (
'configured' => '#configured' ,
2013-05-17 04:09:32 +04:00
'client_id' => 'Client ID' ,
2014-02-07 21:12:01 +04:00
'client_secret' => '*Client secret' ,
2013-05-17 04:09:32 +04:00
'token' => '#token' ),
2012-12-11 00:44:43 +04:00
'custom' => 'google' );
2013-02-22 20:21:57 +04:00
2013-10-22 15:34:24 +04:00
if ( OC_Mount_Config :: checkcurl ()) {
$backends [ '\OC\Files\Storage\Swift' ] = array (
'backend' => 'OpenStack Object Storage' ,
'configuration' => array (
2013-10-29 12:19:43 +04:00
'user' => 'Username (required)' ,
'bucket' => 'Bucket (required)' ,
2013-10-29 13:21:50 +04:00
'region' => '&Region (optional for OpenStack Object Storage)' ,
2013-10-29 12:19:43 +04:00
'key' => '*API Key (required for Rackspace Cloud Files)' ,
2013-10-29 13:21:50 +04:00
'tenant' => '&Tenantname (required for OpenStack Object Storage)' ,
2013-10-29 12:19:43 +04:00
'password' => '*Password (required for OpenStack Object Storage)' ,
2013-10-29 13:21:50 +04:00
'service_name' => '&Service Name (required for OpenStack Object Storage)' ,
'url' => '&URL of identity endpoint (required for OpenStack Object Storage)' ,
'timeout' => '&Timeout of HTTP requests in seconds (optional)' ,
2013-10-22 15:34:24 +04:00
)
);
}
2013-02-22 20:21:57 +04:00
2013-08-15 14:00:02 +04:00
if ( ! OC_Util :: runningOnWindows ()) {
if ( OC_Mount_Config :: checksmbclient ()) {
$backends [ '\OC\Files\Storage\SMB' ] = array (
'backend' => 'SMB / CIFS' ,
'configuration' => array (
'host' => 'URL' ,
'user' => 'Username' ,
'password' => '*Password' ,
'share' => 'Share' ,
'root' => '&Root' ));
2014-03-25 17:54:54 +04:00
$backends [ '\OC\Files\Storage\SMB_OC' ] = array (
'backend' => 'SMB / CIFS using OC login' ,
2014-03-21 18:22:48 +04:00
'configuration' => array (
'host' => 'URL' ,
'username_as_share' => '!Username as share' ,
'share' => '&Share' ,
'root' => '&Root' ));
2013-08-15 14:00:02 +04:00
}
}
2013-02-22 20:21:57 +04:00
2013-10-09 18:54:36 +04:00
if ( OC_Mount_Config :: checkcurl ()){
2014-03-21 18:22:48 +04:00
$backends [ '\OC\Files\Storage\DAV' ] = array (
2013-10-09 18:54:36 +04:00
'backend' => 'WebDAV' ,
'configuration' => array (
'host' => 'URL' ,
'user' => 'Username' ,
'password' => '*Password' ,
'root' => '&Root' ,
'secure' => '!Secure https://' ));
2014-03-21 18:22:48 +04:00
$backends [ '\OC\Files\Storage\OwnCloud' ] = array (
2013-10-09 18:54:36 +04:00
'backend' => 'ownCloud' ,
'configuration' => array (
'host' => 'URL' ,
'user' => 'Username' ,
'password' => '*Password' ,
'root' => '&Remote subfolder' ,
'secure' => '!Secure https://' ));
}
2013-02-22 20:21:57 +04:00
2013-02-10 18:37:05 +04:00
$backends [ '\OC\Files\Storage\SFTP' ] = array (
2012-12-26 21:03:16 +04:00
'backend' => 'SFTP' ,
'configuration' => array (
'host' => 'URL' ,
2013-02-22 20:21:57 +04:00
'user' => 'Username' ,
'password' => '*Password' ,
2012-12-26 21:03:16 +04:00
'root' => '&Root' ));
2012-12-11 00:44:43 +04:00
2013-04-12 17:51:58 +04:00
$backends [ '\OC\Files\Storage\iRODS' ] = array (
'backend' => 'iRODS' ,
'configuration' => array (
'host' => 'Host' ,
'port' => 'Port' ,
2013-04-19 00:20:52 +04:00
'use_logon_credentials' => '!Use ownCloud login' ,
2013-04-12 17:51:58 +04:00
'user' => 'Username' ,
'password' => '*Password' ,
2013-04-26 19:37:41 +04:00
'auth_mode' => 'Authentication Mode' ,
2013-04-12 17:51:58 +04:00
'zone' => 'Zone' ));
2012-12-11 00:44:43 +04:00
return ( $backends );
2012-09-07 16:09:41 +04:00
}
2014-03-19 15:20:48 +04:00
/**
2014-03-19 17:23:36 +04:00
* Hook that mounts the given user ' s visible mount points
2014-03-19 15:20:48 +04:00
* @ param array $data
*/
public static function initMountPointsHook ( $data ) {
2014-03-19 17:23:36 +04:00
$mountPoints = self :: getAbsoluteMountPoints ( $data [ 'user' ]);
2014-03-20 15:52:09 +04:00
foreach ( $mountPoints as $mountPoint => $options ) {
2014-03-19 17:23:36 +04:00
\OC\Files\Filesystem :: mount ( $options [ 'class' ], $options [ 'options' ], $mountPoint );
}
}
/**
* Returns the mount points for the given user .
* The mount point is relative to the data directory .
*
* @ param string $user user
* @ return array of mount point string as key , mountpoint config as value
*/
public static function getAbsoluteMountPoints ( $user ) {
2014-03-21 18:22:48 +04:00
$mountPoints = array ();
2014-03-19 15:20:48 +04:00
$datadir = \OC_Config :: getValue ( " datadirectory " , \OC :: $SERVERROOT . " /data " );
$mount_file = \OC_Config :: getValue ( " mount_file " , $datadir . " /mount.json " );
//move config file to it's new position
if ( is_file ( \OC :: $SERVERROOT . '/config/mount.json' )) {
rename ( \OC :: $SERVERROOT . '/config/mount.json' , $mount_file );
}
// Load system mount points
$mountConfig = self :: readData ( false );
if ( isset ( $mountConfig [ self :: MOUNT_TYPE_GLOBAL ])) {
foreach ( $mountConfig [ self :: MOUNT_TYPE_GLOBAL ] as $mountPoint => $options ) {
$options [ 'options' ] = self :: decryptPasswords ( $options [ 'options' ]);
2014-03-19 17:23:36 +04:00
$mountPoints [ $mountPoint ] = $options ;
2014-03-19 15:20:48 +04:00
}
}
if ( isset ( $mountConfig [ self :: MOUNT_TYPE_GROUP ])) {
foreach ( $mountConfig [ self :: MOUNT_TYPE_GROUP ] as $group => $mounts ) {
if ( \OC_Group :: inGroup ( $user , $group )) {
foreach ( $mounts as $mountPoint => $options ) {
$mountPoint = self :: setUserVars ( $user , $mountPoint );
foreach ( $options as & $option ) {
$option = self :: setUserVars ( $user , $option );
}
$options [ 'options' ] = self :: decryptPasswords ( $options [ 'options' ]);
2014-03-19 17:23:36 +04:00
$mountPoints [ $mountPoint ] = $options ;
2014-03-19 15:20:48 +04:00
}
}
}
}
if ( isset ( $mountConfig [ self :: MOUNT_TYPE_USER ])) {
foreach ( $mountConfig [ self :: MOUNT_TYPE_USER ] as $mountUser => $mounts ) {
if ( $mountUser === 'all' or strtolower ( $mountUser ) === strtolower ( $user )) {
foreach ( $mounts as $mountPoint => $options ) {
$mountPoint = self :: setUserVars ( $user , $mountPoint );
foreach ( $options as & $option ) {
$option = self :: setUserVars ( $user , $option );
}
$options [ 'options' ] = self :: decryptPasswords ( $options [ 'options' ]);
2014-03-19 17:23:36 +04:00
$mountPoints [ $mountPoint ] = $options ;
2014-03-19 15:20:48 +04:00
}
}
}
}
// Load personal mount points
$mountConfig = self :: readData ( true );
if ( isset ( $mountConfig [ self :: MOUNT_TYPE_USER ][ $user ])) {
foreach ( $mountConfig [ self :: MOUNT_TYPE_USER ][ $user ] as $mountPoint => $options ) {
$options [ 'options' ] = self :: decryptPasswords ( $options [ 'options' ]);
2014-03-19 17:23:36 +04:00
$mountPoints [ $mountPoint ] = $options ;
2014-03-19 15:20:48 +04:00
}
}
2014-03-19 17:23:36 +04:00
return $mountPoints ;
2014-03-19 15:20:48 +04:00
}
/**
* fill in the correct values for $user
*
* @ param string $user
* @ param string $input
* @ return string
*/
private static function setUserVars ( $user , $input ) {
return str_replace ( '$user' , $user , $input );
}
2014-02-18 19:36:02 +04:00
/**
* Get details on each of the external storage backends , used for the mount config UI
* Some backends are not available as a personal backend , f . e . Local and such that have
* been disabled by the admin .
*
* If a custom UI is needed , add the key 'custom' and a javascript file with that name will be loaded
* If the configuration parameter should be secret , add a '*' to the beginning of the value
* If the configuration parameter is a boolean , add a '!' to the beginning of the value
* If the configuration parameter is optional , add a '&' to the beginning of the value
* If the configuration parameter is hidden , add a '#' to the beginning of the value
* @ return array
*/
public static function getPersonalBackends () {
$backends = self :: getBackends ();
// Remove local storage and other disabled storages
unset ( $backends [ '\OC\Files\Storage\Local' ]);
$allowed_backends = explode ( ',' , OCP\Config :: getAppValue ( 'files_external' , 'user_mounting_backends' , '' ));
foreach ( $backends as $backend => $null ) {
if ( ! in_array ( $backend , $allowed_backends )) {
unset ( $backends [ $backend ]);
}
}
return $backends ;
}
2012-09-07 16:09:41 +04:00
/**
* Get the system mount points
* The returned array is not in the same format as getUserMountPoints ()
* @ return array
*/
public static function getSystemMountPoints () {
$mountPoints = self :: readData ( false );
$backends = self :: getBackends ();
$system = array ();
if ( isset ( $mountPoints [ self :: MOUNT_TYPE_GROUP ])) {
foreach ( $mountPoints [ self :: MOUNT_TYPE_GROUP ] as $group => $mounts ) {
foreach ( $mounts as $mountPoint => $mount ) {
2013-01-03 21:07:04 +04:00
// Update old classes to new namespace
if ( strpos ( $mount [ 'class' ], 'OC_Filestorage_' ) !== false ) {
2013-01-03 21:13:45 +04:00
$mount [ 'class' ] = '\OC\Files\Storage\\' . substr ( $mount [ 'class' ], 15 );
2013-01-03 21:07:04 +04:00
}
2014-03-19 00:15:11 +04:00
$mount [ 'options' ] = self :: decryptPasswords ( $mount [ 'options' ]);
2012-09-07 16:09:41 +04:00
// Remove '/$user/files/' from mount point
$mountPoint = substr ( $mountPoint , 13 );
2014-03-26 15:10:17 +04:00
$config = array (
'class' => $mount [ 'class' ],
'mountpoint' => $mountPoint ,
'backend' => $backends [ $mount [ 'class' ]][ 'backend' ],
'options' => $mount [ 'options' ],
'applicable' => array ( 'groups' => array ( $group ), 'users' => array ()),
2014-03-26 15:04:13 +04:00
'status' => self :: getBackendStatus ( $mount [ 'class' ], $mount [ 'options' ], false )
2014-03-26 15:10:17 +04:00
);
$hash = self :: makeConfigHash ( $config );
// If an existing config exists (with same class, mountpoint and options)
if ( isset ( $system [ $hash ])) {
// add the groups into that config
$system [ $hash ][ 'applicable' ][ 'groups' ]
= array_merge ( $system [ $hash ][ 'applicable' ][ 'groups' ], array ( $group ));
2012-09-07 16:09:41 +04:00
} else {
2014-03-26 15:10:17 +04:00
$system [ $hash ] = $config ;
2012-09-07 16:09:41 +04:00
}
}
}
}
if ( isset ( $mountPoints [ self :: MOUNT_TYPE_USER ])) {
foreach ( $mountPoints [ self :: MOUNT_TYPE_USER ] as $user => $mounts ) {
foreach ( $mounts as $mountPoint => $mount ) {
2013-01-03 21:07:04 +04:00
// Update old classes to new namespace
if ( strpos ( $mount [ 'class' ], 'OC_Filestorage_' ) !== false ) {
2013-01-03 21:13:45 +04:00
$mount [ 'class' ] = '\OC\Files\Storage\\' . substr ( $mount [ 'class' ], 15 );
2013-01-03 21:07:04 +04:00
}
2014-03-19 00:15:11 +04:00
$mount [ 'options' ] = self :: decryptPasswords ( $mount [ 'options' ]);
2012-09-07 16:09:41 +04:00
// Remove '/$user/files/' from mount point
$mountPoint = substr ( $mountPoint , 13 );
2014-03-26 15:10:17 +04:00
$config = array (
'class' => $mount [ 'class' ],
'mountpoint' => $mountPoint ,
'backend' => $backends [ $mount [ 'class' ]][ 'backend' ],
'options' => $mount [ 'options' ],
'applicable' => array ( 'groups' => array (), 'users' => array ( $user )),
2014-03-26 15:22:47 +04:00
'status' => self :: getBackendStatus ( $mount [ 'class' ], $mount [ 'options' ], false )
2014-03-26 15:10:17 +04:00
);
$hash = self :: makeConfigHash ( $config );
// If an existing config exists (with same class, mountpoint and options)
if ( isset ( $system [ $hash ])) {
// add the users into that config
$system [ $hash ][ 'applicable' ][ 'users' ]
= array_merge ( $system [ $hash ][ 'applicable' ][ 'users' ], array ( $user ));
2012-09-07 16:09:41 +04:00
} else {
2014-03-26 15:10:17 +04:00
$system [ $hash ] = $config ;
2012-09-07 16:09:41 +04:00
}
}
}
}
2014-03-26 15:10:17 +04:00
return array_values ( $system );
2012-09-07 16:09:41 +04:00
}
/**
* Get the personal mount points of the current user
* The returned array is not in the same format as getUserMountPoints ()
* @ return array
*/
public static function getPersonalMountPoints () {
$mountPoints = self :: readData ( true );
$backends = self :: getBackends ();
$uid = OCP\User :: getUser ();
$personal = array ();
if ( isset ( $mountPoints [ self :: MOUNT_TYPE_USER ][ $uid ])) {
foreach ( $mountPoints [ self :: MOUNT_TYPE_USER ][ $uid ] as $mountPoint => $mount ) {
2013-01-03 21:07:04 +04:00
// Update old classes to new namespace
if ( strpos ( $mount [ 'class' ], 'OC_Filestorage_' ) !== false ) {
2013-01-03 21:13:45 +04:00
$mount [ 'class' ] = '\OC\Files\Storage\\' . substr ( $mount [ 'class' ], 15 );
2013-01-03 21:07:04 +04:00
}
2014-03-19 00:15:11 +04:00
$mount [ 'options' ] = self :: decryptPasswords ( $mount [ 'options' ]);
2014-03-26 15:10:17 +04:00
$personal [] = array (
2012-12-24 22:45:52 +04:00
'class' => $mount [ 'class' ],
2014-03-26 15:10:17 +04:00
// Remove '/uid/files/' from mount point
'mountpoint' => substr ( $mountPoint , strlen ( $uid ) + 8 ),
2012-12-24 22:45:52 +04:00
'backend' => $backends [ $mount [ 'class' ]][ 'backend' ],
2014-03-26 15:10:17 +04:00
'options' => $mount [ 'options' ],
2014-03-26 15:04:13 +04:00
'status' => self :: getBackendStatus ( $mount [ 'class' ], $mount [ 'options' ], true )
2012-12-24 22:45:52 +04:00
);
2012-09-07 16:09:41 +04:00
}
}
return $personal ;
}
2014-03-19 15:20:48 +04:00
/**
* Test connecting using the given backend configuration
* @ param string $class backend class name
* @ param array $options backend configuration options
* @ return bool true if the connection succeeded , false otherwise
*/
2014-03-26 15:04:13 +04:00
private static function getBackendStatus ( $class , $options , $isPersonal ) {
2014-03-18 21:29:08 +04:00
if ( self :: $skipTest ) {
return true ;
}
2012-12-24 22:45:52 +04:00
foreach ( $options as & $option ) {
2014-03-19 15:20:48 +04:00
$option = self :: setUserVars ( OCP\User :: getUser (), $option );
2012-12-24 22:45:52 +04:00
}
if ( class_exists ( $class )) {
try {
2012-12-28 21:00:48 +04:00
$storage = new $class ( $options );
2014-03-26 15:04:13 +04:00
return $storage -> test ( $isPersonal );
2012-12-24 22:45:52 +04:00
} catch ( Exception $exception ) {
2013-12-02 19:55:43 +04:00
\OCP\Util :: logException ( 'files_external' , $exception );
2012-12-24 22:45:52 +04:00
return false ;
}
}
return false ;
}
2012-09-07 16:09:41 +04:00
/**
* Add a mount point to the filesystem
2014-02-08 14:47:55 +04:00
* @ param string $mountPoint Mount point
* @ param string $class Backend class
2012-09-07 16:09:41 +04:00
* @ param array Backend parameters for the class
2014-02-08 14:47:55 +04:00
* @ param string $mountType MOUNT_TYPE_GROUP | MOUNT_TYPE_USER
* @ param string $applicable User or group to apply mount to
2012-09-07 16:09:41 +04:00
* @ param bool Personal or system mount point i . e . is this being called from the personal or admin page
2014-02-08 14:47:55 +04:00
* @ return boolean
2012-09-07 16:09:41 +04:00
*/
2012-11-30 19:27:11 +04:00
public static function addMountPoint ( $mountPoint ,
$class ,
$classOptions ,
$mountType ,
$applicable ,
$isPersonal = false ) {
2014-02-19 22:08:28 +04:00
$backends = self :: getBackends ();
2013-11-21 20:21:51 +04:00
$mountPoint = OC\Files\Filesystem :: normalizePath ( $mountPoint );
2013-11-22 21:36:27 +04:00
if ( $mountPoint === '' || $mountPoint === '/' || $mountPoint == '/Shared' ) {
// can't mount at root or "Shared" folder
2013-11-21 20:21:51 +04:00
return false ;
}
2014-02-19 22:08:28 +04:00
if ( ! isset ( $backends [ $class ])) {
// invalid backend
return false ;
2014-02-18 19:36:02 +04:00
}
2012-09-07 16:09:41 +04:00
if ( $isPersonal ) {
// Verify that the mount point applies for the current user
2014-02-18 19:36:02 +04:00
// Prevent non-admin users from mounting local storage and other disabled backends
$allowed_backends = self :: getPersonalBackends ();
2014-03-18 20:54:14 +04:00
if ( $applicable != OCP\User :: getUser () || ! isset ( $allowed_backends [ $class ])) {
2012-09-07 16:09:41 +04:00
return false ;
}
$mountPoint = '/' . $applicable . '/files/' . ltrim ( $mountPoint , '/' );
} else {
$mountPoint = '/$user/files/' . ltrim ( $mountPoint , '/' );
}
2014-03-19 00:15:11 +04:00
$mount = array ( $applicable => array (
$mountPoint => array (
'class' => $class ,
'options' => self :: encryptPasswords ( $classOptions ))
)
);
2012-09-07 16:09:41 +04:00
$mountPoints = self :: readData ( $isPersonal );
// Merge the new mount point into the current mount points
if ( isset ( $mountPoints [ $mountType ])) {
if ( isset ( $mountPoints [ $mountType ][ $applicable ])) {
2012-11-30 19:27:11 +04:00
$mountPoints [ $mountType ][ $applicable ]
= array_merge ( $mountPoints [ $mountType ][ $applicable ], $mount [ $applicable ]);
2012-09-07 16:09:41 +04:00
} else {
$mountPoints [ $mountType ] = array_merge ( $mountPoints [ $mountType ], $mount );
}
} else {
$mountPoints [ $mountType ] = $mount ;
}
self :: writeData ( $isPersonal , $mountPoints );
2014-03-26 15:04:13 +04:00
return self :: getBackendStatus ( $class , $classOptions , $isPersonal );
2012-09-07 16:09:41 +04:00
}
/**
*
* @ param string Mount point
* @ param string MOUNT_TYPE_GROUP | MOUNT_TYPE_USER
* @ param string User or group to remove mount from
* @ param bool Personal or system mount point
* @ return bool
*/
public static function removeMountPoint ( $mountPoint , $mountType , $applicable , $isPersonal = false ) {
// Verify that the mount point applies for the current user
if ( $isPersonal ) {
if ( $applicable != OCP\User :: getUser ()) {
return false ;
}
$mountPoint = '/' . $applicable . '/files/' . ltrim ( $mountPoint , '/' );
} else {
$mountPoint = '/$user/files/' . ltrim ( $mountPoint , '/' );
}
$mountPoints = self :: readData ( $isPersonal );
// Remove mount point
unset ( $mountPoints [ $mountType ][ $applicable ][ $mountPoint ]);
// Unset parent arrays if empty
if ( empty ( $mountPoints [ $mountType ][ $applicable ])) {
unset ( $mountPoints [ $mountType ][ $applicable ]);
if ( empty ( $mountPoints [ $mountType ])) {
unset ( $mountPoints [ $mountType ]);
}
}
self :: writeData ( $isPersonal , $mountPoints );
return true ;
}
/**
* Read the mount points in the config file into an array
2014-02-08 14:47:55 +04:00
* @ param boolean $isPersonal Personal or system config file
2012-09-07 16:09:41 +04:00
* @ return array
*/
private static function readData ( $isPersonal ) {
2013-02-16 04:30:44 +04:00
$parser = new \OC\ArrayParser ();
2012-09-07 16:09:41 +04:00
if ( $isPersonal ) {
2013-02-16 04:50:40 +04:00
$phpFile = OC_User :: getHome ( OCP\User :: getUser ()) . '/mount.php' ;
$jsonFile = OC_User :: getHome ( OCP\User :: getUser ()) . '/mount.json' ;
2012-09-07 16:09:41 +04:00
} else {
2013-02-16 04:50:40 +04:00
$phpFile = OC :: $SERVERROOT . '/config/mount.php' ;
2014-02-24 13:35:24 +04:00
$datadir = \OC_Config :: getValue ( 'datadirectory' , \OC :: $SERVERROOT . '/data/' );
$jsonFile = \OC_Config :: getValue ( 'mount_file' , $datadir . '/mount.json' );
2012-09-07 16:09:41 +04:00
}
2013-02-16 04:50:40 +04:00
if ( is_file ( $jsonFile )) {
$mountPoints = json_decode ( file_get_contents ( $jsonFile ), true );
if ( is_array ( $mountPoints )) {
return $mountPoints ;
}
} elseif ( is_file ( $phpFile )) {
$mountPoints = $parser -> parsePHP ( file_get_contents ( $phpFile ));
2012-09-07 16:09:41 +04:00
if ( is_array ( $mountPoints )) {
return $mountPoints ;
}
}
return array ();
}
/**
* Write the mount points to the config file
* @ param bool Personal or system config file
* @ param array Mount points
2014-02-06 19:30:58 +04:00
* @ param boolean $isPersonal
2012-09-07 16:09:41 +04:00
*/
private static function writeData ( $isPersonal , $data ) {
if ( $isPersonal ) {
2013-02-16 04:50:40 +04:00
$file = OC_User :: getHome ( OCP\User :: getUser ()) . '/mount.json' ;
2012-09-07 16:09:41 +04:00
} else {
2014-02-24 13:35:24 +04:00
$datadir = \OC_Config :: getValue ( 'datadirectory' , \OC :: $SERVERROOT . '/data/' );
$file = \OC_Config :: getValue ( 'mount_file' , $datadir . '/mount.json' );
2012-09-07 16:09:41 +04:00
}
2014-03-26 14:29:04 +04:00
$options = 0 ;
if ( defined ( 'JSON_PRETTY_PRINT' )) {
// only for PHP >= 5.4
$options = JSON_PRETTY_PRINT ;
}
$content = json_encode ( $data , $options );
2012-09-07 16:09:41 +04:00
@ file_put_contents ( $file , $content );
2013-04-06 14:21:21 +04:00
@ chmod ( $file , 0640 );
2012-09-07 16:09:41 +04:00
}
/**
* Returns all user uploaded ssl root certificates
* @ return array
*/
public static function getCertificates () {
2013-12-17 13:13:14 +04:00
$path = OC_User :: getHome ( OC_User :: getUser ()) . '/files_external/uploads/' ;
2012-11-06 00:37:59 +04:00
\OCP\Util :: writeLog ( 'files_external' , 'checking path ' . $path , \OCP\Util :: INFO );
2012-11-30 19:27:11 +04:00
if ( ! is_dir ( $path )) {
2012-11-06 00:37:59 +04:00
//path might not exist (e.g. non-standard OC_User::getHome() value)
//in this case create full path using 3rd (recursive=true) parameter.
mkdir ( $path , 0777 , true );
}
2012-09-07 16:09:41 +04:00
$result = array ();
$handle = opendir ( $path );
2013-09-05 13:58:57 +04:00
if ( ! is_resource ( $handle )) {
2012-10-12 16:52:22 +04:00
return array ();
}
2012-09-07 16:09:41 +04:00
while ( false !== ( $file = readdir ( $handle ))) {
2012-11-30 19:27:11 +04:00
if ( $file != '.' && $file != '..' ) $result [] = $file ;
2012-09-07 16:09:41 +04:00
}
return $result ;
}
/**
* creates certificate bundle
*/
public static function createCertificateBundle () {
2013-12-17 13:13:14 +04:00
$path = OC_User :: getHome ( OC_User :: getUser ()) . '/files_external' ;
2012-09-07 16:09:41 +04:00
$certs = OC_Mount_Config :: getCertificates ();
$fh_certs = fopen ( $path . " /rootcerts.crt " , 'w' );
foreach ( $certs as $cert ) {
$file = $path . '/uploads/' . $cert ;
$fh = fopen ( $file , " r " );
$data = fread ( $fh , filesize ( $file ));
fclose ( $fh );
if ( strpos ( $data , 'BEGIN CERTIFICATE' )) {
fwrite ( $fh_certs , $data );
2012-09-21 18:54:08 +04:00
fwrite ( $fh_certs , " \r \n " );
2012-09-07 16:09:41 +04:00
}
}
fclose ( $fh_certs );
return true ;
}
2012-12-11 00:10:28 +04:00
/**
2013-01-14 23:30:39 +04:00
* check if smbclient is installed
2012-12-11 00:10:28 +04:00
*/
public static function checksmbclient () {
2012-12-11 16:20:20 +04:00
if ( function_exists ( 'shell_exec' )) {
2014-02-21 16:45:57 +04:00
$output = shell_exec ( 'command -v smbclient 2> /dev/null' );
2013-08-17 14:58:10 +04:00
return ! empty ( $output );
2012-12-11 16:20:20 +04:00
} else {
2013-08-17 14:58:10 +04:00
return false ;
2012-12-11 16:20:20 +04:00
}
2012-12-11 00:10:28 +04:00
}
/**
2013-02-22 20:21:57 +04:00
* check if php - ftp is installed
2012-12-11 00:10:28 +04:00
*/
public static function checkphpftp () {
if ( function_exists ( 'ftp_login' )) {
2013-08-17 14:58:10 +04:00
return true ;
2012-12-11 00:10:28 +04:00
} else {
2013-08-17 14:58:10 +04:00
return false ;
2012-12-11 00:10:28 +04:00
}
}
2013-04-23 14:36:30 +04:00
/**
* check if curl is installed
*/
public static function checkcurl () {
2013-08-17 14:58:10 +04:00
return function_exists ( 'curl_init' );
2013-04-23 14:36:30 +04:00
}
2012-12-11 00:10:28 +04:00
/**
* check dependencies
*/
public static function checkDependencies () {
2012-12-11 17:07:01 +04:00
$l = new OC_L10N ( 'files_external' );
2012-12-11 00:10:28 +04:00
$txt = '' ;
2013-08-15 14:00:02 +04:00
if ( ! OC_Util :: runningOnWindows ()) {
if ( ! OC_Mount_Config :: checksmbclient ()) {
$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 />' ;
}
2013-02-14 20:57:19 +04:00
}
if ( ! OC_Mount_Config :: checkphpftp ()) {
2013-02-15 18:54:51 +04:00
$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 />' ;
2013-02-14 20:57:19 +04:00
}
2013-04-23 14:36:30 +04:00
if ( ! OC_Mount_Config :: checkcurl ()) {
$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 />' ;
}
2012-12-11 00:10:28 +04:00
2013-08-17 14:58:10 +04:00
return $txt ;
2012-12-11 00:10:28 +04:00
}
2014-03-19 00:15:11 +04:00
/**
* Encrypt passwords in the given config options
* @ param array $options mount options
* @ return array updated options
*/
private static function encryptPasswords ( $options ) {
if ( isset ( $options [ 'password' ])) {
2014-03-19 14:42:22 +04:00
$options [ 'password_encrypted' ] = self :: encryptPassword ( $options [ 'password' ]);
2014-03-19 20:56:36 +04:00
// do not unset the password, we want to keep the keys order
// on load... because that's how the UI currently works
$options [ 'password' ] = '' ;
2014-03-19 00:15:11 +04:00
}
return $options ;
}
/**
* Decrypt passwords in the given config options
* @ param array $options mount options
* @ return array updated options
*/
private static function decryptPasswords ( $options ) {
// note: legacy options might still have the unencrypted password in the "password" field
if ( isset ( $options [ 'password_encrypted' ])) {
2014-03-19 14:42:22 +04:00
$options [ 'password' ] = self :: decryptPassword ( $options [ 'password_encrypted' ]);
2014-03-19 00:15:11 +04:00
unset ( $options [ 'password_encrypted' ]);
}
return $options ;
}
2014-03-19 14:42:22 +04:00
/**
* Encrypt a single password
* @ param string $password plain text password
* @ return encrypted password
*/
private static function encryptPassword ( $password ) {
$cipher = self :: getCipher ();
$iv = \OCP\Util :: generateRandomBytes ( 16 );
$cipher -> setIV ( $iv );
return base64_encode ( $iv . $cipher -> encrypt ( $password ));
}
/**
* Decrypts a single password
* @ param string $encryptedPassword encrypted password
* @ return plain text password
*/
private static function decryptPassword ( $encryptedPassword ) {
$cipher = self :: getCipher ();
$binaryPassword = base64_decode ( $encryptedPassword );
$iv = substr ( $binaryPassword , 0 , 16 );
$cipher -> setIV ( $iv );
$binaryPassword = substr ( $binaryPassword , 16 );
return $cipher -> decrypt ( $binaryPassword );
}
2014-03-19 00:15:11 +04:00
/**
* Returns the encryption cipher
*/
private static function getCipher () {
2014-03-20 16:21:34 +04:00
if ( ! class_exists ( 'Crypt_AES' , false )) {
include ( 'Crypt/AES.php' );
}
2014-03-19 14:42:22 +04:00
$cipher = new Crypt_AES ( CRYPT_AES_MODE_CBC );
$cipher -> setKey ( \OCP\Config :: getSystemValue ( 'passwordsalt' ));
return $cipher ;
2014-03-19 00:15:11 +04:00
}
2014-03-26 15:10:17 +04:00
/**
* Computes a hash based on the given configuration .
* This is mostly used to find out whether configurations
* are the same .
*/
private static function makeConfigHash ( $config ) {
$data = json_encode (
array (
'c' => $config [ 'class' ],
'm' => $config [ 'mountpoint' ],
'o' => $config [ 'options' ]
)
);
return hash ( 'md5' , $data );
}
2012-09-07 16:09:41 +04:00
}