2013-10-28 19:22:06 +00:00
< ? php
2015-03-26 10:44:34 +00:00
/**
2016-07-21 14:49:16 +00:00
* @ copyright Copyright ( c ) 2016 , ownCloud , Inc .
*
2015-03-26 10:44:34 +00:00
* @ author Bart Visscher < bartv @ thisnet . nl >
2016-05-26 17:56:05 +00:00
* @ author Björn Schießle < bjoern @ schiessle . org >
2016-07-21 14:49:16 +00:00
* @ author Joas Schilling < coding @ schilljs . com >
2016-05-26 17:56:05 +00:00
* @ author Lukas Reschke < lukas @ statuscode . ch >
2015-03-26 10:44:34 +00:00
* @ author Morris Jobke < hey @ morrisjobke . de >
2016-07-21 16:13:36 +00:00
* @ author Robin Appelman < robin @ icewind . nl >
2016-07-21 14:49:16 +00:00
* @ author Roeland Jago Douma < roeland @ famdouma . nl >
2015-03-26 10:44:34 +00:00
* @ author Vincent Petry < pvince81 @ owncloud . com >
*
* @ license AGPL - 3.0
*
* This code is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License , version 3 ,
* as published by the Free Software Foundation .
*
* This program 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 , version 3 ,
* along with this program . If not , see < http :// www . gnu . org / licenses />
*
*/
2013-10-28 19:22:06 +00:00
namespace OCA\Files_Sharing ;
2015-12-10 13:14:54 +00:00
use OC\Files\Filesystem ;
2016-02-18 08:57:29 +00:00
use OC\Files\View ;
2015-06-15 12:10:10 +00:00
use OCP\Files\NotFoundException ;
2016-07-18 07:21:10 +00:00
use OCP\Share\Exceptions\ShareNotFound ;
2016-02-18 08:57:29 +00:00
use OCP\User ;
2015-06-15 12:10:10 +00:00
2013-10-28 19:22:06 +00:00
class Helper {
2014-06-25 13:20:52 +00:00
public static function registerHooks () {
2016-05-02 13:16:20 +00:00
\OCP\Util :: connectHook ( 'OC_Filesystem' , 'post_rename' , '\OCA\Files_Sharing\Updater' , 'renameHook' );
2015-03-18 14:26:04 +00:00
\OCP\Util :: connectHook ( 'OC_Filesystem' , 'post_delete' , '\OCA\Files_Sharing\Hooks' , 'unshareChildren' );
2014-06-25 13:20:52 +00:00
2015-01-20 23:11:15 +00:00
\OCP\Util :: connectHook ( 'OC_User' , 'post_deleteUser' , '\OCA\Files_Sharing\Hooks' , 'deleteUser' );
2014-06-25 13:20:52 +00:00
}
2013-10-28 19:22:06 +00:00
/**
* Sets up the filesystem and user for public sharing
* @ param string $token string share token
* @ param string $relativePath optional path relative to the share
* @ param string $password optional password
2015-06-15 12:10:10 +00:00
* @ return array
2013-10-28 19:22:06 +00:00
*/
public static function setupFromToken ( $token , $relativePath = null , $password = null ) {
\OC_User :: setIncognitoMode ( true );
2016-07-18 07:21:10 +00:00
$shareManager = \OC :: $server -> getShareManager ();
try {
$share = $shareManager -> getShareByToken ( $token );
} catch ( ShareNotFound $e ) {
2013-10-28 19:22:06 +00:00
\OC_Response :: setStatus ( 404 );
2015-04-09 10:36:10 +00:00
\OCP\Util :: writeLog ( 'core-preview' , 'Passed token parameter is not valid' , \OCP\Util :: DEBUG );
2013-10-28 19:22:06 +00:00
exit ;
}
2016-07-18 07:21:10 +00:00
\OCP\JSON :: checkUserExists ( $share -> getShareOwner ());
\OC_Util :: tearDownFS ();
\OC_Util :: setupFS ( $share -> getShareOwner ());
2013-10-28 19:22:06 +00:00
2015-06-15 12:10:10 +00:00
try {
2016-07-18 07:21:10 +00:00
$path = Filesystem :: getPath ( $share -> getNodeId ());
2015-06-15 12:10:10 +00:00
} catch ( NotFoundException $e ) {
2013-10-28 19:22:06 +00:00
\OCP\Util :: writeLog ( 'share' , 'could not resolve linkItem' , \OCP\Util :: DEBUG );
\OC_Response :: setStatus ( 404 );
\OCP\JSON :: error ( array ( 'success' => false ));
exit ();
}
2016-07-18 07:21:10 +00:00
if ( $share -> getShareType () === \OCP\Share :: SHARE_TYPE_LINK && $share -> getPassword () !== null ) {
if ( ! self :: authenticate ( $share , $password )) {
2013-10-28 19:22:06 +00:00
\OC_Response :: setStatus ( 403 );
\OCP\JSON :: error ( array ( 'success' => false ));
exit ();
}
}
$basePath = $path ;
2016-02-18 08:57:29 +00:00
if ( $relativePath !== null && Filesystem :: isReadable ( $basePath . $relativePath )) {
$path .= Filesystem :: normalizePath ( $relativePath );
2013-10-28 19:22:06 +00:00
}
return array (
2016-07-18 07:21:10 +00:00
'share' => $share ,
2013-10-28 19:22:06 +00:00
'basePath' => $basePath ,
'realPath' => $path
);
}
/**
* Authenticate link item with the given password
* or with the session if no password was given .
2016-07-18 07:21:10 +00:00
* @ param \OCP\Share\IShare $share
2013-10-28 19:22:06 +00:00
* @ param string $password optional password
*
2014-04-14 15:49:27 +00:00
* @ return boolean true if authorized , false otherwise
2013-10-28 19:22:06 +00:00
*/
2016-07-18 07:21:10 +00:00
public static function authenticate ( $share , $password = null ) {
$shareManager = \OC :: $server -> getShareManager ();
2013-10-28 19:22:06 +00:00
if ( $password !== null ) {
2016-07-18 07:21:10 +00:00
if ( $share -> getShareType () === \OCP\Share :: SHARE_TYPE_LINK ) {
if ( $shareManager -> checkPassword ( $share , $password )) {
\OC :: $server -> getSession () -> set ( 'public_link_authenticated' , ( string ) $share -> getId ());
return true ;
2013-10-28 19:22:06 +00:00
}
}
2016-07-18 07:21:10 +00:00
} else {
2013-10-28 19:22:06 +00:00
// not authenticated ?
2016-07-18 07:21:10 +00:00
if ( \OC :: $server -> getSession () -> exists ( 'public_link_authenticated' )
&& \OC :: $server -> getSession () -> get ( 'public_link_authenticated' ) !== ( string ) $share -> getId ()) {
return true ;
2013-10-28 19:22:06 +00:00
}
}
2016-07-18 07:21:10 +00:00
return false ;
2013-10-28 19:22:06 +00:00
}
2014-04-14 15:08:46 +00:00
public static function getSharesFromItem ( $target ) {
$result = array ();
2016-02-18 08:57:29 +00:00
$owner = Filesystem :: getOwner ( $target );
Filesystem :: initMountPoints ( $owner );
$info = Filesystem :: getFileInfo ( $target );
$ownerView = new View ( '/' . $owner . '/files' );
if ( $owner != User :: getUser () ) {
2014-04-14 15:08:46 +00:00
$path = $ownerView -> getPath ( $info [ 'fileid' ]);
} else {
$path = $target ;
}
$ids = array ();
2014-05-07 15:37:49 +00:00
while ( $path !== dirname ( $path )) {
2014-04-14 15:08:46 +00:00
$info = $ownerView -> getFileInfo ( $path );
2014-05-07 09:47:52 +00:00
if ( $info instanceof \OC\Files\FileInfo ) {
$ids [] = $info [ 'fileid' ];
} else {
\OCP\Util :: writeLog ( 'sharing' , 'No fileinfo available for: ' . $path , \OCP\Util :: WARN );
}
2014-04-14 15:08:46 +00:00
$path = dirname ( $path );
}
if ( ! empty ( $ids )) {
$idList = array_chunk ( $ids , 99 , true );
foreach ( $idList as $subList ) {
$statement = " SELECT `share_with`, `share_type`, `file_target` FROM `*PREFIX*share` WHERE `file_source` IN ( " . implode ( ',' , $subList ) . " ) AND `share_type` IN (0, 1, 2) " ;
$query = \OCP\DB :: prepare ( $statement );
$r = $query -> execute ();
$result = array_merge ( $result , $r -> fetchAll ());
}
}
return $result ;
}
2014-04-16 14:41:23 +00:00
2016-02-18 08:57:29 +00:00
/**
* get the UID of the owner of the file and the path to the file relative to
* owners files folder
*
* @ param $filename
* @ return array
* @ throws \OC\User\NoUserException
*/
2014-04-16 14:41:23 +00:00
public static function getUidAndFilename ( $filename ) {
2016-02-18 08:57:29 +00:00
$uid = Filesystem :: getOwner ( $filename );
$userManager = \OC :: $server -> getUserManager ();
// if the user with the UID doesn't exists, e.g. because the UID points
// to a remote user with a federated cloud ID we use the current logged-in
// user. We need a valid local user to create the share
if ( ! $userManager -> userExists ( $uid )) {
$uid = User :: getUser ();
}
Filesystem :: initMountPoints ( $uid );
if ( $uid != User :: getUser () ) {
$info = Filesystem :: getFileInfo ( $filename );
$ownerView = new View ( '/' . $uid . '/files' );
try {
$filename = $ownerView -> getPath ( $info [ 'fileid' ]);
} catch ( NotFoundException $e ) {
$filename = null ;
}
}
return [ $uid , $filename ];
2014-04-16 14:41:23 +00:00
}
/**
2014-05-19 15:50:53 +00:00
* Format a path to be relative to the / user / files / directory
2014-04-16 14:41:23 +00:00
* @ param string $path the absolute path
* @ return string e . g . turns '/admin/files/test.txt' into 'test.txt'
*/
public static function stripUserFilesPath ( $path ) {
$trimmed = ltrim ( $path , '/' );
$split = explode ( '/' , $trimmed );
// it is not a file relative to data/user/files
if ( count ( $split ) < 3 || $split [ 1 ] !== 'files' ) {
return false ;
}
$sliced = array_slice ( $split , 2 );
$relPath = implode ( '/' , $sliced );
return $relPath ;
}
2014-04-30 14:56:09 +00:00
/**
* check if file name already exists and generate unique target
*
* @ param string $path
* @ param array $excludeList
2016-02-18 08:57:29 +00:00
* @ param View $view
2014-04-30 14:56:09 +00:00
* @ return string $path
*/
public static function generateUniqueTarget ( $path , $excludeList , $view ) {
$pathinfo = pathinfo ( $path );
$ext = ( isset ( $pathinfo [ 'extension' ])) ? '.' . $pathinfo [ 'extension' ] : '' ;
$name = $pathinfo [ 'filename' ];
$dir = $pathinfo [ 'dirname' ];
$i = 2 ;
while ( $view -> file_exists ( $path ) || in_array ( $path , $excludeList )) {
2016-02-18 08:57:29 +00:00
$path = Filesystem :: normalizePath ( $dir . '/' . $name . ' (' . $i . ')' . $ext );
2014-04-30 14:56:09 +00:00
$i ++ ;
}
return $path ;
}
2014-06-12 17:49:52 +00:00
2014-08-13 10:55:14 +00:00
/**
* get default share folder
*
2016-06-17 09:11:59 +00:00
* @ param \OC\Files\View
2014-08-13 10:55:14 +00:00
* @ return string
*/
2016-06-17 09:11:59 +00:00
public static function getShareFolder ( $view = null ) {
if ( $view === null ) {
$view = Filesystem :: getView ();
}
2014-12-17 10:12:37 +00:00
$shareFolder = \OC :: $server -> getConfig () -> getSystemValue ( 'share_folder' , '/' );
2016-02-18 08:57:29 +00:00
$shareFolder = Filesystem :: normalizePath ( $shareFolder );
2015-03-26 20:56:44 +00:00
2016-06-17 09:11:59 +00:00
if ( ! $view -> file_exists ( $shareFolder )) {
2015-03-26 20:56:44 +00:00
$dir = '' ;
$subdirs = explode ( '/' , $shareFolder );
foreach ( $subdirs as $subdir ) {
$dir = $dir . '/' . $subdir ;
2016-06-17 09:11:59 +00:00
if ( ! $view -> is_dir ( $dir )) {
$view -> mkdir ( $dir );
2015-03-26 20:56:44 +00:00
}
}
}
return $shareFolder ;
2014-08-13 10:55:14 +00:00
}
/**
* set default share folder
*
* @ param string $shareFolder
*/
public static function setShareFolder ( $shareFolder ) {
2014-12-17 10:12:37 +00:00
\OC :: $server -> getConfig () -> setSystemValue ( 'share_folder' , $shareFolder );
2014-08-13 10:55:14 +00:00
}
2013-10-28 19:22:06 +00:00
}