]> source.dussan.org Git - nextcloud-server.git/commitdiff
Move Share20OCS to ShareAPIController
authorRoeland Jago Douma <roeland@famdouma.nl>
Fri, 21 Oct 2016 18:25:07 +0000 (20:25 +0200)
committerRoeland Jago Douma <roeland@famdouma.nl>
Mon, 24 Oct 2016 07:52:34 +0000 (09:52 +0200)
It was already a controller just still residing in its old location.

* Moved ShareAPIController to user plain userID instead of user object
* Moved Share20OCS to ShareAPIController
* Removed initisation of class from Application.php and leave it to the
AppFramework
* Fixed tests

Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
apps/files_sharing/lib/API/Share20OCS.php [deleted file]
apps/files_sharing/lib/AppInfo/Application.php
apps/files_sharing/lib/Controller/ShareAPIController.php [new file with mode: 0644]
apps/files_sharing/lib/Middleware/OCSShareAPIMiddleware.php
apps/files_sharing/tests/API/Share20OCSTest.php [deleted file]
apps/files_sharing/tests/ApiTest.php
apps/files_sharing/tests/Controller/ShareAPIControllerTest.php [new file with mode: 0644]

diff --git a/apps/files_sharing/lib/API/Share20OCS.php b/apps/files_sharing/lib/API/Share20OCS.php
deleted file mode 100644 (file)
index 8d00d17..0000000
+++ /dev/null
@@ -1,805 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Joas Schilling <coding@schilljs.com>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @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/>
- *
- */
-namespace OCA\Files_Sharing\API;
-
-use OCP\AppFramework\Http\DataResponse;
-use OCP\AppFramework\OCS\OCSBadRequestException;
-use OCP\AppFramework\OCS\OCSException;
-use OCP\AppFramework\OCS\OCSForbiddenException;
-use OCP\AppFramework\OCS\OCSNotFoundException;
-use OCP\AppFramework\OCSController;
-use OCP\Files\Node;
-use OCP\Files\NotFoundException;
-use OCP\IGroupManager;
-use OCP\IL10N;
-use OCP\IUserManager;
-use OCP\IRequest;
-use OCP\IURLGenerator;
-use OCP\IUser;
-use OCP\Files\IRootFolder;
-use OCP\Lock\LockedException;
-use OCP\Share\IManager;
-use OCP\Share\Exceptions\ShareNotFound;
-use OCP\Share\Exceptions\GenericShareException;
-use OCP\Lock\ILockingProvider;
-use OCP\Share\IShare;
-
-/**
- * Class Share20OCS
- *
- * @package OCA\Files_Sharing\API
- */
-class Share20OCS extends OCSController {
-
-       /** @var IManager */
-       private $shareManager;
-       /** @var IGroupManager */
-       private $groupManager;
-       /** @var IUserManager */
-       private $userManager;
-       /** @var IRequest */
-       protected $request;
-       /** @var IRootFolder */
-       private $rootFolder;
-       /** @var IURLGenerator */
-       private $urlGenerator;
-       /** @var IUser */
-       private $currentUser;
-       /** @var IL10N */
-       private $l;
-       /** @var \OCP\Files\Node */
-       private $lockedNode;
-
-       /**
-        * Share20OCS constructor.
-        *
-        * @param string $appName
-        * @param IRequest $request
-        * @param IManager $shareManager
-        * @param IGroupManager $groupManager
-        * @param IUserManager $userManager
-        * @param IRootFolder $rootFolder
-        * @param IURLGenerator $urlGenerator
-        * @param IUser $currentUser
-        * @param IL10N $l10n
-        */
-       public function __construct(
-               $appName,
-               IRequest $request,
-               IManager $shareManager,
-               IGroupManager $groupManager,
-               IUserManager $userManager,
-               IRootFolder $rootFolder,
-               IURLGenerator $urlGenerator,
-               IUser $currentUser,
-               IL10N $l10n
-       ) {
-               parent::__construct($appName, $request);
-
-               $this->shareManager = $shareManager;
-               $this->userManager = $userManager;
-               $this->groupManager = $groupManager;
-               $this->request = $request;
-               $this->rootFolder = $rootFolder;
-               $this->urlGenerator = $urlGenerator;
-               $this->currentUser = $currentUser;
-               $this->l = $l10n;
-       }
-
-       /**
-        * Convert an IShare to an array for OCS output
-        *
-        * @param \OCP\Share\IShare $share
-        * @param Node|null $recipientNode
-        * @return array
-        * @throws NotFoundException In case the node can't be resolved.
-        */
-       protected function formatShare(\OCP\Share\IShare $share, Node $recipientNode = null) {
-               $sharedBy = $this->userManager->get($share->getSharedBy());
-               $shareOwner = $this->userManager->get($share->getShareOwner());
-
-               $result = [
-                       'id' => $share->getId(),
-                       'share_type' => $share->getShareType(),
-                       'uid_owner' => $share->getSharedBy(),
-                       'displayname_owner' => $sharedBy !== null ? $sharedBy->getDisplayName() : $share->getSharedBy(),
-                       'permissions' => $share->getPermissions(),
-                       'stime' => $share->getShareTime()->getTimestamp(),
-                       'parent' => null,
-                       'expiration' => null,
-                       'token' => null,
-                       'uid_file_owner' => $share->getShareOwner(),
-                       'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
-               ];
-
-               $userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID());
-               if ($recipientNode) {
-                       $node = $recipientNode;
-               } else {
-                       $nodes = $userFolder->getById($share->getNodeId());
-
-                       if (empty($nodes)) {
-                               // fallback to guessing the path
-                               $node = $userFolder->get($share->getTarget());
-                               if ($node === null) {
-                                       throw new NotFoundException();
-                               }
-                       } else {
-                               $node = $nodes[0];
-                       }
-               }
-
-               $result['path'] = $userFolder->getRelativePath($node->getPath());
-               if ($node instanceOf \OCP\Files\Folder) {
-                       $result['item_type'] = 'folder';
-               } else {
-                       $result['item_type'] = 'file';
-               }
-               $result['mimetype'] = $node->getMimetype();
-               $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();
-               $result['file_target'] = $share->getTarget();
-
-               if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
-                       $sharedWith = $this->userManager->get($share->getSharedWith());
-                       $result['share_with'] = $share->getSharedWith();
-                       $result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
-               } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
-                       $result['share_with'] = $share->getSharedWith();
-                       $result['share_with_displayname'] = $share->getSharedWith();
-               } 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
-        *
-        * @NoAdminRequired
-        *
-        * @param string $id
-        * @return DataResponse
-        * @throws OCSNotFoundException
-        */
-       public function getShare($id) {
-               try {
-                       $share = $this->getShareById($id);
-               } catch (ShareNotFound $e) {
-                       throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
-               }
-
-               if ($this->canAccessShare($share)) {
-                       try {
-                               $share = $this->formatShare($share);
-                               return new DataResponse([$share]);
-                       } catch (NotFoundException $e) {
-                               //Fall trough
-                       }
-               }
-
-               throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
-       }
-
-       /**
-        * Delete a share
-        *
-        * @NoAdminRequired
-        *
-        * @param string $id
-        * @return DataResponse
-        * @throws OCSNotFoundException
-        */
-       public function deleteShare($id) {
-               try {
-                       $share = $this->getShareById($id);
-               } catch (ShareNotFound $e) {
-                       throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
-               }
-
-               try {
-                       $this->lock($share->getNode());
-               } catch (LockedException $e) {
-                       throw new OCSNotFoundException($this->l->t('could not delete share'));
-               }
-
-               if (!$this->canAccessShare($share, false)) {
-                       throw new OCSNotFoundException($this->l->t('Could not delete share'));
-               }
-
-               $this->shareManager->deleteShare($share);
-
-               return new DataResponse();
-       }
-
-       /**
-        * @NoAdminRequired
-        *
-        * @param string $path
-        * @param int $permissions
-        * @param int $shareType
-        * @param string $shareWith
-        * @param string $publicUpload
-        * @param string $password
-        * @param string $expireDate
-        *
-        * @return DataResponse
-        * @throws OCSNotFoundException
-        * @throws OCSForbiddenException
-        * @throws OCSBadRequestException
-        * @throws OCSException
-        */
-       public function createShare(
-               $path = null,
-               $permissions = \OCP\Constants::PERMISSION_ALL,
-               $shareType = -1,
-               $shareWith = null,
-               $publicUpload = 'false',
-               $password = '',
-               $expireDate = ''
-       ) {
-               $share = $this->shareManager->newShare();
-
-               // Verify path
-               if ($path === null) {
-                       throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
-               }
-
-               $userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID());
-               try {
-                       $path = $userFolder->get($path);
-               } catch (NotFoundException $e) {
-                       throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
-               }
-
-               $share->setNode($path);
-
-               try {
-                       $this->lock($share->getNode());
-               } catch (LockedException $e) {
-                       throw new OCSNotFoundException($this->l->t('Could not create share'));
-               }
-
-               if ($permissions < 0 || $permissions > \OCP\Constants::PERMISSION_ALL) {
-                       throw new OCSNotFoundException($this->l->t('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;
-               }
-
-               /*
-                * 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());
-               }
-
-               if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
-                       // Valid user is required to share
-                       if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
-                               throw new OCSNotFoundException($this->l->t('Please specify a valid user'));
-                       }
-                       $share->setSharedWith($shareWith);
-                       $share->setPermissions($permissions);
-               } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
-                       if (!$this->shareManager->allowGroupSharing()) {
-                               throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
-                       }
-
-                       // Valid group is required to share
-                       if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
-                               throw new OCSNotFoundException($this->l->t('Please specify a valid group'));
-                       }
-                       $share->setSharedWith($shareWith);
-                       $share->setPermissions($permissions);
-               } else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
-                       //Can we even share links?
-                       if (!$this->shareManager->shareApiAllowLinks()) {
-                               throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator'));
-                       }
-
-                       /*
-                        * 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)) {
-                               return new DataResponse($this->formatShare($existingShares[0]));
-                       }
-
-                       if ($publicUpload === 'true') {
-                               // Check if public upload is allowed
-                               if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
-                                       throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
-                               }
-
-                               // Public upload can only be set for folders
-                               if ($path instanceof \OCP\Files\File) {
-                                       throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
-                               }
-
-                               $share->setPermissions(
-                                       \OCP\Constants::PERMISSION_READ |
-                                       \OCP\Constants::PERMISSION_CREATE |
-                                       \OCP\Constants::PERMISSION_UPDATE |
-                                       \OCP\Constants::PERMISSION_DELETE
-                               );
-                       } else {
-                               $share->setPermissions(\OCP\Constants::PERMISSION_READ);
-                       }
-
-                       // Set password
-                       if ($password !== '') {
-                               $share->setPassword($password);
-                       }
-
-                       //Expire date
-                       if ($expireDate !== '') {
-                               try {
-                                       $expireDate = $this->parseDate($expireDate);
-                                       $share->setExpirationDate($expireDate);
-                               } catch (\Exception $e) {
-                                       throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
-                               }
-                       }
-
-               } else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
-                       if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
-                               throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType]));
-                       }
-
-                       $share->setSharedWith($shareWith);
-                       $share->setPermissions($permissions);
-               } else {
-                       throw new OCSBadRequestException($this->l->t('Unknown share type'));
-               }
-
-               $share->setShareType($shareType);
-               $share->setSharedBy($this->currentUser->getUID());
-
-               try {
-                       $share = $this->shareManager->createShare($share);
-               } catch (GenericShareException $e) {
-                       $code = $e->getCode() === 0 ? 403 : $e->getCode();
-                       throw new OCSException($e->getHint(), $code);
-               } catch (\Exception $e) {
-                       throw new OCSForbiddenException($e->getMessage());
-               }
-
-               $output = $this->formatShare($share);
-
-               return new DataResponse($output);
-       }
-
-       /**
-        * @param \OCP\Files\File|\OCP\Files\Folder $node
-        * @return DataResponse
-        */
-       private function getSharedWithMe($node = null) {
-               $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);
-
-               $shares = array_merge($userShares, $groupShares);
-
-               $shares = array_filter($shares, function (IShare $share) {
-                       return $share->getShareOwner() !== $this->currentUser->getUID();
-               });
-
-               $formatted = [];
-               foreach ($shares as $share) {
-                       if ($this->canAccessShare($share)) {
-                               try {
-                                       $formatted[] = $this->formatShare($share);
-                               } catch (NotFoundException $e) {
-                                       // Ignore this share
-                               }
-                       }
-               }
-
-               return new DataResponse($formatted);
-       }
-
-       /**
-        * @param \OCP\Files\Folder $folder
-        * @return DataResponse
-        * @throws OCSBadRequestException
-        */
-       private function getSharesInDir($folder) {
-               if (!($folder instanceof \OCP\Files\Folder)) {
-                       throw new OCSBadRequestException($this->l->t('Not a directory'));
-               }
-
-               $nodes = $folder->getDirectoryListing();
-               /** @var \OCP\Share\IShare[] $shares */
-               $shares = [];
-               foreach ($nodes as $node) {
-                       $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_USER, $node, false, -1, 0));
-                       $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
-                       $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_LINK, $node, false, -1, 0));
-                       if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
-                               $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_REMOTE, $node, false, -1, 0));
-                       }
-               }
-
-               $formatted = [];
-               foreach ($shares as $share) {
-                       try {
-                               $formatted[] = $this->formatShare($share);
-                       } catch (NotFoundException $e) {
-                               //Ignore this share
-                       }
-               }
-
-               return new DataResponse($formatted);
-       }
-
-       /**
-        * The getShares function.
-        *
-        * @NoAdminRequired
-        *
-        * @param string $shared_with_me
-        * @param string $reshares
-        * @param string $subfiles
-        * @param string $path
-        *
-        * - 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 DataResponse
-        * @throws OCSNotFoundException
-        */
-       public function getShares(
-               $shared_with_me = 'false',
-               $reshares = 'false',
-               $subfiles = 'false',
-               $path = null
-       ) {
-
-               if ($path !== null) {
-                       $userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID());
-                       try {
-                               $path = $userFolder->get($path);
-                               $this->lock($path);
-                       } catch (\OCP\Files\NotFoundException $e) {
-                               throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
-                       } catch (LockedException $e) {
-                               throw new OCSNotFoundException($this->l->t('Could not lock path'));
-                       }
-               }
-
-               if ($shared_with_me === 'true') {
-                       $result = $this->getSharedWithMe($path);
-                       return $result;
-               }
-
-               if ($subfiles === 'true') {
-                       $result = $this->getSharesInDir($path);
-                       return $result;
-               }
-
-               if ($reshares === 'true') {
-                       $reshares = true;
-               } else {
-                       $reshares = false;
-               }
-
-               // Get all shares
-               $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);
-               $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);
-               }
-
-               $formatted = [];
-               foreach ($shares as $share) {
-                       try {
-                               $formatted[] = $this->formatShare($share, $path);
-                       } catch (NotFoundException $e) {
-                               //Ignore share
-                       }
-               }
-
-               return new DataResponse($formatted);
-       }
-
-       /**
-        * @NoAdminRequired
-        *
-        * @param int $id
-        * @param int $permissions
-        * @param string $password
-        * @param string $publicUpload
-        * @param string $expireDate
-        * @return DataResponse
-        * @throws OCSNotFoundException
-        * @throws OCSBadRequestException
-        * @throws OCSForbiddenException
-        */
-       public function updateShare(
-               $id,
-               $permissions = null,
-               $password = null,
-               $publicUpload = null,
-               $expireDate = null
-       ) {
-               try {
-                       $share = $this->getShareById($id);
-               } catch (ShareNotFound $e) {
-                       throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
-               }
-
-               $this->lock($share->getNode());
-
-               if (!$this->canAccessShare($share, false)) {
-                       throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
-               }
-
-               /*
-                * expirationdate, password and publicUpload only make sense for link shares
-                */
-               if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
-                       if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) {
-                               throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
-                       }
-
-                       $newPermissions = null;
-                       if ($publicUpload === 'true') {
-                               $newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
-                       } else if ($publicUpload === 'false') {
-                               $newPermissions = \OCP\Constants::PERMISSION_READ;
-                       }
-
-                       if ($permissions !== null) {
-                               $newPermissions = (int)$permissions;
-                       }
-
-                       if ($newPermissions !== null &&
-                               !in_array($newPermissions, [
-                                       \OCP\Constants::PERMISSION_READ,
-                                       \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE, // legacy
-                                       \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE, // correct
-                                       \OCP\Constants::PERMISSION_CREATE, // hidden file list
-                               ])
-                       ) {
-                               throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
-                       }
-
-                       if (
-                               // legacy
-                               $newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE) ||
-                               // correct
-                               $newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE)
-                       ) {
-                               if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
-                                       throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
-                               }
-
-                               if (!($share->getNode() instanceof \OCP\Files\Folder)) {
-                                       throw new OCSBadRequestException($this->l->t('Public upload is only possible for publicly shared folders'));
-                               }
-
-                               // normalize to correct public upload permissions
-                               $newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
-                       }
-
-                       if ($newPermissions !== null) {
-                               $share->setPermissions($newPermissions);
-                       }
-
-                       if ($expireDate === '') {
-                               $share->setExpirationDate(null);
-                       } else if ($expireDate !== null) {
-                               try {
-                                       $expireDate = $this->parseDate($expireDate);
-                               } catch (\Exception $e) {
-                                       throw new OCSBadRequestException($e->getMessage());
-                               }
-                               $share->setExpirationDate($expireDate);
-                       }
-
-                       if ($password === '') {
-                               $share->setPassword(null);
-                       } else if ($password !== null) {
-                               $share->setPassword($password);
-                       }
-
-               } else {
-                       // For other shares only permissions is valid.
-                       if ($permissions === null) {
-                               throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
-                       } else {
-                               $permissions = (int)$permissions;
-                               $share->setPermissions($permissions);
-                       }
-               }
-
-               if ($permissions !== null && $share->getShareOwner() !== $this->currentUser->getUID()) {
-                       /* 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));
-
-                       /** @var \OCP\Share\IShare[] $incomingShares */
-                       if (!empty($incomingShares)) {
-                               $maxPermissions = 0;
-                               foreach ($incomingShares as $incomingShare) {
-                                       $maxPermissions |= $incomingShare->getPermissions();
-                               }
-
-                               if ($share->getPermissions() & ~$maxPermissions) {
-                                       throw new OCSNotFoundException($this->l->t('Cannot increase permissions'));
-                               }
-                       }
-               }
-
-
-               try {
-                       $share = $this->shareManager->updateShare($share);
-               } catch (\Exception $e) {
-                       throw new OCSBadRequestException($e->getMessage());
-               }
-
-               return new DataResponse($this->formatShare($share));
-       }
-
-       /**
-        * @param \OCP\Share\IShare $share
-        * @return bool
-        */
-       protected function canAccessShare(\OCP\Share\IShare $share, $checkGroups = true) {
-               // A file with permissions 0 can't be accessed by us. So Don't show it
-               if ($share->getPermissions() === 0) {
-                       return false;
-               }
-
-               // Owner of the file and the sharer of the file can always get share
-               if ($share->getShareOwner() === $this->currentUser->getUID() ||
-                       $share->getSharedBy() === $this->currentUser->getUID()
-               ) {
-                       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 &&
-                       $share->getSharedWith() === $this->currentUser->getUID()
-               ) {
-                       return true;
-               }
-
-               if ($checkGroups && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
-                       $sharedWith = $this->groupManager->get($share->getSharedWith());
-                       if ($sharedWith->inGroup($this->currentUser)) {
-                               return true;
-                       }
-               }
-
-               return false;
-       }
-
-       /**
-        * 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;
-       }
-
-       /**
-        * 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;
-       }
-
-       /**
-        * Lock a Node
-        *
-        * @param \OCP\Files\Node $node
-        */
-       private function lock(\OCP\Files\Node $node) {
-               $node->lock(ILockingProvider::LOCK_SHARED);
-               $this->lockedNode = $node;
-       }
-
-       /**
-        * Cleanup the remaining locks
-        */
-       public function cleanup() {
-               if ($this->lockedNode !== null) {
-                       $this->lockedNode->unlock(ILockingProvider::LOCK_SHARED);
-               }
-       }
-}
index 357860e8fa0912b45c66129de4140855b4c54689..29cdf702a514eb3aae12f4186b7b83beed1cad4b 100644 (file)
@@ -28,7 +28,6 @@
 namespace OCA\Files_Sharing\AppInfo;
 
 use OCA\FederatedFileSharing\DiscoveryManager;
