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 10c96e699b6c819d988106a30b9baecb74791de6 Author: Benoit TELLIER <btell...@linagora.com> AuthorDate: Thu Oct 17 17:07:37 2024 +0200 JAMES-2182 Fix rights for STORE --- .../james/mailbox/store/StoreMessageManager.java | 77 +++++++++++++++------- .../james/imap/scripts/SharingAccessLRI.test | 12 ++-- .../james/imap/scripts/SharingAccessLRS.test | 11 ++-- .../james/imap/scripts/SharingAccessLRT.test | 9 +-- .../james/imap/scripts/SharingAccessLRTE.test | 9 +-- .../james/imap/scripts/SharingAccessLRW.test | 11 ++-- .../imap/processor/AbstractSelectionProcessor.java | 3 +- .../james/imap/processor/StatusProcessor.java | 3 +- 8 files changed, 76 insertions(+), 59 deletions(-) diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java index 61e5fe4a41..699974a7af 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java @@ -679,12 +679,43 @@ public class StoreMessageManager implements MessageManager { } - @Override - public Map<MessageUid, Flags> setFlags(final Flags flags, final FlagsUpdateMode flagsUpdateMode, final MessageRange set, MailboxSession mailboxSession) throws MailboxException { + public Optional<MailboxException> ensureFlagsWrite(Flags flags, FlagsUpdateMode flagsUpdateMode, MailboxSession mailboxSession) { + MailboxACL.Rfc4314Rights myRights = storeRightManager.myRights(mailbox, mailboxSession); - if (!isWriteable(mailboxSession)) { - throw new ReadOnlyException(getMailboxPath()); + if (flagsUpdateMode.equals(FlagsUpdateMode.REPLACE)) { + if (!myRights.contains(MailboxACL.Right.Write, MailboxACL.Right.WriteSeenFlag, MailboxACL.Right.DeleteMessages)) { + return Optional.of(new InsufficientRightsException("'stw' rights are needed to reset flags")); + } + return Optional.empty(); + } + + if (flags.contains(Flag.SEEN) && !myRights.contains(MailboxACL.Right.WriteSeenFlag)) { + return Optional.of(new InsufficientRightsException("'s' right is needed to modify seen flag")); + } + + if (flags.contains(Flag.DELETED) && !myRights.contains(MailboxACL.Right.DeleteMessages)) { + return Optional.of(new InsufficientRightsException("'t' right is needed to modify deleted flag")); + } + + boolean hasOtherFlagChanges = flags.getUserFlags().length > 0 + || flags.contains(Flag.FLAGGED) + || flags.contains(Flag.DRAFT) + || flags.contains(Flag.ANSWERED) + || flags.contains(Flag.RECENT); + + if (hasOtherFlagChanges && !myRights.contains(MailboxACL.Right.Write)) { + return Optional.of(new InsufficientRightsException("'w' right is needed to modify arbitrary flags")); } + return Optional.empty(); + } + + @Override + public Map<MessageUid, Flags> setFlags(Flags flags, FlagsUpdateMode flagsUpdateMode, MessageRange set, MailboxSession mailboxSession) throws MailboxException { + + ensureFlagsWrite(flags, flagsUpdateMode, mailboxSession) + .ifPresent(Throwing.<MailboxException>consumer(e -> { + throw e; + }).sneakyThrow()); trimFlags(flags, mailboxSession); @@ -709,25 +740,25 @@ public class StoreMessageManager implements MessageManager { @Override public Publisher<Map<MessageUid, Flags>> setFlagsReactive(Flags flags, FlagsUpdateMode flagsUpdateMode, MessageRange set, MailboxSession mailboxSession) { - if (!isWriteable(mailboxSession)) { - return Mono.error(new ReadOnlyException(getMailboxPath())); - } - - trimFlags(flags, mailboxSession); - - MessageMapper messageMapper = mapperFactory.getMessageMapper(mailboxSession); - - return messageMapper.executeReactive(messageMapper.updateFlagsReactive(getMailboxEntity(), new FlagsUpdateCalculator(flags, flagsUpdateMode), set)) - .flatMap(updatedFlags -> eventBus.dispatch(EventFactory.flagsUpdated() - .randomEventId() - .mailboxSession(mailboxSession) - .mailbox(getMailboxEntity()) - .updatedFlags(updatedFlags) - .build(), - new MailboxIdRegistrationKey(mailbox.getMailboxId())) - .thenReturn(updatedFlags.stream().collect(ImmutableMap.toImmutableMap( - UpdatedFlags::getUid, - UpdatedFlags::getNewFlags)))); + return ensureFlagsWrite(flags, flagsUpdateMode, mailboxSession) + .map(Mono::<Map<MessageUid, Flags>>error) + .orElseGet(() -> { + trimFlags(flags, mailboxSession); + + MessageMapper messageMapper = mapperFactory.getMessageMapper(mailboxSession); + + return messageMapper.executeReactive(messageMapper.updateFlagsReactive(getMailboxEntity(), new FlagsUpdateCalculator(flags, flagsUpdateMode), set)) + .flatMap(updatedFlags -> eventBus.dispatch(EventFactory.flagsUpdated() + .randomEventId() + .mailboxSession(mailboxSession) + .mailbox(getMailboxEntity()) + .updatedFlags(updatedFlags) + .build(), + new MailboxIdRegistrationKey(mailbox.getMailboxId())) + .thenReturn(updatedFlags.stream().collect(ImmutableMap.toImmutableMap( + UpdatedFlags::getUid, + UpdatedFlags::getNewFlags)))); + }); } /** diff --git a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRI.test b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRI.test index fc1bf6cdd6..860b3038f6 100644 --- a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRI.test +++ b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRI.test @@ -84,21 +84,17 @@ C: F11 FETCH 1 FLAGS S: \* 1 FETCH \(FLAGS \(\\Recent\)\) S: F11 OK FETCH completed. -# TODO Insert is not flags C: F12 STORE 1 +FLAGS (\Deleted) -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Recent\)\) -S: F12 OK STORE completed. +S: F12 NO STORE failed. Save failed. C: F13 STORE 1 +FLAGS (\Seen) -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Recent \\Seen\)\) -S: F13 OK STORE completed. +S: F13 NO STORE failed. Save failed. C: F14 STORE 1 +FLAGS (\Flagged) -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Flagged \\Recent \\Seen\)\) -S: F14 OK STORE completed. +S: F14 NO STORE failed. Save failed. C: F11 FETCH 1 FLAGS -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Flagged \\Recent \\Seen\)\) +S: \* 1 FETCH \(FLAGS \(\\Recent\)\) S: F11 OK FETCH completed. C: F15 EXPUNGE diff --git a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRS.test b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRS.test index d2bb291817..f6e06a156e 100644 --- a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRS.test +++ b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRS.test @@ -86,21 +86,18 @@ C: F11 FETCH 1 FLAGS S: \* 1 FETCH \(FLAGS \(\\Recent\)\) S: F11 OK FETCH completed. -# TODO I shall only be able to manipulate \\Seen... C: F12 STORE 1 +FLAGS (\Deleted) -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Recent\)\) -S: F12 OK STORE completed. +S: F12 NO STORE failed. Save failed. C: F13 STORE 1 +FLAGS (\Seen) -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Recent \\Seen\)\) +S: \* 1 FETCH \(FLAGS \(\\Recent \\Seen\)\) S: F13 OK STORE completed. C: F14 STORE 1 +FLAGS (\Flagged) -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Flagged \\Recent \\Seen\)\) -S: F14 OK STORE completed. +S: F14 NO STORE failed. Save failed. C: F11 FETCH 1 FLAGS -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Flagged \\Recent \\Seen\)\) +S: \* 1 FETCH \(FLAGS \(\\Recent \\Seen\)\) S: F11 OK FETCH completed. C: F15 EXPUNGE diff --git a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRT.test b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRT.test index 579e7905ff..be41d2cac4 100644 --- a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRT.test +++ b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRT.test @@ -90,17 +90,14 @@ C: F12 STORE 1 +FLAGS (\Deleted) S: \* 1 FETCH \(FLAGS \(\\Deleted \\Recent\)\) S: F12 OK STORE completed. -# TODO I shall only be able to manipulate \\Deleted... C: F13 STORE 1 +FLAGS (\Seen) -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Recent \\Seen\)\) -S: F13 OK STORE completed. +S: F13 NO STORE failed. Save failed. C: F14 STORE 1 +FLAGS (\Flagged) -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Flagged \\Recent \\Seen\)\) -S: F14 OK STORE completed. +S: F14 NO STORE failed. Save failed. C: F11 FETCH 1 FLAGS -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Flagged \\Recent \\Seen\)\) +S: \* 1 FETCH \(FLAGS \(\\Deleted \\Recent\)\) S: F11 OK FETCH completed. C: F15 EXPUNGE diff --git a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRTE.test b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRTE.test index eef28d57b9..892cdaab8f 100644 --- a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRTE.test +++ b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRTE.test @@ -90,17 +90,14 @@ C: F12 STORE 1 +FLAGS (\Deleted) S: \* 1 FETCH \(FLAGS \(\\Deleted \\Recent\)\) S: F12 OK STORE completed. -# TODO I shall only be able to manipulate \\Deleted... C: F13 STORE 1 +FLAGS (\Seen) -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Recent \\Seen\)\) -S: F13 OK STORE completed. +S: F13 NO STORE failed. Save failed. C: F14 STORE 1 +FLAGS (\Flagged) -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Flagged \\Recent \\Seen\)\) -S: F14 OK STORE completed. +S: F14 NO STORE failed. Save failed. C: F11 FETCH 1 FLAGS -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Flagged \\Recent \\Seen\)\) +S: \* 1 FETCH \(FLAGS \(\\Deleted \\Recent\)\) S: F11 OK FETCH completed. C: F15 EXPUNGE diff --git a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRW.test b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRW.test index 569879821d..cb96dcf0d2 100644 --- a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRW.test +++ b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/SharingAccessLRW.test @@ -86,21 +86,18 @@ C: F11 FETCH 1 FLAGS S: \* 1 FETCH \(FLAGS \(\\Recent\)\) S: F11 OK FETCH completed. -# TODO I shall only be able to manipulate \\Seen... C: F12 STORE 1 +FLAGS (\Deleted) -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Recent\)\) -S: F12 OK STORE completed. +S: F12 NO STORE failed. Save failed. C: F13 STORE 1 +FLAGS (\Seen) -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Recent \\Seen\)\) -S: F13 OK STORE completed. +S: F13 NO STORE failed. Save failed. C: F14 STORE 1 +FLAGS (\Flagged) -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Flagged \\Recent \\Seen\)\) +S: \* 1 FETCH \(FLAGS \(\\Flagged \\Recent\)\) S: F14 OK STORE completed. C: F11 FETCH 1 FLAGS -S: \* 1 FETCH \(FLAGS \(\\Deleted \\Flagged \\Recent \\Seen\)\) +S: \* 1 FETCH \(FLAGS \(\\Flagged \\Recent\)\) S: F11 OK FETCH completed. C: F15 EXPUNGE diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java index cd32c1ad30..1ca548e699 100644 --- a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java +++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java @@ -404,8 +404,9 @@ abstract class AbstractSelectionProcessor<R extends AbstractMailboxSelectionRequ .<MessageManager>handle(Throwing.biConsumer((mailbox, sink) -> { if (mailboxManager.hasRight(mailbox.getMailboxEntity(), MailboxACL.Right.Read, mailboxSession)) { sink.next(mailbox); + } else { + sink.error(new InsufficientRightsException("'r' right is needed to select a mailbox")); } - sink.error(new InsufficientRightsException("'r' right is needed to select a mailbox")); })) .flatMap(Throwing.function(mailbox -> selectMailbox(session, responder, mailbox, currentMailbox) .flatMap(Throwing.function(sessionMailbox -> diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java index 361fc8f5b0..bade56b99b 100644 --- a/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java +++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java @@ -127,8 +127,9 @@ public class StatusProcessor extends AbstractMailboxProcessor<StatusRequest> imp .<MessageManager>handle(Throwing.biConsumer((mailbox, sink) -> { if (getMailboxManager().hasRight(mailbox.getMailboxEntity(), MailboxACL.Right.Read, mailboxSession)) { sink.next(mailbox); + } else { + sink.error(new InsufficientRightsException("'r' right is needed to status a mailbox")); } - sink.error(new InsufficientRightsException("'r' right is needed to status a mailbox")); })) .flatMap(mailbox -> sendStatus(mailbox, statusDataItems, responder, session, mailboxSession)); } --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org For additional commands, e-mail: notifications-h...@james.apache.org