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/04/06 02:17:28 UTC

[james-project] 03/03: IMAP - Make reactive DeleteACLProcessor

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

commit 7c63388313d6c407cd039cc33a907745a1a8483a
Author: Tung Van TRAN <vt...@linagora.com>
AuthorDate: Wed Mar 29 16:45:43 2023 +0700

    IMAP - Make reactive DeleteACLProcessor
---
 .../james/imap/processor/DeleteACLProcessor.java   | 124 ++++++++++-----------
 .../imap/processor/DeleteACLProcessorTest.java     |  39 ++++---
 2 files changed, 77 insertions(+), 86 deletions(-)

diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteACLProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteACLProcessor.java
index 20d7f1b1e7..4edaf17ab5 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteACLProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteACLProcessor.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.imap.processor;
 
+import static org.apache.james.util.ReactorUtils.logOnError;
+
 import java.util.List;
 
 import javax.inject.Inject;
@@ -39,12 +41,15 @@ import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxACL.EntryKey;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.metrics.api.MetricFactory;
+import org.apache.james.util.FunctionalUtils;
 import org.apache.james.util.MDCBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.ImmutableList;
 
+import reactor.core.publisher.Mono;
+
 /**
  * DELETEACL Processor.
  */
@@ -59,79 +64,62 @@ public class DeleteACLProcessor extends AbstractMailboxProcessor<DeleteACLReques
     }
 
     @Override
