diff --git a/lib/Controller/LocalAttachmentsController.php b/lib/Controller/LocalAttachmentsController.php index f2ec33607d..62f176ff83 100644 --- a/lib/Controller/LocalAttachmentsController.php +++ b/lib/Controller/LocalAttachmentsController.php @@ -13,6 +13,7 @@ use OCA\Mail\Exception\ClientException; use OCA\Mail\Http\TrapError; use OCA\Mail\Service\Attachment\UploadedFile; +use OCA\Mail\Service\DelegationService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\OpenAPI; @@ -22,18 +23,21 @@ #[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)] class LocalAttachmentsController extends Controller { private IAttachmentService $attachmentService; + private DelegationService $delegationService; private string $userId; /** * @param string $appName * @param IRequest $request * @param IAttachmentService $attachmentService + * @param DelegationService $delegationService * @param string $UserId */ public function __construct(string $appName, IRequest $request, - IAttachmentService $attachmentService, $userId) { + IAttachmentService $attachmentService, DelegationService $delegationService, $userId) { parent::__construct($appName, $request); $this->attachmentService = $attachmentService; + $this->delegationService = $delegationService; $this->userId = $userId; } @@ -43,15 +47,21 @@ public function __construct(string $appName, IRequest $request, * @return JSONResponse */ #[TrapError] - public function create(): JSONResponse { + public function create(?int $accountId = null): JSONResponse { $file = $this->request->getUploadedFile('attachment'); if (is_null($file)) { throw new ClientException('no file attached'); } + // Store the attachment under the account owner so it can be linked and + // sent when composing on behalf of a delegated account. + $userId = $accountId !== null + ? $this->delegationService->resolveAccountUserId($accountId, $this->userId) + : $this->userId; + $uploadedFile = new UploadedFile($file); - $attachment = $this->attachmentService->addFile($this->userId, $uploadedFile); + $attachment = $this->attachmentService->addFile($userId, $uploadedFile); return new JSONResponse($attachment, Http::STATUS_CREATED); } diff --git a/src/components/Composer.vue b/src/components/Composer.vue index 9035972e43..5321ec72b2 100644 --- a/src/components/Composer.vue +++ b/src/components/Composer.vue @@ -277,6 +277,7 @@
diff --git a/src/components/ComposerAttachments.vue b/src/components/ComposerAttachments.vue index 83c5f2b164..2e83e1e04c 100644 --- a/src/components/ComposerAttachments.vue +++ b/src/components/ComposerAttachments.vue @@ -104,6 +104,11 @@ export default { type: Number, default: 0, }, + + accountId: { + type: Number, + default: null, + }, }, data() { @@ -292,7 +297,7 @@ export default { uploaded: 0, }) try { - return uploadLocalAttachment(file, progress(file.name), controller) + return uploadLocalAttachment(file, this.accountId, progress(file.name), controller) .catch(() => { this.attachments.some((attachment) => { if (attachment.displayName === file.name && !attachment.error) { diff --git a/src/service/AttachmentService.js b/src/service/AttachmentService.js index a09cc36617..c6a4b96e34 100644 --- a/src/service/AttachmentService.js +++ b/src/service/AttachmentService.js @@ -29,7 +29,7 @@ export function downloadAttachment(url) { return Axios.get(url).then((res) => res.data) } -export function uploadLocalAttachment(file, progress, controller) { +export function uploadLocalAttachment(file, accountId, progress, controller) { const url = generateUrl('/apps/mail/api/attachments') const data = new FormData() const opts = { @@ -40,6 +40,10 @@ export function uploadLocalAttachment(file, progress, controller) { } data.append('attachment', file) + if (accountId) { + data.append('accountId', accountId) + } + return Axios.post(url, data, opts) .then((resp) => resp.data) .then(({ id }) => { diff --git a/tests/Unit/Controller/LocalAttachmentsControllerTest.php b/tests/Unit/Controller/LocalAttachmentsControllerTest.php index 44e3ab1104..cc9be08212 100644 --- a/tests/Unit/Controller/LocalAttachmentsControllerTest.php +++ b/tests/Unit/Controller/LocalAttachmentsControllerTest.php @@ -13,6 +13,7 @@ use OCA\Mail\Db\LocalAttachment; use OCA\Mail\Exception\ClientException; use OCA\Mail\Service\Attachment\UploadedFile; +use OCA\Mail\Service\DelegationService; use OCP\AppFramework\Http\JSONResponse; use OCP\IRequest; use PHPUnit\Framework\MockObject\MockObject; @@ -24,6 +25,9 @@ class LocalAttachmentsControllerTest extends TestCase { /** @var IAttachmentService|MockObject */ private $service; + /** @var DelegationService|MockObject */ + private $delegationService; + /** @var string */ private $userId; @@ -35,9 +39,10 @@ protected function setUp(): void { $this->request = $this->createMock(IRequest::class); $this->service = $this->createMock(IAttachmentService::class); + $this->delegationService = $this->createMock(DelegationService::class); $this->userId = 'jane'; - $this->controller = new LocalAttachmentsController('mail', $this->request, $this->service, $this->userId); + $this->controller = new LocalAttachmentsController('mail', $this->request, $this->service, $this->delegationService, $this->userId); } public function testCreateWithoutFile() { @@ -60,6 +65,8 @@ public function testCreate() { ->willReturn($fileData); $attachment = new LocalAttachment(); $uploadedFile = new UploadedFile($fileData); + $this->delegationService->expects($this->never()) + ->method('resolveAccountUserId'); $this->service->expects($this->once()) ->method('addFile') ->with($this->equalTo($this->userId), $this->equalTo($uploadedFile)) @@ -69,4 +76,28 @@ public function testCreate() { $this->assertEquals(new JSONResponse($attachment, 201), $actual); } + + public function testCreateForDelegatedAccount() { + $fileData = [ + 'name' => 'cat.jpg', + ]; + $this->request->expects($this->once()) + ->method('getUploadedFile') + ->with('attachment') + ->willReturn($fileData); + $attachment = new LocalAttachment(); + $uploadedFile = new UploadedFile($fileData); + $this->delegationService->expects($this->once()) + ->method('resolveAccountUserId') + ->with(42, $this->userId) + ->willReturn('owner'); + $this->service->expects($this->once()) + ->method('addFile') + ->with($this->equalTo('owner'), $this->equalTo($uploadedFile)) + ->willReturn($attachment); + + $actual = $this->controller->create(42); + + $this->assertEquals(new JSONResponse($attachment, 201), $actual); + } }