Exemple #1
0
 /**
  * Convert an IShare to an array for OCS output
  *
  * @param \OCP\Share\IShare $share
  * @return array
  */
 protected function formatShare(\OCP\Share\IShare $share)
 {
     $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->getDisplayName(), 'permissions' => $share->getPermissions(), 'stime' => $share->getShareTime()->getTimestamp(), 'parent' => null, 'expiration' => null, 'token' => null, 'uid_file_owner' => $share->getShareOwner(), 'displayname_file_owner' => $shareOwner->getDisplayName()];
     $node = $share->getNode();
     $result['path'] = $this->rootFolder->getUserFolder($share->getShareOwner())->getRelativePath($node->getPath());
     if ($node instanceof \OCP\Files\Folder) {
         $result['item_type'] = 'folder';
     } else {
         $result['item_type'] = 'file';
     }
     $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'] = $sharedWith->getUID();
         $result['share_with_displayname'] = $sharedWith->getDisplayName();
     } 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;
 }
 /**
  * Share a path
  *
  * @param IShare $share
  * @return IShare The share object
  * @throws ShareNotFound
  * @throws \Exception
  */
 public function create(IShare $share)
 {
     $shareWith = $share->getSharedWith();
     $itemSource = $share->getNodeId();
     $itemType = $share->getNodeType();
     $uidOwner = $share->getShareOwner();
     $permissions = $share->getPermissions();
     $sharedBy = $share->getSharedBy();
     /*
      * Check if file is not already shared with the remote user
      */
     $alreadyShared = $this->getSharedWith($shareWith, self::SHARE_TYPE_REMOTE, $share->getNode(), 1, 0);
     if (!empty($alreadyShared)) {
         $message = 'Sharing %s failed, because this item is already shared with %s';
         $message_t = $this->l->t('Sharing %s failed, because this item is already shared with %s', array($share->getNode()->getName(), $shareWith));
         $this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
         throw new \Exception($message_t);
     }
     // don't allow federated shares if source and target server are the same
     list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
     $currentServer = $this->addressHandler->generateRemoteURL();
     $currentUser = $sharedBy;
     if ($this->addressHandler->compareAddresses($user, $remote, $currentUser, $currentServer)) {
         $message = 'Not allowed to create a federated share with the same user.';
         $message_t = $this->l->t('Not allowed to create a federated share with the same user');
         $this->logger->debug($message, ['app' => 'Federated File Sharing']);
         throw new \Exception($message_t);
     }
     $token = $this->tokenHandler->generateToken();
     $shareWith = $user . '@' . $remote;
     $shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token);
     $send = $this->notifications->sendRemoteShare($token, $shareWith, $share->getNode()->getName(), $shareId, $share->getSharedBy());
     $data = $this->getRawShare($shareId);
     $share = $this->createShare($data);
     if ($send === false) {
         $this->delete($share);
         $message_t = $this->l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable.', [$share->getNode()->getName(), $shareWith]);
         throw new \Exception($message_t);
     }
     return $share;
 }
Exemple #3
0
 /**
  * @inheritdoc
  */
 public function move(\OCP\Share\IShare $share, $recipient)
 {
     if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
         // Just update the target
         $qb = $this->dbConn->getQueryBuilder();
         $qb->update('share')->set('file_target', $qb->createNamedParameter($share->getTarget()))->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))->execute();
     } else {
         if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
             // Check if there is a usergroup share
             $qb = $this->dbConn->getQueryBuilder();
             $stmt = $qb->select('id')->from('share')->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))->setMaxResults(1)->execute();
             $data = $stmt->fetch();
             $stmt->closeCursor();
             if ($data === false) {
                 // No usergroup share yet. Create one.
                 $qb = $this->dbConn->getQueryBuilder();
                 $qb->insert('share')->values(['share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP), 'share_with' => $qb->createNamedParameter($recipient), 'uid_owner' => $qb->createNamedParameter($share->getShareOwner()), 'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()), 'parent' => $qb->createNamedParameter($share->getId()), 'item_type' => $qb->createNamedParameter($share->getNode() instanceof File ? 'file' : 'folder'), 'item_source' => $qb->createNamedParameter($share->getNode()->getId()), 'file_source' => $qb->createNamedParameter($share->getNode()->getId()), 'file_target' => $qb->createNamedParameter($share->getTarget()), 'permissions' => $qb->createNamedParameter($share->getPermissions()), 'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp())])->execute();
             } else {
                 // Already a usergroup share. Update it.
                 $qb = $this->dbConn->getQueryBuilder();
                 $qb->update('share')->set('file_target', $qb->createNamedParameter($share->getTarget()))->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))->execute();
             }
         }
     }
     return $share;
 }
