Skip to content

Commit 532e21f

Browse files
authored
Merge pull request #5423 from nextcloud/bugfix/noid/comment-deleted
2 parents a8625f2 + 569ff6f commit 532e21f

17 files changed

Lines changed: 264 additions & 32 deletions

.github/workflows/integration.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ jobs:
7070
with:
7171
path: apps/${{ env.APP_NAME }}
7272

73+
- name: Checkout activity
74+
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
75+
with:
76+
repository: nextcloud/activity
77+
ref: ${{ matrix.server-versions }}
78+
path: apps/activity
79+
7380
- name: Set up php ${{ matrix.php-versions }}
7481
uses: shivammathur/setup-php@2.28.0
7582
with:

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
"@test:integration"
4040
],
4141
"test:unit": "vendor/bin/phpunit -c tests/phpunit.xml",
42-
"test:integration": "vendor/bin/phpunit -c tests/phpunit.integration.xml && cd tests/integration && ./run.sh"
42+
"test:integration": "vendor/bin/phpunit -c tests/phpunit.integration.xml",
43+
"test:api": "cd tests/integration && ./run.sh"
4344
},
4445
"autoload-dev": {
4546
"psr-4": {

lib/Activity/ActivityManager.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
use OCA\Deck\Db\Label;
3939
use OCA\Deck\Db\Stack;
4040
use OCA\Deck\Db\StackMapper;
41+
use OCA\Deck\NoPermissionException;
4142
use OCA\Deck\Service\PermissionService;
4243
use OCP\Activity\IEvent;
4344
use OCP\Activity\IManager;
@@ -564,4 +565,24 @@ private function findDetailsForAcl($aclId) {
564565
'board' => $board
565566
];
566567
}
568+
569+
public function canSeeCardActivity(int $cardId): bool {
570+
try {
571+
$this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_READ);
572+
$card = $this->cardMapper->find($cardId);
573+
return $card->getDeletedAt() === 0;
574+
} catch (NoPermissionException $e) {
575+
return false;
576+
}
577+
}
578+
579+
public function canSeeBoardActivity(int $boardId): bool {
580+
try {
581+
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
582+
$board = $this->boardMapper->find($boardId);
583+
return $board->getDeletedAt() === 0;
584+
} catch (NoPermissionException $e) {
585+
return false;
586+
}
587+
}
567588
}

lib/Activity/DeckProvider.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ public function parse($language, IEvent $event, IEvent $previousEvent = null): I
111111
$event->setAuthor($author);
112112
}
113113
if ($event->getObjectType() === ActivityManager::DECK_OBJECT_BOARD) {
114+
if (!$this->activityManager->canSeeBoardActivity($event->getObjectId())) {
115+
throw new \InvalidArgumentException();
116+
}
114117
if (isset($subjectParams['board']) && $event->getObjectName() === '') {
115118
$event->setObject($event->getObjectType(), $event->getObjectId(), $subjectParams['board']['title']);
116119
}
@@ -125,6 +128,9 @@ public function parse($language, IEvent $event, IEvent $previousEvent = null): I
125128
}
126129

127130
if (isset($subjectParams['card']) && $event->getObjectType() === ActivityManager::DECK_OBJECT_CARD) {
131+
if (!$this->activityManager->canSeeCardActivity($event->getObjectId())) {
132+
throw new \InvalidArgumentException();
133+
}
128134
if ($event->getObjectName() === '') {
129135
$event->setObject($event->getObjectType(), $event->getObjectId(), $subjectParams['card']['title']);
130136
}

lib/Db/Card.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
* @method int getLastModified()
4040
* @method int getCreatedAt()
4141
* @method bool getArchived()
42+
* @method int getDeletedAt()
43+
* @method void setDeletedAt(int $deletedAt)
4244
* @method bool getNotified()
4345
* @method ?DateTime getDone()
4446
* @method void setDone(?DateTime $done)

lib/Service/BoardService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ public function addAcl($boardId, $type, $participant, $edit, $share, $manage) {
446446
$newAcl = $this->aclMapper->insert($acl);
447447

448448
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_BOARD, $newAcl, ActivityManager::SUBJECT_BOARD_SHARE, [], $this->userId);
449-
$this->notificationHelper->sendBoardShared((int)$boardId, $acl);
449+
$this->notificationHelper->sendBoardShared($boardId, $acl);
450450
$this->boardMapper->mapAcl($newAcl);
451451
$this->changeHelper->boardChanged($boardId);
452452

lib/Service/CardService.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ public function delete($id) {
298298
public function update($id, $title, $stackId, $type, $owner, $description = '', $order = 0, $duedate = null, $deletedAt = null, $archived = null, ?OptionalNullableValue $done = null) {
299299
$this->cardServiceValidator->check(compact('id', 'title', 'stackId', 'type', 'owner', 'order'));
300300

301-
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT);
301+
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT, allowDeletedCard: true);
302302
$this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_EDIT);
303303

