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 a818a65eb8ab13e01c3705ead34917bc989e83d1
Author: Quan Tran <[email protected]>
AuthorDate: Thu Mar 19 15:16:04 2026 +0700

    JAMES-4191 DeletedMessageVaultDeletionListener: only append deleted message 
to the vault if owner no longer has reference to the message
    
    Given we do emit `MessageContentDeletionEvent` upon sharee delete 
message/mailbox now, we need to check if the owner still has reference to the 
message, before actually append to the vault.
---
 .../vault/DeletedMessageVaultDeletionListener.java | 24 +++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git 
a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/DeletedMessageVaultDeletionListener.java
 
b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/DeletedMessageVaultDeletionListener.java
index bfdc1cc9e0..65d251c8db 100644
--- 
a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/DeletedMessageVaultDeletionListener.java
+++ 
b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/DeletedMessageVaultDeletionListener.java
@@ -39,6 +39,9 @@ import org.apache.james.core.MaybeSender;
 import org.apache.james.events.Event;
 import org.apache.james.events.EventListener;
 import org.apache.james.events.Group;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageIdManager;
+import org.apache.james.mailbox.SessionProvider;
 import 
org.apache.james.mailbox.events.MailboxEvents.MessageContentDeletionEvent;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mime4j.MimeIOException;
@@ -68,14 +71,19 @@ public class DeletedMessageVaultDeletionListener implements 
EventListener.Reacti
     private final DeletedMessageVault deletedMessageVault;
     private final BlobStore blobStore;
     private final Clock clock;
+    private final MessageIdManager messageIdManager;
+    private final SessionProvider sessionProvider;
 
     @Inject
     public DeletedMessageVaultDeletionListener(BlobId.Factory blobIdFactory, 
DeletedMessageVault deletedMessageVault,
-                                               BlobStore blobStore, Clock 
clock) {
+                                               BlobStore blobStore, Clock 
clock, MessageIdManager messageIdManager,
+                                               SessionProvider 
sessionProvider) {
         this.blobIdFactory = blobIdFactory;
         this.deletedMessageVault = deletedMessageVault;
         this.blobStore = blobStore;
         this.clock = clock;
+        this.messageIdManager = messageIdManager;
+        this.sessionProvider = sessionProvider;
     }
 
     @Override
@@ -98,7 +106,9 @@ public class DeletedMessageVaultDeletionListener implements 
EventListener.Reacti
     }
 
     public Mono<Void> forMessage(MessageContentDeletionEvent 
messageContentDeletionEvent) {
-        return fetchMessageHeaderBytes(messageContentDeletionEvent)
+        return hasLostAccess(messageContentDeletionEvent)
+            .filter(Boolean::booleanValue)
+            .flatMap(any -> 
fetchMessageHeaderBytes(messageContentDeletionEvent))
             .flatMap(bytes -> {
                 Optional<Message> mimeMessage = parseMessage(new 
ByteArrayInputStream(bytes), messageContentDeletionEvent.messageId());
                 DeletedMessage deletedMessage = DeletedMessage.builder()
@@ -117,7 +127,15 @@ public class DeletedMessageVaultDeletionListener 
implements EventListener.Reacti
                 return 
Mono.from(blobStore.readReactive(blobStore.getDefaultBucketName(), 
blobIdFactory.parse(messageContentDeletionEvent.bodyBlobId()), 
BlobStore.StoragePolicy.LOW_COST))
                     .map(bodyStream -> new SequenceInputStream(new 
ByteArrayInputStream(bytes), bodyStream))
                     .flatMap(bodyStream -> 
Mono.from(deletedMessageVault.append(deletedMessage, bodyStream)));
-            });
+            })
+            .then();
+    }
+
+    private Mono<Boolean> hasLostAccess(MessageContentDeletionEvent 
messageContentDeletionEvent) {
+        MailboxSession session = 
sessionProvider.createSystemSession(messageContentDeletionEvent.getUsername());
+
+        return 
Mono.from(messageIdManager.accessibleMessagesReactive(ImmutableSet.of(messageContentDeletionEvent.messageId()),
 session))
+            .map(accessibleMessages -> 
!accessibleMessages.contains(messageContentDeletionEvent.messageId()));
     }
 
     private Mono<byte[]> fetchMessageHeaderBytes(MessageContentDeletionEvent 
messageContentDeletionEvent) {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to