Skip to content

Commit 0f31e46

Browse files
committed
fixup! feat: add delegation backend
Signed-off-by: Hamza <hamzamahjoubi221@gmail.com>
1 parent 2a25ddd commit 0f31e46

9 files changed

Lines changed: 88 additions & 55 deletions

appinfo/routes.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -505,11 +505,6 @@
505505
'url' => '/api/follow-up/check-message-ids',
506506
'verb' => 'POST',
507507
],
508-
[
509-
'name' => 'delegation#getDelegatedAccounts',
510-
'url' => '/api/delegations',
511-
'verb' => 'GET',
512-
],
513508
[
514509
'name' => 'delegation#getDelegatedUsers',
515510
'url' => '/api/delegations/{accountId}',

lib/Controller/DelegationController.php

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,6 @@ public function __construct(
3636
$this->currentUserId = $UserId;
3737
}
3838

39-
/**
40-
* Get all accounts delegated to the current user
41-
*
42-
* @NoAdminRequired
43-
*
44-
* @return JSONResponse
45-
*/
46-
#[TrapError]
47-
public function getDelegatedAccounts(): JSONResponse {
48-
if ($this->currentUserId === null) {
49-
return new JSONResponse([], Http::STATUS_UNAUTHORIZED);
50-
}
51-
52-
return new JSONResponse(
53-
$this->delegationService->findDelegatedAccountForUser($this->currentUserId)
54-
);
55-
}
56-
5739
/**
5840
* Get all users that have delegation for a given account
5941
*

lib/Controller/DraftsController.php

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use OCA\Mail\Http\JsonResponse;
1515
use OCA\Mail\Http\TrapError;
1616
use OCA\Mail\Service\AccountService;
17+
use OCA\Mail\Service\DelegationService;
1718
use OCA\Mail\Service\DraftsService;
1819
use OCA\Mail\Service\SmimeService;
1920
use OCP\AppFramework\Controller;
@@ -30,6 +31,7 @@ class DraftsController extends Controller {
3031
private AccountService $accountService;
3132
private ITimeFactory $timeFactory;
3233
private SmimeService $smimeService;
34+
private DelegationService $delegationService;
3335

3436

3537
public function __construct(string $appName,
@@ -38,13 +40,15 @@ public function __construct(string $appName,
3840
DraftsService $service,
3941
AccountService $accountService,
4042
ITimeFactory $timeFactory,
41-
SmimeService $smimeService) {
43+
SmimeService $smimeService,
44+
DelegationService $delegationService) {
4245
parent::__construct($appName, $request);
4346
$this->userId = $userId;
4447
$this->service = $service;
4548
$this->accountService = $accountService;
4649
$this->timeFactory = $timeFactory;
4750
$this->smimeService = $smimeService;
51+
$this->delegationService = $delegationService;
4852
}
4953

5054
/**
@@ -93,7 +97,8 @@ public function create(
9397
?int $draftId = null,
9498
bool $requestMdn = false,
9599
bool $isPgpMime = false) : JsonResponse {
96-
$account = $this->accountService->find($this->userId, $accountId);
100+
$effectiveUserId = $this->delegationService->resolveAccountUserId($accountId, $this->userId);
101+
$account = $this->accountService->find($effectiveUserId, $accountId);
97102
if ($draftId !== null) {
98103
$this->service->handleDraft($account, $draftId);
99104
}
@@ -165,8 +170,9 @@ public function update(int $id,
165170
?int $sendAt = null,
166171
bool $requestMdn = false,
167172
bool $isPgpMime = false): JsonResponse {
168-
$message = $this->service->getMessage($id, $this->userId);
169-
$account = $this->accountService->find($this->userId, $accountId);
173+
$effectiveUserId = $this->delegationService->resolveAccountUserId($accountId, $this->userId);
174+
$message = $this->service->getMessage($id, $effectiveUserId);
175+
$account = $this->accountService->find($effectiveUserId, $accountId);
170176

171177
$message->setType(LocalMessage::TYPE_DRAFT);
172178
$message->setAccountId($accountId);
@@ -202,10 +208,11 @@ public function update(int $id,
202208
*/
203209
#[TrapError]
204210
public function destroy(int $id): JsonResponse {
205-
$message = $this->service->getMessage($id, $this->userId);
206-
$this->accountService->find($this->userId, $message->getAccountId());
211+
$effectiveUserId = $this->delegationService->resolveLocalMessageUserId($id, $this->userId);
212+
$message = $this->service->getMessage($id, $effectiveUserId);
213+
$this->accountService->find($effectiveUserId, $message->getAccountId());
207214

208-
$this->service->deleteMessage($this->userId, $message);
215+
$this->service->deleteMessage($effectiveUserId, $message);
209216
return JsonResponse::success('Message deleted', Http::STATUS_ACCEPTED);
210217
}
211218

@@ -217,8 +224,9 @@ public function destroy(int $id): JsonResponse {
217224
*/
218225
#[TrapError]
219226
public function move(int $id): JsonResponse {
220-
$message = $this->service->getMessage($id, $this->userId);
221-
$account = $this->accountService->find($this->userId, $message->getAccountId());
227+
$effectiveUserId = $this->delegationService->resolveLocalMessageUserId($id, $this->userId);
228+
$message = $this->service->getMessage($id, $effectiveUserId);
229+
$account = $this->accountService->find($effectiveUserId, $message->getAccountId());
222230

223231
$this->service->sendMessage($message, $account);
224232
return JsonResponse::success(

lib/Controller/FollowUpController.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use OCA\Mail\Db\ThreadMapper;
1515
use OCA\Mail\Http\JsonResponse;
1616
use OCA\Mail\Http\TrapError;
17+
use OCA\Mail\Service\DelegationService;
1718
use OCP\AppFramework\Controller;
1819
use OCP\AppFramework\Db\DoesNotExistException;
1920
use OCP\AppFramework\Http;
@@ -31,6 +32,7 @@ public function __construct(
3132
private ThreadMapper $threadMapper,
3233
private MessageMapper $messageMapper,
3334
private MailboxMapper $mailboxMapper,
35+
private DelegationService $delegationService,
3436
) {
3537
parent::__construct($appName, $request);
3638
}
@@ -54,7 +56,8 @@ public function checkMessageIds(array $messageIds): JsonResponse {
5456
$mailboxId = $message->getMailboxId();
5557
if (!isset($mailboxes[$mailboxId])) {
5658
try {
57-
$mailboxes[$mailboxId] = $this->mailboxMapper->findByUid($mailboxId, $userId);
59+
$effectiveUserId = $this->delegationService->resolveMailboxUserId($mailboxId, $userId);
60+
$mailboxes[$mailboxId] = $this->mailboxMapper->findByUid($mailboxId, $effectiveUserId);
5861
} catch (DoesNotExistException $e) {
5962
continue;
6063
}

lib/Controller/OutboxController.php

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use OCA\Mail\Http\JsonResponse;
1515
use OCA\Mail\Http\TrapError;
1616
use OCA\Mail\Service\AccountService;
17+
use OCA\Mail\Service\DelegationService;
1718
use OCA\Mail\Service\DraftsService;
1819
use OCA\Mail\Service\OutboxService;
1920
use OCA\Mail\Service\SmimeService;
@@ -29,18 +30,21 @@ class OutboxController extends Controller {
2930
private string $userId;
3031
private AccountService $accountService;
3132
private SmimeService $smimeService;
33+
private DelegationService $delegationService;
3234

3335
public function __construct(string $appName,
3436
$userId,
3537
IRequest $request,
3638
OutboxService $service,
3739
AccountService $accountService,
38-
SmimeService $smimeService) {
40+
SmimeService $smimeService,
41+
DelegationService $delegationService) {
3942
parent::__construct($appName, $request);
4043
$this->userId = $userId;
4144
$this->service = $service;
4245
$this->accountService = $accountService;
4346
$this->smimeService = $smimeService;
47+
$this->delegationService = $delegationService;
4448
}
4549

4650
/**
@@ -61,7 +65,8 @@ public function index(): JsonResponse {
6165
*/
6266
#[TrapError]
6367
public function show(int $id): JsonResponse {
64-
$message = $this->service->getMessage($id, $this->userId);
68+
$effectiveUserId = $this->delegationService->resolveLocalMessageUserId($id, $this->userId);
69+
$message = $this->service->getMessage($id, $effectiveUserId);
6570
return JsonResponse::success($message);
6671
}
6772

@@ -108,7 +113,8 @@ public function create(
108113
bool $requestMdn = false,
109114
bool $isPgpMime = false,
110115
): JsonResponse {
111-
$account = $this->accountService->find($this->userId, $accountId);
116+
$effectiveUserId = $this->delegationService->resolveAccountUserId($accountId, $this->userId);
117+
$account = $this->accountService->find($effectiveUserId, $accountId);
112118

113119
if ($draftId !== null) {
114120
$this->service->handleDraft($account, $draftId);
@@ -147,9 +153,10 @@ public function create(
147153
*/
148154
#[TrapError]
149155
public function createFromDraft(DraftsService $draftsService, int $id, int $sendAt): JsonResponse {
150-
$draftMessage = $draftsService->getMessage($id, $this->userId);
156+
$effectiveUserId = $this->delegationService->resolveLocalMessageUserId($id, $this->userId);
157+
$draftMessage = $draftsService->getMessage($id, $effectiveUserId);
151158
// Locate the account to check authorization
152-
$this->accountService->find($this->userId, $draftMessage->getAccountId());
159+
$this->accountService->find($effectiveUserId, $draftMessage->getAccountId());
153160

154161
$outboxMessage = $this->service->convertDraft($draftMessage, $sendAt);
155162

@@ -201,11 +208,12 @@ public function update(
201208
bool $requestMdn = false,
202209
bool $isPgpMime = false,
203210
): JsonResponse {
204-
$message = $this->service->getMessage($id, $this->userId);
211+
$effectiveUserId = $this->delegationService->resolveAccountUserId($accountId, $this->userId);
212+
$message = $this->service->getMessage($id, $effectiveUserId);
205213
if ($message->getStatus() === LocalMessage::STATUS_PROCESSED) {
206214
return JsonResponse::error('Cannot modify already sent message', Http::STATUS_FORBIDDEN, [$message]);
207215
}
208-
$account = $this->accountService->find($this->userId, $accountId);
216+
$account = $this->accountService->find($effectiveUserId, $accountId);
209217

210218
$message->setAccountId($accountId);
211219
$message->setAliasId($aliasId);
@@ -239,8 +247,9 @@ public function update(
239247
*/
240248
#[TrapError]
241249
public function send(int $id): JsonResponse {
242-
$message = $this->service->getMessage($id, $this->userId);
243-
$account = $this->accountService->find($this->userId, $message->getAccountId());
250+
$effectiveUserId = $this->delegationService->resolveLocalMessageUserId($id, $this->userId);
251+
$message = $this->service->getMessage($id, $effectiveUserId);
252+
$account = $this->accountService->find($effectiveUserId, $message->getAccountId());
244253

245254
$message = $this->service->sendMessage($message, $account);
246255

@@ -260,8 +269,9 @@ public function send(int $id): JsonResponse {
260269
*/
261270
#[TrapError]
262271
public function destroy(int $id): JsonResponse {
263-
$message = $this->service->getMessage($id, $this->userId);
264-
$this->service->deleteMessage($this->userId, $message);
272+
$effectiveUserId = $this->delegationService->resolveLocalMessageUserId($id, $this->userId);
273+
$message = $this->service->getMessage($id, $effectiveUserId);
274+
$this->service->deleteMessage($effectiveUserId, $message);
265275
return JsonResponse::success('Message deleted', Http::STATUS_ACCEPTED);
266276
}
267277
}

lib/Db/AliasMapper.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,28 @@ public function deleteProvisionedAliasesByUid(string $uid): void {
141141
}
142142
}
143143

144+
/**
145+
* Find the account ID for a given alias ID without ownership checks.
146+
*
147+
* @throws DoesNotExistException
148+
*/
149+
public function findAccountIdForAlias(int $aliasId): int {
150+
$qb = $this->db->getQueryBuilder();
151+
$qb->select('account_id')
152+
->from($this->getTableName())
153+
->where($qb->expr()->eq('id', $qb->createNamedParameter($aliasId)));
154+
155+
$result = $qb->executeQuery();
156+
$row = $result->fetch();
157+
$result->closeCursor();
158+
159+
if ($row === false) {
160+
throw new DoesNotExistException('Alias not found');
161+
}
162+
163+
return (int)$row['account_id'];
164+
}
165+
144166
public function deleteOrphans(): void {
145167
$qb1 = $this->db->getQueryBuilder();
146168
$idsQuery = $qb1->select('a.id')

lib/Db/DelegationMapper.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,7 @@ public function find(int $accountId, string $uid): Delegation {
5959
}
6060

6161
/**
62-
* Get the account owner's user ID for a delegated user.
63-
*
64-
* JOINs mail_delegations with mail_accounts to return the owner's user_id
65-
* in a single query, verifying that the delegation exists.
66-
*
67-
* @throws DoesNotExistException if no delegation exists for this account/user pair
62+
* @throws DoesNotExistException
6863
*/
6964
public function findAccountOwnerForDelegatedUser(int $accountId, string $delegatedUserId): string {
7065
$qb = $this->db->getQueryBuilder();

lib/Db/LocalMessageMapper.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,28 @@ public function findById(int $id, string $userId, int $type): LocalMessage {
104104
return $entity;
105105
}
106106

107+
/**
108+
* Find the account ID for a local message without ownership checks.
109+
*
110+
* @throws DoesNotExistException if the local message does not exist
111+
*/
112+
public function findAccountIdForLocalMessage(int $localMessageId): int {
113+
$qb = $this->db->getQueryBuilder();
114+
$qb->select('account_id')
115+
->from($this->getTableName())
116+
->where($qb->expr()->eq('id', $qb->createNamedParameter($localMessageId, IQueryBuilder::PARAM_INT)));
117+
118+
$result = $qb->executeQuery();
119+
$row = $result->fetch();
120+
$result->closeCursor();
121+
122+
if ($row === false) {
123+
throw new DoesNotExistException('Local message not found');
124+
}
125+
126+
return (int)$row['account_id'];
127+
}
128+
107129
/**
108130
* Find all messages that should be sent
109131
*

lib/Service/DelegationService.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public function delegate(int $accountId, string $userId): Delegation {
3636
$this->delegationMapper->find($accountId, $userId);
3737
throw new DelegationExistsException("Delegation already exists for account $accountId and user $userId");
3838
} catch (DoesNotExistException) {
39-
// continue
39+
// delegation doesn't exist, continue
4040
}
4141

4242
$delegation = new Delegation();
@@ -45,10 +45,6 @@ public function delegate(int $accountId, string $userId): Delegation {
4545
return $this->delegationMapper->insert($delegation);
4646
}
4747

48-
public function findDelegatedAccountForUser(string $userId): array {
49-
return $this->delegationMapper->findDelegatedAccountsForUser($userId);
50-
}
51-
5248
public function findDelegatedToUsersForAccount(int $accountId): array {
5349
return $this->delegationMapper->findDelegatedToUsers($accountId);
5450
}

0 commit comments

Comments
 (0)