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 <[email protected]> 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: [email protected] For additional commands, e-mail: [email protected]