304304
if ($this->boardService->isArchived($this->cardMapper, $id)) {
@@ -310,9 +310,9 @@ public function update($id, $title, $stackId, $type, $owner, $description = '',
310310
}
311311

312312
if ($card->getDeletedAt() !== 0) {
313-
if ($deletedAt === null) {
313+
if ($deletedAt === null || $deletedAt > 0) {
314314
// Only allow operations when restoring the card
315-
throw new StatusException('Operation not allowed. This card was deleted.');
315+
throw new NoPermissionException('Operation not allowed. This card was deleted.');
316316
}
317317
}
318318

lib/Service/CommentService.php

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ private function get(int $cardId, int $commentId): IComment {
9494
throw new NotFoundException('No comment found.');
9595
}
9696
if ($comment->getParentId() !== '0') {
97-
$this->permissionService->checkPermission($this->cardMapper, $comment->getParentId(), Acl::PERMISSION_READ);
97+
$this->permissionService->checkPermission($this->cardMapper, (int)$comment->getParentId(), Acl::PERMISSION_READ);
9898
}
9999

100100
return $comment;
@@ -113,24 +113,17 @@ public function getFormatted(int $cardId, int $commentId): array {
113113
}
114114

115115
/**
116-
* @param string $cardId
117-
* @param string $message
118-
* @param string $replyTo
119-
* @return DataResponse
120116
* @throws BadRequestException
121117
* @throws NotFoundException|NoPermissionException
122118
*/
123-
public function create(string $cardId, string $message, string $replyTo = '0'): DataResponse {
124-
if (!is_numeric($cardId)) {
125-
throw new BadRequestException('A valid card id must be provided');
126-
}
119+
public function create(int $cardId, string $message, string $replyTo = '0'): DataResponse {
127120
$this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_READ);
128121

129122
// Check if parent is a comment on the same card
130123
if ($replyTo !== '0') {
131124
try {
132125
$comment = $this->commentsManager->get($replyTo);
133-
if ($comment->getObjectType() !== Application::COMMENT_ENTITY_TYPE || $comment->getObjectId() !== $cardId) {
126+
if ($comment->getObjectType() !== Application::COMMENT_ENTITY_TYPE || (int)$comment->getObjectId() !== $cardId) {
134127
throw new CommentNotFoundException();
135128
}
136129
} catch (CommentNotFoundException $e) {
@@ -139,7 +132,7 @@ public function create(string $cardId, string $message, string $replyTo = '0'):
139132
}
140133

141134
try {
142-
$comment = $this->commentsManager->create('users', $this->userId, Application::COMMENT_ENTITY_TYPE, $cardId);
135+
$comment = $this->commentsManager->create('users', $this->userId, Application::COMMENT_ENTITY_TYPE, (string)$cardId);
143136
$comment->setMessage($message);
144137
$comment->setVerb('comment');
145138
$comment->setParentId($replyTo);

lib/Service/PermissionService.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use OCA\Deck\Db\AclMapper;
2929
use OCA\Deck\Db\Board;
3030
use OCA\Deck\Db\BoardMapper;
31+
use OCA\Deck\Db\CardMapper;
3132
use OCA\Deck\Db\IPermissionMapper;
3233
use OCA\Deck\Db\User;
3334
use OCA\Deck\NoPermissionException;
@@ -107,8 +108,9 @@ public function getPermissions($boardId, ?string $userId = null) {
107108
return $cached;
108109
}
109110

111+
$board = $this->getBoard($boardId);
110112
$owner = $this->userIsBoardOwner($boardId, $userId);
111-
$acls = $this->aclMapper->findAll($boardId);
113+
$acls = $board->getDeletedAt() === 0 ? $this->aclMapper->findAll($boardId) : [];
112114
$permissions = [
113115
Acl::PERMISSION_READ => $owner || $this->userCan($acls, Acl::PERMISSION_READ, $userId),
114116
Acl::PERMISSION_EDIT => $owner || $this->userCan($acls, Acl::PERMISSION_EDIT, $userId),
@@ -142,13 +144,10 @@ public function matchPermissions(Board $board) {
142144
/**
143145
* check permissions for replacing dark magic middleware
144146
*
145-
* @param $mapper IPermissionMapper|null null if $id is a boardId
146-
* @param $id int unique identifier of the Entity
147-
* @param $permission int
148-
* @return bool
147+
* @param numeric $id
149148
* @throws NoPermissionException
150149
*/
151-
public function checkPermission($mapper, $id, $permission, $userId = null): bool {
150+
public function checkPermission(?IPermissionMapper $mapper, $id, int $permission, $userId = null, bool $allowDeletedCard = false): bool {
152151
$boardId = $id;
153152
if ($mapper instanceof IPermissionMapper && !($mapper instanceof BoardMapper)) {
154153
$boardId = $mapper->findBoardId($id);
@@ -160,6 +159,14 @@ public function checkPermission($mapper, $id, $permission, $userId = null): bool
160159

161160
$permissions = $this->getPermissions($boardId, $userId);
162161
if ($permissions[$permission] === true) {
162+
163+
if (!$allowDeletedCard && $mapper instanceof CardMapper) {
164+
$card = $mapper->find($id);
165+
if ($card->getDeletedAt() > 0) {
166+
throw new NoPermissionException('Card is deleted');
167+
}
168+
}
169+
163170
return true;
164171
}
165172

lib/Sharing/ShareAPIHelper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ private function parseDate(string $expireDate): \DateTime {
115115
*/
116116
public function canAccessShare(IShare $share, string $user): bool {
117117
try {
118-
$this->permissionService->checkPermission($this->cardMapper, $share->getSharedWith(), Acl::PERMISSION_READ, $user);
118+
$this->permissionService->checkPermission($this->cardMapper, (int)$share->getSharedWith(), Acl::PERMISSION_READ, $user);
119119
} catch (NoPermissionException $e) {
120120
return false;
121121
}

0 commit comments

Comments
 (0)