-use OCA\Files_Sharing\API\Share20OCS;
 use OCA\Files_Sharing\Middleware\OCSShareAPIMiddleware;
 use OCA\Files_Sharing\MountProvider;
 use OCP\AppFramework\App;
@@ -78,19 +77,6 @@ class Application extends App {
                                $c->query('HttpClientService')
                        );
                });
-               $container->registerService('ShareAPIController', function (SimpleContainer $c) use ($server) {
-                       return new Share20OCS(
-                               $c->query('AppName'),
-                               $c->query('Request'),
-                               $server->getShareManager(),
-                               $server->getGroupManager(),
-                               $server->getUserManager(),
-                               $server->getRootFolder(),
-                               $server->getURLGenerator(),
-                               $server->getUserSession()->getUser(),
-                               $server->getL10N($c->query('AppName'))
-                       );
-               });
 
                /**
                 * Core class wrappers
diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php
new file mode 100644 (file)
index 0000000..ad9ac6c
--- /dev/null
@@ -0,0 +1,806 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ *
+ * @author Joas Schilling <coding@schilljs.com>
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ * @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/>
+ *
+ */
+namespace OCA\Files_Sharing\Controller;
+
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\OCS\OCSBadRequestException;
+use OCP\AppFramework\OCS\OCSException;
+use OCP\AppFramework\OCS\OCSForbiddenException;
+use OCP\AppFramework\OCS\OCSNotFoundException;
+use OCP\AppFramework\OCSController;
+use OCP\Files\Node;
+use OCP\Files\NotFoundException;
+use OCP\IGroupManager;
+use OCP\IL10N;
+use OCP\IUserManager;
+use OCP\IRequest;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\Files\IRootFolder;
+use OCP\Lock\LockedException;
+use OCP\Share\IManager;
+use OCP\Share\Exceptions\ShareNotFound;
+use OCP\Share\Exceptions\GenericShareException;
+use OCP\Lock\ILockingProvider;
+use OCP\Share\IShare;
+
+/**
+ * Class Share20OCS
+ *
+ * @package OCA\Files_Sharing\API
+ */
+class ShareAPIController extends OCSController {
+
+       /** @var IManager */
+       private $shareManager;
+       /** @var IGroupManager */
+       private $groupManager;
+       /** @var IUserManager */
+       private $userManager;
+       /** @var IRequest */
+       protected $request;
+       /** @var IRootFolder */
+       private $rootFolder;
+       /** @var IURLGenerator */
+       private $urlGenerator;
+       /** @var string */
+       private $currentUser;
+       /** @var IL10N */
+       private $l;
+       /** @var \OCP\Files\Node */
+       private $lockedNode;
+
+       /**
+        * Share20OCS constructor.
+        *
+        * @param string $appName
+        * @param IRequest $request
+        * @param IManager $shareManager
+        * @param IGroupManager $groupManager
+        * @param IUserManager $userManager
+        * @param IRootFolder $rootFolder
+        * @param IURLGenerator $urlGenerator
+        * @param string $userId
+        * @param IL10N $l10n
+        */
+       public function __construct(
+               $appName,
+               IRequest $request,
+               IManager $shareManager,
+               IGroupManager $groupManager,
+               IUserManager $userManager,
+               IRootFolder $rootFolder,
+               IURLGenerator $urlGenerator,
+               $userId,
+               IL10N $l10n
+       ) {
+               parent::__construct($appName, $request);
+
+               $this->shareManager = $shareManager;
+               $this->userManager = $userManager;
+               $this->groupManager = $groupManager;
+               $this->request = $request;
+               $this->rootFolder = $rootFolder;
+               $this->urlGenerator = $urlGenerator;
+               $this->currentUser = $userId;
+               $this->l = $l10n;
+       }
+
+       /**
+        * Convert an IShare to an array for OCS output
+        *
+        * @param \OCP\Share\IShare $share
+        * @param Node|null $recipientNode
+        * @return array
+        * @throws NotFoundException In case the node can't be resolved.
+        */
+       protected function formatShare(\OCP\Share\IShare $share, Node $recipientNode = null) {
+               $sharedBy = $this->userManager->get($share->getSharedBy());
+               $shareOwner = $this->userManager->get($share->getShareOwner());
+
+               $result = [
+                       'id' => $share->getId(),
+                       'share_type' => $share->getShareType(),
+                       'uid_owner' => $share->getSharedBy(),
+                       'displayname_owner' => $sharedBy !== null ? $sharedBy->getDisplayName() : $share->getSharedBy(),
+                       'permissions' => $share->getPermissions(),
+                       'stime' => $share->getShareTime()->getTimestamp(),
+                       'parent' => null,
+                       'expiration' => null,
+                       'token' => null,
+                       'uid_file_owner' => $share->getShareOwner(),
+                       'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
+               ];
+
+               $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
+               if ($recipientNode) {
+                       $node = $recipientNode;
+               } else {
+                       $nodes = $userFolder->getById($share->getNodeId());
+
+                       if (empty($nodes)) {
+                               // fallback to guessing the path
+                               $node = $userFolder->get($share->getTarget());
+                               if ($node === null) {
+                                       throw new NotFoundException();
+                               }
+                       } else {
+                               $node = $nodes[0];
+                       }
+               }
+
+               $result['path'] = $userFolder->getRelativePath($node->getPath());
+               if ($node instanceOf \OCP\Files\Folder) {
+                       $result['item_type'] = 'folder';
+               } else {
+                       $result['item_type'] = 'file';
+               }
+               $result['mimetype'] = $node->getMimetype();
+               $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();
+               $result['file_target'] = $share->getTarget();
+
+               if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
+                       $sharedWith = $this->userManager->get($share->getSharedWith());
+                       $result['share_with'] = $share->getSharedWith();
+                       $result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
+               } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
+                       $result['share_with'] = $share->getSharedWith();
+                       $result['share_with_displayname'] = $share->getSharedWith();
+               } 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
+        *
+        * @NoAdminRequired
+        *
+        * @param string $id
+        * @return DataResponse
+        * @throws OCSNotFoundException
+        */
+       public function getShare($id) {
+               try {
+                       $share = $this->getShareById($id);
+               } catch (ShareNotFound $e) {
+                       throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
+               }
+
+               if ($this->canAccessShare($share)) {
+                       try {
+                               $share = $this->formatShare($share);
+                               return new DataResponse([$share]);
+                       } catch (NotFoundException $e) {
+                               //Fall trough
+                       }
+               }
+
+               throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
+       }
+
+       /**
+        * Delete a share
+        *
+        * @NoAdminRequired
+        *
+        * @param string $id
+        * @return DataResponse
+        * @throws OCSNotFoundException
+        */
+       public function deleteShare($id) {
+               try {
+                       $share = $this->getShareById($id);
+               } catch (ShareNotFound $e) {
+                       throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
+               }
+
+               try {
+                       $this->lock($share->getNode());
+               } catch (LockedException $e) {
+                       throw new OCSNotFoundException($this->l->t('could not delete share'));
+               }
+
+               if (!$this->canAccessShare($share, false)) {
+                       throw new OCSNotFoundException($this->l->t('Could not delete share'));
+               }
+
+               $this->shareManager->deleteShare($share);
+
+               return new DataResponse();
+       }
+
+       /**
+        * @NoAdminRequired
+        *
+        * @param string $path
+        * @param int $permissions
+        * @param int $shareType
+        * @param string $shareWith
+        * @param string $publicUpload
+        * @param string $password
+        * @param string $expireDate
+        *
+        * @return DataResponse
+        * @throws OCSNotFoundException
+        * @throws OCSForbiddenException
+        * @throws OCSBadRequestException
+        * @throws OCSException
+        */
+       public function createShare(
+               $path = null,
+               $permissions = \OCP\Constants::PERMISSION_ALL,
+               $shareType = -1,
+               $shareWith = null,
+               $publicUpload = 'false',
+               $password = '',
+               $expireDate = ''
+       ) {
+               $share = $this->shareManager->newShare();
+
+               // Verify path
+               if ($path === null) {
+                       throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
+               }
+
+               $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
+               try {
+                       $path = $userFolder->get($path);
+               } catch (NotFoundException $e) {
+                       throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
+               }
+
+               $share->setNode($path);
+
+               try {
+                       $this->lock($share->getNode());
+               } catch (LockedException $e) {
+                       throw new OCSNotFoundException($this->l->t('Could not create share'));
+               }
+
+               if ($permissions < 0 || $permissions > \OCP\Constants::PERMISSION_ALL) {
+                       throw new OCSNotFoundException($this->l->t('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;
+               }
+
+               /*
+                * 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());
+               }
+
+               if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
+                       // Valid user is required to share
+                       if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
+                               throw new OCSNotFoundException($this->l->t('Please specify a valid user'));
+                       }
+                       $share->setSharedWith($shareWith);
+                       $share->setPermissions($permissions);
+               } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
+                       if (!$this->shareManager->allowGroupSharing()) {
+                               throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
+                       }
+
+                       // Valid group is required to share
+                       if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
+                               throw new OCSNotFoundException($this->l->t('Please specify a valid group'));
+                       }
+                       $share->setSharedWith($shareWith);
+                       $share->setPermissions($permissions);
+               } else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
+                       //Can we even share links?
+                       if (!$this->shareManager->shareApiAllowLinks()) {
+                               throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator'));
+                       }
+
+                       /*
+                        * For now we only allow 1 link share.
+                        * Return the existing link share if this is a duplicate
+                        */
+                       $existingShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, false, 1, 0);
+                       if (!empty($existingShares)) {
+                               return new DataResponse($this->formatShare($existingShares[0]));
+                       }
+
+                       if ($publicUpload === 'true') {
+                               // Check if public upload is allowed
+                               if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
+                                       throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
+                               }
+
+                               // Public upload can only be set for folders
+                               if ($path instanceof \OCP\Files\File) {
+                                       throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
+                               }
+
+                               $share->setPermissions(
+                                       \OCP\Constants::PERMISSION_READ |
+                                       \OCP\Constants::PERMISSION_CREATE |
+                                       \OCP\Constants::PERMISSION_UPDATE |
+                                       \OCP\Constants::PERMISSION_DELETE
+                               );
+                       } else {
+                               $share->setPermissions(\OCP\Constants::PERMISSION_READ);
+                       }
+
+                       // Set password
+                       if ($password !== '') {
+                               $share->setPassword($password);
+                       }
+
+                       //Expire date
+                       if ($expireDate !== '') {
+                               try {
+                                       $expireDate = $this->parseDate($expireDate);
+                                       $share->setExpirationDate($expireDate);
+                               } catch (\Exception $e) {
+                                       throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
+                               }
+                       }
+
+               } else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
+                       if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
+                               throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType]));
+                       }
+
+                       $share->setSharedWith($shareWith);
+                       $share->setPermissions($permissions);
+               } else {
+                       throw new OCSBadRequestException($this->l->t('Unknown share type'));
+               }
+
+               $share->setShareType($shareType);
+               $share->setSharedBy($this->currentUser);
+
+               try {
+                       $share = $this->shareManager->createShare($share);
+               } catch (GenericShareException $e) {
+                       $code = $e->getCode() === 0 ? 403 : $e->getCode();
+                       throw new OCSException($e->getHint(), $code);
+               } catch (\Exception $e) {
+                       throw new OCSForbiddenException($e->getMessage());
+               }
+
+               $output = $this->formatShare($share);
+
+               return new DataResponse($output);
+       }
+
+       /**
+        * @param \OCP\Files\File|\OCP\Files\Folder $node
+        * @return DataResponse
+        */
+       private function getSharedWithMe($node = null) {
+               $userShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, -1, 0);
+               $groupShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, -1, 0);
+
+               $shares = array_merge($userShares, $groupShares);
+
+               $shares = array_filter($shares, function (IShare $share) {
+                       return $share->getShareOwner() !== $this->currentUser;
+               });
+
+               $formatted = [];
+               foreach ($shares as $share) {
+                       if ($this->canAccessShare($share)) {
+                               try {
+                                       $formatted[] = $this->formatShare($share);
+                               } catch (NotFoundException $e) {
+                                       // Ignore this share
+                               }
+                       }
+               }
+
+               return new DataResponse($formatted);
+       }
+
+       /**
+        * @param \OCP\Files\Folder $folder
+        * @return DataResponse
+        * @throws OCSBadRequestException
+        */
+       private function getSharesInDir($folder) {
+               if (!($folder instanceof \OCP\Files\Folder)) {
+                       throw new OCSBadRequestException($this->l->t('Not a directory'));
+               }
+
+               $nodes = $folder->getDirectoryListing();
+               /** @var \OCP\Share\IShare[] $shares */
+               $shares = [];
+               foreach ($nodes as $node) {
+                       $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, false, -1, 0));
+                       $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
+                       $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $node, false, -1, 0));
+                       if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
+                               $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $node, false, -1, 0));
+                       }
+               }
+
+               $formatted = [];
+               foreach ($shares as $share) {
+                       try {
+                               $formatted[] = $this->formatShare($share);
+                       } catch (NotFoundException $e) {
+                               //Ignore this share
+                       }
+               }
+
+               return new DataResponse($formatted);
+       }
+
+       /**
+        * The getShares function.
+        *
+        * @NoAdminRequired
+        *
+        * @param string $shared_with_me
+        * @param string $reshares
+        * @param string $subfiles
+        * @param string $path
+        *
+        * - 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 DataResponse
+        * @throws OCSNotFoundException
+        */
+       public function getShares(
+               $shared_with_me = 'false',
+               $reshares = 'false',
+               $subfiles = 'false',
+               $path = null
+       ) {
+
+               if ($path !== null) {
+                       $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
+                       try {
+                               $path = $userFolder->get($path);
+                               $this->lock($path);
+                       } catch (\OCP\Files\NotFoundException $e) {
+                               throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
+                       } catch (LockedException $e) {
+                               throw new OCSNotFoundException($this->l->t('Could not lock path'));
+                       }
+               }
+
+               if ($shared_with_me === 'true') {
+                       $result = $this->getSharedWithMe($path);
+                       return $result;
+               }
+
+               if ($subfiles === 'true') {
+                       $result = $this->getSharesInDir($path);
+                       return $result;
+               }
+
+               if ($reshares === 'true') {
+                       $reshares = true;
+               } else {
+                       $reshares = false;
+               }
+
+               // Get all shares
+               $userShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);
+               $groupShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);
+               $linkShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);
+               $shares = array_merge($userShares, $groupShares, $linkShares);
+
+               if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
+                       $federatedShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);
+                       $shares = array_merge($shares, $federatedShares);
+               }
+
+               $formatted = [];
+               foreach ($shares as $share) {
+                       try {
+                               $formatted[] = $this->formatShare($share, $path);
+                       } catch (NotFoundException $e) {
+                               //Ignore share
+                       }
+               }
+
+               return new DataResponse($formatted);
+       }
+
+       /**
+        * @NoAdminRequired
+        *
+        * @param int $id
+        * @param int $permissions
+        * @param string $password
+        * @param string $publicUpload
+        * @param string $expireDate
+        * @return DataResponse
+        * @throws OCSNotFoundException
+        * @throws OCSBadRequestException
+        * @throws OCSForbiddenException
+        */
+       public function updateShare(
+               $id,
+               $permissions = null,
+               $password = null,
+               $publicUpload = null,
+               $expireDate = null
+       ) {
+               try {
+                       $share = $this->getShareById($id);
+               } catch (ShareNotFound $e) {
+                       throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
+               }
+
+               $this->lock($share->getNode());
+
+               if (!$this->canAccessShare($share, false)) {
+                       throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
+               }
+
+               /*
+                * expirationdate, password and publicUpload only make sense for link shares
+                */
+               if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
+                       if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) {
+                               throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
+                       }
+
+                       $newPermissions = null;
+                       if ($publicUpload === 'true') {
+                               $newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
+                       } else if ($publicUpload === 'false') {
+                               $newPermissions = \OCP\Constants::PERMISSION_READ;
+                       }
+
+                       if ($permissions !== null) {
+                               $newPermissions = (int)$permissions;
+                       }
+
+                       if ($newPermissions !== null &&
+                               !in_array($newPermissions, [
+                                       \OCP\Constants::PERMISSION_READ,
+                                       \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE, // legacy
+                                       \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE, // correct
+                                       \OCP\Constants::PERMISSION_CREATE, // hidden file list
+                               ])
+                       ) {
+                               throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
+                       }
+
+                       if (
+                               // legacy
+                               $newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE) ||
+                               // correct
+                               $newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE)
+                       ) {
+                               if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
+                                       throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
+                               }
+
+                               if (!($share->getNode() instanceof \OCP\Files\Folder)) {
+                                       throw new OCSBadRequestException($this->l->t('Public upload is only possible for publicly shared folders'));
+                               }
+
+                               // normalize to correct public upload permissions
+                               $newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
+                       }
+
+                       if ($newPermissions !== null) {
+                               $share->setPermissions($newPermissions);
+                       }
+
+                       if ($expireDate === '') {
+                               $share->setExpirationDate(null);
+                       } else if ($expireDate !== null) {
+                               try {
+                                       $expireDate = $this->parseDate($expireDate);
+                               } catch (\Exception $e) {
+                                       throw new OCSBadRequestException($e->getMessage());
+                               }
+                               $share->setExpirationDate($expireDate);
+                       }
+
+                       if ($password === '') {
+                               $share->setPassword(null);
+                       } else if ($password !== null) {
+                               $share->setPassword($password);
+                       }
+
+               } else {
+                       // For other shares only permissions is valid.
+                       if ($permissions === null) {
+                               throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
+                       } else {
+                               $permissions = (int)$permissions;
+                               $share->setPermissions($permissions);
+                       }
+               }
+
+               if ($permissions !== null && $share->getShareOwner() !== $this->currentUser) {
+                       /* Check if this is an incomming share */
+                       $incomingShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $share->getNode(), -1, 0);
+                       $incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0));
+
+                       /** @var \OCP\Share\IShare[] $incomingShares */
+                       if (!empty($incomingShares)) {
+                               $maxPermissions = 0;
+                               foreach ($incomingShares as $incomingShare) {
+                                       $maxPermissions |= $incomingShare->getPermissions();
+                               }
+
+                               if ($share->getPermissions() & ~$maxPermissions) {
+                                       throw new OCSNotFoundException($this->l->t('Cannot increase permissions'));
+                               }
+                       }
+               }
+
+
+               try {
+                       $share = $this->shareManager->updateShare($share);
+               } catch (\Exception $e) {
+                       throw new OCSBadRequestException($e->getMessage());
+               }
+
+               return new DataResponse($this->formatShare($share));
+       }
+
+       /**
+        * @param \OCP\Share\IShare $share
+        * @return bool
+        */
+       protected function canAccessShare(\OCP\Share\IShare $share, $checkGroups = true) {
+               // A file with permissions 0 can't be accessed by us. So Don't show it
+               if ($share->getPermissions() === 0) {
+                       return false;
+               }
+
+               // Owner of the file and the sharer of the file can always get share
+               if ($share->getShareOwner() === $this->currentUser ||
+                       $share->getSharedBy() === $this->currentUser
+               ) {
+                       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 &&
+                       $share->getSharedWith() === $this->currentUser
+               ) {
+                       return true;
+               }
+
+               if ($checkGroups && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
+                       $sharedWith = $this->groupManager->get($share->getSharedWith());
+                       $user = $this->userManager->get($this->currentUser);
+                       if ($user !== null && $sharedWith->inGroup($user)) {
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+
+       /**
+        * 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;
+       }
+
+       /**
+        * 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;
+       }
+
+       /**
+        * Lock a Node
+        *
+        * @param \OCP\Files\Node $node
+        */
+       private function lock(\OCP\Files\Node $node) {
+               $node->lock(ILockingProvider::LOCK_SHARED);
+               $this->lockedNode = $node;
+       }
+
+       /**
+        * Cleanup the remaining locks
+        */
+       public function cleanup() {
+               if ($this->lockedNode !== null) {
+                       $this->lockedNode->unlock(ILockingProvider::LOCK_SHARED);
+               }
+       }
+}
index 04a6545c9a7f4eb0dfac37dcb1e4f06664326b2c..5d2c168e876d9ee28c8c8c683349bdc1c3d6786d 100644 (file)
@@ -2,7 +2,7 @@
 
 namespace OCA\Files_Sharing\Middleware;
 
-use OCA\Files_Sharing\API\Share20OCS;
+use OCA\Files_Sharing\Controller\ShareAPIController;
 use OCP\AppFramework\Http\Response;
 use OCP\AppFramework\Middleware;
 use OCP\AppFramework\OCS\OCSNotFoundException;
@@ -28,7 +28,7 @@ class OCSShareAPIMiddleware extends Middleware {
         * @throws OCSNotFoundException
         */
        public function beforeController($controller, $methodName) {
-               if ($controller instanceof Share20OCS) {
+               if ($controller instanceof ShareAPIController) {
                        if (!$this->shareManager->shareApiEnabled()) {
                                throw new OCSNotFoundException($this->l->t('Share API is disabled'));
                        }
@@ -42,8 +42,8 @@ class OCSShareAPIMiddleware extends Middleware {
         * @return Response
         */
        public function afterController($controller, $methodName, Response $response) {
-               if ($controller instanceof Share20OCS) {
-                       /** @var Share20OCS $controller */
+               if ($controller instanceof ShareAPIController) {
+                       /** @var ShareAPIController $controller */
                        $controller->cleanup();
                }
 
diff --git a/apps/files_sharing/tests/API/Share20OCSTest.php b/apps/files_sharing/tests/API/Share20OCSTest.php
deleted file mode 100644 (file)
index f9579b8..0000000
+++ /dev/null
@@ -1,1997 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @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/>
- *
- */
-namespace OCA\Files_Sharing\Tests\API;
-
-use OCP\AppFramework\Http\DataResponse;
-use OCP\AppFramework\OCS\OCSNotFoundException;
-use OCP\Files\Folder;
-use OCP\IL10N;
-use OCA\Files_Sharing\API\Share20OCS;
-use OCP\Files\NotFoundException;
-use OCP\IGroupManager;
-use OCP\IUserManager;
-use OCP\IRequest;
-use OCP\IURLGenerator;
-use OCP\IUser;
-use OCP\Files\IRootFolder;
-use OCP\Lock\LockedException;
-
-/**
- * Class Share20OCSTest
- *
- * @package OCA\Files_Sharing\Tests\API
- * @group DB
- */
-class Share20OCSTest extends \Test\TestCase {
-
-       /** @var string */
-       private $appName = 'files_sharing';
-
-       /** @var \OC\Share20\Manager|\PHPUnit_Framework_MockObject_MockObject */
-       private $shareManager;
-
-       /** @var IGroupManager|\PHPUnit_Framework_MockObject_MockObject */
-       private $groupManager;
-
-       /** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */
-       private $userManager;
-
-       /** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */
-       private $request;
-
-       /** @var IRootFolder|\PHPUnit_Framework_MockObject_MockObject */
-       private $rootFolder;
-
-       /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
-       private $urlGenerator;
-
-       /** @var IUser|\PHPUnit_Framework_MockObject_MockObject */
-       private $currentUser;
-
-       /** @var Share20OCS */
-       private $ocs;
-
-       /** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */
-       private $l;
-
-       protected function setUp() {
-               $this->shareManager = $this->getMockBuilder('OCP\Share\IManager')
-                       ->disableOriginalConstructor()
-                       ->getMock();
-               $this->shareManager
-                       ->expects($this->any())
-                       ->method('shareApiEnabled')
-                       ->willReturn(true);
-               $this->groupManager = $this->getMockBuilder('OCP\IGroupManager')->getMock();
-               $this->userManager = $this->getMockBuilder('OCP\IUserManager')->getMock();
-               $this->request = $this->getMockBuilder('OCP\IRequest')->getMock();
-               $this->rootFolder = $this->getMockBuilder('OCP\Files\IRootFolder')->getMock();
-               $this->urlGenerator = $this->getMockBuilder('OCP\IURLGenerator')->getMock();
-               $this->currentUser = $this->getMockBuilder('OCP\IUser')->getMock();
-               $this->currentUser->method('getUID')->willReturn('currentUser');
-
-               $this->l = $this->getMockBuilder('\OCP\IL10N')->getMock();
-               $this->l->method('t')
-                       ->will($this->returnCallback(function($text, $parameters = []) {
-                               return vsprintf($text, $parameters);
-                       }));
-
-               $this->ocs = new Share20OCS(
-                       $this->appName,
-                       $this->request,
-                       $this->shareManager,
-                       $this->groupManager,
-                       $this->userManager,
-                       $this->rootFolder,
-                       $this->urlGenerator,
-                       $this->currentUser,
-                       $this->l
-               );
-       }
-
-       /**
-        * @return Share20OCS|\PHPUnit_Framework_MockObject_MockObject
-        */
-       private function mockFormatShare() {
-               return $this->getMockBuilder(Share20OCS::class)
-                       ->setConstructorArgs([
-                               $this->appName,
-                               $this->request,
-                               $this->shareManager,
-                               $this->groupManager,
-                               $this->userManager,
-                               $this->rootFolder,
-                               $this->urlGenerator,
-                               $this->currentUser,
-                               $this->l,
-                       ])->setMethods(['formatShare'])
-                       ->getMock();
-       }
-
-       private function newShare() {
-               return \OC::$server->getShareManager()->newShare();
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
-        * @expectedExceptionMessage Wrong share ID, share doesn't exist
-        */
-       public function testDeleteShareShareNotFound() {
-               $this->shareManager
-                       ->expects($this->exactly(2))
-                       ->method('getShareById')
-                       ->will($this->returnCallback(function($id) {
-                               if ($id === 'ocinternal:42' || $id === 'ocFederatedSharing:42') {
-                                       throw new \OCP\Share\Exceptions\ShareNotFound();
-                               } else {
-                                       throw new \Exception();
-                               }
-                       }));
-
-               $this->shareManager->method('outgoingServer2ServerSharesAllowed')->willReturn(true);
-
-               $this->ocs->deleteShare(42);
-       }
-
-       public function testDeleteShare() {
-               $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
-
-               $share = $this->newShare();
-               $share->setSharedBy($this->currentUser->getUID())
-                       ->setNode($node);
-               $this->shareManager
-                       ->expects($this->once())
-                       ->method('getShareById')
-                       ->with('ocinternal:42')
-                       ->willReturn($share);
-               $this->shareManager
-                       ->expects($this->once())
-                       ->method('deleteShare')
-                       ->with($share);
-
-               $node->expects($this->once())
-                       ->method('lock')
-                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
-
-               $expected = new DataResponse();
-               $result = $this->ocs->deleteShare(42);
-
-               $this->assertInstanceOf(get_class($expected), $result);
-               $this->assertEquals($expected->getData(), $result->getData());
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
-        * @expectedExceptionMessage could not delete share
-        */
-       public function testDeleteShareLocked() {
-               $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
-
-               $share = $this->newShare();
-               $share->setSharedBy($this->currentUser->getUID())
-                       ->setNode($node);
-               $this->shareManager
-                       ->expects($this->once())
-                       ->method('getShareById')
-                       ->with('ocinternal:42')
-                       ->willReturn($share);
-               $this->shareManager
-                       ->expects($this->never())
-                       ->method('deleteShare')
-                       ->with($share);
-
-               $node->expects($this->once())
-                       ->method('lock')
-                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED)
-                       ->will($this->throwException(new LockedException('mypath')));
-
-               $this->ocs->deleteShare(42);
-       }
-
-       /*
-        * FIXME: Enable once we have a federated Share Provider
-
-       public function testGetGetShareNotExists() {
-               $this->shareManager
-                       ->expects($this->once())
-                       ->method('getShareById')
-                       ->with('ocinternal:42')
-                       ->will($this->throwException(new \OC\Share20\Exception\ShareNotFound()));
-
-               $expected = new \OC_OCS_Result(null, 404, 'wrong share ID, share doesn\'t exist.');
-               $this->assertEquals($expected, $this->ocs->getShare(42));
-       }
-       */
-
-       public function createShare($id, $shareType, $sharedWith, $sharedBy, $shareOwner, $path, $permissions,
-                                                               $shareTime, $expiration, $parent, $target, $mail_send, $token=null,
-                                                               $password=null) {
-               $share = $this->getMockBuilder('\OCP\Share\IShare')->getMock();
-               $share->method('getId')->willReturn($id);
-               $share->method('getShareType')->willReturn($shareType);
-               $share->method('getSharedWith')->willReturn($sharedWith);
-               $share->method('getSharedBy')->willReturn($sharedBy);
-               $share->method('getShareOwner')->willReturn($shareOwner);
-               $share->method('getNode')->willReturn($path);
-               $share->method('getPermissions')->willReturn($permissions);
-               $time = new \DateTime();
-               $time->setTimestamp($shareTime);
-               $share->method('getShareTime')->willReturn($time);
-               $share->method('getExpirationDate')->willReturn($expiration);
-               $share->method('getTarget')->willReturn($target);
-               $share->method('getMailSend')->willReturn($mail_send);
-               $share->method('getToken')->willReturn($token);
-               $share->method('getPassword')->willReturn($password);
-
-               if ($shareType === \OCP\Share::SHARE_TYPE_USER  ||
-                       $shareType === \OCP\Share::SHARE_TYPE_GROUP ||
-                       $shareType === \OCP\Share::SHARE_TYPE_LINK) {
-                       $share->method('getFullId')->willReturn('ocinternal:'.$id);
-               }
-
-               return $share;
-       }
-
-       public function dataGetShare() {
-               $data = [];
-
-               $cache = $this->getMockBuilder('OC\Files\Cache\Cache')
-                       ->disableOriginalConstructor()
-                       ->getMock();
-               $cache->method('getNumericStorageId')->willReturn(101);
-
-               $storage = $this->getMockBuilder('OC\Files\Storage\Storage')
-                       ->disableOriginalConstructor()
-                       ->getMock();
-               $storage->method('getId')->willReturn('STORAGE');
-               $storage->method('getCache')->willReturn($cache);
-
-               $parentFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
-               $parentFolder->method('getId')->willReturn(3);
-
-               $file = $this->getMockBuilder('OCP\Files\File')->getMock();
-               $file->method('getId')->willReturn(1);
-               $file->method('getPath')->willReturn('file');
-               $file->method('getStorage')->willReturn($storage);
-               $file->method('getParent')->willReturn($parentFolder);
-               $file->method('getMimeType')->willReturn('myMimeType');
-
-               $folder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
-               $folder->method('getId')->willReturn(2);
-               $folder->method('getPath')->willReturn('folder');
-               $folder->method('getStorage')->willReturn($storage);
-               $folder->method('getParent')->willReturn($parentFolder);
-               $folder->method('getMimeType')->willReturn('myFolderMimeType');
-
-               // File shared with user
-               $share = $this->createShare(
-                       100,
-                       \OCP\Share::SHARE_TYPE_USER,
-                       'userId',
-                       'initiatorId',
-                       'ownerId',
-                       $file,
-                       4,
-                       5,
-                       null,
-                       6,
-                       'target',
-                       0
-               );
-               $expected = [
-                       'id' => 100,
-                       'share_type' => \OCP\Share::SHARE_TYPE_USER,
-                       'share_with' => 'userId',
-                       'share_with_displayname' => 'userDisplay',
-                       'uid_owner' => 'initiatorId',
-                       'displayname_owner' => 'initiatorDisplay',
-                       'item_type' => 'file',
-                       'item_source' => 1,
-                       'file_source' => 1,
-                       'file_target' => 'target',
-                       'file_parent' => 3,
-                       'token' => null,
-                       'expiration' => null,
-                       'permissions' => 4,
-                       'stime' => 5,
-                       'parent' => null,
-                       'storage_id' => 'STORAGE',
-                       'path' => 'file',
-                       'storage' => 101,
-                       'mail_send' => 0,
-                       'uid_file_owner' => 'ownerId',
-                       'displayname_file_owner' => 'ownerDisplay',
-                       'mimetype' => 'myMimeType',
-               ];
-               $data[] = [$share, $expected];
-
-               // Folder shared with group
-               $share = $this->createShare(
-                       101,
-                       \OCP\Share::SHARE_TYPE_GROUP,
-                       'groupId',
-                       'initiatorId',
-                       'ownerId',
-                       $folder,
-                       4,
-                       5,
-                       null,
-                       6,
-                       'target',
-                       0
-               );
-               $expected = [
-                       'id' => 101,
-                       'share_type' => \OCP\Share::SHARE_TYPE_GROUP,
-                       'share_with' => 'groupId',
-                       'share_with_displayname' => 'groupId',
-                       'uid_owner' => 'initiatorId',
-                       'displayname_owner' => 'initiatorDisplay',
-                       'item_type' => 'folder',
-                       'item_source' => 2,
-                       'file_source' => 2,
-                       'file_target' => 'target',
-                       'file_parent' => 3,
-                       'token' => null,
-                       'expiration' => null,
-                       'permissions' => 4,
-                       'stime' => 5,
-                       'parent' => null,
-                       'storage_id' => 'STORAGE',
-                       'path' => 'folder',
-                       'storage' => 101,
-                       'mail_send' => 0,
-                       'uid_file_owner' => 'ownerId',
-                       'displayname_file_owner' => 'ownerDisplay',
-                       'mimetype' => 'myFolderMimeType',
-               ];
-               $data[] = [$share, $expected];
-
-               // File shared by link with Expire
-               $expire = \DateTime::createFromFormat('Y-m-d h:i:s', '2000-01-02 01:02:03');
-               $share = $this->createShare(
-                       101,
-                       \OCP\Share::SHARE_TYPE_LINK,
-                       null,
-                       'initiatorId',
-                       'ownerId',
-                       $folder,
-                       4,
-                       5,
-                       $expire,
-                       6,
-                       'target',
-                       0,
-                       'token',
-                       'password'
-               );
-               $expected = [
-                       'id' => 101,
-                       'share_type' => \OCP\Share::SHARE_TYPE_LINK,
-                       'share_with' => 'password',
-                       'share_with_displayname' => 'password',
-                       'uid_owner' => 'initiatorId',
-                       'displayname_owner' => 'initiatorDisplay',
-                       'item_type' => 'folder',
-                       'item_source' => 2,
-                       'file_source' => 2,
-                       'file_target' => 'target',
-                       'file_parent' => 3,
-                       'token' => 'token',
-                       'expiration' => '2000-01-02 00:00:00',
-                       'permissions' => 4,
-                       'stime' => 5,
-                       'parent' => null,
-                       'storage_id' => 'STORAGE',
-                       'path' => 'folder',
-                       'storage' => 101,
-                       'mail_send' => 0,
-                       'url' => 'url',
-                       'uid_file_owner' => 'ownerId',
-                       'displayname_file_owner' => 'ownerDisplay',
-                       'mimetype' => 'myFolderMimeType',
-               ];
-               $data[] = [$share, $expected];
-
-               return $data;
-       }
-
-       /**
-        * @dataProvider dataGetShare
-        */
-       public function testGetShare(\OCP\Share\IShare $share, array $result) {
-               $ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS')
-                               ->setConstructorArgs([
-                                       $this->appName,
-                                       $this->request,
-                                       $this->shareManager,
-                                       $this->groupManager,
-                                       $this->userManager,
-                                       $this->rootFolder,
-                                       $this->urlGenerator,
-                                       $this->currentUser,
-                                       $this->l,
-                               ])->setMethods(['canAccessShare'])
-                               ->getMock();
-
-               $ocs->expects($this->any())
-                       ->method('canAccessShare')
-                       ->willReturn(true);
-
-               $this->shareManager
-                       ->expects($this->once())
-                       ->method('getShareById')
-                       ->with($share->getFullId())
-                       ->willReturn($share);
-
-               $userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
-               $userFolder
-                       ->method('getRelativePath')
-                       ->will($this->returnArgument(0));
-
-               $userFolder->method('getById')
-                       ->with($share->getNodeId())
-                       ->willReturn([$share->getNode()]);
-
-               $this->rootFolder->method('getUserFolder')
-                       ->with($this->currentUser->getUID())
-                       ->willReturn($userFolder);
-
-               $this->urlGenerator
-                       ->method('linkToRouteAbsolute')
-                       ->willReturn('url');
-
-               $initiator = $this->getMockBuilder('OCP\IUser')->getMock();
-               $initiator->method('getUID')->willReturn('initiatorId');
-               $initiator->method('getDisplayName')->willReturn('initiatorDisplay');
-
-               $owner = $this->getMockBuilder('OCP\IUser')->getMock();
-               $owner->method('getUID')->willReturn('ownerId');
-               $owner->method('getDisplayName')->willReturn('ownerDisplay');
-
-               $user = $this->getMockBuilder('OCP\IUser')->getMock();
-               $user->method('getUID')->willReturn('userId');
-               $user->method('getDisplayName')->willReturn('userDisplay');
-
-               $group = $this->getMockBuilder('OCP\IGroup')->getMock();
-               $group->method('getGID')->willReturn('groupId');
-
-               $this->userManager->method('get')->will($this->returnValueMap([
-                       ['userId', $user],
-                       ['initiatorId', $initiator],
-                       ['ownerId', $owner],
-               ]));
-               $this->groupManager->method('get')->will($this->returnValueMap([
-                       ['group', $group],
-               ]));
-
-               $this->assertEquals($result, $ocs->getShare($share->getId())->getData()[0]);
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
-        * @expectedExceptionMessage Wrong share ID, share doesn't exist
-        */
-       public function testGetShareInvalidNode() {
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setSharedBy('initiator')
-                       ->setSharedWith('recipient')
-                       ->setShareOwner('owner');
-
-               $this->shareManager
-                       ->expects($this->once())
-                       ->method('getShareById')
-                       ->with('ocinternal:42')
-                       ->willReturn($share);
-
-               $this->ocs->getShare(42);
-       }
-
-       public function testCanAccessShare() {
-               $share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
-               $share->method('getShareOwner')->willReturn($this->currentUser->getUID());
-               $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
-
-               $share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
-               $share->method('getSharedBy')->willReturn($this->currentUser->getUID());
-               $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
-
-               $share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
-               $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER);
-               $share->method('getSharedWith')->willReturn($this->currentUser->getUID());
-               $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
-
-               $share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
-               $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER);
-               $share->method('getSharedWith')->willReturn($this->getMockBuilder('OCP\IUser')->getMock());
-               $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
-
-               $share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
-               $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_GROUP);
-               $share->method('getSharedWith')->willReturn('group');
-
-               $group = $this->getMockBuilder('OCP\IGroup')->getMock();
-               $group->method('inGroup')->with($this->currentUser)->willReturn(true);
-               $group2 = $this->getMockBuilder('OCP\IGroup')->getMock();
-               $group2->method('inGroup')->with($this->currentUser)->willReturn(false);
-
-
-               $this->groupManager->method('get')->will($this->returnValueMap([
-                       ['group', $group],
-                       ['group2', $group2],
-               ]));
-               $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
-
-               $share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
-               $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_GROUP);
-               $share->method('getSharedWith')->willReturn('group2');
-
-               $this->groupManager->method('get')->with('group2')->willReturn($group);
-               $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
-
-               $share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
-               $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_LINK);
-               $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
-        * @expectedExceptionMessage Please specify a file or folder path
-        */
-       public function testCreateShareNoPath() {
-               $this->ocs->createShare();
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
-        * @expectedExceptionMessage Wrong path, file/folder doesn't exist
-        */
-       public function testCreateShareInvalidPath() {
-               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $this->rootFolder->expects($this->once())
-                       ->method('getUserFolder')
-                       ->with('currentUser')
-                       ->willReturn($userFolder);
-
-               $userFolder->expects($this->once())
-                       ->method('get')
-                       ->with('invalid-path')
-                       ->will($this->throwException(new \OCP\Files\NotFoundException()));
-
-               $this->ocs->createShare('invalid-path');
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
-        * @expectedExceptionMessage invalid permissions
-        */
-       public function testCreateShareInvalidPermissions() {
-               $share = $this->newShare();
-               $this->shareManager->method('newShare')->willReturn($share);
-
-               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $this->rootFolder->expects($this->once())
-                               ->method('getUserFolder')
-                               ->with('currentUser')
-                               ->willReturn($userFolder);
-
-               $path = $this->getMockBuilder('\OCP\Files\File')->getMock();
-               $userFolder->expects($this->once())
-                               ->method('get')
-                               ->with('valid-path')
-                               ->willReturn($path);
-
-               $path->expects($this->once())
-                       ->method('lock')
-                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
-
-               $this->ocs->createShare('valid-path', 32);
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
-        * @expectedExceptionMessage Please specify a valid user
-        */
-       public function testCreateShareUserNoShareWith() {
-               $share = $this->newShare();
-               $this->shareManager->method('newShare')->willReturn($share);
-
-               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $this->rootFolder->expects($this->once())
-                       ->method('getUserFolder')
-                       ->with('currentUser')
-                       ->willReturn($userFolder);
-
-               $path = $this->getMockBuilder('\OCP\Files\File')->getMock();
-               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
-               $storage->method('instanceOfStorage')
-                       ->with('OCA\Files_Sharing\External\Storage')
-                       ->willReturn(false);
-               $path->method('getStorage')->willReturn($storage);
-               $userFolder->expects($this->once())
-                       ->method('get')
-                       ->with('valid-path')
-                       ->willReturn($path);
-
-               $path->expects($this->once())
-                       ->method('lock')
-                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
-
-               $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_USER);
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
-        * @expectedExceptionMessage Please specify a valid user
-        */
-       public function testCreateShareUserNoValidShareWith() {
-               $share = $this->newShare();
-               $this->shareManager->method('newShare')->willReturn($share);
-
-               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $this->rootFolder->expects($this->once())
-                       ->method('getUserFolder')
-                       ->with('currentUser')
-                       ->willReturn($userFolder);
-
-               $path = $this->getMockBuilder('\OCP\Files\File')->getMock();
-               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
-               $storage->method('instanceOfStorage')
-                       ->with('OCA\Files_Sharing\External\Storage')
-                       ->willReturn(false);
-               $path->method('getStorage')->willReturn($storage);
-               $userFolder->expects($this->once())
-                       ->method('get')
-                       ->with('valid-path')
-                       ->willReturn($path);
-               $path->expects($this->once())
-                       ->method('lock')
-                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
-               $this->userManager->method('userExists')
-                       ->with('invalidUser')
-                       ->willReturn(false);
-
-               $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_USER, 'invalidUser');
-       }
-
-       public function testCreateShareUser() {
-               $share = $this->newShare();
-               $this->shareManager->method('newShare')->willReturn($share);
-
-               /** @var \OCA\Files_Sharing\API\Share20OCS $ocs */
-               $ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS')
-                       ->setConstructorArgs([
-                               $this->appName,
-                               $this->request,
-                               $this->shareManager,
-                               $this->groupManager,
-                               $this->userManager,
-                               $this->rootFolder,
-                               $this->urlGenerator,
-                               $this->currentUser,
-                               $this->l,
-                       ])->setMethods(['formatShare'])
-                       ->getMock();
-
-               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $this->rootFolder->expects($this->once())
-                               ->method('getUserFolder')
-                               ->with('currentUser')
-                               ->willReturn($userFolder);
-
-               $path = $this->getMockBuilder('\OCP\Files\File')->getMock();
-               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
-               $storage->method('instanceOfStorage')
-                       ->with('OCA\Files_Sharing\External\Storage')
-                       ->willReturn(false);
-               $path->method('getStorage')->willReturn($storage);
-               $userFolder->expects($this->once())
-                               ->method('get')
-                               ->with('valid-path')
-                               ->willReturn($path);
-
-               $this->userManager->method('userExists')->with('validUser')->willReturn(true);
-
-               $path->expects($this->once())
-                       ->method('lock')
-                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
-
-               $this->shareManager->method('createShare')
-                       ->with($this->callback(function (\OCP\Share\IShare $share) use ($path) {
-                               return $share->getNode() === $path &&
-                                       $share->getPermissions() === (
-                                               \OCP\Constants::PERMISSION_ALL &
-                                               ~\OCP\Constants::PERMISSION_DELETE &
-                                               ~\OCP\Constants::PERMISSION_CREATE
-                                       ) &&
-                                       $share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
-                                       $share->getSharedWith() === 'validUser' &&
-                                       $share->getSharedBy() === 'currentUser';
-                       }))
-                       ->will($this->returnArgument(0));
-
-               $expected = new DataResponse(null);
-               $result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_USER, 'validUser');
-
-               $this->assertInstanceOf(get_class($expected), $result);
-               $this->assertEquals($expected->getData(), $result->getData());
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
-        * @expectedExceptionMessage Please specify a valid group
-        */
-       public function testCreateShareGroupNoValidShareWith() {
-               $share = $this->newShare();
-               $this->shareManager->method('newShare')->willReturn($share);
-               $this->shareManager->method('createShare')->will($this->returnArgument(0));
-               $this->shareManager->method('allowGroupSharing')->willReturn(true);
-
-               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $this->rootFolder->expects($this->once())
-                               ->method('getUserFolder')
-                               ->with('currentUser')
-                               ->willReturn($userFolder);
-
-               $path = $this->getMockBuilder('\OCP\Files\File')->getMock();
-               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
-               $storage->method('instanceOfStorage')
-                       ->with('OCA\Files_Sharing\External\Storage')
-                       ->willReturn(false);
-               $path->method('getStorage')->willReturn($storage);
-               $userFolder->expects($this->once())
-                               ->method('get')
-                               ->with('valid-path')
-                               ->willReturn($path);
-
-               $path->expects($this->once())
-                       ->method('lock')
-                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
-
-               $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_GROUP, 'invalidGroup');
-       }
-
-       public function testCreateShareGroup() {
-               $share = $this->newShare();
-               $this->shareManager->method('newShare')->willReturn($share);
-
-               $ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS')
-                       ->setConstructorArgs([
-                               $this->appName,
-                               $this->request,
-                               $this->shareManager,
-                               $this->groupManager,
-                               $this->userManager,
-                               $this->rootFolder,
-                               $this->urlGenerator,
-                               $this->currentUser,
-                               $this->l,
-                       ])->setMethods(['formatShare'])
-                       ->getMock();
-
-               $this->request
-                       ->method('getParam')
-                       ->will($this->returnValueMap([
-                               ['path', null, 'valid-path'],
-                               ['permissions', null, \OCP\Constants::PERMISSION_ALL],
-                               ['shareType', '-1', \OCP\Share::SHARE_TYPE_GROUP],
-                               ['shareWith', null, 'validGroup'],
-                       ]));
-
-               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $this->rootFolder->expects($this->once())
-                       ->method('getUserFolder')
-                       ->with('currentUser')
-                       ->willReturn($userFolder);
-
-               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
-               $storage->method('instanceOfStorage')
-                       ->with('OCA\Files_Sharing\External\Storage')
-                       ->willReturn(false);
-               $path->method('getStorage')->willReturn($storage);
-               $userFolder->expects($this->once())
-                       ->method('get')
-                       ->with('valid-path')
-                       ->willReturn($path);
-
-               $this->groupManager->method('groupExists')->with('validGroup')->willReturn(true);
-
-               $this->shareManager->expects($this->once())
-                       ->method('allowGroupSharing')
-                       ->willReturn(true);
-
-               $path->expects($this->once())
-                       ->method('lock')
-                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
-
-               $this->shareManager->method('createShare')
-                       ->with($this->callback(function (\OCP\Share\IShare $share) use ($path) {
-                               return $share->getNode() === $path &&
-                               $share->getPermissions() === \OCP\Constants::PERMISSION_ALL &&
-                               $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP &&
-                               $share->getSharedWith() === 'validGroup' &&
-                               $share->getSharedBy() === 'currentUser';
-                       }))
-                       ->will($this->returnArgument(0));
-
-               $expected = new DataResponse(null);
-               $result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_GROUP, 'validGroup');
-
-               $this->assertInstanceOf(get_class($expected), $result);
-               $this->assertEquals($expected->getData(), $result->getData());
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
-        * @expectedExceptionMessage Group sharing is disabled by the administrator
-        */
-       public function testCreateShareGroupNotAllowed() {
-               $share = $this->newShare();
-               $this->shareManager->method('newShare')->willReturn($share);
-
-               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $this->rootFolder->expects($this->once())
-                       ->method('getUserFolder')
-                       ->with('currentUser')
-                       ->willReturn($userFolder);
-
-               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
-               $storage->method('instanceOfStorage')
-                       ->with('OCA\Files_Sharing\External\Storage')
-                       ->willReturn(false);
-               $path->method('getStorage')->willReturn($storage);
-               $userFolder->expects($this->once())
-                       ->method('get')
-                       ->with('valid-path')
-                       ->willReturn($path);
-
-               $this->groupManager->method('groupExists')->with('validGroup')->willReturn(true);
-
-               $this->shareManager->expects($this->once())
-                       ->method('allowGroupSharing')
-                       ->willReturn(false);
-
-               $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_GROUP, 'invalidGroup');
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
-        * @expectedExceptionMessage Public link sharing is disabled by the administrator
-        */
-       public function testCreateShareLinkNoLinksAllowed() {
-               $this->request
-                       ->method('getParam')
-                       ->will($this->returnValueMap([
-                               ['path', null, 'valid-path'],
-                               ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK],
-                       ]));
-
-               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
-               $storage->method('instanceOfStorage')
-                       ->with('OCA\Files_Sharing\External\Storage')
-                       ->willReturn(false);
-               $path->method('getStorage')->willReturn($storage);
-               $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf());
-               $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
-
-               $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
-
-               $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK);
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSForbiddenException
-        * @expectedExceptionMessage Public upload disabled by the administrator
-        */
-       public function testCreateShareLinkNoPublicUpload() {
-               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
-               $storage->method('instanceOfStorage')
-                       ->with('OCA\Files_Sharing\External\Storage')
-                       ->willReturn(false);
-               $path->method('getStorage')->willReturn($storage);
-               $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf());
-               $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
-
-               $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
-               $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
-
-               $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'true');
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
-        * @expectedExceptionMessage Public upload is only possible for publicly shared folders
-        */
-       public function testCreateShareLinkPublicUploadFile() {
-               $path = $this->getMockBuilder('\OCP\Files\File')->getMock();
-               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
-               $storage->method('instanceOfStorage')
-                       ->with('OCA\Files_Sharing\External\Storage')
-                       ->willReturn(false);
-               $path->method('getStorage')->willReturn($storage);
-               $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf());
-               $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
-
-               $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
-               $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
-               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
-               $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'true');
-       }
-
-       public function testCreateShareLinkPublicUploadFolder() {
-               $ocs = $this->mockFormatShare();
-
-               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
-               $storage->method('instanceOfStorage')
-                       ->with('OCA\Files_Sharing\External\Storage')
-                       ->willReturn(false);
-               $path->method('getStorage')->willReturn($storage);
-               $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf());
-               $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
-
-               $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
-               $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
-               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
-               $this->shareManager->expects($this->once())->method('createShare')->with(
-                       $this->callback(function (\OCP\Share\IShare $share) use ($path) {
-                               return $share->getNode() === $path &&
-                                       $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
-                                       $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) &&
-                                       $share->getSharedBy() === 'currentUser' &&
-                                       $share->getPassword() === null &&
-                                       $share->getExpirationDate() === null;
-                       })
-               )->will($this->returnArgument(0));
-
-               $expected = new DataResponse(null);
-               $result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'true', '', '');
-
-               $this->assertInstanceOf(get_class($expected), $result);
-               $this->assertEquals($expected->getData(), $result->getData());
-       }
-
-       public function testCreateShareLinkPassword() {
-               $ocs = $this->mockFormatShare();
-
-               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
-               $storage->method('instanceOfStorage')
-                       ->with('OCA\Files_Sharing\External\Storage')
-                       ->willReturn(false);
-               $path->method('getStorage')->willReturn($storage);
-               $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf());
-               $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
-
-               $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
-               $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
-               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
-               $this->shareManager->expects($this->once())->method('createShare')->with(
-                       $this->callback(function (\OCP\Share\IShare $share) use ($path) {
-                               return $share->getNode() === $path &&
-                               $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
-                               $share->getPermissions() === \OCP\Constants::PERMISSION_READ &&
-                               $share->getSharedBy() === 'currentUser' &&
-                               $share->getPassword() === 'password' &&
-                               $share->getExpirationDate() === null;
-                       })
-               )->will($this->returnArgument(0));
-
-               $expected = new DataResponse(null);
-               $result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', 'password', '');
-
-               $this->assertInstanceOf(get_class($expected), $result);
-               $this->assertEquals($expected->getData(), $result->getData());
-       }
-
-       public function testCreateShareValidExpireDate() {
-               $ocs = $this->mockFormatShare();
-
-               $this->request
-                       ->method('getParam')
-                       ->will($this->returnValueMap([
-                               ['path', null, 'valid-path'],
-                               ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK],
-                               ['publicUpload', null, 'false'],
-                               ['expireDate', '', '2000-01-01'],
-                               ['password', '', ''],
-                       ]));
-
-               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
-               $storage->method('instanceOfStorage')
-                       ->with('OCA\Files_Sharing\External\Storage')
-                       ->willReturn(false);
-               $path->method('getStorage')->willReturn($storage);
-               $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf());
-               $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
-
-               $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
-               $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
-               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
-               $this->shareManager->expects($this->once())->method('createShare')->with(
-                       $this->callback(function (\OCP\Share\IShare $share) use ($path) {
-                               $date = new \DateTime('2000-01-01');
-                               $date->setTime(0,0,0);
-
-                               return $share->getNode() === $path &&
-                               $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
-                               $share->getPermissions() === \OCP\Constants::PERMISSION_READ &&
-                               $share->getSharedBy() === 'currentUser' &&
-                               $share->getPassword() === null &&
-                               $share->getExpirationDate() == $date;
-                       })
-               )->will($this->returnArgument(0));
-
-               $expected = new DataResponse(null);
-               $result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', '2000-01-01');
-
-               $this->assertInstanceOf(get_class($expected), $result);
-               $this->assertEquals($expected->getData(), $result->getData());
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
-        * @expectedExceptionMessage Invalid date, date format must be YYYY-MM-DD
-        */
-       public function testCreateShareInvalidExpireDate() {
-               $ocs = $this->mockFormatShare();
-
-               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
-               $storage->method('instanceOfStorage')
-                       ->with('OCA\Files_Sharing\External\Storage')
-                       ->willReturn(false);
-               $path->method('getStorage')->willReturn($storage);
-               $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf());
-               $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
-
-               $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
-               $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
-               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
-               $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', 'a1b2d3');
-       }
-
-       /**
-        * Test for https://github.com/owncloud/core/issues/22587
-        * TODO: Remove once proper solution is in place
-        */
-       public function testCreateReshareOfFederatedMountNoDeletePermissions() {
-               $share = \OC::$server->getShareManager()->newShare();
-               $this->shareManager->method('newShare')->willReturn($share);
-
-               $ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS')
-                       ->setConstructorArgs([
-                               $this->appName,
-                               $this->request,
-                               $this->shareManager,
-                               $this->groupManager,
-                               $this->userManager,
-                               $this->rootFolder,
-                               $this->urlGenerator,
-                               $this->currentUser,
-                               $this->l,
-                       ])->setMethods(['formatShare'])
-                       ->getMock();
-
-               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $this->rootFolder->expects($this->once())
-                       ->method('getUserFolder')
-                       ->with('currentUser')
-                       ->willReturn($userFolder);
-
-               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
-               $storage->method('instanceOfStorage')
-                       ->with('OCA\Files_Sharing\External\Storage')
-                       ->willReturn(true);
-               $path->method('getStorage')->willReturn($storage);
-               $path->method('getPermissions')->willReturn(\OCP\Constants::PERMISSION_READ);
-               $userFolder->expects($this->once())
-                       ->method('get')
-                       ->with('valid-path')
-                       ->willReturn($path);
-
-               $this->userManager->method('userExists')->with('validUser')->willReturn(true);
-
-               $this->shareManager
-                       ->expects($this->once())
-                       ->method('createShare')
-                       ->with($this->callback(function (\OCP\Share\IShare $share) {
-                               return $share->getPermissions() === \OCP\Constants::PERMISSION_READ;
-                       }))
-                       ->will($this->returnArgument(0));
-
-               $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_USER, 'validUser');
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
-        * @expectedExceptionMessage Wrong share ID, share doesn't exist
-        */
-       public function testUpdateShareCantAccess() {
-               $node = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $share = $this->newShare();
-               $share->setNode($node);
-
-               $node->expects($this->once())
-                       ->method('lock')
-                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-
-               $this->ocs->updateShare(42);
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSBadRequestException
-        * @expectedExceptionMessage Wrong or no update parameter given
-        */
-       public function testUpdateNoParametersLink() {
-               $node = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $share = $this->newShare();
-               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
-                       ->setNode($node);
-
-               $node->expects($this->once())
-                       ->method('lock')
-                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-
-               $this->ocs->updateShare(42);
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSBadRequestException
-        * @expectedExceptionMessage Wrong or no update parameter given
-        */
-       public function testUpdateNoParametersOther() {
-               $node = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $share = $this->newShare();
-               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
-                       ->setNode($node);
-
-               $node->expects($this->once())
-                       ->method('lock')
-                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-
-               $this->ocs->updateShare(42);
-       }
-
-       public function testUpdateLinkShareClear() {
-               $ocs = $this->mockFormatShare();
-
-               $node = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $share = $this->newShare();
-               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
-                       ->setPassword('password')
-                       ->setExpirationDate(new \DateTime())
-                       ->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setNode($node);
-
-               $node->expects($this->once())
-                       ->method('lock')
-                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-
-               $this->shareManager->expects($this->once())->method('updateShare')->with(
-                       $this->callback(function (\OCP\Share\IShare $share) {
-                               return $share->getPermissions() === \OCP\Constants::PERMISSION_READ &&
-                               $share->getPassword() === null &&
-                               $share->getExpirationDate() === null;
-                       })
-               )->will($this->returnArgument(0));
-
-               $expected = new DataResponse(null);
-               $result = $ocs->updateShare(42, null, '', 'false', '');
-
-               $this->assertInstanceOf(get_class($expected), $result);
-               $this->assertEquals($expected->getData(), $result->getData());
-       }
-
-       public function testUpdateLinkShareSet() {
-               $ocs = $this->mockFormatShare();
-
-               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
-                       ->setNode($folder);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
-               $this->shareManager->expects($this->once())->method('updateShare')->with(
-                       $this->callback(function (\OCP\Share\IShare $share) {
-                               $date = new \DateTime('2000-01-01');
-                               $date->setTime(0,0,0);
-
-                               return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) &&
-                               $share->getPassword() === 'password' &&
-                               $share->getExpirationDate() == $date;
-                       })
-               )->will($this->returnArgument(0));
-
-               $expected = new DataResponse(null);
-               $result = $ocs->updateShare(42, null, 'password', 'true', '2000-01-01');
-
-               $this->assertInstanceOf(get_class($expected), $result);
-               $this->assertEquals($expected->getData(), $result->getData());
-       }
-
-       /**
-        * @dataProvider publicUploadParamsProvider
-        */
-       public function testUpdateLinkShareEnablePublicUpload($permissions, $publicUpload, $expireDate, $password) {
-               $ocs = $this->mockFormatShare();
-
-               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
-                       ->setPassword('password')
-                       ->setNode($folder);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-               $this->shareManager->method('getSharedWith')->willReturn([]);
-
-               $this->shareManager->expects($this->once())->method('updateShare')->with(
-                       $this->callback(function (\OCP\Share\IShare $share) {
-                               return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) &&
-                               $share->getPassword() === 'password' &&
-                               $share->getExpirationDate() === null;
-                       })
-               )->will($this->returnArgument(0));
-
-               $expected = new DataResponse(null);
-               $result = $ocs->updateShare(42, $permissions, $password, $publicUpload, $expireDate);
-
-               $this->assertInstanceOf(get_class($expected), $result);
-               $this->assertEquals($expected->getData(), $result->getData());
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSBadRequestException
-        * @expectedExceptionMessage Invalid date. Format must be YYYY-MM-DD
-        */
-       public function testUpdateLinkShareInvalidDate() {
-               $ocs = $this->mockFormatShare();
-
-               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
-                       ->setNode($folder);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
-               $ocs->updateShare(42, null, 'password', 'true', '2000-01-a');
-       }
-
-       public function publicUploadParamsProvider() {
-               return [
-                       [null, 'true', null, 'password'],
-                       // legacy had no delete
-                       [
-                               \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE,
-                               null, null, 'password'
-                       ],
-                       // correct
-                       [
-                               \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE,
-                               null, null, 'password'
-                       ],
-               ];
-       }
-
-       /**
-        * @dataProvider publicUploadParamsProvider
-        * @expectedException \OCP\AppFramework\OCS\OCSForbiddenException
-        * @expectedExceptionMessage Public upload disabled by the administrator
-        */
-       public function testUpdateLinkSharePublicUploadNotAllowed($permissions, $publicUpload, $expireDate, $password) {
-               $ocs = $this->mockFormatShare();
-
-               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
-                       ->setNode($folder);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(false);
-
-               $ocs->updateShare(42, $permissions, $password, $publicUpload, $expireDate);
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSBadRequestException
-        * @expectedExceptionMessage Public upload is only possible for publicly shared folders
-        */
-       public function testUpdateLinkSharePublicUploadOnFile() {
-               $ocs = $this->mockFormatShare();
-
-               $file = $this->getMockBuilder('\OCP\Files\File')->getMock();
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
-                       ->setNode($file);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
-               $ocs->updateShare(42, null, 'password', 'true', '');
-       }
-
-       public function testUpdateLinkSharePasswordDoesNotChangeOther() {
-               $ocs = $this->mockFormatShare();
-
-               $date = new \DateTime('2000-01-01');
-               $date->setTime(0,0,0);
-
-               $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
-               $share = $this->newShare();
-               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
-                       ->setPassword('password')
-                       ->setExpirationDate($date)
-                       ->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setNode($node);
-
-               $node->expects($this->once())
-                       ->method('lock')
-                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-
-               $this->shareManager->expects($this->once())->method('updateShare')->with(
-                       $this->callback(function (\OCP\Share\IShare $share) use ($date) {
-                               return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL &&
-                               $share->getPassword() === 'newpassword' &&
-                               $share->getExpirationDate() === $date;
-                       })
-               )->will($this->returnArgument(0));
-
-               $expected = new DataResponse(null);
-               $result = $ocs->updateShare(42, null, 'newpassword', null, null);
-
-               $this->assertInstanceOf(get_class($expected), $result);
-               $this->assertEquals($expected->getData(), $result->getData());
-       }
-
-       public function testUpdateLinkShareExpireDateDoesNotChangeOther() {
-               $ocs = $this->mockFormatShare();
-
-               $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
-               $share = $this->newShare();
-               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
-                       ->setPassword('password')
-                       ->setExpirationDate(new \DateTime())
-                       ->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setNode($node);
-
-               $node->expects($this->once())
-                       ->method('lock')
-                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-
-               $this->shareManager->expects($this->once())->method('updateShare')->with(
-                       $this->callback(function (\OCP\Share\IShare $share) {
-                               $date = new \DateTime('2010-12-23');
-                               $date->setTime(0,0,0);
-
-                               return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL &&
-                               $share->getPassword() === 'password' &&
-                               $share->getExpirationDate() == $date;
-                       })
-               )->will($this->returnArgument(0));
-
-               $expected = new DataResponse(null);
-               $result = $ocs->updateShare(42, null, null, null, '2010-12-23');
-
-               $this->assertInstanceOf(get_class($expected), $result);
-               $this->assertEquals($expected->getData(), $result->getData());
-       }
-
-       public function testUpdateLinkSharePublicUploadDoesNotChangeOther() {
-               $ocs = $this->mockFormatShare();
-
-               $date = new \DateTime('2000-01-01');
-
-               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
-                       ->setPassword('password')
-                       ->setExpirationDate($date)
-                       ->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setNode($folder);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
-               $this->shareManager->expects($this->once())->method('updateShare')->with(
-                       $this->callback(function (\OCP\Share\IShare $share) use ($date) {
-                               return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) &&
-                               $share->getPassword() === 'password' &&
-                               $share->getExpirationDate() === $date;
-                       })
-               )->will($this->returnArgument(0));
-
-               $expected = new DataResponse(null);
-               $result = $ocs->updateShare(42, null, null, 'true', null);
-
-               $this->assertInstanceOf(get_class($expected), $result);
-               $this->assertEquals($expected->getData(), $result->getData());
-       }
-
-       public function testUpdateLinkSharePermissions() {
-               $ocs = $this->mockFormatShare();
-
-               $date = new \DateTime('2000-01-01');
-
-               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
-                       ->setPassword('password')
-                       ->setExpirationDate($date)
-                       ->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setNode($folder);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
-               $this->shareManager->expects($this->once())->method('updateShare')->with(
-                       $this->callback(function (\OCP\Share\IShare $share) use ($date) {
-                               return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) &&
-                               $share->getPassword() === 'password' &&
-                               $share->getExpirationDate() === $date;
-                       })
-               )->will($this->returnArgument(0));
-
-               $this->shareManager->method('getSharedWith')->willReturn([]);
-
-               $expected = new DataResponse(null);
-               $result = $ocs->updateShare(42, 7, null, null, null);
-
-               $this->assertInstanceOf(get_class($expected), $result);
-               $this->assertEquals($expected->getData(), $result->getData());
-       }
-
-       /**
-        * @expectedException \OCP\AppFramework\OCS\OCSBadRequestException
-        * @expectedExceptionMessage Can't change permissions for public share links
-        */
-       public function testUpdateLinkShareInvalidPermissions() {
-               $ocs = $this->mockFormatShare();
-
-               $date = new \DateTime('2000-01-01');
-
-               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
-                       ->setPassword('password')
-                       ->setExpirationDate($date)
-                       ->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setNode($folder);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
-               $ocs->updateShare(42, 31);
-       }
-
-       public function testUpdateOtherPermissions() {
-               $ocs = $this->mockFormatShare();
-
-               $file = $this->getMockBuilder('\OCP\Files\File')->getMock();
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_USER)
-                       ->setNode($file);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
-               $this->shareManager->expects($this->once())->method('updateShare')->with(
-                       $this->callback(function (\OCP\Share\IShare $share) {
-                               return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL;
-                       })
-               )->will($this->returnArgument(0));
-
-               $this->shareManager->method('getSharedWith')->willReturn([]);
-
-               $expected = new DataResponse(null);
-               $result = $ocs->updateShare(42, 31, null, null, null);
-
-               $this->assertInstanceOf(get_class($expected), $result);
-               $this->assertEquals($expected->getData(), $result->getData());
-       }
-
-       public function testUpdateShareCannotIncreasePermissions() {
-               $ocs = $this->mockFormatShare();
-
-               $folder = $this->createMock(Folder::class);
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share
-                       ->setId(42)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareOwner('anotheruser')
-                       ->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
-                       ->setSharedWith('group1')
-                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
-                       ->setNode($folder);
-
-               // note: updateShare will modify the received instance but getSharedWith will reread from the database,
-               // so their values will be different
-               $incomingShare = \OC::$server->getShareManager()->newShare();
-               $incomingShare
-                       ->setId(42)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareOwner('anotheruser')
-                       ->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
-                       ->setSharedWith('group1')
-                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
-                       ->setNode($folder);
-
-               $this->request
-                       ->method('getParam')
-                       ->will($this->returnValueMap([
-                               ['permissions', null, '31'],
-                       ]));
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-
-               $this->shareManager->expects($this->any(0))
-                       ->method('getSharedWith')
-                       ->will($this->returnValueMap([
-                               ['currentUser', \OCP\Share::SHARE_TYPE_USER, $share->getNode(), -1, 0, []],
-                               ['currentUser', \OCP\Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0, [$incomingShare]]
-                       ]));
-
-               $this->shareManager->expects($this->never())->method('updateShare');
-
-               try {
-                       $ocs->updateShare(42, 31);
-                       $this->fail();
-               } catch (OCSNotFoundException $e) {
-                       $this->assertEquals('Cannot increase permissions', $e->getMessage());
-               }
-       }
-
-       public function testUpdateShareCanIncreasePermissionsIfOwner() {
-               $ocs = $this->mockFormatShare();
-
-               $folder = $this->createMock(Folder::class);
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share
-                       ->setId(42)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareOwner($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
-                       ->setSharedWith('group1')
-                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
-                       ->setNode($folder);
-
-               // note: updateShare will modify the received instance but getSharedWith will reread from the database,
-               // so their values will be different
-               $incomingShare = \OC::$server->getShareManager()->newShare();
-               $incomingShare
-                       ->setId(42)
-                       ->setSharedBy($this->currentUser->getUID())
-                       ->setShareOwner($this->currentUser->getUID())
-                       ->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
-                       ->setSharedWith('group1')
-                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
-                       ->setNode($folder);
-
-               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-
-               $this->shareManager->expects($this->any(0))
-                       ->method('getSharedWith')
-                       ->will($this->returnValueMap([
-                               ['currentUser', \OCP\Share::SHARE_TYPE_USER, $share->getNode(), -1, 0, []],
-                               ['currentUser', \OCP\Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0, [$incomingShare]]
-                       ]));
-
-               $this->shareManager->expects($this->once())
-                       ->method('updateShare')
-                       ->with($share)
-                       ->willReturn($share);
-
-               $result = $ocs->updateShare(42, 31);
-               $this->assertInstanceOf(DataResponse::class, $result);
-       }
-
-       public function dataFormatShare() {
-               $file = $this->getMockBuilder('\OCP\Files\File')->getMock();
-               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-               $parent = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
-
-               $file->method('getMimeType')->willReturn('myMimeType');
-               $folder->method('getMimeType')->willReturn('myFolderMimeType');
-
-               $file->method('getPath')->willReturn('file');
-               $folder->method('getPath')->willReturn('folder');
-
-               $parent->method('getId')->willReturn(1);
-               $folder->method('getId')->willReturn(2);
-               $file->method('getId')->willReturn(3);
-
-               $file->method('getParent')->willReturn($parent);
-               $folder->method('getParent')->willReturn($parent);
-
-               $cache = $this->getMockBuilder('OCP\Files\Cache\ICache')->getMock();
-               $cache->method('getNumericStorageId')->willReturn(100);
-               $storage = $this->getMockBuilder('\OCP\Files\Storage')->getMock();
-               $storage->method('getId')->willReturn('storageId');
-               $storage->method('getCache')->willReturn($cache);
-
-               $file->method('getStorage')->willReturn($storage);
-               $folder->method('getStorage')->willReturn($storage);
-
-               $owner = $this->getMockBuilder('\OCP\IUser')->getMock();
-               $owner->method('getDisplayName')->willReturn('ownerDN');
-               $initiator = $this->getMockBuilder('\OCP\IUser')->getMock();
-               $initiator->method('getDisplayName')->willReturn('initiatorDN');
-               $recipient = $this->getMockBuilder('\OCP\IUser')->getMock();
-               $recipient->method('getDisplayName')->willReturn('recipientDN');
-
-               $result = [];
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setShareType(\OCP\Share::SHARE_TYPE_USER)
-                       ->setSharedWith('recipient')
-                       ->setSharedBy('initiator')
-                       ->setShareOwner('owner')
-                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
-                       ->setNode($file)
-                       ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
-                       ->setTarget('myTarget')
-                       ->setId(42);
-
-               /* User backend down */
-               $result[] = [
-                       [
-                               'id' => 42,
-                               'share_type' => \OCP\Share::SHARE_TYPE_USER,
-                               'uid_owner' => 'initiator',
-                               'displayname_owner' => 'initiator',
-                               'permissions' => 1,
-                               'stime' => 946684862,
-                               'parent' => null,
-                               'expiration' => null,
-                               'token' => null,
-                               'uid_file_owner' => 'owner',
-                               'displayname_file_owner' => 'owner',
-                               'path' => 'file',
-                               'item_type' => 'file',
-                               'storage_id' => 'storageId',
-                               'storage' => 100,
-                               'item_source' => 3,
-                               'file_source' => 3,
-                               'file_parent' => 1,
-                               'file_target' => 'myTarget',
-                               'share_with' => 'recipient',
-                               'share_with_displayname' => 'recipient',
-                               'mail_send' => 0,
-                               'mimetype' => 'myMimeType',
-                       ], $share, [], false
-               ];
-
-               /* User backend up */
-               $result[] = [
-                       [
-                               'id' => 42,
-                               'share_type' => \OCP\Share::SHARE_TYPE_USER,
-                               'uid_owner' => 'initiator',
-                               'displayname_owner' => 'initiatorDN',
-                               'permissions' => 1,
-                               'stime' => 946684862,
-                               'parent' => null,
-                               'expiration' => null,
-                               'token' => null,
-                               'uid_file_owner' => 'owner',
-                               'displayname_file_owner' => 'ownerDN',
-                               'path' => 'file',
-                               'item_type' => 'file',
-                               'storage_id' => 'storageId',
-                               'storage' => 100,
-                               'item_source' => 3,
-                               'file_source' => 3,
-                               'file_parent' => 1,
-                               'file_target' => 'myTarget',
-                               'share_with' => 'recipient',
-                               'share_with_displayname' => 'recipientDN',
-                               'mail_send' => 0,
-                               'mimetype' => 'myMimeType',
-                       ], $share, [
-                               ['owner', $owner],
-                               ['initiator', $initiator],
-                               ['recipient', $recipient],
-                       ], false
-               ];
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setShareType(\OCP\Share::SHARE_TYPE_USER)
-                       ->setSharedWith('recipient')
-                       ->setSharedBy('initiator')
-                       ->setShareOwner('owner')
-                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
-                       ->setNode($file)
-                       ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
-                       ->setTarget('myTarget')
-                       ->setId(42);
-
-               /* User backend down */
-               $result[] = [
-                       [
-                               'id' => 42,
-                               'share_type' => \OCP\Share::SHARE_TYPE_USER,
-                               'uid_owner' => 'initiator',
-                               'displayname_owner' => 'initiator',
-                               'permissions' => 1,
-                               'stime' => 946684862,
-                               'parent' => null,
-                               'expiration' => null,
-                               'token' => null,
-                               'uid_file_owner' => 'owner',
-                               'displayname_file_owner' => 'owner',
-                               'path' => 'file',
-                               'item_type' => 'file',
-                               'storage_id' => 'storageId',
-                               'storage' => 100,
-                               'item_source' => 3,
-                               'file_source' => 3,
-                               'file_parent' => 1,
-                               'file_target' => 'myTarget',
-                               'share_with' => 'recipient',
-                               'share_with_displayname' => 'recipient',
-                               'mail_send' => 0,
-                               'mimetype' => 'myMimeType',
-                       ], $share, [], false
-               ];
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
-                       ->setSharedWith('recipient')
-                       ->setSharedBy('initiator')
-                       ->setShareOwner('owner')
-                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
-                       ->setNode($file)
-                       ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
-                       ->setTarget('myTarget')
-                       ->setId(42);
-
-               $result[] = [
-                       [
-                               'id' => 42,
-                               'share_type' => \OCP\Share::SHARE_TYPE_GROUP,
-                               'uid_owner' => 'initiator',
-                               'displayname_owner' => 'initiator',
-                               'permissions' => 1,
-                               'stime' => 946684862,
-                               'parent' => null,
-                               'expiration' => null,
-                               'token' => null,
-                               'uid_file_owner' => 'owner',
-                               'displayname_file_owner' => 'owner',
-                               'path' => 'file',
-                               'item_type' => 'file',
-                               'storage_id' => 'storageId',
-                               'storage' => 100,
-                               'item_source' => 3,
-                               'file_source' => 3,
-                               'file_parent' => 1,
-                               'file_target' => 'myTarget',
-                               'share_with' => 'recipient',
-                               'share_with_displayname' => 'recipient',
-                               'mail_send' => 0,
-                               'mimetype' => 'myMimeType',
-                       ], $share, [], false
-               ];
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setShareType(\OCP\Share::SHARE_TYPE_LINK)
-                       ->setSharedBy('initiator')
-                       ->setShareOwner('owner')
-                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
-                       ->setNode($file)
-                       ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
-                       ->setTarget('myTarget')
-                       ->setPassword('mypassword')
-                       ->setExpirationDate(new \DateTime('2001-01-02T00:00:00'))
-                       ->setToken('myToken')
-                       ->setId(42);
-
-               $result[] = [
-                       [
-                               'id' => 42,
-                               'share_type' => \OCP\Share::SHARE_TYPE_LINK,
-                               'uid_owner' => 'initiator',
-                               'displayname_owner' => 'initiator',
-                               'permissions' => 1,
-                               'stime' => 946684862,
-                               'parent' => null,
-                               'expiration' => '2001-01-02 00:00:00',
-                               'token' => 'myToken',
-                               'uid_file_owner' => 'owner',
-                               'displayname_file_owner' => 'owner',
-                               'path' => 'file',
-                               'item_type' => 'file',
-                               'storage_id' => 'storageId',
-                               'storage' => 100,
-                               'item_source' => 3,
-                               'file_source' => 3,
-                               'file_parent' => 1,
-                               'file_target' => 'myTarget',
-                               'share_with' => 'mypassword',
-                               'share_with_displayname' => 'mypassword',
-                               'mail_send' => 0,
-                               'url' => 'myLink',
-                               'mimetype' => 'myMimeType',
-                       ], $share, [], false
-               ];
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setShareType(\OCP\Share::SHARE_TYPE_REMOTE)
-                       ->setSharedBy('initiator')
-                       ->setSharedWith('user@server.com')
-                       ->setShareOwner('owner')
-                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
-                       ->setNode($folder)
-                       ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
-                       ->setTarget('myTarget')
-                       ->setId(42);
-
-               $result[] = [
-                       [
-                               'id' => 42,
-                               'share_type' => \OCP\Share::SHARE_TYPE_REMOTE,
-                               'uid_owner' => 'initiator',
-                               'displayname_owner' => 'initiator',
-                               'permissions' => 1,
-                               'stime' => 946684862,
-                               'parent' => null,
-                               'expiration' => null,
-                               'token' => null,
-                               'uid_file_owner' => 'owner',
-                               'displayname_file_owner' => 'owner',
-                               'path' => 'folder',
-                               'item_type' => 'folder',
-                               'storage_id' => 'storageId',
-                               'storage' => 100,
-                               'item_source' => 2,
-                               'file_source' => 2,
-                               'file_parent' => 1,
-                               'file_target' => 'myTarget',
-                               'share_with' => 'user@server.com',
-                               'share_with_displayname' => 'user@server.com',
-                               'mail_send' => 0,
-                               'mimetype' => 'myFolderMimeType',
-                       ], $share, [], false
-               ];
-
-               $share = \OC::$server->getShareManager()->newShare();
-               $share->setShareType(\OCP\Share::SHARE_TYPE_USER)
-                       ->setSharedBy('initiator')
-                       ->setSharedWith('recipient')
-                       ->setShareOwner('owner')
-                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
-                       ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
-                       ->setTarget('myTarget')
-                       ->setId(42);
-
-               $result[] = [
-                       [], $share, [], true
-               ];
-
-               return $result;
-       }
-
-       /**
-        * @dataProvider dataFormatShare
-        *
-        * @param array $expects
-        * @param \OCP\Share\IShare $share
-        * @param array $users
-        * @param $exception
-        */
-       public function testFormatShare(array $expects, \OCP\Share\IShare $share, array $users, $exception) {
-               $this->userManager->method('get')->will($this->returnValueMap($users));
-               $this->urlGenerator->method('linkToRouteAbsolute')
-                       ->with('files_sharing.sharecontroller.showShare', ['token' => 'myToken'])
-                       ->willReturn('myLink');
-
-
-               $this->rootFolder->method('getUserFolder')
-                       ->with($this->currentUser->getUID())
-                       ->will($this->returnSelf());
-
-               if (!$exception) {
-                       $this->rootFolder->method('getById')
-                               ->with($share->getNodeId())
-                               ->willReturn([$share->getNode()]);
-
-                       $this->rootFolder->method('getRelativePath')
-                               ->with($share->getNode()->getPath())
-                               ->will($this->returnArgument(0));
-               }
-
-               try {
-                       $result = $this->invokePrivate($this->ocs, 'formatShare', [$share]);
-                       $this->assertFalse($exception);
-                       $this->assertEquals($expects, $result);
-               } catch (NotFoundException $e) {
-                       $this->assertTrue($exception);
-               }
-       }
-}
index aff3aadd7e7f91c6eb89f2a1b543ecec3d4e7d51..6ab0cb4e1a67f0a9c199a39f38879be987c96982 100644 (file)
@@ -30,6 +30,7 @@
 namespace OCA\Files_Sharing\Tests;
 
 use OC\Files\Cache\Scanner;
