You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by rc...@apache.org on 2023/03/21 02:19:03 UTC

[james-project] branch master updated: JAMES-3885 - Change username - should migrate succeed when mailboxes from old user already exist on the new user (#1492)

This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git


The following commit(s) were added to refs/heads/master by this push:
     new 0a481617f8 JAMES-3885 - Change username - should migrate succeed when mailboxes from old user already exist on the new user (#1492)
0a481617f8 is described below

commit 0a481617f85f28248ec43f1999b4e0e5653b0267
Author: vttran <vt...@linagora.com>
AuthorDate: Tue Mar 21 09:18:57 2023 +0700

    JAMES-3885 - Change username - should migrate succeed when mailboxes from old user already exist on the new user (#1492)
---
 .../mailbox/MailboxUsernameChangeTaskStep.java     | 32 +++++++++++++-
 .../mailbox/MailboxUsernameChangeTaskStepTest.java | 51 ++++++++++++++++++++++
 2 files changed, 81 insertions(+), 2 deletions(-)

diff --git a/server/container/mailbox-adapter/src/main/java/org/apache/james/adapter/mailbox/MailboxUsernameChangeTaskStep.java b/server/container/mailbox-adapter/src/main/java/org/apache/james/adapter/mailbox/MailboxUsernameChangeTaskStep.java
index cf3ee76bc5..cdf02d268a 100644
--- a/server/container/mailbox-adapter/src/main/java/org/apache/james/adapter/mailbox/MailboxUsernameChangeTaskStep.java
+++ b/server/container/mailbox-adapter/src/main/java/org/apache/james/adapter/mailbox/MailboxUsernameChangeTaskStep.java
@@ -28,6 +28,7 @@ import org.apache.james.mailbox.SubscriptionManager;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxMetaData;
 import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.search.MailboxQuery;
 import org.apache.james.mailbox.store.StoreMailboxManager;
 import org.apache.james.user.api.UsernameChangeTaskStep;
@@ -76,13 +77,40 @@ public class MailboxUsernameChangeTaskStep implements UsernameChangeTaskStep {
 
     private Mono<Void> migrateMailbox(MailboxSession fromSession, MailboxSession toSession, org.apache.james.mailbox.model.MailboxMetaData mailbox) {
         MailboxPath renamedPath = mailbox.getPath().withUser(toSession.getUser());
+        return mailboxManager.mailboxExists(renamedPath, toSession)
+            .flatMap(exist -> {
+                if (!exist) {
+                    return renameMailboxAndRenameSubscriptionForDelegatee(fromSession, toSession, mailbox, renamedPath);
+                } else {
+                    return renameWhenMailboxExist(toSession, renamedPath,
+                        renameMailboxAndRenameSubscriptionForDelegatee(fromSession, toSession, mailbox, renamedPath));
+                }
+            });
+    }
+
+    private Mono<Void> renameMailboxAndRenameSubscriptionForDelegatee(MailboxSession fromSession, MailboxSession toSession, MailboxMetaData mailbox, MailboxPath renamedPath) {
         return mailboxManager.renameMailboxReactive(mailbox.getPath(), renamedPath,
-            MailboxManager.RenameOption.RENAME_SUBSCRIPTIONS,
-            fromSession, toSession)
+                MailboxManager.RenameOption.RENAME_SUBSCRIPTIONS,
+                fromSession, toSession)
             .then(renameSubscriptionsForDelegatee(mailbox, renamedPath))
             .then();
     }
 
+    // rename: renamedPath -> temporaryPath
+    // rename: mailbox.getPath -> renamedPath
+    // copy messages: temporaryPath -> renamedPath
+    // delete: temporaryPath
+    private Mono<Void> renameWhenMailboxExist(MailboxSession toSession, MailboxPath renamedPath, Mono<Void> renamePublisher) {
+        MailboxPath temporaryPath = new MailboxPath(renamedPath.getNamespace(), renamedPath.getUser(), renamedPath.getName() + "tmp");
+        return mailboxManager.renameMailboxReactive(renamedPath, temporaryPath,
+                MailboxManager.RenameOption.NONE, toSession)
+            .then(renamePublisher)
+            .then(mailboxManager.copyMessagesReactive(MessageRange.all(),
+                    temporaryPath, renamedPath, toSession)
+                .then())
+            .then(mailboxManager.deleteMailboxReactive(temporaryPath, toSession));
+    }
+
     private Mono<Void> renameSubscriptionsForDelegatee(MailboxMetaData mailbox, MailboxPath renamedPath) {
         return Flux.fromIterable(mailbox.getResolvedAcls().getEntries().entrySet())
             .filter(entry -> entry.getKey().getNameType() == MailboxACL.NameType.user && !entry.getKey().isNegative())
diff --git a/server/container/mailbox-adapter/src/test/java/org/apache/james/adapter/mailbox/MailboxUsernameChangeTaskStepTest.java b/server/container/mailbox-adapter/src/test/java/org/apache/james/adapter/mailbox/MailboxUsernameChangeTaskStepTest.java
index 3ed5fdf096..18c5187116 100644
--- a/server/container/mailbox-adapter/src/test/java/org/apache/james/adapter/mailbox/MailboxUsernameChangeTaskStepTest.java
+++ b/server/container/mailbox-adapter/src/test/java/org/apache/james/adapter/mailbox/MailboxUsernameChangeTaskStepTest.java
@@ -23,9 +23,12 @@ import static org.apache.james.mailbox.MailboxManager.MailboxSearchFetchType.Min
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 
+import java.nio.charset.StandardCharsets;
+
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.inmemory.InMemoryMailboxManager;
 import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
 import org.apache.james.mailbox.model.MailboxACL;
@@ -33,6 +36,7 @@ import org.apache.james.mailbox.model.MailboxMetaData;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.search.MailboxQuery;
 import org.apache.james.mailbox.store.StoreSubscriptionManager;
+import org.apache.james.mime4j.dom.Message;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -147,4 +151,51 @@ class MailboxUsernameChangeTaskStepTest {
         assertThat(subscriptionManager.subscriptions(mailboxManager.createSystemSession(BOB)))
             .containsOnly(MailboxPath.forUser(BOB, "subscribed"));
     }
+
+    @Test
+    void shouldMigrateMailboxesWhenNewUserHasAlreadyMailbox() throws Exception {
+        MailboxSession aliceSession = mailboxManager.createSystemSession(ALICE);
+        MailboxSession bobSession = mailboxManager.createSystemSession(BOB);
+        MailboxPath aliceInbox = MailboxPath.inbox(ALICE);
+        MailboxPath bobInbox = MailboxPath.inbox(BOB);
+        mailboxManager.createMailbox(aliceInbox, MailboxManager.CreateOption.NONE, aliceSession);
+        mailboxManager.createMailbox(bobInbox, MailboxManager.CreateOption.NONE, bobSession);
+
+        mailboxManager.getMailbox(aliceInbox, aliceSession)
+            .appendMessage(MessageManager.AppendCommand.from(Message.Builder.of()
+                .setSubject("toto")
+                .setBody("alice33333", StandardCharsets.UTF_8)
+                .build()), aliceSession);
+
+        mailboxManager.getMailbox(bobInbox, bobSession)
+            .appendMessage(MessageManager.AppendCommand.from(Message.Builder.of()
+                .setSubject("toto")
+                .setBody("bob", StandardCharsets.UTF_8)
+                .build()), bobSession);
+
+        Mono.from(testee.changeUsername(ALICE, BOB)).block();
+
+        assertThat(mailboxManager.getMailbox(bobInbox, bobSession).getMessageCount(bobSession))
+            .isEqualTo(2);
+
+        assertThat(mailboxManager.list(bobSession)).containsOnly(bobInbox);
+    }
+
+    @Test
+    void shouldMigrateMailboxesWhenNewUserHasAlreadyOtherMailboxes() throws Exception {
+        MailboxSession fromSession = mailboxManager.createSystemSession(ALICE);
+        mailboxManager.createMailbox(MailboxPath.forUser(ALICE, "test"), MailboxManager.CreateOption.NONE, fromSession);
+        mailboxManager.createMailbox(MailboxPath.forUser(ALICE, "test.child"), MailboxManager.CreateOption.NONE, fromSession);
+
+        MailboxSession bobSession = mailboxManager.createSystemSession(BOB);
+        MailboxPath bobInbox = MailboxPath.inbox(BOB);
+        mailboxManager.createMailbox(bobInbox, MailboxManager.CreateOption.NONE, bobSession);
+
+        Mono.from(testee.changeUsername(ALICE, BOB)).block();
+
+        assertThat(mailboxManager.list(mailboxManager.createSystemSession(BOB)))
+            .containsOnly(MailboxPath.forUser(BOB, "test"),
+                MailboxPath.forUser(BOB, "test.child"),
+                bobInbox);
+    }
 }
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org