Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 20 additions & 27 deletions lib/Service/ApprovalService.php
Original file line number Diff line number Diff line change
Expand Up @@ -438,18 +438,18 @@ public function reject(int $fileId, ?string $userId, string $etag, string $messa
*
* @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 cannot share this file')];
}

Expand All @@ -458,24 +458,27 @@ 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']);

// still produce an activity entry for the user who requests
$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
Expand Down Expand Up @@ -530,29 +533,19 @@ public function requestViaTagAssignment(int $fileId, int $ruleId, string $reques
*
* @param int $fileId
* @param array $rule
* @param string $userId
* @param string $requesterUserId
* @return void
* @throws \OCP\Files\NotPermittedException
* @throws \OC\User\NoUserException
*/
private function shareWithApprovers(int $fileId, array $rule, string $userId): void {
private function shareWithApprovers(int $fileId, array $rule, string $requesterUserId): void {
// get node
$userFolder = $this->root->getUserFolder($userId);
$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 {
$userFolder = $this->root->getUserFolder($requesterUserId);
$node = $userFolder->getFirstNodeById($fileId);
if ($node === null) {
return;
}
$label = $this->l10n->t('Please check my approval request');
$fileOwner = $node->getOwner()->getUID();

// Gets all users that have access to the file
$mounts = $this->userMountCache->getMountsForFileId($fileId);
Expand All @@ -561,7 +554,7 @@ private function shareWithApprovers(int $fileId, array $rule, string $userId): v
foreach ($rule['approvers'] as $approver) {
if ($approver['type'] === 'user' && !in_array($approver['entityId'], $userIdsWithAccess, true)) {
// 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)) {
$this->logger->warning('Failed to create user share for file {fileId} with approver {approverId}', ['fileId' => $fileId, 'approverId' => $approver['entityId']]);
}
}
Expand All @@ -574,13 +567,13 @@ private function shareWithApprovers(int $fileId, array $rule, string $userId): v
$groupMembersThatNeedAccess = array_diff($groupMemberIds, $userIdsWithAccess);
// Create group share if everyone in the group needs access
if (count($groupMembersThatNeedAccess) === count($groupMemberIds)) {
if (!$this->utilsService->createShare($node, IShare::TYPE_GROUP, $approver['entityId'], $fileOwner, $label)) {
if (!$this->utilsService->createShare($node, IShare::TYPE_GROUP, $approver['entityId'], $requesterUserId, $label)) {
$this->logger->warning('Failed to create group share for file {fileId} with approver {approverId}', ['fileId' => $fileId, 'approverId' => $approver['entityId']]);
}
} elseif (count($groupMembersThatNeedAccess) > 0) {
// Create user shares for each member that needs access
foreach ($groupMembersThatNeedAccess as $groupMemberId) {
if (!$this->utilsService->createShare($node, IShare::TYPE_USER, $groupMemberId, $fileOwner, $label)) {
if (!$this->utilsService->createShare($node, IShare::TYPE_USER, $groupMemberId, $requesterUserId, $label)) {
$this->logger->warning('Failed to create user share for file {fileId} with approver {approverId}', ['fileId' => $fileId, 'approverId' => $groupMemberId]);
}
}
Expand All @@ -593,7 +586,7 @@ private function shareWithApprovers(int $fileId, array $rule, string $userId): v
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)) {
$this->logger->warning('Failed to create circle share for file {fileId} with approver {approverId}', ['fileId' => $fileId, 'approverId' => $approver['entityId']]);
}
}
Expand Down
6 changes: 2 additions & 4 deletions lib/Service/UtilsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,8 @@ public function __construct(
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)
Expand Down
Loading