-    protected void processRequest(DeleteACLRequest request, ImapSession session, Responder responder) {
-
+    protected Mono<Void> processRequestReactive(DeleteACLRequest request, ImapSession session, Responder responder) {
         final MailboxManager mailboxManager = getMailboxManager();
         final MailboxSession mailboxSession = session.getMailboxSession();
         final String mailboxName = request.getMailboxName();
         final String identifier = request.getIdentifier();
-        try {
-
-            MailboxPath mailboxPath = PathConverter.forSession(session).buildFullPath(mailboxName);
-            // Check that mailbox exists
-            mailboxManager.getMailbox(mailboxPath, mailboxSession);
-            /*
-             * RFC 4314 section 6.
-             * An implementation MUST make sure the ACL commands themselves do
-             * not give information about mailboxes with appropriately
-             * restricted ACLs. For example, when a user agent executes a GETACL
-             * command on a mailbox that the user has no permission to LIST, the
-             * server would respond to that request with the same error that
-             * would be used if the mailbox did not exist, thus revealing no
-             * existence information, much less the mailbox’s ACL.
-             */
-            if (!mailboxManager.hasRight(mailboxPath, MailboxACL.Right.Lookup, mailboxSession)) {
-                no(request, responder, HumanReadableText.MAILBOX_NOT_FOUND);
-            } else if (!mailboxManager.hasRight(mailboxPath, MailboxACL.Right.Administer, mailboxSession)) {
-                /* RFC 4314 section 4. */
-                Object[] params = new Object[] {
-                        MailboxACL.Right.Administer.toString(),
-                        request.getCommand().getName(),
-                        mailboxName
-                };
-                HumanReadableText text = new HumanReadableText(HumanReadableText.UNSUFFICIENT_RIGHTS_KEY, HumanReadableText.UNSUFFICIENT_RIGHTS_DEFAULT_VALUE, params);
-                no(request, responder, text);
-            } else {
-                
-                EntryKey key = EntryKey.deserialize(identifier);
-                
-                // FIXME check if identifier is a valid user or group
-                // FIXME Servers, when processing a command that has an identifier as a
-                // parameter (i.e., any of SETACL, DELETEACL, and LISTRIGHTS commands),
-                // SHOULD first prepare the received identifier using "SASLprep" profile
-                // [SASLprep] of the "stringprep" algorithm [Stringprep].  If the
-                // preparation of the identifier fails or results in an empty string,
-                // the server MUST refuse to perform the command with a BAD response.
-                // Note that Section 6 recommends additional identifier’s verification
-                // steps.
-
-                mailboxManager.applyRightsCommand(
-                    mailboxPath,
-                    MailboxACL.command().key(key).noRights().asReplacement(),
-                    mailboxSession
-                );
-
-                okComplete(request, responder);
-                // FIXME should we send unsolicited responses here?
-                // unsolicitedResponses(session, responder, false);
-            }
-        } catch (UnsupportedRightException e) {
-            /*
-             * RFc 4314, section 3.1
-             * Note that an unrecognized right MUST cause the command to return the
-             * BAD response.  In particular, the server MUST NOT silently ignore
-             * unrecognized rights.
-             * */
-            Object[] params = new Object[] {e.getUnsupportedRight()};
-            HumanReadableText text = new HumanReadableText(HumanReadableText.UNSUPPORTED_RIGHT_KEY, HumanReadableText.UNSUPPORTED_RIGHT_DEFAULT_VALUE, params);
-            taggedBad(request, responder, text);
-        } catch (MailboxNotFoundException e) {
-            no(request, responder, HumanReadableText.MAILBOX_NOT_FOUND);
-        } catch (MailboxException e) {
-            LOGGER.error("{} failed for mailbox {}", request.getCommand().getName(), mailboxName, e);
-            no(request, responder, HumanReadableText.GENERIC_FAILURE_DURING_PROCESSING);
-        }
+        MailboxPath mailboxPath = PathConverter.forSession(session).buildFullPath(mailboxName);
+
+        return checkLookupRight(request, responder, mailboxManager, mailboxSession, mailboxPath)
+            .filter(FunctionalUtils.identityPredicate())
+            .flatMap(hasLookupRight -> checkAdminRight(request, responder, mailboxManager, mailboxSession, mailboxName, mailboxPath))
+            .filter(FunctionalUtils.identityPredicate())
+            .flatMap(hasAdminRight -> applyRight(mailboxManager, mailboxSession, identifier, mailboxPath)
+                .then(Mono.fromRunnable(() -> okComplete(request, responder)))
+                .then())
+            .onErrorResume(UnsupportedRightException.class,
+                error -> Mono.fromRunnable(() -> taggedBad(request, responder,
+                    new HumanReadableText(
+                        HumanReadableText.UNSUPPORTED_RIGHT_KEY,
+                        HumanReadableText.UNSUPPORTED_RIGHT_DEFAULT_VALUE,
+                        error.getUnsupportedRight()))))
+            .onErrorResume(MailboxNotFoundException.class,
+                error -> Mono.fromRunnable(() -> no(request, responder, HumanReadableText.MAILBOX_NOT_FOUND)))
+            .doOnEach(logOnError(MailboxException.class, e -> LOGGER.error("{} failed for mailbox {}", request.getCommand().getName(), mailboxName, e)))
+            .onErrorResume(MailboxException.class,
+                error -> Mono.fromRunnable(() -> no(request, responder, HumanReadableText.GENERIC_FAILURE_DURING_PROCESSING)));
+    }
+
+    private static Mono<Void> applyRight(MailboxManager mailboxManager, MailboxSession mailboxSession, String identifier, MailboxPath mailboxPath) {
+        return Mono.from(mailboxManager.applyRightsCommandReactive(
+            mailboxPath,
+            MailboxACL.command().key(EntryKey.deserialize(identifier)).noRights().asReplacement(),
+            mailboxSession));
+    }
+
+    private Mono<Boolean> checkAdminRight(DeleteACLRequest request, Responder responder, MailboxManager mailboxManager, MailboxSession mailboxSession, String mailboxName, MailboxPath mailboxPath) {
+        return Mono.from(mailboxManager.hasRightReactive(mailboxPath, MailboxACL.Right.Administer, mailboxSession))
+            .doOnNext(hasRight -> {
+                if (!hasRight) {
+                    no(request, responder,
+                        new HumanReadableText(
+                            HumanReadableText.UNSUFFICIENT_RIGHTS_KEY,
+                            HumanReadableText.UNSUFFICIENT_RIGHTS_DEFAULT_VALUE,
+                            MailboxACL.Right.Administer.toString(),
+                            request.getCommand().getName(),
+                            mailboxName));
+                }
+            });
+    }
 
+    private Mono<Boolean> checkLookupRight(DeleteACLRequest request, Responder responder, MailboxManager mailboxManager, MailboxSession mailboxSession, MailboxPath mailboxPath) {
+        return Mono.from(mailboxManager.hasRightReactive(mailboxPath, MailboxACL.Right.Lookup, mailboxSession))
+            .doOnNext(hasRight -> {
+                if (!hasRight) {
+                    no(request, responder, HumanReadableText.MAILBOX_NOT_FOUND);
+                }
+            });
     }
 
     @Override
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/processor/DeleteACLProcessorTest.java b/protocols/imap/src/test/java/org/apache/james/imap/processor/DeleteACLProcessorTest.java
index f709722568..8ee9813ba7 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/processor/DeleteACLProcessorTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/processor/DeleteACLProcessorTest.java
@@ -41,7 +41,6 @@ import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageManager.MailboxMetaData;
 import org.apache.james.mailbox.MessageManager.MailboxMetaData.FetchGroup;
-import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxACL.EntryKey;
@@ -106,9 +105,9 @@ class DeleteACLProcessorTest {
     }
     
     @Test
-    void testNoListRight() throws Exception {
-        when(mailboxManager.hasRight(path, MailboxACL.Right.Lookup, mailboxSession))
-            .thenReturn(false);
+    void testNoListRight() {
+        when(mailboxManager.hasRightReactive(path, MailboxACL.Right.Lookup, mailboxSession))
+            .thenReturn(Mono.just(false));
 
         subject.doProcess(deleteACLRequest, responder, imapSession).block();
 
@@ -122,11 +121,11 @@ class DeleteACLProcessorTest {
     }
 
     @Test
-    void testNoAdminRight() throws Exception {
-        when(mailboxManager.hasRight(path, MailboxACL.Right.Lookup, mailboxSession))
-            .thenReturn(true);
-        when(mailboxManager.hasRight(path, MailboxACL.Right.Administer, mailboxSession))
-            .thenReturn(false);
+    void testNoAdminRight() {
+        when(mailboxManager.hasRightReactive(path, MailboxACL.Right.Lookup, mailboxSession))
+            .thenReturn(Mono.just(true));
+        when(mailboxManager.hasRightReactive(path, MailboxACL.Right.Administer, mailboxSession))
+            .thenReturn(Mono.just(false));
 
         subject.doProcess(deleteACLRequest, responder, imapSession).block();
 
@@ -140,9 +139,10 @@ class DeleteACLProcessorTest {
     }
 
     @Test
-    void testNonExistentMailboxName() throws Exception {
-        when(mailboxManager.getMailbox(any(MailboxPath.class), any(MailboxSession.class)))
-            .thenThrow(new MailboxNotFoundException(""));
+    void testNonExistentMailboxName() {
+        when(mailboxManager.hasRightReactive(any(MailboxPath.class),
+            any(),any(MailboxSession.class)))
+            .thenReturn(Mono.error(new MailboxNotFoundException("")));
 
         subject.doProcess(deleteACLRequest, responder, imapSession).block();
 
@@ -157,17 +157,20 @@ class DeleteACLProcessorTest {
 
     
     @Test
-    void testDelete() throws MailboxException {
+    void testDelete() {
         MailboxACL acl = MailboxACL.OWNER_FULL_ACL;
-        when(mailboxManager.hasRight(path, MailboxACL.Right.Lookup, mailboxSession))
-            .thenReturn(true);
-        when(mailboxManager.hasRight(path, MailboxACL.Right.Administer, mailboxSession))
-            .thenReturn(true);
+        when(mailboxManager.hasRightReactive(path, MailboxACL.Right.Lookup, mailboxSession))
+            .thenReturn(Mono.just(true));
+        when(mailboxManager.hasRightReactive(path, MailboxACL.Right.Administer, mailboxSession))
+            .thenReturn(Mono.just(true));
         when(metaData.getACL()).thenReturn(acl);
+        when(mailboxManager.applyRightsCommandReactive(path, MailboxACL.command().key(user1Key).noRights().asReplacement(),
+            mailboxSession))
+            .thenReturn(Mono.empty());
 
         subject.doProcess(deleteACLRequest, responder, imapSession).block();
 
-        verify(mailboxManager).applyRightsCommand(path,
+        verify(mailboxManager).applyRightsCommandReactive(path,
             MailboxACL.command().key(user1Key).noRights().asReplacement(),
             mailboxSession);
 


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