diff --git a/lib/Service/ApprovalService.php b/lib/Service/ApprovalService.php index 2e29624b..3f77eb23 100644 --- a/lib/Service/ApprovalService.php +++ b/lib/Service/ApprovalService.php @@ -435,18 +435,18 @@ public function reject(int $fileId, ?string $userId, string $etag): bool { * * @param int $fileId * @param int $ruleId - * @param string|null $userId + * @param string|null $requesterUserId * @param bool $createShares * @return array potential error message * @throws \OCP\Files\NotPermittedException * @throws \OC\User\NoUserException */ - public function request(int $fileId, int $ruleId, ?string $userId, bool $createShares): array { - if (!$this->utilsService->userHasAccessTo($fileId, $userId)) { + public function request(int $fileId, int $ruleId, ?string $requesterUserId, bool $createShares): array { + if (!$this->utilsService->userHasAccessTo($fileId, $requesterUserId)) { return ['error' => $this->l10n->t('You do not have access to this file')]; } - if ($createShares && !$this->utilsService->userCanShareFile($fileId, $userId)) { + if ($createShares && !$this->utilsService->userCanShareFile($fileId, $requesterUserId)) { return ['error' => $this->l10n->t('You can not share this file')]; } @@ -455,16 +455,19 @@ public function request(int $fileId, int $ruleId, ?string $userId, bool $createS return ['error' => $this->l10n->t('Rule does not exist')]; } - if ($this->userIsAuthorizedByRule($userId, $rule, 'requesters')) { + if ($this->userIsAuthorizedByRule($requesterUserId, $rule, 'requesters')) { + if ($this->tagObjectMapper->haveTag((string) $fileId, 'files', $rule['tagApproved'])) { + return ['error' => $this->l10n->t('Approval has already been granted with this rule for this file')]; + } // only request if it has not yet been requested for this rule if (!$this->tagObjectMapper->haveTag((string) $fileId, 'files', $rule['tagPending'])) { if ($createShares) { - $this->shareWithApprovers($fileId, $rule, $userId); + $this->shareWithApprovers($fileId, $rule, $requesterUserId); // if shares are auto created, request is actually done in a separated request with $createShares === false return []; } // store activity in our tables - $this->ruleService->storeAction($fileId, $ruleId, $userId, Application::STATE_PENDING); + $this->ruleService->storeAction($fileId, $ruleId, $requesterUserId, Application::STATE_PENDING); $this->tagObjectMapper->assignTags((string) $fileId, 'files', $rule['tagPending']); @@ -472,7 +475,7 @@ public function request(int $fileId, int $ruleId, ?string $userId, bool $createS $this->activityManager->triggerEvent( ActivityManager::APPROVAL_OBJECT_NODE, $fileId, ActivityManager::SUBJECT_REQUESTED_ORIGIN, - ['origin_user_id' => $userId] + ['origin_user_id' => $requesterUserId] ); // check if someone can actually approve @@ -527,35 +530,27 @@ public function requestViaTagAssignment(int $fileId, int $ruleId, string $reques * * @param int $fileId * @param array $rule - * @param string $userId + * @param string $requesterUserId * @return array list of created shares * @throws \OCP\Files\NotPermittedException * @throws \OC\User\NoUserException */ - private function shareWithApprovers(int $fileId, array $rule, string $userId): array { + private function shareWithApprovers(int $fileId, array $rule, string $requesterUserId): array { $createdShares = []; // get node - $userFolder = $this->root->getUserFolder($userId); + $userFolder = $this->root->getUserFolder($requesterUserId); $nodeResults = $userFolder->getById($fileId); if (count($nodeResults) > 0) { $node = $nodeResults[0]; - // get the node again from the owner's storage to avoid sharing permission issues - $ownerId = $node->getOwner()->getUID(); - $ownerFolder = $this->root->getUserFolder($ownerId); - $ownerNodeResults = $ownerFolder->getById($fileId); - if (count($ownerNodeResults) > 0) { - $node = $ownerNodeResults[0]; - } } else { return []; } $label = $this->l10n->t('Please check my approval request'); - $fileOwner = $node->getOwner()->getUID(); foreach ($rule['approvers'] as $approver) { if ($approver['type'] === 'user' && !$this->utilsService->userHasAccessTo($fileId, $approver['entityId'])) { // create user share - if ($this->utilsService->createShare($node, IShare::TYPE_USER, $approver['entityId'], $fileOwner, $label)) { + if ($this->utilsService->createShare($node, IShare::TYPE_USER, $approver['entityId'], $requesterUserId, $label)) { $createdShares[] = $approver; } } @@ -563,7 +558,7 @@ private function shareWithApprovers(int $fileId, array $rule, string $userId): a if ($this->shareManager->allowGroupSharing()) { foreach ($rule['approvers'] as $approver) { if ($approver['type'] === 'group') { - if ($this->utilsService->createShare($node, IShare::TYPE_GROUP, $approver['entityId'], $fileOwner, $label)) { + if ($this->utilsService->createShare($node, IShare::TYPE_GROUP, $approver['entityId'], $requesterUserId, $label)) { $createdShares[] = $approver; } } @@ -574,7 +569,7 @@ private function shareWithApprovers(int $fileId, array $rule, string $userId): a if ($circlesEnabled) { foreach ($rule['approvers'] as $approver) { if ($approver['type'] === 'circle') { - if ($this->utilsService->createShare($node, IShare::TYPE_CIRCLE, $approver['entityId'], $fileOwner, $label)) { + if ($this->utilsService->createShare($node, IShare::TYPE_CIRCLE, $approver['entityId'], $requesterUserId, $label)) { $createdShares[] = $approver; } } diff --git a/lib/Service/UtilsService.php b/lib/Service/UtilsService.php index 18766340..05bb12d5 100644 --- a/lib/Service/UtilsService.php +++ b/lib/Service/UtilsService.php @@ -85,10 +85,8 @@ public function setEncryptedAppValue(string $key, string $value): void { public function createShare(Node $node, int $type, string $sharedWith, string $sharedBy, string $label): bool { $share = $this->shareManager->newShare(); $share->setNode($node) - // share permission is not necessary for rule chaining - // because we get the file from its owner's storage so we can share it whatsoever - // ->setPermissions(Constants::PERMISSION_READ | Constants::PERMISSION_SHARE) - ->setPermissions(Constants::PERMISSION_READ) + // share permission is necessary for rule chaining + ->setPermissions(Constants::PERMISSION_READ | Constants::PERMISSION_SHARE) ->setSharedWith($sharedWith) ->setShareType($type) ->setSharedBy($sharedBy)