Skip to content

Commit d2d653c

Browse files
grnd-altbackportbot[bot]
authored andcommitted
enh(performance): get deck share permissions in one query
Signed-off-by: grnd-alt <git@belakkaf.net>
1 parent b159064 commit d2d653c

3 files changed

Lines changed: 69 additions & 17 deletions

File tree

‎lib/Db/AclMapper.php‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,33 @@ public function findAll(int $boardId, ?int $limit = null, ?int $offset = null) {
4343
return $this->findEntities($qb);
4444
}
4545

46+
/**
47+
* @return array<int, Acl[]> Acl entries grouped by card id
48+
* @throws \OCP\DB\Exception
49+
*/
50+
public function findInCards(array $cardIds, ?int $limit = null, ?int $offset = null): array {
51+
$qb = $this->db->getQueryBuilder();
52+
$qb->select('acl.id', 'acl.board_id', 'acl.type', 'acl.participant', 'acl.permission_edit', 'acl.permission_share', 'acl.permission_manage', 'acl.created_at', 'acl.last_modified_at', 'c.id AS card_id')
53+
->from('deck_board_acl', 'acl')
54+
->innerJoin('acl', 'deck_boards', 'b', 'acl.board_id = b.id')
55+
->innerJoin('b', 'deck_stacks', 's', 's.board_id = b.id')
56+
->innerJoin('s', 'deck_cards', 'c', 'c.stack_id = s.id')
57+
->where($qb->expr()->in('c.id', $qb->createParameter('cardIds')))
58+
->setMaxResults($limit)
59+
->setFirstResult($offset);
60+
61+
$aclsByCardId = [];
62+
foreach ($this->chunkQuery($cardIds, function (array $ids) use ($qb) {
63+
$qb->setParameter('cardIds', $ids, IQueryBuilder::PARAM_INT_ARRAY);
64+
return $qb->executeQuery()->fetchAll();
65+
}) as $row) {
66+
$cardId = (int)$row['card_id'];
67+
unset($row['card_id']);
68+
$aclsByCardId[$cardId][] = Acl::fromRow($row);
69+
}
70+
return $aclsByCardId;
71+
}
72+
4673
public function findIn(array $boardIds, ?int $limit = null, ?int $offset = null): array {
4774
$qb = $this->db->getQueryBuilder();
4875
$qb->select('id', 'board_id', 'type', 'participant', 'permission_edit', 'permission_share', 'permission_manage')

‎lib/Service/PermissionService.php‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,31 @@ public function setAccessToken(string $token) {
6363
$this->accessToken = $token;
6464
}
6565

66+
/**
67+
* Get permissions for all supplied card ids
68+
* @param int[] $cardIds
69+
* @param ?string $userId
70+
* @param bool $allowDeleted
71+
* @return array<int, array<Acl::PERMISSION_*, bool>>
72+
*/
73+
public function getPermissionsForCards(array $cardIds, ?string $userId = null, bool $allowDeleted = false): array {
74+
if ($userId === null) {
75+
$userId = $this->userId;
76+
}
77+
$permissions = $this->aclMapper->findInCards($cardIds);
78+
return array_map(
79+
function (array $acls) use ($userId) {
80+
return [
81+
Acl::PERMISSION_READ => $this->userCan($acls, Acl::PERMISSION_READ, $userId),
82+
Acl::PERMISSION_EDIT => $this->userCan($acls, Acl::PERMISSION_EDIT, $userId),
83+
Acl::PERMISSION_MANAGE => $this->userCan($acls, Acl::PERMISSION_MANAGE, $userId),
84+
Acl::PERMISSION_SHARE => $this->userCan($acls, Acl::PERMISSION_SHARE, $userId),
85+
];
86+
},
87+
$permissions
88+
);
89+
}
90+
6691
/**
6792
* Get current user permissions for a board by id
6893
*

‎lib/Sharing/DeckShareProvider.php‎

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -270,22 +270,6 @@ private function createShareObject(array $data): IShare {
270270
return $share;
271271
}
272272

273-
private function applyBoardPermission($share, $permissions, $userId) {
274-
try {
275-
$this->permissionService->checkPermission($this->cardMapper, $share->getSharedWith(), Acl::PERMISSION_EDIT, $userId, true);
276-
} catch (NoPermissionException $e) {
277-
$permissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_UPDATE;
278-
$permissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE;
279-
$permissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_DELETE;
280-
}
281-
282-
try {
283-
$this->permissionService->checkPermission($this->cardMapper, $share->getSharedWith(), Acl::PERMISSION_SHARE, $userId, true);
284-
} catch (NoPermissionException $e) {
285-
$permissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE;
286-
}
287-
$share->setPermissions($permissions);
288-
}
289273
/**
290274
* @inheritDoc
291275
*/
@@ -653,11 +637,13 @@ private function resolveSharesForRecipient(array $shares, string $userId): array
653637

654638
/** @var int[] $ids */
655639
$ids = [];
640+
$cardIds = [];
656641
/** @var IShare[] $shareMap */
657642
$shareMap = [];
658643

659644
foreach ($shareSlice as $share) {
660645
$ids[] = (int)$share->getId();
646+
$cardIds[] = (int)$share->getSharedWith();
661647
$shareMap[$share->getId()] = $share;
662648
}
663649

@@ -674,8 +660,22 @@ private function resolveSharesForRecipient(array $shares, string $userId): array
674660

675661
$stmt = $query->executeQuery();
676662

663+
$permissions = $this->permissionService->getPermissionsForCards($cardIds, $userId);
664+
677665
while ($data = $stmt->fetch()) {
678-
$this->applyBoardPermission($shareMap[$data['parent']], (int)$data['permissions'], $userId);
666+
$parent = $shareMap[$data['parent']];
667+
$sharePermissions = (int)$data['permissions'];
668+
if (isset($permissions[(int)$parent->getSharedWith()])) {
669+
if ($permissions[(int)$parent->getSharedWith()][Acl::PERMISSION_EDIT] === false) {
670+
$sharePermissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_UPDATE;
671+
$sharePermissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE;
672+
$sharePermissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_DELETE;
673+
}
674+
if ($permissions[(int)$parent->getSharedWith()][Acl::PERMISSION_SHARE] === false) {
675+
$sharePermissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE;
676+
}
677+
}
678+
$shareMap[$data['parent']]->setPermissions($sharePermissions);
679679
$shareMap[$data['parent']]->setTarget($data['file_target']);
680680
}
681681

0 commit comments

Comments
 (0)