Skip to content
Open
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
2 changes: 1 addition & 1 deletion appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ The rating depends on the installed text processing backend. See [the rating ove

Learn more about the Nextcloud Ethical AI Rating [in our blog](https://nextcloud.com/blog/nextcloud-ethical-ai-rating/).
]]></description>
<version>5.8.0-dev.2</version>
<version>5.8.0-dev.3</version>
<licence>agpl</licence>
<author homepage="https://github.com/ChristophWurst">Christoph Wurst</author>
<author homepage="https://github.com/GretaD">GretaD</author>
Expand Down
15 changes: 15 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,21 @@
'url' => '/api/follow-up/check-message-ids',
'verb' => 'POST',
],
[
'name' => 'delegation#getDelegatedUsers',
'url' => '/api/delegations/{accountId}',
'verb' => 'GET',
],
[
'name' => 'delegation#delegate',
'url' => '/api/delegations/{accountId}',
'verb' => 'POST',
],
[
'name' => 'delegation#unDelegate',
'url' => '/api/delegations/{accountId}/{userId}',
'verb' => 'DELETE',
],
[
'name' => 'textBlockShares#getTextBlockShares',
'url' => '/api/textBlocks/{id}/shares',
Expand Down
25 changes: 23 additions & 2 deletions lib/Controller/AccountApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use OCA\Mail\ResponseDefinitions;
use OCA\Mail\Service\AccountService;
use OCA\Mail\Service\AliasesService;
use OCA\Mail\Service\DelegationService;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\ApiRoute;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
Expand All @@ -32,6 +33,7 @@ public function __construct(
private readonly ?string $userId,
private readonly AccountService $accountService,
private readonly AliasesService $aliasesService,
private readonly DelegationService $delegationService,
) {
parent::__construct($appName, $request);
}
Expand All @@ -54,17 +56,36 @@ public function list(): DataResponse {
}

$accounts = $this->accountService->findByUserId($userId);
return new DataResponse(array_map(function (Account $account) use ($userId) {
$result = array_map(function (Account $account) use ($userId) {
$aliases = $this->aliasesService->findAll($account->getId(), $userId);
return [
'id' => $account->getId(),
'email' => $account->getEmail(),
'isDelegated' => false,
'aliases' => array_map(static fn (Alias $alias) => [
'id' => $alias->getId(),
'email' => $alias->getAlias(),
'name' => $alias->getName(),
], $aliases),
];
}, $accounts));
}, $accounts);

$delegatedAccounts = $this->accountService->findDelegatedAccounts($userId);
foreach ($delegatedAccounts as $account) {
$ownerUserId = $account->getUserId();
$aliases = $this->aliasesService->findAll($account->getId(), $ownerUserId);
$result[] = [
'id' => $account->getId(),
'email' => $account->getEmail(),
'isDelegated' => true,
'aliases' => array_map(static fn (Alias $alias) => [
'id' => $alias->getId(),
'email' => $alias->getAlias(),
'name' => $alias->getName(),
], $aliases),
];
}

return new DataResponse($result);
}
}
68 changes: 49 additions & 19 deletions lib/Controller/AccountsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use OCA\Mail\Model\NewMessageData;
use OCA\Mail\Service\AccountService;
use OCA\Mail\Service\AliasesService;
use OCA\Mail\Service\DelegationService;
use OCA\Mail\Service\SetupService;
use OCA\Mail\Service\Sync\SyncService;
use OCP\AppFramework\Controller;
Expand Down Expand Up @@ -52,6 +53,7 @@ class AccountsController extends Controller {
private IConfig $config;
private IRemoteHostValidator $hostValidator;
private MailboxSync $mailboxSync;
private DelegationService $delegationService;

public function __construct(
string $appName,
Expand All @@ -69,6 +71,7 @@ public function __construct(
IRemoteHostValidator $hostValidator,
MailboxSync $mailboxSync,
private ITimeFactory $timeFactory,
DelegationService $delegationService,
) {
parent::__construct($appName, $request);
$this->accountService = $accountService;
Expand All @@ -83,6 +86,7 @@ public function __construct(
$this->config = $config;
$this->hostValidator = $hostValidator;
$this->mailboxSync = $mailboxSync;
$this->delegationService = $delegationService;
}

/**
Expand All @@ -98,6 +102,15 @@ public function index(): JSONResponse {
foreach ($mailAccounts as $mailAccount) {
$conf = $mailAccount->jsonSerialize();
$conf['aliases'] = $this->aliasesService->findAll($conf['accountId'], $this->currentUserId);
$conf['isDelegated'] = false;
$json[] = $conf;
}

$delegatedAccounts = $this->accountService->findDelegatedAccounts($this->currentUserId);
foreach ($delegatedAccounts as $delegatedAccount) {
$conf = $delegatedAccount->jsonSerialize();
$conf['isDelegated'] = true;
$conf['aliases'] = $this->aliasesService->findAll($conf['accountId'], $delegatedAccount->getUserId());
$json[] = $conf;
}
return new JSONResponse($json);
Expand All @@ -113,7 +126,8 @@ public function index(): JSONResponse {
*/
#[TrapError]
public function show(int $id): JSONResponse {
return new JSONResponse($this->accountService->find($this->currentUserId, $id));
$effectiveUserId = $this->delegationService->resolveAccountUserId($id, $this->currentUserId);
return new JSONResponse($this->accountService->find($effectiveUserId, $id));
}

/**
Expand All @@ -136,9 +150,10 @@ public function update(int $id,
?string $imapPassword = null,
?string $smtpPassword = null,
string $authMethod = 'password'): JSONResponse {
$effectiveUserId = $this->delegationService->resolveAccountUserId($id, $this->currentUserId);
try {
// Make sure the account actually exists
$this->accountService->find($this->currentUserId, $id);
$this->accountService->find($effectiveUserId, $id);
} catch (ClientException $e) {
return new JSONResponse([], Http::STATUS_BAD_REQUEST);
}
Expand All @@ -164,9 +179,11 @@ public function update(int $id,
}

try {
return MailJsonResponse::success(
$this->setup->createNewAccount($accountName, $emailAddress, $imapHost, $imapPort, $imapSslMode, $imapUser, $imapPassword, $smtpHost, $smtpPort, $smtpSslMode, $smtpUser, $smtpPassword, $this->currentUserId, $authMethod, $id)
$result = MailJsonResponse::success(
$this->setup->createNewAccount($accountName, $emailAddress, $imapHost, $imapPort, $imapSslMode, $imapUser, $imapPassword, $smtpHost, $smtpPort, $smtpSslMode, $smtpUser, $smtpPassword, $effectiveUserId, $authMethod, $id)
);
$this->delegationService->logDelegatedAction("$this->currentUserId updated account <$id> on behalf of $effectiveUserId");
return $result;
} catch (CouldNotConnectException $e) {
$data = [
'error' => $e->getReason(),
Expand Down Expand Up @@ -221,28 +238,29 @@ public function patchAccount(int $id,
?bool $classificationEnabled = null,
?bool $imipCreate = null,
): JSONResponse {
$account = $this->accountService->find($this->currentUserId, $id);
$effectiveUserId = $this->delegationService->resolveAccountUserId($id, $this->currentUserId);
$account = $this->accountService->find($effectiveUserId, $id);

$dbAccount = $account->getMailAccount();

if ($draftsMailboxId !== null) {
$this->mailManager->getMailbox($this->currentUserId, $draftsMailboxId);
$this->mailManager->getMailbox($effectiveUserId, $draftsMailboxId);
$dbAccount->setDraftsMailboxId($draftsMailboxId);
}
if ($sentMailboxId !== null) {
$this->mailManager->getMailbox($this->currentUserId, $sentMailboxId);
$this->mailManager->getMailbox($effectiveUserId, $sentMailboxId);
$dbAccount->setSentMailboxId($sentMailboxId);
}
if ($trashMailboxId !== null) {
$this->mailManager->getMailbox($this->currentUserId, $trashMailboxId);
$this->mailManager->getMailbox($effectiveUserId, $trashMailboxId);
$dbAccount->setTrashMailboxId($trashMailboxId);
}
if ($archiveMailboxId !== null) {
$this->mailManager->getMailbox($this->currentUserId, $archiveMailboxId);
$this->mailManager->getMailbox($effectiveUserId, $archiveMailboxId);
$dbAccount->setarchiveMailboxId($archiveMailboxId);
}
if ($snoozeMailboxId !== null) {
$this->mailManager->getMailbox($this->currentUserId, $snoozeMailboxId);
$this->mailManager->getMailbox($effectiveUserId, $snoozeMailboxId);
$dbAccount->setSnoozeMailboxId($snoozeMailboxId);
}
if ($editorMode !== null) {
Expand All @@ -262,7 +280,7 @@ public function patchAccount(int $id,
$dbAccount->setTrashRetentionDays($trashRetentionDays <= 0 ? null : $trashRetentionDays);
}
if ($junkMailboxId !== null) {
$this->mailManager->getMailbox($this->currentUserId, $junkMailboxId);
$this->mailManager->getMailbox($effectiveUserId, $junkMailboxId);
$dbAccount->setJunkMailboxId($junkMailboxId);
}
if ($searchBody !== null) {
Expand All @@ -274,9 +292,11 @@ public function patchAccount(int $id,
if ($imipCreate !== null) {
$dbAccount->setImipCreate($imipCreate);
}
return new JSONResponse(
$result = new JSONResponse(
new Account($this->accountService->save($dbAccount))
);
$this->delegationService->logDelegatedAction("$this->currentUserId patched account <$id> on behalf of $effectiveUserId");
return $result;
}

/**
Expand All @@ -292,7 +312,9 @@ public function patchAccount(int $id,
*/
#[TrapError]
public function updateSignature(int $id, ?string $signature = null): JSONResponse {
$this->accountService->updateSignature($id, $this->currentUserId, $signature);
$effectiveUserId = $this->delegationService->resolveAccountUserId($id, $this->currentUserId);
$this->accountService->updateSignature($id, $effectiveUserId, $signature);
$this->delegationService->logDelegatedAction("$this->currentUserId updated signature for account <$id> on behalf of $effectiveUserId");
return new JSONResponse();
}

Expand All @@ -307,7 +329,9 @@ public function updateSignature(int $id, ?string $signature = null): JSONRespons
*/
#[TrapError]
public function destroy(int $id): JSONResponse {
$this->accountService->delete($this->currentUserId, $id);
$effectiveUserId = $this->delegationService->resolveAccountUserId($id, $this->currentUserId);
$this->accountService->delete($effectiveUserId, $id);
$this->delegationService->logDelegatedAction("$this->currentUserId deleted account <$id> on behalf of $effectiveUserId");
return new JSONResponse();
}

Expand Down Expand Up @@ -420,11 +444,12 @@ public function draft(int $id,
$this->logger->info("Updating draft <$draftId> in account <$id>");
}

$account = $this->accountService->find($this->currentUserId, $id);
$effectiveUserId = $this->delegationService->resolveAccountUserId($id, $this->currentUserId);
$account = $this->accountService->find($effectiveUserId, $id);
$previousDraft = null;
if ($draftId !== null) {
try {
$previousDraft = $this->mailManager->getMessage($this->currentUserId, $draftId);
$previousDraft = $this->mailManager->getMessage($effectiveUserId, $draftId);
} catch (ClientException $e) {
$this->logger->info("Draft {$draftId} could not be loaded: {$e->getMessage()}");
}
Expand All @@ -442,6 +467,7 @@ public function draft(int $id,
null,
[]
);
$this->delegationService->logDelegatedAction("$this->currentUserId saved draft in account <$id> on behalf of $effectiveUserId");
return new JSONResponse([
'id' => $this->mailManager->getMessageIdForUid($draftsMailbox, $newUID)
]);
Expand All @@ -460,7 +486,8 @@ public function draft(int $id,
* @throws ClientException
*/
public function getQuota(int $id): JSONResponse {
$account = $this->accountService->find($this->currentUserId, $id);
$effectiveUserId = $this->delegationService->resolveAccountUserId($id, $this->currentUserId);
$account = $this->accountService->find($effectiveUserId, $id);

$quota = $this->mailManager->getQuota($account);
if ($quota === null) {
Expand All @@ -479,9 +506,11 @@ public function getQuota(int $id): JSONResponse {
* @throws ClientException
*/
public function updateSmimeCertificate(int $id, ?int $smimeCertificateId = null) {
$account = $this->accountService->find($this->currentUserId, $id)->getMailAccount();
$effectiveUserId = $this->delegationService->resolveAccountUserId($id, $this->currentUserId);
$account = $this->accountService->find($effectiveUserId, $id)->getMailAccount();
$account->setSmimeCertificateId($smimeCertificateId);
$this->accountService->update($account);
$this->delegationService->logDelegatedAction("$this->currentUserId updated S/MIME certificate for account <$id> on behalf of $effectiveUserId");
return MailJsonResponse::success();
}

Expand All @@ -494,8 +523,9 @@ public function updateSmimeCertificate(int $id, ?int $smimeCertificateId = null)
* @throws ClientException
*/
public function testAccountConnection(int $id) {
$effectiveUserId = $this->delegationService->resolveAccountUserId($id, $this->currentUserId);
return new JSONResponse([
'data' => $this->accountService->testAccountConnection($this->currentUserId, $id),
'data' => $this->accountService->testAccountConnection($effectiveUserId, $id),
]);
}

Expand Down
Loading
Loading