Exemple #4
0
 /**
  * Check for pre share requirements for group shares
  *
  * @param \OCP\Share\IShare $share
  * @throws \Exception
  */
 protected function groupCreateChecks(\OCP\Share\IShare $share)
 {
     // Verify if the user can share with this group
     if ($this->shareWithGroupMembersOnly()) {
         $sharedBy = $this->userManager->get($share->getSharedBy());
         $sharedWith = $this->groupManager->get($share->getSharedWith());
         if (!$sharedWith->inGroup($sharedBy)) {
             throw new \Exception('Only sharing within your own groups is allowed');
         }
     }
     /*
      * TODO: Could be costly, fix
      *
      * Also this is not what we want in the future.. then we want to squash identical shares.
      */
     $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
     $existingShares = $provider->getSharesByPath($share->getNode());
     foreach ($existingShares as $existingShare) {
         if ($existingShare->getFullId() === $share->getFullId()) {
             continue;
         }
         if ($existingShare->getSharedWith() === $share->getSharedWith()) {
             throw new \Exception('Path already shared with this group');
         }
     }
 }
 /**
  * @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);
     }
 }
 /**
  * Validate the permissions of the share
  *
  * @param Share\IShare $share
  * @return bool
  */
 private function validateShare(\OCP\Share\IShare $share)
 {
     return $share->getNode()->isReadable() && $share->getNode()->isShareable();
 }
 /**
  * create federated share and inform the recipient
  *
  * @param IShare $share
  * @return int
  * @throws ShareNotFound
  * @throws \Exception
  */
 protected function createFederatedShare(IShare $share)
 {
     $token = $this->tokenHandler->generateToken();
     $shareId = $this->addShareToDB($share->getNodeId(), $share->getNodeType(), $share->getSharedWith(), $share->getSharedBy(), $share->getShareOwner(), $share->getPermissions(), $token);
     $sharedByFederatedId = $share->getSharedBy();
     if ($this->userManager->userExists($sharedByFederatedId)) {
         $sharedByFederatedId = $sharedByFederatedId . '@' . $this->addressHandler->generateRemoteURL();
     }
     $send = $this->notifications->sendRemoteShare($token, $share->getSharedWith(), $share->getNode()->getName(), $shareId, $share->getShareOwner(), $share->getShareOwner() . '@' . $this->addressHandler->generateRemoteURL(), $share->getSharedBy(), $sharedByFederatedId);
     if ($send === false) {
         $data = $this->getRawShare($shareId);
         $share = $this->createShareObject($data);
         $this->removeShareFromTable($share);
         $message_t = $this->l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable.', [$share->getNode()->getName(), $share->getSharedWith()]);
         throw new \Exception($message_t);
     }
     return $shareId;
 }
 /**
  * Unshare a share from the recipient. If this is a group share
  * this means we need a special entry in the share db.
  *
  * @param \OCP\Share\IShare $share
  * @param IUser $recipient
  * @throws BackendError
  * @throws ProviderException
  */
 public function deleteFromSelf(\OCP\Share\IShare $share, IUser $recipient)
 {
     if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
         /** @var IGroup $group */
         $group = $share->getSharedWith();
         if (!$group->inGroup($recipient)) {
             throw new ProviderException('Recipient not in receiving group');
         }
         // Try to fetch user specific share
         $qb = $this->dbConn->getQueryBuilder();
         $stmt = $qb->select('*')->from('share')->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient->getUID())))->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))->execute();
         $data = $stmt->fetch();
         /*
          * Check if there already is a user specific group share.
          * If there is update it (if required).
          */
         if ($data === false) {
             $qb = $this->dbConn->getQueryBuilder();
             $type = $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder';
             //Insert new share
             $qb->insert('share')->values(['share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP), 'share_with' => $qb->createNamedParameter($recipient->getUID()), 'uid_owner' => $qb->createNamedParameter($share->getShareOwner()->getUID()), 'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()->getUID()), 'parent' => $qb->createNamedParameter($share->getId()), 'item_type' => $qb->createNamedParameter($type), 'item_source' => $qb->createNamedParameter($share->getNode()->getId()), 'file_source' => $qb->createNamedParameter($share->getNode()->getId()), 'file_target' => $qb->createNamedParameter($share->getTarget()), 'permissions' => $qb->createNamedParameter(0), 'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp())])->execute();
         } else {
             if ($data['permissions'] !== 0) {
                 // Update existing usergroup share
                 $qb = $this->dbConn->getQueryBuilder();
                 $qb->update('share')->set('permissions', $qb->createNamedParameter(0))->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))->execute();
             }
         }
     } else {
         if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
             if ($share->getSharedWith() !== $recipient) {
                 throw new ProviderException('Recipient does not match');
             }
             // We can just delete user and link shares
             $this->delete($share);
         } else {
             throw new ProviderException('Invalid shareType');
         }
     }
 }
 /**
  * Creates the environment based on the share the token links to
  *
  * @param IShare $share
  */
 public function setTokenBasedEnv($share)
 {
     $origShareOwnerId = $share->getShareOwner();
     $this->userFolder = $this->rootFolder->getUserFolder($origShareOwnerId);
     $this->sharedNodeId = $share->getNodeId();
     $this->sharedNode = $share->getNode();
     $this->fromRootToFolder = $this->buildFromRootToFolder($this->sharedNodeId);
     $this->folderName = $share->getTarget();
     $this->userId = $origShareOwnerId;
     $this->sharePassword = $share->getPassword();
 }
 /**
  * create federated share and inform the recipient
  *
  * @param IShare $share
  * @return int
  * @throws ShareNotFound
  * @throws \Exception
  */
 protected function createFederatedShare(IShare $share)
 {
     $token = $this->tokenHandler->generateToken();
     $shareId = $this->addShareToDB($share->getNodeId(), $share->getNodeType(), $share->getSharedWith(), $share->getSharedBy(), $share->getShareOwner(), $share->getPermissions(), $token);
     try {
         $sharedByFederatedId = $share->getSharedBy();
         if ($this->userManager->userExists($sharedByFederatedId)) {
             $sharedByFederatedId = $sharedByFederatedId . '@' . $this->addressHandler->generateRemoteURL();
         }
         $send = $this->notifications->sendRemoteShare($token, $share->getSharedWith(), $share->getNode()->getName(), $shareId, $share->getShareOwner(), $share->getShareOwner() . '@' . $this->addressHandler->generateRemoteURL(), $share->getSharedBy(), $sharedByFederatedId);
         if ($send === false) {
             $message_t = $this->l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable.', [$share->getNode()->getName(), $share->getSharedWith()]);
             throw new \Exception($message_t);
         }
     } catch (\Exception $e) {
         $this->logger->error('Failed to notify remote server of federated share, removing share (' . $e->getMessage() . ')');
         $this->removeShareFromTableById($shareId);
         throw $e;
     }
     return $shareId;
 }