+use OCA\Files_Sharing\Controller\ShareAPIController;
 use OCP\AppFramework\OCS\OCSBadRequestException;
 use OCP\AppFramework\OCS\OCSException;
 use OCP\AppFramework\OCS\OCSForbiddenException;
@@ -92,18 +93,16 @@ class ApiTest extends TestCase {
 
        /**
         * @param string $userId The userId of the caller
-        * @return \OCA\Files_Sharing\API\Share20OCS
+        * @return \OCA\Files_Sharing\Controller\ShareAPIController
         */
        private function createOCS($userId) {
-               $currentUser = \OC::$server->getUserManager()->get($userId);
-
                $l = $this->getMockBuilder('\OCP\IL10N')->getMock();
                $l->method('t')
                        ->will($this->returnCallback(function($text, $parameters = []) {
                                return vsprintf($text, $parameters);
                        }));
 
-               return new \OCA\Files_Sharing\API\Share20OCS(
+               return new ShareAPIController(
                        self::APP_NAME,
                        $this->getMockBuilder('OCP\IRequest')->getMock(),
                        $this->shareManager,
@@ -111,7 +110,7 @@ class ApiTest extends TestCase {
                        \OC::$server->getUserManager(),
                        \OC::$server->getRootFolder(),
                        \OC::$server->getURLGenerator(),
-                       $currentUser,
+                       $userId,
                        $l
                );
        }
@@ -715,7 +714,6 @@ class ApiTest extends TestCase {
                /*
                 * Test as recipient
                 */
-               $request = $this->createRequest(['path' => '/', 'subfiles' => 'true']);
                $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER3);
                $result = $ocs->getShares();
                $ocs->cleanup();
diff --git a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php
new file mode 100644 (file)
index 0000000..6ad0576
--- /dev/null
@@ -0,0 +1,2002 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ *
+ * @author Björn Schießle <bjoern@schiessle.org>
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ * @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/>
+ *
+ */
+namespace OCA\Files_Sharing\Tests\Controller;
+
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\OCS\OCSNotFoundException;
+use OCP\Files\Folder;
+use OCP\IL10N;
+use OCA\Files_Sharing\Controller\ShareAPIController;
+use OCP\Files\NotFoundException;
+use OCP\IGroupManager;
+use OCP\IUserManager;
+use OCP\IRequest;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\Files\IRootFolder;
+use OCP\Lock\LockedException;
+use OCP\Share\IManager;
+
+/**
+ * Class ShareAPIControllerTest
+ *
+ * @package OCA\Files_Sharing\Tests\Controller
+ * @group DB
+ */
+class ShareAPIControllerTest extends \Test\TestCase {
+
+       /** @var string */
+       private $appName = 'files_sharing';
+
+       /** @var \OC\Share20\Manager|\PHPUnit_Framework_MockObject_MockObject */
+       private $shareManager;
+
+       /** @var IGroupManager|\PHPUnit_Framework_MockObject_MockObject */
+       private $groupManager;
+
+       /** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */
+       private $userManager;
+
+       /** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */
+       private $request;
+
+       /** @var IRootFolder|\PHPUnit_Framework_MockObject_MockObject */
+       private $rootFolder;
+
+       /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
+       private $urlGenerator;
+
+       /** @var string|\PHPUnit_Framework_MockObject_MockObject */
+       private $currentUser;
+
+       /** @var ShareAPIController */
+       private $ocs;
+
+       /** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */
+       private $l;
+
+       protected function setUp() {
+               $this->shareManager = $this->createMock(IManager::class);
+               $this->shareManager
+                       ->expects($this->any())
+                       ->method('shareApiEnabled')
+                       ->willReturn(true);
+               $this->groupManager = $this->createMock(IGroupManager::class);
+               $this->userManager = $this->createMock(IUserManager::class);
+               $this->request = $this->createMock(IRequest::class);
+               $this->rootFolder = $this->createMock(IRootFolder::class);
+               $this->urlGenerator = $this->createMock(IURLGenerator::class);
+               $this->currentUser = 'currentUser';
+
+               $this->l = $this->createMock(IL10N::class);
+               $this->l->method('t')
+                       ->will($this->returnCallback(function($text, $parameters = []) {
+                               return vsprintf($text, $parameters);
+                       }));
+
+               $this->ocs = new ShareAPIController(
+                       $this->appName,
+                       $this->request,
+                       $this->shareManager,
+                       $this->groupManager,
+                       $this->userManager,
+                       $this->rootFolder,
+                       $this->urlGenerator,
+                       $this->currentUser,
+                       $this->l
+               );
+       }
+
+       /**
+        * @return ShareAPIController|\PHPUnit_Framework_MockObject_MockObject
+        */
+       private function mockFormatShare() {
+               return $this->getMockBuilder(ShareAPIController::class)
+                       ->setConstructorArgs([
+                               $this->appName,
+                               $this->request,
+                               $this->shareManager,
+                               $this->groupManager,
+                               $this->userManager,
+                               $this->rootFolder,
+                               $this->urlGenerator,
+                               $this->currentUser,
+                               $this->l,
+                       ])->setMethods(['formatShare'])
+                       ->getMock();
+       }
+
+       private function newShare() {
+               return \OC::$server->getShareManager()->newShare();
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
+        * @expectedExceptionMessage Wrong share ID, share doesn't exist
+        */
+       public function testDeleteShareShareNotFound() {
+               $this->shareManager
+                       ->expects($this->exactly(2))
+                       ->method('getShareById')
+                       ->will($this->returnCallback(function($id) {
+                               if ($id === 'ocinternal:42' || $id === 'ocFederatedSharing:42') {
+                                       throw new \OCP\Share\Exceptions\ShareNotFound();
+                               } else {
+                                       throw new \Exception();
+                               }
+                       }));
+
+               $this->shareManager->method('outgoingServer2ServerSharesAllowed')->willReturn(true);
+
+               $this->ocs->deleteShare(42);
+       }
+
+       public function testDeleteShare() {
+               $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
+
+               $share = $this->newShare();
+               $share->setSharedBy($this->currentUser)
+                       ->setNode($node);
+               $this->shareManager
+                       ->expects($this->once())
+                       ->method('getShareById')
+                       ->with('ocinternal:42')
+                       ->willReturn($share);
+               $this->shareManager
+                       ->expects($this->once())
+                       ->method('deleteShare')
+                       ->with($share);
+
+               $node->expects($this->once())
+                       ->method('lock')
+                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+               $expected = new DataResponse();
+               $result = $this->ocs->deleteShare(42);
+
+               $this->assertInstanceOf(get_class($expected), $result);
+               $this->assertEquals($expected->getData(), $result->getData());
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
+        * @expectedExceptionMessage could not delete share
+        */
+       public function testDeleteShareLocked() {
+               $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
+
+               $share = $this->newShare();
+               $share->setSharedBy($this->currentUser)
+                       ->setNode($node);
+               $this->shareManager
+                       ->expects($this->once())
+                       ->method('getShareById')
+                       ->with('ocinternal:42')
+                       ->willReturn($share);
+               $this->shareManager
+                       ->expects($this->never())
+                       ->method('deleteShare')
+                       ->with($share);
+
+               $node->expects($this->once())
+                       ->method('lock')
+                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED)
+                       ->will($this->throwException(new LockedException('mypath')));
+
+               $this->ocs->deleteShare(42);
+       }
+
+       /*
+        * FIXME: Enable once we have a federated Share Provider
+
+       public function testGetGetShareNotExists() {
+               $this->shareManager
+                       ->expects($this->once())
+                       ->method('getShareById')
+                       ->with('ocinternal:42')
+                       ->will($this->throwException(new \OC\Share20\Exception\ShareNotFound()));
+
+               $expected = new \OC_OCS_Result(null, 404, 'wrong share ID, share doesn\'t exist.');
+               $this->assertEquals($expected, $this->ocs->getShare(42));
+       }
+       */
+
+       public function createShare($id, $shareType, $sharedWith, $sharedBy, $shareOwner, $path, $permissions,
+                                                               $shareTime, $expiration, $parent, $target, $mail_send, $token=null,
+                                                               $password=null) {
+               $share = $this->getMockBuilder('\OCP\Share\IShare')->getMock();
+               $share->method('getId')->willReturn($id);
+               $share->method('getShareType')->willReturn($shareType);
+               $share->method('getSharedWith')->willReturn($sharedWith);
+               $share->method('getSharedBy')->willReturn($sharedBy);
+               $share->method('getShareOwner')->willReturn($shareOwner);
+               $share->method('getNode')->willReturn($path);
+               $share->method('getPermissions')->willReturn($permissions);
+               $time = new \DateTime();
+               $time->setTimestamp($shareTime);
+               $share->method('getShareTime')->willReturn($time);
+               $share->method('getExpirationDate')->willReturn($expiration);
+               $share->method('getTarget')->willReturn($target);
+               $share->method('getMailSend')->willReturn($mail_send);
+               $share->method('getToken')->willReturn($token);
+               $share->method('getPassword')->willReturn($password);
+
+               if ($shareType === \OCP\Share::SHARE_TYPE_USER  ||
+                       $shareType === \OCP\Share::SHARE_TYPE_GROUP ||
+                       $shareType === \OCP\Share::SHARE_TYPE_LINK) {
+                       $share->method('getFullId')->willReturn('ocinternal:'.$id);
+               }
+
+               return $share;
+       }
+
+       public function dataGetShare() {
+               $data = [];
+
+               $cache = $this->getMockBuilder('OC\Files\Cache\Cache')
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $cache->method('getNumericStorageId')->willReturn(101);
+
+               $storage = $this->getMockBuilder('OC\Files\Storage\Storage')
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $storage->method('getId')->willReturn('STORAGE');
+               $storage->method('getCache')->willReturn($cache);
+
+               $parentFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
+               $parentFolder->method('getId')->willReturn(3);
+
+               $file = $this->getMockBuilder('OCP\Files\File')->getMock();
+               $file->method('getId')->willReturn(1);
+               $file->method('getPath')->willReturn('file');
+               $file->method('getStorage')->willReturn($storage);
+               $file->method('getParent')->willReturn($parentFolder);
+               $file->method('getMimeType')->willReturn('myMimeType');
+
+               $folder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
+               $folder->method('getId')->willReturn(2);
+               $folder->method('getPath')->willReturn('folder');
+               $folder->method('getStorage')->willReturn($storage);
+               $folder->method('getParent')->willReturn($parentFolder);
+               $folder->method('getMimeType')->willReturn('myFolderMimeType');
+
+               // File shared with user
+               $share = $this->createShare(
+                       100,
+                       \OCP\Share::SHARE_TYPE_USER,
+                       'userId',
+                       'initiatorId',
+                       'ownerId',
+                       $file,
+                       4,
+                       5,
+                       null,
+                       6,
+                       'target',
+                       0
+               );
+               $expected = [
+                       'id' => 100,
+                       'share_type' => \OCP\Share::SHARE_TYPE_USER,
+                       'share_with' => 'userId',
+                       'share_with_displayname' => 'userDisplay',
+                       'uid_owner' => 'initiatorId',
+                       'displayname_owner' => 'initiatorDisplay',
+                       'item_type' => 'file',
+                       'item_source' => 1,
+                       'file_source' => 1,
+                       'file_target' => 'target',
+                       'file_parent' => 3,
+                       'token' => null,
+                       'expiration' => null,
+                       'permissions' => 4,
+                       'stime' => 5,
+                       'parent' => null,
+                       'storage_id' => 'STORAGE',
+                       'path' => 'file',
+                       'storage' => 101,
+                       'mail_send' => 0,
+                       'uid_file_owner' => 'ownerId',
+                       'displayname_file_owner' => 'ownerDisplay',
+                       'mimetype' => 'myMimeType',
+               ];
+               $data[] = [$share, $expected];
+
+               // Folder shared with group
+               $share = $this->createShare(
+                       101,
+                       \OCP\Share::SHARE_TYPE_GROUP,
+                       'groupId',
+                       'initiatorId',
+                       'ownerId',
+                       $folder,
+                       4,
+                       5,
+                       null,
+                       6,
+                       'target',
+                       0
+               );
+               $expected = [
+                       'id' => 101,
+                       'share_type' => \OCP\Share::SHARE_TYPE_GROUP,
+                       'share_with' => 'groupId',
+                       'share_with_displayname' => 'groupId',
+                       'uid_owner' => 'initiatorId',
+                       'displayname_owner' => 'initiatorDisplay',
+                       'item_type' => 'folder',
+                       'item_source' => 2,
+                       'file_source' => 2,
+                       'file_target' => 'target',
+                       'file_parent' => 3,
+                       'token' => null,
+                       'expiration' => null,
+                       'permissions' => 4,
+                       'stime' => 5,
+                       'parent' => null,
+                       'storage_id' => 'STORAGE',
+                       'path' => 'folder',
+                       'storage' => 101,
+                       'mail_send' => 0,
+                       'uid_file_owner' => 'ownerId',
+                       'displayname_file_owner' => 'ownerDisplay',
+                       'mimetype' => 'myFolderMimeType',
+               ];
+               $data[] = [$share, $expected];
+
+               // File shared by link with Expire
+               $expire = \DateTime::createFromFormat('Y-m-d h:i:s', '2000-01-02 01:02:03');
+               $share = $this->createShare(
+                       101,
+                       \OCP\Share::SHARE_TYPE_LINK,
+                       null,
+                       'initiatorId',
+                       'ownerId',
+                       $folder,
+                       4,
+                       5,
+                       $expire,
+                       6,
+                       'target',
+                       0,
+                       'token',
+                       'password'
+               );
+               $expected = [
+                       'id' => 101,
+                       'share_type' => \OCP\Share::SHARE_TYPE_LINK,
+                       'share_with' => 'password',
+                       'share_with_displayname' => 'password',
+                       'uid_owner' => 'initiatorId',
+                       'displayname_owner' => 'initiatorDisplay',
+                       'item_type' => 'folder',
+                       'item_source' => 2,
+                       'file_source' => 2,
+                       'file_target' => 'target',
+                       'file_parent' => 3,
+                       'token' => 'token',
+                       'expiration' => '2000-01-02 00:00:00',
+                       'permissions' => 4,
+                       'stime' => 5,
+                       'parent' => null,
+                       'storage_id' => 'STORAGE',
+                       'path' => 'folder',
+                       'storage' => 101,
+                       'mail_send' => 0,
+                       'url' => 'url',
+                       'uid_file_owner' => 'ownerId',
+                       'displayname_file_owner' => 'ownerDisplay',
+                       'mimetype' => 'myFolderMimeType',
+               ];
+               $data[] = [$share, $expected];
+
+               return $data;
+       }
+
+       /**
+        * @dataProvider dataGetShare
+        */
+       public function testGetShare(\OCP\Share\IShare $share, array $result) {
+               /** @var ShareAPIController|\PHPUnit_Framework_MockObject_MockObject $ocs */
+               $ocs = $this->getMockBuilder(ShareAPIController::class)
+                               ->setConstructorArgs([
+                                       $this->appName,
+                                       $this->request,
+                                       $this->shareManager,
+                                       $this->groupManager,
+                                       $this->userManager,
+                                       $this->rootFolder,
+                                       $this->urlGenerator,
+                                       $this->currentUser,
+                                       $this->l,
+                               ])->setMethods(['canAccessShare'])
+                               ->getMock();
+
+               $ocs->expects($this->any())
+                       ->method('canAccessShare')
+                       ->willReturn(true);
+
+               $this->shareManager
+                       ->expects($this->once())
+                       ->method('getShareById')
+                       ->with($share->getFullId())
+                       ->willReturn($share);
+
+               $userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
+               $userFolder
+                       ->method('getRelativePath')
+                       ->will($this->returnArgument(0));
+
+               $userFolder->method('getById')
+                       ->with($share->getNodeId())
+                       ->willReturn([$share->getNode()]);
+
+               $this->rootFolder->method('getUserFolder')
+                       ->with($this->currentUser)
+                       ->willReturn($userFolder);
+
+               $this->urlGenerator
+                       ->method('linkToRouteAbsolute')
+                       ->willReturn('url');
+
+               $initiator = $this->getMockBuilder('OCP\IUser')->getMock();
+               $initiator->method('getUID')->willReturn('initiatorId');
+               $initiator->method('getDisplayName')->willReturn('initiatorDisplay');
+
+               $owner = $this->getMockBuilder('OCP\IUser')->getMock();
+               $owner->method('getUID')->willReturn('ownerId');
+               $owner->method('getDisplayName')->willReturn('ownerDisplay');
+
+               $user = $this->getMockBuilder('OCP\IUser')->getMock();
+               $user->method('getUID')->willReturn('userId');
+               $user->method('getDisplayName')->willReturn('userDisplay');
+
+               $group = $this->getMockBuilder('OCP\IGroup')->getMock();
+               $group->method('getGID')->willReturn('groupId');
+
+               $this->userManager->method('get')->will($this->returnValueMap([
+                       ['userId', $user],
+                       ['initiatorId', $initiator],
+                       ['ownerId', $owner],
+               ]));
+               $this->groupManager->method('get')->will($this->returnValueMap([
+                       ['group', $group],
+               ]));
+
+               $this->assertEquals($result, $ocs->getShare($share->getId())->getData()[0]);
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
+        * @expectedExceptionMessage Wrong share ID, share doesn't exist
+        */
+       public function testGetShareInvalidNode() {
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setSharedBy('initiator')
+                       ->setSharedWith('recipient')
+                       ->setShareOwner('owner');
+
+               $this->shareManager
+                       ->expects($this->once())
+                       ->method('getShareById')
+                       ->with('ocinternal:42')
+                       ->willReturn($share);
+
+               $this->ocs->getShare(42);
+       }
+
+       public function testCanAccessShare() {
+               $share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
+               $share->method('getShareOwner')->willReturn($this->currentUser);
+               $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+
+               $share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
+               $share->method('getSharedBy')->willReturn($this->currentUser);
+               $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+
+               $share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
+               $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER);
+               $share->method('getSharedWith')->willReturn($this->currentUser);
+               $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+
+               $share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
+               $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER);
+               $share->method('getSharedWith')->willReturn($this->getMockBuilder('OCP\IUser')->getMock());
+               $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+
+               $share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
+               $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_GROUP);
+               $share->method('getSharedWith')->willReturn('group');
+
+               $user = $this->createMock(IUser::class);
+               $this->userManager->method('get')
+                       ->with($this->currentUser)
+                       ->willReturn($user);
+
+               $group = $this->getMockBuilder('OCP\IGroup')->getMock();
+               $group->method('inGroup')->with($user)->willReturn(true);
+               $group2 = $this->getMockBuilder('OCP\IGroup')->getMock();
+               $group2->method('inGroup')->with($user)->willReturn(false);
+
+               $this->groupManager->method('get')->will($this->returnValueMap([
+                       ['group', $group],
+                       ['group2', $group2],
+               ]));
+               $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+
+               $share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
+               $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_GROUP);
+               $share->method('getSharedWith')->willReturn('group2');
+
+               $this->groupManager->method('get')->with('group2')->willReturn($group);
+               $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+
+               $share = $this->getMockBuilder('OCP\Share\IShare')->getMock();
+               $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_LINK);
+               $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
+        * @expectedExceptionMessage Please specify a file or folder path
+        */
+       public function testCreateShareNoPath() {
+               $this->ocs->createShare();
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
+        * @expectedExceptionMessage Wrong path, file/folder doesn't exist
+        */
+       public function testCreateShareInvalidPath() {
+               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $this->rootFolder->expects($this->once())
+                       ->method('getUserFolder')
+                       ->with('currentUser')
+                       ->willReturn($userFolder);
+
+               $userFolder->expects($this->once())
+                       ->method('get')
+                       ->with('invalid-path')
+                       ->will($this->throwException(new \OCP\Files\NotFoundException()));
+
+               $this->ocs->createShare('invalid-path');
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
+        * @expectedExceptionMessage invalid permissions
+        */
+       public function testCreateShareInvalidPermissions() {
+               $share = $this->newShare();
+               $this->shareManager->method('newShare')->willReturn($share);
+
+               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $this->rootFolder->expects($this->once())
+                               ->method('getUserFolder')
+                               ->with('currentUser')
+                               ->willReturn($userFolder);
+
+               $path = $this->getMockBuilder('\OCP\Files\File')->getMock();
+               $userFolder->expects($this->once())
+                               ->method('get')
+                               ->with('valid-path')
+                               ->willReturn($path);
+
+               $path->expects($this->once())
+                       ->method('lock')
+                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+               $this->ocs->createShare('valid-path', 32);
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
+        * @expectedExceptionMessage Please specify a valid user
+        */
+       public function testCreateShareUserNoShareWith() {
+               $share = $this->newShare();
+               $this->shareManager->method('newShare')->willReturn($share);
+
+               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $this->rootFolder->expects($this->once())
+                       ->method('getUserFolder')
+                       ->with('currentUser')
+                       ->willReturn($userFolder);
+
+               $path = $this->getMockBuilder('\OCP\Files\File')->getMock();
+               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
+               $storage->method('instanceOfStorage')
+                       ->with('OCA\Files_Sharing\External\Storage')
+                       ->willReturn(false);
+               $path->method('getStorage')->willReturn($storage);
+               $userFolder->expects($this->once())
+                       ->method('get')
+                       ->with('valid-path')
+                       ->willReturn($path);
+
+               $path->expects($this->once())
+                       ->method('lock')
+                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+               $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_USER);
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
+        * @expectedExceptionMessage Please specify a valid user
+        */
+       public function testCreateShareUserNoValidShareWith() {
+               $share = $this->newShare();
+               $this->shareManager->method('newShare')->willReturn($share);
+
+               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $this->rootFolder->expects($this->once())
+                       ->method('getUserFolder')
+                       ->with('currentUser')
+                       ->willReturn($userFolder);
+
+               $path = $this->getMockBuilder('\OCP\Files\File')->getMock();
+               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
+               $storage->method('instanceOfStorage')
+                       ->with('OCA\Files_Sharing\External\Storage')
+                       ->willReturn(false);
+               $path->method('getStorage')->willReturn($storage);
+               $userFolder->expects($this->once())
+                       ->method('get')
+                       ->with('valid-path')
+                       ->willReturn($path);
+               $path->expects($this->once())
+                       ->method('lock')
+                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+               $this->userManager->method('userExists')
+                       ->with('invalidUser')
+                       ->willReturn(false);
+
+               $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_USER, 'invalidUser');
+       }
+
+       public function testCreateShareUser() {
+               $share = $this->newShare();
+               $this->shareManager->method('newShare')->willReturn($share);
+
+               /** @var \OCA\Files_Sharing\Controller\ShareAPIController $ocs */
+               $ocs = $this->getMockBuilder(ShareAPIController::class)
+                       ->setConstructorArgs([
+                               $this->appName,
+                               $this->request,
+                               $this->shareManager,
+                               $this->groupManager,
+                               $this->userManager,
+                               $this->rootFolder,
+                               $this->urlGenerator,
+                               $this->currentUser,
+                               $this->l,
+                       ])->setMethods(['formatShare'])
+                       ->getMock();
+
+               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $this->rootFolder->expects($this->once())
+                               ->method('getUserFolder')
+                               ->with('currentUser')
+                               ->willReturn($userFolder);
+
+               $path = $this->getMockBuilder('\OCP\Files\File')->getMock();
+               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
+               $storage->method('instanceOfStorage')
+                       ->with('OCA\Files_Sharing\External\Storage')
+                       ->willReturn(false);
+               $path->method('getStorage')->willReturn($storage);
+               $userFolder->expects($this->once())
+                               ->method('get')
+                               ->with('valid-path')
+                               ->willReturn($path);
+
+               $this->userManager->method('userExists')->with('validUser')->willReturn(true);
+
+               $path->expects($this->once())
+                       ->method('lock')
+                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+               $this->shareManager->method('createShare')
+                       ->with($this->callback(function (\OCP\Share\IShare $share) use ($path) {
+                               return $share->getNode() === $path &&
+                                       $share->getPermissions() === (
+                                               \OCP\Constants::PERMISSION_ALL &
+                                               ~\OCP\Constants::PERMISSION_DELETE &
+                                               ~\OCP\Constants::PERMISSION_CREATE
+                                       ) &&
+                                       $share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
+                                       $share->getSharedWith() === 'validUser' &&
+                                       $share->getSharedBy() === 'currentUser';
+                       }))
+                       ->will($this->returnArgument(0));
+
+               $expected = new DataResponse(null);
+               $result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_USER, 'validUser');
+
+               $this->assertInstanceOf(get_class($expected), $result);
+               $this->assertEquals($expected->getData(), $result->getData());
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
+        * @expectedExceptionMessage Please specify a valid group
+        */
+       public function testCreateShareGroupNoValidShareWith() {
+               $share = $this->newShare();
+               $this->shareManager->method('newShare')->willReturn($share);
+               $this->shareManager->method('createShare')->will($this->returnArgument(0));
+               $this->shareManager->method('allowGroupSharing')->willReturn(true);
+
+               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $this->rootFolder->expects($this->once())
+                               ->method('getUserFolder')
+                               ->with('currentUser')
+                               ->willReturn($userFolder);
+
+               $path = $this->getMockBuilder('\OCP\Files\File')->getMock();
+               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
+               $storage->method('instanceOfStorage')
+                       ->with('OCA\Files_Sharing\External\Storage')
+                       ->willReturn(false);
+               $path->method('getStorage')->willReturn($storage);
+               $userFolder->expects($this->once())
+                               ->method('get')
+                               ->with('valid-path')
+                               ->willReturn($path);
+
+               $path->expects($this->once())
+                       ->method('lock')
+                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+               $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_GROUP, 'invalidGroup');
+       }
+
+       public function testCreateShareGroup() {
+               $share = $this->newShare();
+               $this->shareManager->method('newShare')->willReturn($share);
+
+               /** @var ShareAPIController|\PHPUnit_Framework_MockObject_MockObject $ocs */
+               $ocs = $this->getMockBuilder(ShareAPIController::class)
+                       ->setConstructorArgs([
+                               $this->appName,
+                               $this->request,
+                               $this->shareManager,
+                               $this->groupManager,
+                               $this->userManager,
+                               $this->rootFolder,
+                               $this->urlGenerator,
+                               $this->currentUser,
+                               $this->l,
+                       ])->setMethods(['formatShare'])
+                       ->getMock();
+
+               $this->request
+                       ->method('getParam')
+                       ->will($this->returnValueMap([
+                               ['path', null, 'valid-path'],
+                               ['permissions', null, \OCP\Constants::PERMISSION_ALL],
+                               ['shareType', '-1', \OCP\Share::SHARE_TYPE_GROUP],
+                               ['shareWith', null, 'validGroup'],
+                       ]));
+
+               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $this->rootFolder->expects($this->once())
+                       ->method('getUserFolder')
+                       ->with('currentUser')
+                       ->willReturn($userFolder);
+
+               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
+               $storage->method('instanceOfStorage')
+                       ->with('OCA\Files_Sharing\External\Storage')
+                       ->willReturn(false);
+               $path->method('getStorage')->willReturn($storage);
+               $userFolder->expects($this->once())
+                       ->method('get')
+                       ->with('valid-path')
+                       ->willReturn($path);
+
+               $this->groupManager->method('groupExists')->with('validGroup')->willReturn(true);
+
+               $this->shareManager->expects($this->once())
+                       ->method('allowGroupSharing')
+                       ->willReturn(true);
+
+               $path->expects($this->once())
+                       ->method('lock')
+                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+               $this->shareManager->method('createShare')
+                       ->with($this->callback(function (\OCP\Share\IShare $share) use ($path) {
+                               return $share->getNode() === $path &&
+                               $share->getPermissions() === \OCP\Constants::PERMISSION_ALL &&
+                               $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP &&
+                               $share->getSharedWith() === 'validGroup' &&
+                               $share->getSharedBy() === 'currentUser';
+                       }))
+                       ->will($this->returnArgument(0));
+
+               $expected = new DataResponse(null);
+               $result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_GROUP, 'validGroup');
+
+               $this->assertInstanceOf(get_class($expected), $result);
+               $this->assertEquals($expected->getData(), $result->getData());
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
+        * @expectedExceptionMessage Group sharing is disabled by the administrator
+        */
+       public function testCreateShareGroupNotAllowed() {
+               $share = $this->newShare();
+               $this->shareManager->method('newShare')->willReturn($share);
+
+               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $this->rootFolder->expects($this->once())
+                       ->method('getUserFolder')
+                       ->with('currentUser')
+                       ->willReturn($userFolder);
+
+               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
+               $storage->method('instanceOfStorage')
+                       ->with('OCA\Files_Sharing\External\Storage')
+                       ->willReturn(false);
+               $path->method('getStorage')->willReturn($storage);
+               $userFolder->expects($this->once())
+                       ->method('get')
+                       ->with('valid-path')
+                       ->willReturn($path);
+
+               $this->groupManager->method('groupExists')->with('validGroup')->willReturn(true);
+
+               $this->shareManager->expects($this->once())
+                       ->method('allowGroupSharing')
+                       ->willReturn(false);
+
+               $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_GROUP, 'invalidGroup');
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
+        * @expectedExceptionMessage Public link sharing is disabled by the administrator
+        */
+       public function testCreateShareLinkNoLinksAllowed() {
+               $this->request
+                       ->method('getParam')
+                       ->will($this->returnValueMap([
+                               ['path', null, 'valid-path'],
+                               ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK],
+                       ]));
+
+               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
+               $storage->method('instanceOfStorage')
+                       ->with('OCA\Files_Sharing\External\Storage')
+                       ->willReturn(false);
+               $path->method('getStorage')->willReturn($storage);
+               $this->rootFolder->method('getUserFolder')->with($this->currentUser)->will($this->returnSelf());
+               $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
+
+               $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
+
+               $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK);
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSForbiddenException
+        * @expectedExceptionMessage Public upload disabled by the administrator
+        */
+       public function testCreateShareLinkNoPublicUpload() {
+               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
+               $storage->method('instanceOfStorage')
+                       ->with('OCA\Files_Sharing\External\Storage')
+                       ->willReturn(false);
+               $path->method('getStorage')->willReturn($storage);
+               $this->rootFolder->method('getUserFolder')->with($this->currentUser)->will($this->returnSelf());
+               $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
+
+               $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
+               $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
+
+               $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'true');
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
+        * @expectedExceptionMessage Public upload is only possible for publicly shared folders
+        */
+       public function testCreateShareLinkPublicUploadFile() {
+               $path = $this->getMockBuilder('\OCP\Files\File')->getMock();
+               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
+               $storage->method('instanceOfStorage')
+                       ->with('OCA\Files_Sharing\External\Storage')
+                       ->willReturn(false);
+               $path->method('getStorage')->willReturn($storage);
+               $this->rootFolder->method('getUserFolder')->with($this->currentUser)->will($this->returnSelf());
+               $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
+
+               $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
+               $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
+               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+               $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'true');
+       }
+
+       public function testCreateShareLinkPublicUploadFolder() {
+               $ocs = $this->mockFormatShare();
+
+               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
+               $storage->method('instanceOfStorage')
+                       ->with('OCA\Files_Sharing\External\Storage')
+                       ->willReturn(false);
+               $path->method('getStorage')->willReturn($storage);
+               $this->rootFolder->method('getUserFolder')->with($this->currentUser)->will($this->returnSelf());
+               $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
+
+               $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
+               $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
+               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+               $this->shareManager->expects($this->once())->method('createShare')->with(
+                       $this->callback(function (\OCP\Share\IShare $share) use ($path) {
+                               return $share->getNode() === $path &&
+                                       $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
+                                       $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) &&
+                                       $share->getSharedBy() === 'currentUser' &&
+                                       $share->getPassword() === null &&
+                                       $share->getExpirationDate() === null;
+                       })
+               )->will($this->returnArgument(0));
+
+               $expected = new DataResponse(null);
+               $result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'true', '', '');
+
+               $this->assertInstanceOf(get_class($expected), $result);
+               $this->assertEquals($expected->getData(), $result->getData());
+       }
+
+       public function testCreateShareLinkPassword() {
+               $ocs = $this->mockFormatShare();
+
+               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
+               $storage->method('instanceOfStorage')
+                       ->with('OCA\Files_Sharing\External\Storage')
+                       ->willReturn(false);
+               $path->method('getStorage')->willReturn($storage);
+               $this->rootFolder->method('getUserFolder')->with($this->currentUser)->will($this->returnSelf());
+               $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
+
+               $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
+               $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
+               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+               $this->shareManager->expects($this->once())->method('createShare')->with(
+                       $this->callback(function (\OCP\Share\IShare $share) use ($path) {
+                               return $share->getNode() === $path &&
+                               $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
+                               $share->getPermissions() === \OCP\Constants::PERMISSION_READ &&
+                               $share->getSharedBy() === 'currentUser' &&
+                               $share->getPassword() === 'password' &&
+                               $share->getExpirationDate() === null;
+                       })
+               )->will($this->returnArgument(0));
+
+               $expected = new DataResponse(null);
+               $result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', 'password', '');
+
+               $this->assertInstanceOf(get_class($expected), $result);
+               $this->assertEquals($expected->getData(), $result->getData());
+       }
+
+       public function testCreateShareValidExpireDate() {
+               $ocs = $this->mockFormatShare();
+
+               $this->request
+                       ->method('getParam')
+                       ->will($this->returnValueMap([
+                               ['path', null, 'valid-path'],
+                               ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK],
+                               ['publicUpload', null, 'false'],
+                               ['expireDate', '', '2000-01-01'],
+                               ['password', '', ''],
+                       ]));
+
+               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
+               $storage->method('instanceOfStorage')
+                       ->with('OCA\Files_Sharing\External\Storage')
+                       ->willReturn(false);
+               $path->method('getStorage')->willReturn($storage);
+               $this->rootFolder->method('getUserFolder')->with($this->currentUser)->will($this->returnSelf());
+               $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
+
+               $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
+               $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
+               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+               $this->shareManager->expects($this->once())->method('createShare')->with(
+                       $this->callback(function (\OCP\Share\IShare $share) use ($path) {
+                               $date = new \DateTime('2000-01-01');
+                               $date->setTime(0,0,0);
+
+                               return $share->getNode() === $path &&
+                               $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
+                               $share->getPermissions() === \OCP\Constants::PERMISSION_READ &&
+                               $share->getSharedBy() === 'currentUser' &&
+                               $share->getPassword() === null &&
+                               $share->getExpirationDate() == $date;
+                       })
+               )->will($this->returnArgument(0));
+
+               $expected = new DataResponse(null);
+               $result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', '2000-01-01');
+
+               $this->assertInstanceOf(get_class($expected), $result);
+               $this->assertEquals($expected->getData(), $result->getData());
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
+        * @expectedExceptionMessage Invalid date, date format must be YYYY-MM-DD
+        */
+       public function testCreateShareInvalidExpireDate() {
+               $ocs = $this->mockFormatShare();
+
+               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
+               $storage->method('instanceOfStorage')
+                       ->with('OCA\Files_Sharing\External\Storage')
+                       ->willReturn(false);
+               $path->method('getStorage')->willReturn($storage);
+               $this->rootFolder->method('getUserFolder')->with($this->currentUser)->will($this->returnSelf());
+               $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
+
+               $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
+               $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
+               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+               $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', 'a1b2d3');
+       }
+
+       /**
+        * Test for https://github.com/owncloud/core/issues/22587
+        * TODO: Remove once proper solution is in place
+        */
+       public function testCreateReshareOfFederatedMountNoDeletePermissions() {
+               $share = \OC::$server->getShareManager()->newShare();
+               $this->shareManager->method('newShare')->willReturn($share);
+
+               /** @var ShareAPIController|\PHPUnit_Framework_MockObject_MockObject $ocs */
+               $ocs = $this->getMockBuilder(ShareAPIController::class)
+                       ->setConstructorArgs([
+                               $this->appName,
+                               $this->request,
+                               $this->shareManager,
+                               $this->groupManager,
+                               $this->userManager,
+                               $this->rootFolder,
+                               $this->urlGenerator,
+                               $this->currentUser,
+                               $this->l,
+                       ])->setMethods(['formatShare'])
+                       ->getMock();
+
+               $userFolder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $this->rootFolder->expects($this->once())
+                       ->method('getUserFolder')
+                       ->with('currentUser')
+                       ->willReturn($userFolder);
+
+               $path = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $storage = $this->getMockBuilder('OCP\Files\Storage')->getMock();
+               $storage->method('instanceOfStorage')
+                       ->with('OCA\Files_Sharing\External\Storage')
+                       ->willReturn(true);
+               $path->method('getStorage')->willReturn($storage);
+               $path->method('getPermissions')->willReturn(\OCP\Constants::PERMISSION_READ);
+               $userFolder->expects($this->once())
+                       ->method('get')
+                       ->with('valid-path')
+                       ->willReturn($path);
+
+               $this->userManager->method('userExists')->with('validUser')->willReturn(true);
+
+               $this->shareManager
+                       ->expects($this->once())
+                       ->method('createShare')
+                       ->with($this->callback(function (\OCP\Share\IShare $share) {
+                               return $share->getPermissions() === \OCP\Constants::PERMISSION_READ;
+                       }))
+                       ->will($this->returnArgument(0));
+
+               $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_USER, 'validUser');
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSNotFoundException
+        * @expectedExceptionMessage Wrong share ID, share doesn't exist
+        */
+       public function testUpdateShareCantAccess() {
+               $node = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $share = $this->newShare();
+               $share->setNode($node);
+
+               $node->expects($this->once())
+                       ->method('lock')
+                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+               $this->ocs->updateShare(42);
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSBadRequestException
+        * @expectedExceptionMessage Wrong or no update parameter given
+        */
+       public function testUpdateNoParametersLink() {
+               $node = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $share = $this->newShare();
+               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
+                       ->setNode($node);
+
+               $node->expects($this->once())
+                       ->method('lock')
+                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+               $this->ocs->updateShare(42);
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSBadRequestException
+        * @expectedExceptionMessage Wrong or no update parameter given
+        */
+       public function testUpdateNoParametersOther() {
+               $node = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $share = $this->newShare();
+               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
+                       ->setNode($node);
+
+               $node->expects($this->once())
+                       ->method('lock')
+                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+               $this->ocs->updateShare(42);
+       }
+
+       public function testUpdateLinkShareClear() {
+               $ocs = $this->mockFormatShare();
+
+               $node = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $share = $this->newShare();
+               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
+                       ->setPassword('password')
+                       ->setExpirationDate(new \DateTime())
+                       ->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setNode($node);
+
+               $node->expects($this->once())
+                       ->method('lock')
+                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+               $this->shareManager->expects($this->once())->method('updateShare')->with(
+                       $this->callback(function (\OCP\Share\IShare $share) {
+                               return $share->getPermissions() === \OCP\Constants::PERMISSION_READ &&
+                               $share->getPassword() === null &&
+                               $share->getExpirationDate() === null;
+                       })
+               )->will($this->returnArgument(0));
+
+               $expected = new DataResponse(null);
+               $result = $ocs->updateShare(42, null, '', 'false', '');
+
+               $this->assertInstanceOf(get_class($expected), $result);
+               $this->assertEquals($expected->getData(), $result->getData());
+       }
+
+       public function testUpdateLinkShareSet() {
+               $ocs = $this->mockFormatShare();
+
+               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
+                       ->setNode($folder);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+               $this->shareManager->expects($this->once())->method('updateShare')->with(
+                       $this->callback(function (\OCP\Share\IShare $share) {
+                               $date = new \DateTime('2000-01-01');
+                               $date->setTime(0,0,0);
+
+                               return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) &&
+                               $share->getPassword() === 'password' &&
+                               $share->getExpirationDate() == $date;
+                       })
+               )->will($this->returnArgument(0));
+
+               $expected = new DataResponse(null);
+               $result = $ocs->updateShare(42, null, 'password', 'true', '2000-01-01');
+
+               $this->assertInstanceOf(get_class($expected), $result);
+               $this->assertEquals($expected->getData(), $result->getData());
+       }
+
+       /**
+        * @dataProvider publicUploadParamsProvider
+        */
+       public function testUpdateLinkShareEnablePublicUpload($permissions, $publicUpload, $expireDate, $password) {
+               $ocs = $this->mockFormatShare();
+
+               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
+                       ->setPassword('password')
+                       ->setNode($folder);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+               $this->shareManager->method('getSharedWith')->willReturn([]);
+
+               $this->shareManager->expects($this->once())->method('updateShare')->with(
+                       $this->callback(function (\OCP\Share\IShare $share) {
+                               return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) &&
+                               $share->getPassword() === 'password' &&
+                               $share->getExpirationDate() === null;
+                       })
+               )->will($this->returnArgument(0));
+
+               $expected = new DataResponse(null);
+               $result = $ocs->updateShare(42, $permissions, $password, $publicUpload, $expireDate);
+
+               $this->assertInstanceOf(get_class($expected), $result);
+               $this->assertEquals($expected->getData(), $result->getData());
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSBadRequestException
+        * @expectedExceptionMessage Invalid date. Format must be YYYY-MM-DD
+        */
+       public function testUpdateLinkShareInvalidDate() {
+               $ocs = $this->mockFormatShare();
+
+               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
+                       ->setNode($folder);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+               $ocs->updateShare(42, null, 'password', 'true', '2000-01-a');
+       }
+
+       public function publicUploadParamsProvider() {
+               return [
+                       [null, 'true', null, 'password'],
+                       // legacy had no delete
+                       [
+                               \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE,
+                               null, null, 'password'
+                       ],
+                       // correct
+                       [
+                               \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE,
+                               null, null, 'password'
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider publicUploadParamsProvider
+        * @expectedException \OCP\AppFramework\OCS\OCSForbiddenException
+        * @expectedExceptionMessage Public upload disabled by the administrator
+        */
+       public function testUpdateLinkSharePublicUploadNotAllowed($permissions, $publicUpload, $expireDate, $password) {
+               $ocs = $this->mockFormatShare();
+
+               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
+                       ->setNode($folder);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(false);
+
+               $ocs->updateShare(42, $permissions, $password, $publicUpload, $expireDate);
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSBadRequestException
+        * @expectedExceptionMessage Public upload is only possible for publicly shared folders
+        */
+       public function testUpdateLinkSharePublicUploadOnFile() {
+               $ocs = $this->mockFormatShare();
+
+               $file = $this->getMockBuilder('\OCP\Files\File')->getMock();
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
+                       ->setNode($file);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+               $ocs->updateShare(42, null, 'password', 'true', '');
+       }
+
+       public function testUpdateLinkSharePasswordDoesNotChangeOther() {
+               $ocs = $this->mockFormatShare();
+
+               $date = new \DateTime('2000-01-01');
+               $date->setTime(0,0,0);
+
+               $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
+               $share = $this->newShare();
+               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
+                       ->setPassword('password')
+                       ->setExpirationDate($date)
+                       ->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setNode($node);
+
+               $node->expects($this->once())
+                       ->method('lock')
+                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+               $this->shareManager->expects($this->once())->method('updateShare')->with(
+                       $this->callback(function (\OCP\Share\IShare $share) use ($date) {
+                               return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL &&
+                               $share->getPassword() === 'newpassword' &&
+                               $share->getExpirationDate() === $date;
+                       })
+               )->will($this->returnArgument(0));
+
+               $expected = new DataResponse(null);
+               $result = $ocs->updateShare(42, null, 'newpassword', null, null);
+
+               $this->assertInstanceOf(get_class($expected), $result);
+               $this->assertEquals($expected->getData(), $result->getData());
+       }
+
+       public function testUpdateLinkShareExpireDateDoesNotChangeOther() {
+               $ocs = $this->mockFormatShare();
+
+               $node = $this->getMockBuilder('\OCP\Files\File')->getMock();
+               $share = $this->newShare();
+               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
+                       ->setPassword('password')
+                       ->setExpirationDate(new \DateTime())
+                       ->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setNode($node);
+
+               $node->expects($this->once())
+                       ->method('lock')
+                       ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+               $this->shareManager->expects($this->once())->method('updateShare')->with(
+                       $this->callback(function (\OCP\Share\IShare $share) {
+                               $date = new \DateTime('2010-12-23');
+                               $date->setTime(0,0,0);
+
+                               return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL &&
+                               $share->getPassword() === 'password' &&
+                               $share->getExpirationDate() == $date;
+                       })
+               )->will($this->returnArgument(0));
+
+               $expected = new DataResponse(null);
+               $result = $ocs->updateShare(42, null, null, null, '2010-12-23');
+
+               $this->assertInstanceOf(get_class($expected), $result);
+               $this->assertEquals($expected->getData(), $result->getData());
+       }
+
+       public function testUpdateLinkSharePublicUploadDoesNotChangeOther() {
+               $ocs = $this->mockFormatShare();
+
+               $date = new \DateTime('2000-01-01');
+
+               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
+                       ->setPassword('password')
+                       ->setExpirationDate($date)
+                       ->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setNode($folder);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+               $this->shareManager->expects($this->once())->method('updateShare')->with(
+                       $this->callback(function (\OCP\Share\IShare $share) use ($date) {
+                               return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) &&
+                               $share->getPassword() === 'password' &&
+                               $share->getExpirationDate() === $date;
+                       })
+               )->will($this->returnArgument(0));
+
+               $expected = new DataResponse(null);
+               $result = $ocs->updateShare(42, null, null, 'true', null);
+
+               $this->assertInstanceOf(get_class($expected), $result);
+               $this->assertEquals($expected->getData(), $result->getData());
+       }
+
+       public function testUpdateLinkSharePermissions() {
+               $ocs = $this->mockFormatShare();
+
+               $date = new \DateTime('2000-01-01');
+
+               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
+                       ->setPassword('password')
+                       ->setExpirationDate($date)
+                       ->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setNode($folder);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+               $this->shareManager->expects($this->once())->method('updateShare')->with(
+                       $this->callback(function (\OCP\Share\IShare $share) use ($date) {
+                               return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) &&
+                               $share->getPassword() === 'password' &&
+                               $share->getExpirationDate() === $date;
+                       })
+               )->will($this->returnArgument(0));
+
+               $this->shareManager->method('getSharedWith')->willReturn([]);
+
+               $expected = new DataResponse(null);
+               $result = $ocs->updateShare(42, 7, null, null, null);
+
+               $this->assertInstanceOf(get_class($expected), $result);
+               $this->assertEquals($expected->getData(), $result->getData());
+       }
+
+       /**
+        * @expectedException \OCP\AppFramework\OCS\OCSBadRequestException
+        * @expectedExceptionMessage Can't change permissions for public share links
+        */
+       public function testUpdateLinkShareInvalidPermissions() {
+               $ocs = $this->mockFormatShare();
+
+               $date = new \DateTime('2000-01-01');
+
+               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
+                       ->setPassword('password')
+                       ->setExpirationDate($date)
+                       ->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setNode($folder);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+               $ocs->updateShare(42, 31);
+       }
+
+       public function testUpdateOtherPermissions() {
+               $ocs = $this->mockFormatShare();
+
+               $file = $this->getMockBuilder('\OCP\Files\File')->getMock();
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_USER)
+                       ->setNode($file);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+               $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+               $this->shareManager->expects($this->once())->method('updateShare')->with(
+                       $this->callback(function (\OCP\Share\IShare $share) {
+                               return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL;
+                       })
+               )->will($this->returnArgument(0));
+
+               $this->shareManager->method('getSharedWith')->willReturn([]);
+
+               $expected = new DataResponse(null);
+               $result = $ocs->updateShare(42, 31, null, null, null);
+
+               $this->assertInstanceOf(get_class($expected), $result);
+               $this->assertEquals($expected->getData(), $result->getData());
+       }
+
+       public function testUpdateShareCannotIncreasePermissions() {
+               $ocs = $this->mockFormatShare();
+
+               $folder = $this->createMock(Folder::class);
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share
+                       ->setId(42)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareOwner('anotheruser')
+                       ->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
+                       ->setSharedWith('group1')
+                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
+                       ->setNode($folder);
+
+               // note: updateShare will modify the received instance but getSharedWith will reread from the database,
+               // so their values will be different
+               $incomingShare = \OC::$server->getShareManager()->newShare();
+               $incomingShare
+                       ->setId(42)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareOwner('anotheruser')
+                       ->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
+                       ->setSharedWith('group1')
+                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
+                       ->setNode($folder);
+
+               $this->request
+                       ->method('getParam')
+                       ->will($this->returnValueMap([
+                               ['permissions', null, '31'],
+                       ]));
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+               $this->shareManager->expects($this->any())
+                       ->method('getSharedWith')
+                       ->will($this->returnValueMap([
+                               ['currentUser', \OCP\Share::SHARE_TYPE_USER, $share->getNode(), -1, 0, []],
+                               ['currentUser', \OCP\Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0, [$incomingShare]]
+                       ]));
+
+               $this->shareManager->expects($this->never())->method('updateShare');
+
+               try {
+                       $ocs->updateShare(42, 31);
+                       $this->fail();
+               } catch (OCSNotFoundException $e) {
+                       $this->assertEquals('Cannot increase permissions', $e->getMessage());
+               }
+       }
+
+       public function testUpdateShareCanIncreasePermissionsIfOwner() {
+               $ocs = $this->mockFormatShare();
+
+               $folder = $this->createMock(Folder::class);
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share
+                       ->setId(42)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareOwner($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
+                       ->setSharedWith('group1')
+                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
+                       ->setNode($folder);
+
+               // note: updateShare will modify the received instance but getSharedWith will reread from the database,
+               // so their values will be different
+               $incomingShare = \OC::$server->getShareManager()->newShare();
+               $incomingShare
+                       ->setId(42)
+                       ->setSharedBy($this->currentUser)
+                       ->setShareOwner($this->currentUser)
+                       ->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
+                       ->setSharedWith('group1')
+                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
+                       ->setNode($folder);
+
+               $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+               $this->shareManager->expects($this->any())
+                       ->method('getSharedWith')
+                       ->will($this->returnValueMap([
+                               ['currentUser', \OCP\Share::SHARE_TYPE_USER, $share->getNode(), -1, 0, []],
+                               ['currentUser', \OCP\Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0, [$incomingShare]]
+                       ]));
+
+               $this->shareManager->expects($this->once())
+                       ->method('updateShare')
+                       ->with($share)
+                       ->willReturn($share);
+
+               $result = $ocs->updateShare(42, 31);
+               $this->assertInstanceOf(DataResponse::class, $result);
+       }
+
+       public function dataFormatShare() {
+               $file = $this->getMockBuilder('\OCP\Files\File')->getMock();
+               $folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+               $parent = $this->getMockBuilder('\OCP\Files\Folder')->getMock();
+
+               $file->method('getMimeType')->willReturn('myMimeType');
+               $folder->method('getMimeType')->willReturn('myFolderMimeType');
+
+               $file->method('getPath')->willReturn('file');
+               $folder->method('getPath')->willReturn('folder');
+
+               $parent->method('getId')->willReturn(1);
+               $folder->method('getId')->willReturn(2);
+               $file->method('getId')->willReturn(3);
+
+               $file->method('getParent')->willReturn($parent);
+               $folder->method('getParent')->willReturn($parent);
+
+               $cache = $this->getMockBuilder('OCP\Files\Cache\ICache')->getMock();
+               $cache->method('getNumericStorageId')->willReturn(100);
+               $storage = $this->getMockBuilder('\OCP\Files\Storage')->getMock();
+               $storage->method('getId')->willReturn('storageId');
+               $storage->method('getCache')->willReturn($cache);
+
+               $file->method('getStorage')->willReturn($storage);
+               $folder->method('getStorage')->willReturn($storage);
+
+               $owner = $this->getMockBuilder('\OCP\IUser')->getMock();
+               $owner->method('getDisplayName')->willReturn('ownerDN');
+               $initiator = $this->getMockBuilder('\OCP\IUser')->getMock();
+               $initiator->method('getDisplayName')->willReturn('initiatorDN');
+               $recipient = $this->getMockBuilder('\OCP\IUser')->getMock();
+               $recipient->method('getDisplayName')->willReturn('recipientDN');
+
+               $result = [];
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setShareType(\OCP\Share::SHARE_TYPE_USER)
+                       ->setSharedWith('recipient')
+                       ->setSharedBy('initiator')
+                       ->setShareOwner('owner')
+                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
+                       ->setNode($file)
+                       ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+                       ->setTarget('myTarget')
+                       ->setId(42);
+
+               /* User backend down */
+               $result[] = [
+                       [
+                               'id' => 42,
+                               'share_type' => \OCP\Share::SHARE_TYPE_USER,
+                               'uid_owner' => 'initiator',
+                               'displayname_owner' => 'initiator',
+                               'permissions' => 1,
+                               'stime' => 946684862,
+                               'parent' => null,
+                               'expiration' => null,
+                               'token' => null,
+                               'uid_file_owner' => 'owner',
+                               'displayname_file_owner' => 'owner',
+                               'path' => 'file',
+                               'item_type' => 'file',
+                               'storage_id' => 'storageId',
+                               'storage' => 100,
+                               'item_source' => 3,
+                               'file_source' => 3,
+                               'file_parent' => 1,
+                               'file_target' => 'myTarget',
+                               'share_with' => 'recipient',
+                               'share_with_displayname' => 'recipient',
+                               'mail_send' => 0,
+                               'mimetype' => 'myMimeType',
+                       ], $share, [], false
+               ];
+
+               /* User backend up */
+               $result[] = [
+                       [
+                               'id' => 42,
+                               'share_type' => \OCP\Share::SHARE_TYPE_USER,
+                               'uid_owner' => 'initiator',
+                               'displayname_owner' => 'initiatorDN',
+                               'permissions' => 1,
+                               'stime' => 946684862,
+                               'parent' => null,
+                               'expiration' => null,
+                               'token' => null,
+                               'uid_file_owner' => 'owner',
+                               'displayname_file_owner' => 'ownerDN',
+                               'path' => 'file',
+                               'item_type' => 'file',
+                               'storage_id' => 'storageId',
+                               'storage' => 100,
+                               'item_source' => 3,
+                               'file_source' => 3,
+                               'file_parent' => 1,
+                               'file_target' => 'myTarget',
+                               'share_with' => 'recipient',
+                               'share_with_displayname' => 'recipientDN',
+                               'mail_send' => 0,
+                               'mimetype' => 'myMimeType',
+                       ], $share, [
+                               ['owner', $owner],
+                               ['initiator', $initiator],
+                               ['recipient', $recipient],
+                       ], false
+               ];
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setShareType(\OCP\Share::SHARE_TYPE_USER)
+                       ->setSharedWith('recipient')
+                       ->setSharedBy('initiator')
+                       ->setShareOwner('owner')
+                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
+                       ->setNode($file)
+                       ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+                       ->setTarget('myTarget')
+                       ->setId(42);
+
+               /* User backend down */
+               $result[] = [
+                       [
+                               'id' => 42,
+                               'share_type' => \OCP\Share::SHARE_TYPE_USER,
+                               'uid_owner' => 'initiator',
+                               'displayname_owner' => 'initiator',
+                               'permissions' => 1,
+                               'stime' => 946684862,
+                               'parent' => null,
+                               'expiration' => null,
+                               'token' => null,
+                               'uid_file_owner' => 'owner',
+                               'displayname_file_owner' => 'owner',
+                               'path' => 'file',
+                               'item_type' => 'file',
+                               'storage_id' => 'storageId',
+                               'storage' => 100,
+                               'item_source' => 3,
+                               'file_source' => 3,
+                               'file_parent' => 1,
+                               'file_target' => 'myTarget',
+                               'share_with' => 'recipient',
+                               'share_with_displayname' => 'recipient',
+                               'mail_send' => 0,
+                               'mimetype' => 'myMimeType',
+                       ], $share, [], false
+               ];
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
+                       ->setSharedWith('recipient')
+                       ->setSharedBy('initiator')
+                       ->setShareOwner('owner')
+                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
+                       ->setNode($file)
+                       ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+                       ->setTarget('myTarget')
+                       ->setId(42);
+
+               $result[] = [
+                       [
+                               'id' => 42,
+                               'share_type' => \OCP\Share::SHARE_TYPE_GROUP,
+                               'uid_owner' => 'initiator',
+                               'displayname_owner' => 'initiator',
+                               'permissions' => 1,
+                               'stime' => 946684862,
+                               'parent' => null,
+                               'expiration' => null,
+                               'token' => null,
+                               'uid_file_owner' => 'owner',
+                               'displayname_file_owner' => 'owner',
+                               'path' => 'file',
+                               'item_type' => 'file',
+                               'storage_id' => 'storageId',
+                               'storage' => 100,
+                               'item_source' => 3,
+                               'file_source' => 3,
+                               'file_parent' => 1,
+                               'file_target' => 'myTarget',
+                               'share_with' => 'recipient',
+                               'share_with_displayname' => 'recipient',
+                               'mail_send' => 0,
+                               'mimetype' => 'myMimeType',
+                       ], $share, [], false
+               ];
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setShareType(\OCP\Share::SHARE_TYPE_LINK)
+                       ->setSharedBy('initiator')
+                       ->setShareOwner('owner')
+                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
+                       ->setNode($file)
+                       ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+                       ->setTarget('myTarget')
+                       ->setPassword('mypassword')
+                       ->setExpirationDate(new \DateTime('2001-01-02T00:00:00'))
+                       ->setToken('myToken')
+                       ->setId(42);
+
+               $result[] = [
+                       [
+                               'id' => 42,
+                               'share_type' => \OCP\Share::SHARE_TYPE_LINK,
+                               'uid_owner' => 'initiator',
+                               'displayname_owner' => 'initiator',
+                               'permissions' => 1,
+                               'stime' => 946684862,
+                               'parent' => null,
+                               'expiration' => '2001-01-02 00:00:00',
+                               'token' => 'myToken',
+                               'uid_file_owner' => 'owner',
+                               'displayname_file_owner' => 'owner',
+                               'path' => 'file',
+                               'item_type' => 'file',
+                               'storage_id' => 'storageId',
+                               'storage' => 100,
+                               'item_source' => 3,
+                               'file_source' => 3,
+                               'file_parent' => 1,
+                               'file_target' => 'myTarget',
+                               'share_with' => 'mypassword',
+                               'share_with_displayname' => 'mypassword',
+                               'mail_send' => 0,
+                               'url' => 'myLink',
+                               'mimetype' => 'myMimeType',
+                       ], $share, [], false
+               ];
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setShareType(\OCP\Share::SHARE_TYPE_REMOTE)
+                       ->setSharedBy('initiator')
+                       ->setSharedWith('user@server.com')
+                       ->setShareOwner('owner')
+                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
+                       ->setNode($folder)
+                       ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+                       ->setTarget('myTarget')
+                       ->setId(42);
+
+               $result[] = [
+                       [
+                               'id' => 42,
+                               'share_type' => \OCP\Share::SHARE_TYPE_REMOTE,
+                               'uid_owner' => 'initiator',
+                               'displayname_owner' => 'initiator',
+                               'permissions' => 1,
+                               'stime' => 946684862,
+                               'parent' => null,
+                               'expiration' => null,
+                               'token' => null,
+                               'uid_file_owner' => 'owner',
+                               'displayname_file_owner' => 'owner',
+                               'path' => 'folder',
+                               'item_type' => 'folder',
+                               'storage_id' => 'storageId',
+                               'storage' => 100,
+                               'item_source' => 2,
+                               'file_source' => 2,
+                               'file_parent' => 1,
+                               'file_target' => 'myTarget',
+                               'share_with' => 'user@server.com',
+                               'share_with_displayname' => 'user@server.com',
+                               'mail_send' => 0,
+                               'mimetype' => 'myFolderMimeType',
+                       ], $share, [], false
+               ];
+
+               $share = \OC::$server->getShareManager()->newShare();
+               $share->setShareType(\OCP\Share::SHARE_TYPE_USER)
+                       ->setSharedBy('initiator')
+                       ->setSharedWith('recipient')
+                       ->setShareOwner('owner')
+                       ->setPermissions(\OCP\Constants::PERMISSION_READ)
+                       ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+                       ->setTarget('myTarget')
+                       ->setId(42);
+
+               $result[] = [
+                       [], $share, [], true
+               ];
+
+               return $result;
+       }
+
+       /**
+        * @dataProvider dataFormatShare
+        *
+        * @param array $expects
+        * @param \OCP\Share\IShare $share
+        * @param array $users
+        * @param $exception
+        */
+       public function testFormatShare(array $expects, \OCP\Share\IShare $share, array $users, $exception) {
+               $this->userManager->method('get')->will($this->returnValueMap($users));
+               $this->urlGenerator->method('linkToRouteAbsolute')
+                       ->with('files_sharing.sharecontroller.showShare', ['token' => 'myToken'])
+                       ->willReturn('myLink');
+
+
+               $this->rootFolder->method('getUserFolder')
+                       ->with($this->currentUser)
+                       ->will($this->returnSelf());
+
+               if (!$exception) {
+                       $this->rootFolder->method('getById')
+                               ->with($share->getNodeId())
+                               ->willReturn([$share->getNode()]);
+
+                       $this->rootFolder->method('getRelativePath')
+                               ->with($share->getNode()->getPath())
+                               ->will($this->returnArgument(0));
+               }
+
+               try {
+                       $result = $this->invokePrivate($this->ocs, 'formatShare', [$share]);
+                       $this->assertFalse($exception);
+                       $this->assertEquals($expects, $result);
+               } catch (NotFoundException $e) {
+                       $this->assertTrue($exception);
+               }
+       }
+}