2015-10-30 15:10:08 +03:00
< ? php
/**
* @ author Roeland Jago Douma < rullzer @ owncloud . com >
*
2016-01-12 17:02:16 +03:00
* @ copyright Copyright ( c ) 2016 , ownCloud , Inc .
2015-10-30 15:10:08 +03:00
* @ 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 />
*
*/
namespace OCA\Files_Sharing\API ;
2016-02-16 18:04:17 +03:00
use OCP\Files\NotFoundException ;
2015-11-24 11:37:17 +03:00
use OCP\IGroupManager ;
2016-04-15 15:05:36 +03:00
use OCP\IL10N ;
2015-11-24 11:37:17 +03:00
use OCP\IUserManager ;
use OCP\IRequest ;
use OCP\IURLGenerator ;
use OCP\IUser ;
2015-11-24 12:16:02 +03:00
use OCP\Files\IRootFolder ;
2016-03-09 11:11:41 +03:00
use OCP\Lock\LockedException ;
2016-02-04 12:01:40 +03:00
use OCP\Share ;
2016-02-03 10:14:48 +03:00
use OCP\Share\IManager ;
2016-02-02 16:18:59 +03:00
use OCP\Share\Exceptions\ShareNotFound ;
use OCP\Share\Exceptions\GenericShareException ;
2016-03-17 13:09:11 +03:00
use OCP\Lock\ILockingProvider ;
2016-02-02 16:18:59 +03:00
2016-03-07 18:12:40 +03:00
/**
* Class Share20OCS
*
* @ package OCA\Files_Sharing\API
*/
2015-10-30 15:10:08 +03:00
class Share20OCS {
2016-02-03 10:14:48 +03:00
/** @var IManager */
2015-10-30 15:10:08 +03:00
private $shareManager ;
2015-11-24 11:37:17 +03:00
/** @var IGroupManager */
2015-10-30 15:10:08 +03:00
private $groupManager ;
2015-11-24 11:37:17 +03:00
/** @var IUserManager */
2015-10-30 15:10:08 +03:00
private $userManager ;
2015-11-24 11:37:17 +03:00
/** @var IRequest */
2015-10-30 15:10:08 +03:00
private $request ;
2015-11-24 12:16:02 +03:00
/** @var IRootFolder */
private $rootFolder ;
2016-03-10 23:35:22 +03:00
/** @var IURLGenerator */
2015-11-24 11:37:17 +03:00
private $urlGenerator ;
/** @var IUser */
private $currentUser ;
2016-04-15 15:05:36 +03:00
/** @var IL10N */
private $l ;
2015-11-24 11:37:17 +03:00
2016-02-03 10:14:48 +03:00
/**
* Share20OCS constructor .
*
* @ param IManager $shareManager
* @ param IGroupManager $groupManager
* @ param IUserManager $userManager
* @ param IRequest $request
* @ param IRootFolder $rootFolder
* @ param IURLGenerator $urlGenerator
* @ param IUser $currentUser
*/
2015-11-24 11:37:17 +03:00
public function __construct (
2016-02-03 10:14:48 +03:00
IManager $shareManager ,
2015-11-24 11:58:37 +03:00
IGroupManager $groupManager ,
IUserManager $userManager ,
IRequest $request ,
2015-11-24 12:16:02 +03:00
IRootFolder $rootFolder ,
2015-11-24 11:58:37 +03:00
IURLGenerator $urlGenerator ,
2016-04-15 15:05:36 +03:00
IUser $currentUser ,
IL10N $l10n
2015-11-24 11:37:17 +03:00
) {
2015-10-30 15:10:08 +03:00
$this -> shareManager = $shareManager ;
$this -> userManager = $userManager ;
$this -> groupManager = $groupManager ;
$this -> request = $request ;
2015-11-24 12:16:02 +03:00
$this -> rootFolder = $rootFolder ;
2015-11-06 14:05:19 +03:00
$this -> urlGenerator = $urlGenerator ;
2015-11-24 11:37:17 +03:00
$this -> currentUser = $currentUser ;
2016-04-15 15:05:36 +03:00
$this -> l = $l10n ;
2015-11-06 14:05:19 +03:00
}
/**
* Convert an IShare to an array for OCS output
*
2016-01-27 14:13:53 +03:00
* @ param \OCP\Share\IShare $share
2015-11-06 14:05:19 +03:00
* @ return array
2016-02-16 18:04:17 +03:00
* @ throws NotFoundException In case the node can ' t be resolved .
2015-11-06 14:05:19 +03:00
*/
2016-01-27 14:13:53 +03:00
protected function formatShare ( \OCP\Share\IShare $share ) {
2016-02-03 10:14:48 +03:00
$sharedBy = $this -> userManager -> get ( $share -> getSharedBy ());
2016-05-11 21:48:27 +03:00
// for federated shares the owner can be a remote user, in this
// case we use the initiator
if ( $this -> userManager -> userExists ( $share -> getShareOwner ())) {
$shareOwner = $this -> userManager -> get ( $share -> getShareOwner ());
$localUser = $share -> getShareOwner ();
} else {
$shareOwner = $this -> userManager -> get ( $share -> getSharedBy ());
$localUser = $share -> getSharedBy ();
}
2015-11-06 14:05:19 +03:00
$result = [
'id' => $share -> getId (),
'share_type' => $share -> getShareType (),
2016-02-03 10:14:48 +03:00
'uid_owner' => $share -> getSharedBy (),
2016-02-11 23:17:22 +03:00
'displayname_owner' => $sharedBy !== null ? $sharedBy -> getDisplayName () : $share -> getSharedBy (),
2015-11-06 14:05:19 +03:00
'permissions' => $share -> getPermissions (),
2016-01-27 22:51:26 +03:00
'stime' => $share -> getShareTime () -> getTimestamp (),
'parent' => null ,
2015-11-06 14:05:19 +03:00
'expiration' => null ,
'token' => null ,
2016-02-03 10:14:48 +03:00
'uid_file_owner' => $share -> getShareOwner (),
2016-02-12 12:44:34 +03:00
'displayname_file_owner' => $shareOwner !== null ? $shareOwner -> getDisplayName () : $share -> getShareOwner (),
2015-11-06 14:05:19 +03:00
];
2016-01-27 22:51:26 +03:00
$node = $share -> getNode ();
2016-05-11 21:48:27 +03:00
$result [ 'path' ] = $this -> rootFolder -> getUserFolder ( $localUser ) -> getRelativePath ( $node -> getPath ());
2016-01-27 22:51:26 +03:00
if ( $node instanceOf \OCP\Files\Folder ) {
2015-11-06 14:05:19 +03:00
$result [ 'item_type' ] = 'folder' ;
} else {
$result [ 'item_type' ] = 'file' ;
}
2016-03-09 22:20:37 +03:00
$result [ 'mimetype' ] = $node -> getMimeType ();
2016-01-27 22:51:26 +03:00
$result [ 'storage_id' ] = $node -> getStorage () -> getId ();
$result [ 'storage' ] = $node -> getStorage () -> getCache () -> getNumericStorageId ();
$result [ 'item_source' ] = $node -> getId ();
$result [ 'file_source' ] = $node -> getId ();
$result [ 'file_parent' ] = $node -> getParent () -> getId ();
2015-11-06 14:05:19 +03:00
$result [ 'file_target' ] = $share -> getTarget ();
if ( $share -> getShareType () === \OCP\Share :: SHARE_TYPE_USER ) {
2016-02-03 10:14:48 +03:00
$sharedWith = $this -> userManager -> get ( $share -> getSharedWith ());
2016-02-12 12:44:34 +03:00
$result [ 'share_with' ] = $share -> getSharedWith ();
$result [ 'share_with_displayname' ] = $sharedWith !== null ? $sharedWith -> getDisplayName () : $share -> getSharedWith ();
2015-11-06 14:05:19 +03:00
} else if ( $share -> getShareType () === \OCP\Share :: SHARE_TYPE_GROUP ) {
2016-02-03 10:14:48 +03:00
$result [ 'share_with' ] = $share -> getSharedWith ();
$result [ 'share_with_displayname' ] = $share -> getSharedWith ();
2015-11-06 14:05:19 +03:00
} else if ( $share -> getShareType () === \OCP\Share :: SHARE_TYPE_LINK ) {
$result [ 'share_with' ] = $share -> getPassword ();
$result [ 'share_with_displayname' ] = $share -> getPassword ();
$result [ 'token' ] = $share -> getToken ();
$result [ 'url' ] = $this -> urlGenerator -> linkToRouteAbsolute ( 'files_sharing.sharecontroller.showShare' , [ 'token' => $share -> getToken ()]);
$expiration = $share -> getExpirationDate ();
if ( $expiration !== null ) {
$result [ 'expiration' ] = $expiration -> format ( 'Y-m-d 00:00:00' );
}
} else if ( $share -> getShareType () === \OCP\Share :: SHARE_TYPE_REMOTE ) {
$result [ 'share_with' ] = $share -> getSharedWith ();
$result [ 'share_with_displayname' ] = $share -> getSharedWith ();
$result [ 'token' ] = $share -> getToken ();
}
$result [ 'mail_send' ] = $share -> getMailSend () ? 1 : 0 ;
return $result ;
}
/**
* Get a specific share by id
*
* @ param string $id
* @ return \OC_OCS_Result
*/
public function getShare ( $id ) {
2016-02-26 16:58:41 +03:00
if ( ! $this -> shareManager -> shareApiEnabled ()) {
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Share API is disabled' ));
2016-02-26 16:58:41 +03:00
}
2015-11-06 14:05:19 +03:00
try {
2016-03-07 18:10:27 +03:00
$share = $this -> getShareById ( $id );
2016-02-02 16:18:59 +03:00
} catch ( ShareNotFound $e ) {
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Wrong share ID, share doesn\'t exist' ));
2015-11-06 14:05:19 +03:00
}
2015-11-24 11:37:17 +03:00
if ( $this -> canAccessShare ( $share )) {
2016-02-16 18:04:17 +03:00
try {
$share = $this -> formatShare ( $share );
return new \OC_OCS_Result ([ $share ]);
} catch ( NotFoundException $e ) {
//Fall trough
}
2015-11-24 11:37:17 +03:00
}
2016-02-16 18:04:17 +03:00
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Wrong share ID, share doesn\'t exist' ));
2015-10-30 15:10:08 +03:00
}
/**
* Delete a share
*
2015-11-06 14:05:19 +03:00
* @ param string $id
2015-10-30 15:10:08 +03:00
* @ return \OC_OCS_Result
*/
public function deleteShare ( $id ) {
2016-02-26 16:58:41 +03:00
if ( ! $this -> shareManager -> shareApiEnabled ()) {
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Share API is disabled' ));
2016-02-26 16:58:41 +03:00
}
2015-10-30 15:10:08 +03:00
try {
2016-03-07 18:10:27 +03:00
$share = $this -> getShareById ( $id );
2016-02-02 16:18:59 +03:00
} catch ( ShareNotFound $e ) {
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Wrong share ID, share doesn\'t exist' ));
2015-11-02 21:49:39 +03:00
}
2016-03-09 11:11:41 +03:00
try {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> lock ( ILockingProvider :: LOCK_SHARED );
2016-03-09 11:11:41 +03:00
} catch ( LockedException $e ) {
return new \OC_OCS_Result ( null , 404 , 'could not delete share' );
}
2015-11-24 11:37:17 +03:00
if ( ! $this -> canAccessShare ( $share )) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Could not delete share' ));
2015-11-24 11:37:17 +03:00
}
2016-02-02 16:18:59 +03:00
$this -> shareManager -> deleteShare ( $share );
2015-10-30 15:10:08 +03:00
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-03-09 11:11:41 +03:00
2015-10-30 15:10:08 +03:00
return new \OC_OCS_Result ();
}
2015-11-24 11:37:17 +03:00
2015-12-15 11:54:50 +03:00
/**
* @ return \OC_OCS_Result
*/
public function createShare () {
$share = $this -> shareManager -> newShare ();
2016-02-26 16:58:41 +03:00
if ( ! $this -> shareManager -> shareApiEnabled ()) {
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Share API is disabled' ));
2016-02-26 16:58:41 +03:00
}
2015-12-15 11:54:50 +03:00
// Verify path
$path = $this -> request -> getParam ( 'path' , null );
if ( $path === null ) {
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Please specify a file or folder path' ));
2015-12-15 11:54:50 +03:00
}
$userFolder = $this -> rootFolder -> getUserFolder ( $this -> currentUser -> getUID ());
try {
$path = $userFolder -> get ( $path );
2016-03-17 13:09:11 +03:00
} catch ( NotFoundException $e ) {
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Wrong path, file/folder doesn\'t exist' ));
2015-12-15 11:54:50 +03:00
}
2016-01-27 22:51:26 +03:00
$share -> setNode ( $path );
2016-03-17 13:09:11 +03:00
try {
$share -> getNode () -> lock ( ILockingProvider :: LOCK_SHARED );
} catch ( LockedException $e ) {
return new \OC_OCS_Result ( null , 404 , 'Could not create share' );
}
2015-12-15 11:54:50 +03:00
// Parse permissions (if available)
$permissions = $this -> request -> getParam ( 'permissions' , null );
if ( $permissions === null ) {
$permissions = \OCP\Constants :: PERMISSION_ALL ;
} else {
$permissions = ( int ) $permissions ;
}
if ( $permissions < 0 || $permissions > \OCP\Constants :: PERMISSION_ALL ) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2015-12-15 11:54:50 +03:00
return new \OC_OCS_Result ( null , 404 , 'invalid permissions' );
}
// Shares always require read permissions
$permissions |= \OCP\Constants :: PERMISSION_READ ;
if ( $path instanceof \OCP\Files\File ) {
// Single file shares should never have delete or create permissions
$permissions &= ~ \OCP\Constants :: PERMISSION_DELETE ;
$permissions &= ~ \OCP\Constants :: PERMISSION_CREATE ;
}
2016-02-25 12:30:03 +03:00
/*
* Hack for https :// github . com / owncloud / core / issues / 22587
* We check the permissions via webdav . But the permissions of the mount point
* do not equal the share permissions . Here we fix that for federated mounts .
*/
if ( $path -> getStorage () -> instanceOfStorage ( 'OCA\Files_Sharing\External\Storage' )) {
$permissions &= ~ ( $permissions & ~ $path -> getPermissions ());
}
2015-12-15 11:54:50 +03:00
$shareWith = $this -> request -> getParam ( 'shareWith' , null );
$shareType = ( int ) $this -> request -> getParam ( 'shareType' , '-1' );
if ( $shareType === \OCP\Share :: SHARE_TYPE_USER ) {
// Valid user is required to share
if ( $shareWith === null || ! $this -> userManager -> userExists ( $shareWith )) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Please specify a valid user' ));
2015-12-15 11:54:50 +03:00
}
2016-02-03 10:14:48 +03:00
$share -> setSharedWith ( $shareWith );
2015-12-15 11:54:50 +03:00
$share -> setPermissions ( $permissions );
} else if ( $shareType === \OCP\Share :: SHARE_TYPE_GROUP ) {
2016-03-18 18:36:27 +03:00
if ( ! $this -> shareManager -> allowGroupSharing ()) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Group sharing is disabled by the administrator' ));
2016-03-18 18:36:27 +03:00
}
2015-12-15 11:54:50 +03:00
// Valid group is required to share
if ( $shareWith === null || ! $this -> groupManager -> groupExists ( $shareWith )) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Please specify a valid group' ));
2015-12-15 11:54:50 +03:00
}
2016-02-03 10:14:48 +03:00
$share -> setSharedWith ( $shareWith );
2015-12-15 11:54:50 +03:00
$share -> setPermissions ( $permissions );
} else if ( $shareType === \OCP\Share :: SHARE_TYPE_LINK ) {
//Can we even share links?
if ( ! $this -> shareManager -> shareApiAllowLinks ()) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Public link sharing is disabled by the administrator' ));
2015-12-15 11:54:50 +03:00
}
2016-02-28 23:24:23 +03:00
/*
* For now we only allow 1 link share .
* Return the existing link share if this is a duplicate
*/
$existingShares = $this -> shareManager -> getSharesBy ( $this -> currentUser -> getUID (), \OCP\Share :: SHARE_TYPE_LINK , $path , false , 1 , 0 );
if ( ! empty ( $existingShares )) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-02-28 23:24:23 +03:00
return new \OC_OCS_Result ( $this -> formatShare ( $existingShares [ 0 ]));
}
2015-12-15 11:54:50 +03:00
$publicUpload = $this -> request -> getParam ( 'publicUpload' , null );
if ( $publicUpload === 'true' ) {
// Check if public upload is allowed
if ( ! $this -> shareManager -> shareApiLinkAllowPublicUpload ()) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 403 , $this -> l -> t ( 'Public upload disabled by the administrator' ));
2015-12-15 11:54:50 +03:00
}
// Public upload can only be set for folders
if ( $path instanceof \OCP\Files\File ) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Public upload is only possible for publicly shared folders' ));
2015-12-15 11:54:50 +03:00
}
$share -> setPermissions (
2016-01-05 14:50:00 +03:00
\OCP\Constants :: PERMISSION_READ |
\OCP\Constants :: PERMISSION_CREATE |
\OCP\Constants :: PERMISSION_UPDATE
2015-12-15 11:54:50 +03:00
);
} else {
$share -> setPermissions ( \OCP\Constants :: PERMISSION_READ );
}
// Set password
2016-01-27 17:42:11 +03:00
$password = $this -> request -> getParam ( 'password' , '' );
if ( $password !== '' ) {
$share -> setPassword ( $password );
}
2015-12-15 11:54:50 +03:00
//Expire date
2016-01-27 17:42:11 +03:00
$expireDate = $this -> request -> getParam ( 'expireDate' , '' );
2015-12-15 11:54:50 +03:00
2016-01-27 17:42:11 +03:00
if ( $expireDate !== '' ) {
2015-12-15 11:54:50 +03:00
try {
$expireDate = $this -> parseDate ( $expireDate );
$share -> setExpirationDate ( $expireDate );
} catch ( \Exception $e ) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Invalid date, date format must be YYYY-MM-DD' ));
2015-12-15 11:54:50 +03:00
}
}
} else if ( $shareType === \OCP\Share :: SHARE_TYPE_REMOTE ) {
2016-02-04 13:13:06 +03:00
if ( ! $this -> shareManager -> outgoingServer2ServerSharesAllowed ()) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 403 , $this -> l -> t ( 'Sharing %s failed because the back end does not allow shares from type %s' , [ $path -> getPath (), $shareType ]));
2016-02-04 13:13:06 +03:00
}
2016-02-04 12:01:40 +03:00
$share -> setSharedWith ( $shareWith );
$share -> setPermissions ( $permissions );
2015-12-15 11:54:50 +03:00
} else {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 400 , $this -> l -> t ( 'Unknown share type' ));
2015-12-15 11:54:50 +03:00
}
$share -> setShareType ( $shareType );
2016-02-03 10:14:48 +03:00
$share -> setSharedBy ( $this -> currentUser -> getUID ());
2015-12-15 11:54:50 +03:00
try {
$share = $this -> shareManager -> createShare ( $share );
2016-02-02 16:18:59 +03:00
} catch ( GenericShareException $e ) {
2016-01-05 14:50:00 +03:00
$code = $e -> getCode () === 0 ? 403 : $e -> getCode ();
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-01-05 14:50:00 +03:00
return new \OC_OCS_Result ( null , $code , $e -> getHint ());
} catch ( \Exception $e ) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-01-05 13:00:09 +03:00
return new \OC_OCS_Result ( null , 403 , $e -> getMessage ());
2015-12-15 11:54:50 +03:00
}
2016-03-09 11:11:41 +03:00
$output = $this -> formatShare ( $share );
$share -> getNode () -> unlock ( \OCP\Lock\ILockingProvider :: LOCK_SHARED );
return new \OC_OCS_Result ( $output );
2015-12-15 11:54:50 +03:00
}
2016-01-29 17:26:04 +03:00
/**
* @ param \OCP\Files\File | \OCP\Files\Folder $node
* @ return \OC_OCS_Result
*/
private function getSharedWithMe ( $node = null ) {
2016-02-03 10:14:48 +03:00
$userShares = $this -> shareManager -> getSharedWith ( $this -> currentUser -> getUID (), \OCP\Share :: SHARE_TYPE_USER , $node , - 1 , 0 );
$groupShares = $this -> shareManager -> getSharedWith ( $this -> currentUser -> getUID (), \OCP\Share :: SHARE_TYPE_GROUP , $node , - 1 , 0 );
2015-12-03 12:51:41 +03:00
$shares = array_merge ( $userShares , $groupShares );
$formatted = [];
foreach ( $shares as $share ) {
2016-01-27 11:02:12 +03:00
if ( $this -> canAccessShare ( $share )) {
2016-02-16 18:04:17 +03:00
try {
$formatted [] = $this -> formatShare ( $share );
} catch ( NotFoundException $e ) {
// Ignore this share
}
2016-01-27 11:02:12 +03:00
}
2015-12-03 12:51:41 +03:00
}
return new \OC_OCS_Result ( $formatted );
}
2016-01-19 16:35:16 +03:00
/**
* @ param \OCP\Files\Folder $folder
* @ return \OC_OCS_Result
*/
private function getSharesInDir ( $folder ) {
if ( ! ( $folder instanceof \OCP\Files\Folder )) {
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 400 , $this -> l -> t ( 'Not a directory' ));
2016-01-19 16:35:16 +03:00
}
$nodes = $folder -> getDirectoryListing ();
2016-01-27 14:13:53 +03:00
/** @var \OCP\Share\IShare[] $shares */
2016-01-19 16:35:16 +03:00
$shares = [];
foreach ( $nodes as $node ) {
2016-02-04 12:01:40 +03:00
$shares = array_merge ( $shares , $this -> shareManager -> getSharesBy ( $this -> currentUser -> getUID (), \OCP\Share :: SHARE_TYPE_USER , $node , false , - 1 , 0 ));
2016-02-03 10:14:48 +03:00
$shares = array_merge ( $shares , $this -> shareManager -> getSharesBy ( $this -> currentUser -> getUID (), \OCP\Share :: SHARE_TYPE_GROUP , $node , false , - 1 , 0 ));
2016-02-04 12:01:40 +03:00
$shares = array_merge ( $shares , $this -> shareManager -> getSharesBy ( $this -> currentUser -> getUID (), \OCP\Share :: SHARE_TYPE_LINK , $node , false , - 1 , 0 ));
2016-02-04 13:13:06 +03:00
if ( $this -> shareManager -> outgoingServer2ServerSharesAllowed ()) {
$shares = array_merge ( $shares , $this -> shareManager -> getSharesBy ( $this -> currentUser -> getUID (), \OCP\Share :: SHARE_TYPE_REMOTE , $node , false , - 1 , 0 ));
}
2016-01-19 16:35:16 +03:00
}
$formatted = [];
foreach ( $shares as $share ) {
2016-02-16 18:04:17 +03:00
try {
$formatted [] = $this -> formatShare ( $share );
} catch ( NotFoundException $e ) {
//Ignore this share
}
2016-01-19 16:35:16 +03:00
}
return new \OC_OCS_Result ( $formatted );
}
/**
* The getShares function .
*
* - Get shares by the current user
* - Get shares by the current user and reshares ( ? reshares = true )
* - Get shares with the current user ( ? shared_with_me = true )
* - Get shares for a specific path ( ? path =... )
* - Get all shares in a folder ( ? subfiles = true & path =.. )
*
* @ return \OC_OCS_Result
*/
2015-12-03 12:51:41 +03:00
public function getShares () {
2016-02-26 16:58:41 +03:00
if ( ! $this -> shareManager -> shareApiEnabled ()) {
return new \OC_OCS_Result ();
}
2015-12-03 12:51:41 +03:00
$sharedWithMe = $this -> request -> getParam ( 'shared_with_me' , null );
$reshares = $this -> request -> getParam ( 'reshares' , null );
$subfiles = $this -> request -> getParam ( 'subfiles' );
$path = $this -> request -> getParam ( 'path' , null );
if ( $path !== null ) {
$userFolder = $this -> rootFolder -> getUserFolder ( $this -> currentUser -> getUID ());
try {
$path = $userFolder -> get ( $path );
2016-03-17 13:09:11 +03:00
$path -> lock ( ILockingProvider :: LOCK_SHARED );
2015-12-03 12:51:41 +03:00
} catch ( \OCP\Files\NotFoundException $e ) {
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Wrong path, file/folder doesn\'t exist' ));
2016-03-17 13:09:11 +03:00
} catch ( LockedException $e ) {
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Could not lock path' ));
2015-12-03 12:51:41 +03:00
}
}
2016-01-29 17:26:04 +03:00
if ( $sharedWithMe === 'true' ) {
2016-03-17 13:09:11 +03:00
$result = $this -> getSharedWithMe ( $path );
if ( $path !== null ) {
$path -> unlock ( ILockingProvider :: LOCK_SHARED );
}
return $result ;
2016-01-29 17:26:04 +03:00
}
2016-01-19 16:35:16 +03:00
if ( $subfiles === 'true' ) {
2016-03-17 13:09:11 +03:00
$result = $this -> getSharesInDir ( $path );
if ( $path !== null ) {
$path -> unlock ( ILockingProvider :: LOCK_SHARED );
}
return $result ;
2016-01-19 16:35:16 +03:00
}
2015-12-03 12:51:41 +03:00
if ( $reshares === 'true' ) {
$reshares = true ;
} else {
$reshares = false ;
}
// Get all shares
2016-02-03 10:14:48 +03:00
$userShares = $this -> shareManager -> getSharesBy ( $this -> currentUser -> getUID (), \OCP\Share :: SHARE_TYPE_USER , $path , $reshares , - 1 , 0 );
$groupShares = $this -> shareManager -> getSharesBy ( $this -> currentUser -> getUID (), \OCP\Share :: SHARE_TYPE_GROUP , $path , $reshares , - 1 , 0 );
$linkShares = $this -> shareManager -> getSharesBy ( $this -> currentUser -> getUID (), \OCP\Share :: SHARE_TYPE_LINK , $path , $reshares , - 1 , 0 );
2016-02-04 13:13:06 +03:00
$shares = array_merge ( $userShares , $groupShares , $linkShares );
if ( $this -> shareManager -> outgoingServer2ServerSharesAllowed ()) {
$federatedShares = $this -> shareManager -> getSharesBy ( $this -> currentUser -> getUID (), \OCP\Share :: SHARE_TYPE_REMOTE , $path , $reshares , - 1 , 0 );
$shares = array_merge ( $shares , $federatedShares );
}
2015-12-03 12:51:41 +03:00
$formatted = [];
foreach ( $shares as $share ) {
2016-02-16 18:04:17 +03:00
try {
$formatted [] = $this -> formatShare ( $share );
} catch ( NotFoundException $e ) {
//Ignore share
}
2015-12-03 12:51:41 +03:00
}
2016-03-17 13:09:11 +03:00
if ( $path !== null ) {
$path -> unlock ( ILockingProvider :: LOCK_SHARED );
}
2015-12-03 12:51:41 +03:00
return new \OC_OCS_Result ( $formatted );
}
2016-01-22 16:52:20 +03:00
/**
* @ param int $id
* @ return \OC_OCS_Result
*/
public function updateShare ( $id ) {
2016-02-26 16:58:41 +03:00
if ( ! $this -> shareManager -> shareApiEnabled ()) {
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Share API is disabled' ));
2016-02-26 16:58:41 +03:00
}
2016-01-22 16:52:20 +03:00
try {
2016-03-07 18:10:27 +03:00
$share = $this -> getShareById ( $id );
2016-02-02 16:18:59 +03:00
} catch ( ShareNotFound $e ) {
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Wrong share ID, share doesn\'t exist' ));
2016-01-22 16:52:20 +03:00
}
2016-03-09 11:11:41 +03:00
$share -> getNode () -> lock ( \OCP\Lock\ILockingProvider :: LOCK_SHARED );
2016-01-22 16:52:20 +03:00
if ( ! $this -> canAccessShare ( $share )) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Wrong share ID, share doesn\'t exist' ));
2016-01-22 16:52:20 +03:00
}
$permissions = $this -> request -> getParam ( 'permissions' , null );
$password = $this -> request -> getParam ( 'password' , null );
$publicUpload = $this -> request -> getParam ( 'publicUpload' , null );
$expireDate = $this -> request -> getParam ( 'expireDate' , null );
2016-01-27 18:46:48 +03:00
/*
* expirationdate , password and publicUpload only make sense for link shares
*/
if ( $share -> getShareType () === \OCP\Share :: SHARE_TYPE_LINK ) {
2016-01-27 22:32:04 +03:00
if ( $permissions === null && $password === null && $publicUpload === null && $expireDate === null ) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-01-27 18:46:48 +03:00
return new \OC_OCS_Result ( null , 400 , 'Wrong or no update parameter given' );
}
2016-01-22 16:52:20 +03:00
2016-01-27 22:32:04 +03:00
$newPermissions = null ;
if ( $publicUpload === 'true' ) {
$newPermissions = \OCP\Constants :: PERMISSION_READ | \OCP\Constants :: PERMISSION_CREATE | \OCP\Constants :: PERMISSION_UPDATE ;
} else if ( $publicUpload === 'false' ) {
$newPermissions = \OCP\Constants :: PERMISSION_READ ;
2016-01-22 16:52:20 +03:00
}
2016-01-27 22:32:04 +03:00
if ( $permissions !== null ) {
$newPermissions = ( int ) $permissions ;
}
2016-01-22 16:52:20 +03:00
2016-01-27 22:32:04 +03:00
if ( $newPermissions !== null &&
$newPermissions !== \OCP\Constants :: PERMISSION_READ &&
$newPermissions !== ( \OCP\Constants :: PERMISSION_READ | \OCP\Constants :: PERMISSION_CREATE | \OCP\Constants :: PERMISSION_UPDATE )) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 400 , $this -> l -> t ( 'Can\'t change permissions for public share links' ));
2016-01-27 22:32:04 +03:00
}
if ( $newPermissions === ( \OCP\Constants :: PERMISSION_READ | \OCP\Constants :: PERMISSION_CREATE | \OCP\Constants :: PERMISSION_UPDATE )) {
if ( ! $this -> shareManager -> shareApiLinkAllowPublicUpload ()) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 403 , $this -> l -> t ( 'Public upload disabled by the administrator' ));
2016-01-27 22:32:04 +03:00
}
2016-01-28 15:17:16 +03:00
if ( ! ( $share -> getNode () instanceof \OCP\Files\Folder )) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 400 , $this -> l -> t ( 'Public upload is only possible for publicly shared folders' ));
2016-01-27 22:32:04 +03:00
}
}
if ( $newPermissions !== null ) {
$share -> setPermissions ( $newPermissions );
}
2016-01-22 16:52:20 +03:00
2016-01-27 18:46:48 +03:00
if ( $expireDate === '' ) {
$share -> setExpirationDate ( null );
2016-01-27 19:09:02 +03:00
} else if ( $expireDate !== null ) {
2016-01-27 18:46:48 +03:00
try {
$expireDate = $this -> parseDate ( $expireDate );
} catch ( \Exception $e ) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-01-27 18:46:48 +03:00
return new \OC_OCS_Result ( null , 400 , $e -> getMessage ());
}
$share -> setExpirationDate ( $expireDate );
}
2016-01-22 16:52:20 +03:00
2016-01-27 18:46:48 +03:00
if ( $password === '' ) {
$share -> setPassword ( null );
2016-01-27 19:09:02 +03:00
} else if ( $password !== null ) {
2016-01-27 18:46:48 +03:00
$share -> setPassword ( $password );
2016-01-22 16:52:20 +03:00
}
2016-01-27 18:46:48 +03:00
} else {
2016-01-27 22:32:04 +03:00
// For other shares only permissions is valid.
2016-01-27 18:46:48 +03:00
if ( $permissions === null ) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 400 , $this -> l -> t ( 'Wrong or no update parameter given' ));
2016-01-27 18:46:48 +03:00
} else {
$permissions = ( int ) $permissions ;
$share -> setPermissions ( $permissions );
}
2016-01-22 16:52:20 +03:00
}
2016-02-29 21:12:19 +03:00
if ( $permissions !== null ) {
/* Check if this is an incomming share */
$incomingShares = $this -> shareManager -> getSharedWith ( $this -> currentUser -> getUID (), \OCP\Share :: SHARE_TYPE_USER , $share -> getNode (), - 1 , 0 );
$incomingShares = array_merge ( $incomingShares , $this -> shareManager -> getSharedWith ( $this -> currentUser -> getUID (), \OCP\Share :: SHARE_TYPE_GROUP , $share -> getNode (), - 1 , 0 ));
if ( ! empty ( $incomingShares )) {
$maxPermissions = 0 ;
foreach ( $incomingShares as $incomingShare ) {
$maxPermissions |= $incomingShare -> getPermissions ();
}
if ( $share -> getPermissions () & ~ $maxPermissions ) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-04-15 15:05:36 +03:00
return new \OC_OCS_Result ( null , 404 , $this -> l -> t ( 'Cannot increase permissions' ));
2016-02-29 21:12:19 +03:00
}
}
}
2016-01-27 18:46:48 +03:00
2016-01-22 16:52:20 +03:00
try {
$share = $this -> shareManager -> updateShare ( $share );
} catch ( \Exception $e ) {
2016-03-17 13:09:11 +03:00
$share -> getNode () -> unlock ( ILockingProvider :: LOCK_SHARED );
2016-01-22 16:52:20 +03:00
return new \OC_OCS_Result ( null , 400 , $e -> getMessage ());
}
2016-03-09 11:11:41 +03:00
$share -> getNode () -> unlock ( \OCP\Lock\ILockingProvider :: LOCK_SHARED );
2016-01-22 16:52:20 +03:00
return new \OC_OCS_Result ( $this -> formatShare ( $share ));
}
2015-11-24 11:37:17 +03:00
/**
2016-01-27 14:13:53 +03:00
* @ param \OCP\Share\IShare $share
2015-11-24 11:37:17 +03:00
* @ return bool
*/
2016-01-27 14:13:53 +03:00
protected function canAccessShare ( \OCP\Share\IShare $share ) {
2016-01-27 11:02:12 +03:00
// A file with permissions 0 can't be accessed by us. So Don't show it
if ( $share -> getPermissions () === 0 ) {
return false ;
}
2015-11-24 11:37:17 +03:00
// Owner of the file and the sharer of the file can always get share
2016-02-03 10:14:48 +03:00
if ( $share -> getShareOwner () === $this -> currentUser -> getUID () ||
$share -> getSharedBy () === $this -> currentUser -> getUID ()
2015-11-24 11:37:17 +03:00
) {
return true ;
}
// If the share is shared with you (or a group you are a member of)
if ( $share -> getShareType () === \OCP\Share :: SHARE_TYPE_USER &&
2016-02-03 10:14:48 +03:00
$share -> getSharedWith () === $this -> currentUser -> getUID ()) {
2015-11-24 11:37:17 +03:00
return true ;
}
2016-02-03 10:14:48 +03:00
if ( $share -> getShareType () === \OCP\Share :: SHARE_TYPE_GROUP ) {
$sharedWith = $this -> groupManager -> get ( $share -> getSharedWith ());
if ( $sharedWith -> inGroup ( $this -> currentUser )) {
return true ;
}
2015-11-24 11:37:17 +03:00
}
return false ;
}
2015-12-15 11:54:50 +03:00
/**
* Make sure that the passed date is valid ISO 8601
* So YYYY - MM - DD
* If not throw an exception
*
* @ param string $expireDate
*
* @ throws \Exception
* @ return \DateTime
*/
private function parseDate ( $expireDate ) {
try {
$date = new \DateTime ( $expireDate );
} catch ( \Exception $e ) {
throw new \Exception ( 'Invalid date. Format must be YYYY-MM-DD' );
}
if ( $date === false ) {
throw new \Exception ( 'Invalid date. Format must be YYYY-MM-DD' );
}
$date -> setTime ( 0 , 0 , 0 );
return $date ;
}
2016-03-07 18:10:27 +03:00
/**
* Since we have multiple providers but the OCS Share API v1 does
* not support this we need to check all backends .
*
* @ param string $id
* @ return \OCP\Share\IShare
* @ throws ShareNotFound
*/
private function getShareById ( $id ) {
$share = null ;
// First check if it is an internal share.
try {
$share = $this -> shareManager -> getShareById ( 'ocinternal:' . $id );
} catch ( ShareNotFound $e ) {
if ( ! $this -> shareManager -> outgoingServer2ServerSharesAllowed ()) {
throw new ShareNotFound ();
}
$share = $this -> shareManager -> getShareById ( 'ocFederatedSharing:' . $id );
}
return $share ;
}
2015-10-30 15:10:08 +03:00
}