This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 1e020547fb209438acb6e2bd644671d2dfb7487f Author: Quan Tran <[email protected]> AuthorDate: Wed Mar 18 16:07:09 2026 +0700 JAMES-4191 Enrich MessageContentDeletionEvent with mailboxACL --- .../apache/james/mailbox/events/MailboxEvents.java | 2 +- .../mailbox/cassandra/DeleteMessageListener.java | 45 +++++++------ .../james/event/json/MailboxEventSerializer.scala | 5 +- .../MessageContentDeletionSerializationTest.java | 76 ++++++++++++++++++++++ .../mailbox/postgres/DeleteMessageListener.java | 51 ++++++++++++--- .../PostgresMailboxSessionMapperFactory.java | 2 +- .../PostgresMailboxManagerAttachmentTest.java | 2 +- .../james/mailbox/store/event/EventFactory.java | 11 +++- 8 files changed, 159 insertions(+), 35 deletions(-) diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxEvents.java b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxEvents.java index b648cb24fb..9673fb78e7 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxEvents.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/events/MailboxEvents.java @@ -538,7 +538,7 @@ public interface MailboxEvents { } } - record MessageContentDeletionEvent(EventId eventId, Username username, MailboxId mailboxId, MessageId messageId, long size, + record MessageContentDeletionEvent(EventId eventId, Username username, MailboxId mailboxId, MailboxACL mailboxACL, MessageId messageId, long size, Instant internalDate, Flags flags, boolean hasAttachments, Optional<String> headerBlobId, Optional<String> headerContent, String bodyBlobId, Optional<String> mailboxPath) implements Event { diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java index 919b08f5e6..b4a80b22c9 100644 --- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/DeleteMessageListener.java @@ -167,19 +167,20 @@ public class DeleteMessageListener implements EventListener.ReactiveGroupEventLi private Mono<Void> handleMailboxDeletion(CassandraId mailboxId, MailboxPath path) { int prefetch = 1; - return Flux.mergeDelayError(prefetch, - messageIdDAO.retrieveMessages(mailboxId, MessageRange.all(), Limit.unlimited()) - .concatMap(metadata -> handleMessageDeletionAsPartOfMailboxDeletion((CassandraMessageId) metadata.getComposedMessageId().getComposedMessageId().getMessageId(), - metadata.getComposedMessageId().getThreadId(), metadata.getComposedMessageId().getFlags(), mailboxId, path.getUser(), path) - .then(imapUidDAO.delete((CassandraMessageId) metadata.getComposedMessageId().getComposedMessageId().getMessageId(), mailboxId)) - .then(messageIdDAO.delete(mailboxId, metadata.getComposedMessageId().getComposedMessageId().getUid()))), - deleteAcl(mailboxId), - applicableFlagDAO.delete(mailboxId), - firstUnseenDAO.removeAll(mailboxId), - deletedMessageDAO.removeAll(mailboxId), - counterDAO.delete(mailboxId), - recentsDAO.delete(mailboxId)) - .then(); + return getMailboxACL(mailboxId) + .flatMap(mailboxACL -> Flux.mergeDelayError(prefetch, + messageIdDAO.retrieveMessages(mailboxId, MessageRange.all(), Limit.unlimited()) + .concatMap(metadata -> handleMessageDeletionAsPartOfMailboxDeletion((CassandraMessageId) metadata.getComposedMessageId().getComposedMessageId().getMessageId(), + metadata.getComposedMessageId().getThreadId(), metadata.getComposedMessageId().getFlags(), mailboxId, path.getUser(), path, mailboxACL) + .then(imapUidDAO.delete((CassandraMessageId) metadata.getComposedMessageId().getComposedMessageId().getMessageId(), mailboxId)) + .then(messageIdDAO.delete(mailboxId, metadata.getComposedMessageId().getComposedMessageId().getUid()))), + deleteAcl(mailboxId), + applicableFlagDAO.delete(mailboxId), + firstUnseenDAO.removeAll(mailboxId), + deletedMessageDAO.removeAll(mailboxId), + counterDAO.delete(mailboxId), + recentsDAO.delete(mailboxId)) + .then()); } private Mono<Void> handleMessageDeletion(Expunged expunged) { @@ -189,6 +190,11 @@ public class DeleteMessageListener implements EventListener.ReactiveGroupEventLi .then(); } + private Mono<MailboxACL> getMailboxACL(CassandraId mailboxId) { + return aclMapper.getACL(mailboxId) + .defaultIfEmpty(MailboxACL.EMPTY); + } + private Mono<Void> deleteAcl(CassandraId mailboxId) { return aclMapper.getACL(mailboxId) .flatMap(acl -> rightsDAO.update(mailboxId, ACLDiff.computeDiff(acl, MailboxACL.EMPTY)) @@ -198,9 +204,9 @@ public class DeleteMessageListener implements EventListener.ReactiveGroupEventLi private Mono<Void> handleMessageDeletion(CassandraMessageId messageId, MailboxId mailboxId, ThreadId threadId, Flags flags, Username owner, MailboxPath mailboxPath) { return Mono.just(messageId) .filterWhen(this::isReferenced) - .flatMap(id -> readMessage(id) - .flatMap(message -> dispatchMessageContentDeletionEvent(mailboxId, owner, flags, message, mailboxPath) - .thenReturn(message)) + .flatMap(id -> Mono.zip(readMessage(id), getMailboxACL((CassandraId) mailboxId)) + .flatMap(tuple -> dispatchMessageContentDeletionEvent(mailboxId, owner, tuple.getT2(), flags, tuple.getT1(), mailboxPath) + .thenReturn(tuple.getT1())) .flatMap(message -> deleteUnreferencedAttachments(message).thenReturn(message)) .flatMap(this::deleteMessageBlobs) .then(messageDAOV3.delete(messageId)) @@ -210,7 +216,7 @@ public class DeleteMessageListener implements EventListener.ReactiveGroupEventLi .then(threadLookupDAO.deleteOneRow(threadId, messageId))); } - private Mono<Void> dispatchMessageContentDeletionEvent(MailboxId mailboxId, Username owner, Flags flags, MessageRepresentation message, MailboxPath mailboxPath) { + private Mono<Void> dispatchMessageContentDeletionEvent(MailboxId mailboxId, Username owner, MailboxACL mailboxACL, Flags flags, MessageRepresentation message, MailboxPath mailboxPath) { AuditTrail.entry() .action("DELETION") .username(owner::asString) @@ -224,6 +230,7 @@ public class DeleteMessageListener implements EventListener.ReactiveGroupEventLi .randomEventId() .user(owner) .mailboxId(mailboxId) + .mailboxACL(mailboxACL) .messageId(message.getMessageId()) .size(message.getSize()) .instant(message.getInternalDate().toInstant()) @@ -236,11 +243,11 @@ public class DeleteMessageListener implements EventListener.ReactiveGroupEventLi ImmutableSet.of())); } - private Mono<Void> handleMessageDeletionAsPartOfMailboxDeletion(CassandraMessageId messageId, ThreadId threadId, Flags flags, CassandraId excludedId, Username owner, MailboxPath mailboxPath) { + private Mono<Void> handleMessageDeletionAsPartOfMailboxDeletion(CassandraMessageId messageId, ThreadId threadId, Flags flags, CassandraId excludedId, Username owner, MailboxPath mailboxPath, MailboxACL mailboxACL) { return Mono.just(messageId) .filterWhen(id -> isReferenced(id, excludedId)) .flatMap(id -> readMessage(id) - .flatMap(message -> dispatchMessageContentDeletionEvent(excludedId, owner, flags, message, mailboxPath) + .flatMap(message -> dispatchMessageContentDeletionEvent(excludedId, owner, mailboxACL, flags, message, mailboxPath) .thenReturn(message))) .flatMap(message -> deleteUnreferencedAttachments(message).thenReturn(message)) .flatMap(this::deleteMessageBlobs) diff --git a/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala b/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala index e112a21879..17b3a2008d 100644 --- a/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala +++ b/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala @@ -137,6 +137,7 @@ private object DTO { case class MessageContentDeletionEvent(eventId: EventId, username: Username, mailboxId: MailboxId, + mailboxACL: Option[MailboxACL], messageId: MessageId, size: Long, internalDate: Instant, @@ -146,7 +147,7 @@ private object DTO { headerContent: Option[String], bodyBlobId: String, mailboxPath: Option[String] = None) extends Event { - override def toJava: JavaEvent = new JavaMessageContentDeletionEvent(eventId, username, mailboxId, messageId, size, internalDate, DTOs.Flags.toJavaFlags(flags.getOrElse(DTOs.Flags.empty)), hasAttachments, headerBlobId.toJava, headerContent.toJava, bodyBlobId, mailboxPath.toJava) + override def toJava: JavaEvent = new JavaMessageContentDeletionEvent(eventId, username, mailboxId, mailboxACL.map(_.toJava).getOrElse(new JavaMailboxACL()), messageId, size, internalDate, DTOs.Flags.toJavaFlags(flags.getOrElse(DTOs.Flags.empty)), hasAttachments, headerBlobId.toJava, headerContent.toJava, bodyBlobId, mailboxPath.toJava) } } @@ -246,6 +247,7 @@ private object ScalaConverter { eventId = event.getEventId, username = event.getUsername, mailboxId = event.mailboxId(), + mailboxACL = MailboxACL.fromJava(event.mailboxACL()), messageId = event.messageId(), size = event.size(), internalDate = event.internalDate(), @@ -468,4 +470,3 @@ class MailboxEventSerializer @Inject()(mailboxIdFactory: MailboxId.Factory, mess override def asEvent(serialized: String): JavaEvent = fromJson(serialized).get } - diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageContentDeletionSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageContentDeletionSerializationTest.java index b8fa5151d8..39b663f8ac 100644 --- a/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageContentDeletionSerializationTest.java +++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageContentDeletionSerializationTest.java @@ -32,6 +32,8 @@ import jakarta.mail.Flags; import org.apache.james.core.Username; import org.apache.james.mailbox.FlagsBuilder; import org.apache.james.mailbox.events.MailboxEvents.MessageContentDeletionEvent; +import org.apache.james.mailbox.exception.UnsupportedRightException; +import org.apache.james.mailbox.model.MailboxACL; import org.apache.james.mailbox.model.MailboxId; import org.apache.james.mailbox.model.MessageId; import org.apache.james.mailbox.model.TestId; @@ -39,11 +41,21 @@ import org.apache.james.mailbox.model.TestMessageId; import org.junit.jupiter.api.Test; class MessageContentDeletionSerializationTest { + private static MailboxACL asMailboxACL(Username username, MailboxACL.Right right) { + try { + return new MailboxACL() + .union(MailboxACL.EntryKey.createUserEntryKey(username), new MailboxACL.Rfc4314Rights(right)); + } catch (UnsupportedRightException e) { + throw new RuntimeException(e); + } + } + private static final Username USERNAME = Username.of("[email protected]"); private static final MailboxId MAILBOX_ID = TestId.of(18); private static final MessageId MESSAGE_ID = TestMessageId.of(42); private static final long SIZE = 12345L; private static final Instant INTERNAL_DATE = Instant.parse("2024-12-15T08:23:45Z"); + private static final MailboxACL MAILBOX_ACL = asMailboxACL(Username.of("[email protected]"), MailboxACL.Right.Read); private static final Flags FLAGS = new FlagsBuilder() .add(Flags.Flag.FLAGGED) .add("$Forwarded") @@ -59,6 +71,7 @@ class MessageContentDeletionSerializationTest { EVENT_ID, USERNAME, MAILBOX_ID, + MAILBOX_ACL, MESSAGE_ID, SIZE, INTERNAL_DATE, @@ -82,6 +95,11 @@ class MessageContentDeletionSerializationTest { "userFlags": ["$Forwarded"] }, "mailboxId": "18", + "mailboxACL": { + "entries": { + "[email protected]": "r" + } + }, "headerBlobId": "header-blob-id", "messageId": "42", "bodyBlobId": "body-blob-id", @@ -95,6 +113,7 @@ class MessageContentDeletionSerializationTest { EVENT_ID, USERNAME, MAILBOX_ID, + MAILBOX_ACL, MESSAGE_ID, SIZE, INTERNAL_DATE, @@ -109,6 +128,7 @@ class MessageContentDeletionSerializationTest { EVENT_ID, USERNAME, MAILBOX_ID, + MAILBOX_ACL, MESSAGE_ID, SIZE, INTERNAL_DATE, @@ -132,6 +152,11 @@ class MessageContentDeletionSerializationTest { "userFlags": ["$Forwarded"] }, "mailboxId": "18", + "mailboxACL": { + "entries": { + "[email protected]": "r" + } + }, "headerBlobId": "header-blob-id", "messageId": "42", "bodyBlobId": "body-blob-id", @@ -149,6 +174,11 @@ class MessageContentDeletionSerializationTest { "hasAttachments": true, "internalDate": "2024-12-15T08:23:45Z", "mailboxId": "18", + "mailboxACL": { + "entries": { + "[email protected]": "r" + } + }, "headerBlobId": "header-blob-id", "messageId": "42", "bodyBlobId": "body-blob-id" @@ -156,6 +186,27 @@ class MessageContentDeletionSerializationTest { } """; + private static final String LEGACY_JSON_WITHOUT_MAILBOX_ACL = """ + { + "MessageContentDeletionEvent": { + "eventId": "6e0dd59d-660e-4d9b-b22f-0354479f47b4", + "username": "[email protected]", + "size": 12345, + "hasAttachments": true, + "internalDate": "2024-12-15T08:23:45Z", + "flags": { + "systemFlags": ["Flagged"], + "userFlags": ["$Forwarded"] + }, + "mailboxId": "18", + "headerBlobId": "header-blob-id", + "messageId": "42", + "bodyBlobId": "body-blob-id", + "headerContent": "Header: value" + } + } + """; + private static final String JSON_WITHOUT_HEADER_CONTENT = """ { "MessageContentDeletionEvent": { @@ -169,6 +220,11 @@ class MessageContentDeletionSerializationTest { "userFlags": ["$Forwarded"] }, "mailboxId": "18", + "mailboxACL": { + "entries": { + "[email protected]": "r" + } + }, "headerBlobId": "header-blob-id", "messageId": "42", "bodyBlobId": "body-blob-id" @@ -205,6 +261,7 @@ class MessageContentDeletionSerializationTest { EVENT_ID, USERNAME, MAILBOX_ID, + MAILBOX_ACL, MESSAGE_ID, SIZE, INTERNAL_DATE, @@ -216,4 +273,23 @@ class MessageContentDeletionSerializationTest { Optional.empty())); } + @Test + void legacyMessageContentDeletionEventWithoutMailboxACLShouldBeWellDeserialized() { + assertThat(EVENT_SERIALIZER.fromJson(LEGACY_JSON_WITHOUT_MAILBOX_ACL).get()) + .isEqualTo(new MessageContentDeletionEvent( + EVENT_ID, + USERNAME, + MAILBOX_ID, + MailboxACL.EMPTY, + MESSAGE_ID, + SIZE, + INTERNAL_DATE, + FLAGS, + HAS_ATTACHMENTS, + HEADER_BLOB_ID, + HEADER_CONTENT, + BODY_BLOB_ID, + Optional.empty())); + } + } diff --git a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/DeleteMessageListener.java b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/DeleteMessageListener.java index f2b723b632..cdaffdd8e8 100644 --- a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/DeleteMessageListener.java +++ b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/DeleteMessageListener.java @@ -26,7 +26,9 @@ import jakarta.inject.Named; import jakarta.mail.Flags; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.tuple.Pair; import org.apache.james.backends.postgres.PostgresConfiguration; +import org.apache.james.backends.postgres.utils.PostgresExecutor; import org.apache.james.blob.api.BlobStore; import org.apache.james.core.Username; import org.apache.james.events.Event; @@ -36,10 +38,12 @@ import org.apache.james.events.Group; import org.apache.james.mailbox.events.MailboxEvents; import org.apache.james.mailbox.events.MailboxEvents.Expunged; import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion; +import org.apache.james.mailbox.model.MailboxACL; import org.apache.james.mailbox.model.MailboxId; import org.apache.james.mailbox.model.MailboxPath; import org.apache.james.mailbox.postgres.mail.MessageRepresentation; import org.apache.james.mailbox.postgres.mail.dao.PostgresAttachmentDAO; +import org.apache.james.mailbox.postgres.mail.dao.PostgresMailboxDAO; import org.apache.james.mailbox.postgres.mail.dao.PostgresMailboxMessageDAO; import org.apache.james.mailbox.postgres.mail.dao.PostgresMessageDAO; import org.apache.james.mailbox.postgres.mail.dao.PostgresThreadDAO; @@ -65,6 +69,7 @@ public class DeleteMessageListener implements EventListener.ReactiveGroupEventLi private final PostgresMailboxMessageDAO.Factory mailboxMessageDAOFactory; private final PostgresAttachmentDAO.Factory attachmentDAOFactory; private final PostgresThreadDAO.Factory threadDAOFactory; + private final PostgresExecutor.Factory executorFactory; private final EventBus contentDeletionEventBus; private final PostgresConfiguration postgresConfiguration; @@ -74,6 +79,7 @@ public class DeleteMessageListener implements EventListener.ReactiveGroupEventLi PostgresMessageDAO.Factory messageDAOFactory, PostgresAttachmentDAO.Factory attachmentDAOFactory, PostgresThreadDAO.Factory threadDAOFactory, + PostgresExecutor.Factory executorFactory, @Named(CONTENT_DELETION) EventBus contentDeletionEventBus, PostgresConfiguration postgresConfiguration) { this.messageDAOFactory = messageDAOFactory; @@ -81,6 +87,7 @@ public class DeleteMessageListener implements EventListener.ReactiveGroupEventLi this.blobStore = blobStore; this.attachmentDAOFactory = attachmentDAOFactory; this.threadDAOFactory = threadDAOFactory; + this.executorFactory = executorFactory; this.contentDeletionEventBus = contentDeletionEventBus; this.postgresConfiguration = postgresConfiguration; } @@ -114,10 +121,11 @@ public class DeleteMessageListener implements EventListener.ReactiveGroupEventLi PostgresAttachmentDAO attachmentDAO = attachmentDAOFactory.create(event.getUsername().getDomainPart()); PostgresThreadDAO threadDAO = threadDAOFactory.create(event.getUsername().getDomainPart()); - return postgresMailboxMessageDAO.deleteByMailboxId((PostgresMailboxId) event.getMailboxId()) - .flatMap(metaData -> handleMessageDeletion(postgresMessageDAO, postgresMailboxMessageDAO, attachmentDAO, threadDAO, - (PostgresMessageId) metaData.getMessageId(), event.getMailboxId(), event.getMailboxPath().getUser(), metaData.getFlags(), event.getMailboxPath()), - LOW_CONCURRENCY) + return mailboxACL(event.getMailboxPath().getUser(), event.getMailboxId()) + .flatMapMany(mailboxACL -> postgresMailboxMessageDAO.deleteByMailboxId((PostgresMailboxId) event.getMailboxId()) + .flatMap(metaData -> handleMessageDeletion(postgresMessageDAO, postgresMailboxMessageDAO, attachmentDAO, threadDAO, + (PostgresMessageId) metaData.getMessageId(), event.getMailboxId(), event.getMailboxPath().getUser(), metaData.getFlags(), event.getMailboxPath(), mailboxACL), + LOW_CONCURRENCY)) .then(); } @@ -143,28 +151,49 @@ public class DeleteMessageListener implements EventListener.ReactiveGroupEventLi Username owner, Flags flags, MailboxPath mailboxPath) { + return Mono.just(messageId) + .filterWhen(msgId -> isUnreferenced(msgId, postgresMailboxMessageDAO)) + .flatMap(msgId -> Mono.zip(postgresMessageDAO.retrieveMessage(messageId), mailboxACL(owner, mailboxId)) + .flatMap(tuple -> dispatchMessageContentDeletionEvent(mailboxId, owner, tuple.getT2(), flags, tuple.getT1(), mailboxPath))) + .then(deleteBodyBlob(msgId, postgresMessageDAO)) + .then(deleteAttachmentIfEnabled(msgId, attachmentDAO)) + .then(threadDAO.deleteSome(owner, msgId)) + .then(postgresMessageDAO.deleteByMessageId(msgId))); + } + + private Mono<Void> handleMessageDeletion(PostgresMessageDAO postgresMessageDAO, + PostgresMailboxMessageDAO postgresMailboxMessageDAO, + PostgresAttachmentDAO attachmentDAO, + PostgresThreadDAO threadDAO, + PostgresMessageId messageId, + MailboxId mailboxId, + Username owner, + Flags flags, + MailboxPath mailboxPath, + MailboxACL mailboxACL) { return Mono.just(messageId) .filterWhen(msgId -> isUnreferenced(msgId, postgresMailboxMessageDAO)) .flatMap(msgId -> postgresMessageDAO.retrieveMessage(messageId) - .flatMap(messageRepresentation -> dispatchMessageContentDeletionEvent(mailboxId, owner, flags, messageRepresentation, mailboxPath)) + .flatMap(messageRepresentation -> dispatchMessageContentDeletionEvent(mailboxId, owner, mailboxACL, flags, messageRepresentation, mailboxPath)) .then(deleteBodyBlob(msgId, postgresMessageDAO)) .then(deleteAttachmentIfEnabled(msgId, attachmentDAO)) .then(threadDAO.deleteSome(owner, msgId)) .then(postgresMessageDAO.deleteByMessageId(msgId))); } - private Mono<Void> dispatchMessageContentDeletionEvent(MailboxId mailboxId, Username owner, Flags flags, MessageRepresentation message, MailboxPath mailboxPath) { + private Mono<Void> dispatchMessageContentDeletionEvent(MailboxId mailboxId, Username owner, MailboxACL mailboxACL, Flags flags, MessageRepresentation message, MailboxPath mailboxPath) { return Mono.fromCallable(() -> IOUtils.toString(message.getHeaderContent().getInputStream(), StandardCharsets.UTF_8)) .subscribeOn(ReactorUtils.BLOCKING_CALL_WRAPPER) - .flatMap(headerContent -> Mono.from(contentDeletionEventBus.dispatch(messageContentDeletionEvent(mailboxId, owner, flags, message, headerContent, mailboxPath), + .flatMap(headerContent -> Mono.from(contentDeletionEventBus.dispatch(messageContentDeletionEvent(mailboxId, owner, mailboxACL, flags, message, headerContent, mailboxPath), ImmutableSet.of()))); } - private MailboxEvents.MessageContentDeletionEvent messageContentDeletionEvent(MailboxId mailboxId, Username owner, Flags flags, MessageRepresentation message, String headerContent, MailboxPath mailboxPath) { + private MailboxEvents.MessageContentDeletionEvent messageContentDeletionEvent(MailboxId mailboxId, Username owner, MailboxACL mailboxACL, Flags flags, MessageRepresentation message, String headerContent, MailboxPath mailboxPath) { return EventFactory.messageContentDeleted() .randomEventId() .user(owner) .mailboxId(mailboxId) + .mailboxACL(mailboxACL) .messageId(message.getMessageId()) .size(message.getSize()) .instant(message.getInternalDate().toInstant()) @@ -176,6 +205,12 @@ public class DeleteMessageListener implements EventListener.ReactiveGroupEventLi .build(); } + private Mono<MailboxACL> mailboxACL(Username owner, MailboxId mailboxId) { + return new PostgresMailboxDAO(executorFactory.create(owner.getDomainPart())) + .getACL(mailboxId) + .map(Pair::getLeft); + } + private Mono<Void> deleteBodyBlob(PostgresMessageId id, PostgresMessageDAO postgresMessageDAO) { return postgresMessageDAO.getBodyBlobId(id) .flatMap(blobId -> Mono.from(blobStore.delete(blobStore.getDefaultBucketName(), blobId)) diff --git a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/PostgresMailboxSessionMapperFactory.java b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/PostgresMailboxSessionMapperFactory.java index 5daa6d52ad..42b749fe28 100644 --- a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/PostgresMailboxSessionMapperFactory.java +++ b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/PostgresMailboxSessionMapperFactory.java @@ -161,6 +161,6 @@ public class PostgresMailboxSessionMapperFactory extends MailboxSessionMapperFac PostgresAttachmentDAO.Factory attachmentDAOFactory = new PostgresAttachmentDAO.Factory(executorFactory, blobIdFactory); PostgresThreadDAO.Factory threadDAOFactory = new PostgresThreadDAO.Factory(executorFactory); return new DeleteMessageListener(blobStore, postgresMailboxMessageDAOFactory, postgresMessageDAOFactory, - attachmentDAOFactory, threadDAOFactory, contentDeletionEventBus, postgresConfiguration); + attachmentDAOFactory, threadDAOFactory, executorFactory, contentDeletionEventBus, postgresConfiguration); } } diff --git a/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/PostgresMailboxManagerAttachmentTest.java b/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/PostgresMailboxManagerAttachmentTest.java index b2190334b4..0701ca8295 100644 --- a/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/PostgresMailboxManagerAttachmentTest.java +++ b/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/PostgresMailboxManagerAttachmentTest.java @@ -110,7 +110,7 @@ public class PostgresMailboxManagerAttachmentTest extends AbstractMailboxManager PostgresThreadDAO.Factory threadDAOFactory = new PostgresThreadDAO.Factory(postgresExtension.getExecutorFactory()); eventBus.register(new DeleteMessageListener(blobStore, postgresMailboxMessageDAOFactory, postgresMessageDAOFactory, - attachmentDAOFactory, threadDAOFactory,eventBus, postgresConfiguration)); + attachmentDAOFactory, threadDAOFactory, postgresExtension.getExecutorFactory(), eventBus, postgresConfiguration)); mailboxManager = new PostgresMailboxManager(mapperFactory, sessionProvider, messageParser, new PostgresMessageId.Factory(), diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java index b902a5dd9a..2456005054 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java @@ -552,6 +552,7 @@ public class EventFactory { private final Event.EventId eventId; private final Username username; private final MailboxId mailboxId; + private final MailboxACL mailboxACL; private final MessageId messageId; private final long size; private final Instant internalDate; @@ -565,6 +566,7 @@ public class EventFactory { MessageContentDeletionFinalStage(Event.EventId eventId, Username username, MailboxId mailboxId, + MailboxACL mailboxACL, MessageId messageId, long size, Instant internalDate, @@ -574,6 +576,7 @@ public class EventFactory { this.eventId = eventId; this.username = username; this.mailboxId = mailboxId; + this.mailboxACL = mailboxACL; this.messageId = messageId; this.size = size; this.internalDate = internalDate; @@ -604,6 +607,7 @@ public class EventFactory { Preconditions.checkNotNull(eventId); Preconditions.checkNotNull(username); Preconditions.checkNotNull(mailboxId); + Preconditions.checkNotNull(mailboxACL); Preconditions.checkNotNull(messageId); Preconditions.checkNotNull(internalDate); Preconditions.checkNotNull(flags); @@ -614,6 +618,7 @@ public class EventFactory { eventId, username, mailboxId, + mailboxACL, messageId, size, internalDate, @@ -712,9 +717,9 @@ public class EventFactory { return eventId -> user -> quotaRoot -> quotaCount -> quotaSize -> instant -> new QuotaUsageUpdatedFinalStage(eventId, user, quotaRoot, quotaCount, quotaSize, instant); } - public static RequireEventId<RequireUser<RequireMailboxId<RequireMessageId<RequireSize<RequireInstant<RequireFlags<RequireHasAttachments<RequireBodyBlobId<MessageContentDeletionFinalStage>>>>>>>>> messageContentDeleted() { - return eventId -> user -> mailboxId -> messageId -> size -> instant -> flags -> hasAttachments -> bodyBlobId -> - new MessageContentDeletionFinalStage(eventId, user, mailboxId, messageId, size, instant, flags, hasAttachments, bodyBlobId); + public static RequireEventId<RequireUser<RequireMailboxId<RequireMailboxACL<RequireMessageId<RequireSize<RequireInstant<RequireFlags<RequireHasAttachments<RequireBodyBlobId<MessageContentDeletionFinalStage>>>>>>>>>> messageContentDeleted() { + return eventId -> user -> mailboxId -> mailboxACL -> messageId -> size -> instant -> flags -> hasAttachments -> bodyBlobId -> + new MessageContentDeletionFinalStage(eventId, user, mailboxId, mailboxACL, messageId, size, instant, flags, hasAttachments, bodyBlobId); } public static RequireMailboxEvent<MailboxSubscribedFinalStage> mailboxSubscribed() { --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
