/** * ACL is sensible information and as such we should expose as few information as possible * to users. This method allows to filter a {@link MailboxACL} in order to present it to * the connected user. */ @VisibleForTesting static MailboxACL filteredForSession(Mailbox mailbox, MailboxACL acl, MailboxSession mailboxSession) throws UnsupportedRightException { if (mailbox.generateAssociatedPath().belongsTo(mailboxSession)) { return acl; } MailboxACL.EntryKey userAsKey = MailboxACL.EntryKey.createUserEntryKey(mailboxSession.getUser().getUserName()); Rfc4314Rights rights = acl.getEntries().getOrDefault(userAsKey, new Rfc4314Rights()); if (rights.contains(MailboxACL.Right.Administer)) { return acl; } return new MailboxACL(ImmutableMap.of(userAsKey, rights)); } }
@Test public void getValueShouldReturnEmptyWhenNone() throws UnsupportedRightException { assertThat(Rfc4314Rights.fromSerializedRfc4314Rights("").list()).isEmpty(); }
@Override protected void doEncode(ImapMessage acceptableMessage, ImapResponseComposer composer, ImapSession session) throws IOException { final ACLResponse aclResponse = (ACLResponse) acceptableMessage; final Map<EntryKey, Rfc4314Rights> entries = aclResponse.getAcl().getEntries(); composer.untagged(); composer.commandName(ImapConstants.ACL_RESPONSE_NAME); String mailboxName = aclResponse.getMailboxName(); composer.mailbox(mailboxName == null ? "" : mailboxName); if (entries != null) { for (Entry<EntryKey, Rfc4314Rights> entry : entries.entrySet()) { String identifier = entry.getKey().serialize(); composer.quote(identifier); String rights = entry.getValue().serialize(); composer.quote(rights == null ? "" : rights); } } composer.end(); }
return toListRightsArray(positiveNegativePair[NEGATIVE_INDEX]); } else { return toListRightsArray(positiveNegativePair[POSITIVE_INDEX].except(positiveNegativePair[NEGATIVE_INDEX]));
@Test public void testResolveRightsNullUserGlobals() throws UnsupportedRightException { assertThat( anyoneReadListGlobal.resolveRights(null, groupMembershipResolver, user1Read, USER_2, false) .contains(MailboxACL.Right.Read)) .isTrue(); assertThat( authenticatedReadListWriteGlobal.resolveRights(null, groupMembershipResolver, MailboxACL.EMPTY, USER_2, false) .contains(MailboxACL.Right.Read)) .isFalse(); assertThat( ownerFullGlobal.resolveRights(null, groupMembershipResolver, MailboxACL.EMPTY, USER_2, false) .contains(MailboxACL.Right.Read)) .isFalse(); assertThat( noGlobals.resolveRights(null, groupMembershipResolver, MailboxACL.EMPTY, USER_2, false) .contains(MailboxACL.Right.Read)) .isFalse(); assertThat( negativeGroup2FullGlobal.resolveRights(null, groupMembershipResolver, MailboxACL.EMPTY, USER_2, false) .contains(MailboxACL.Right.Read)) .isFalse(); }
private void addMessageToMailboxes(MailboxMessage mailboxMessage, Set<MailboxId> mailboxIds, MailboxSession mailboxSession) throws MailboxException { MessageIdMapper messageIdMapper = mailboxSessionMapperFactory.getMessageIdMapper(mailboxSession); MailboxMapper mailboxMapper = mailboxSessionMapperFactory.getMailboxMapper(mailboxSession); for (MailboxId mailboxId : mailboxIds) { boolean shouldPreserveFlags = mailboxManager.myRights(mailboxId, mailboxSession).contains(Right.Write); SimpleMailboxMessage copy = SimpleMailboxMessage.from(mailboxMessage) .mailboxId(mailboxId) .flags( FlagsFactory .builder() .flags(mailboxMessage.createFlags()) .filteringFlags( FlagsFilter.builder() .systemFlagFilter(f -> shouldPreserveFlags) .userFlagFilter(f -> shouldPreserveFlags) .build()) .build()) .build(); save(mailboxSession, messageIdMapper, copy); dispatcher.added(mailboxSession, mailboxMapper.findMailboxById(mailboxId), copy); } }
@Test public void changedEntriesShouldReturnEntryWhenChangedEntry() throws Exception { PositiveUserACLDiff positiveUserAclDiff = PositiveUserACLDiff.computeDiff( MailboxACL.EMPTY.apply( MailboxACL.command() .key(USER_ENTRY_KEY) .rights(Right.Administer) .asAddition()), MailboxACL.EMPTY.apply( MailboxACL.command() .key(USER_ENTRY_KEY) .rights(Right.Lookup) .asAddition())); assertThat(positiveUserAclDiff.changedEntries()) .containsOnly(new Entry(USER_ENTRY_KEY, new Rfc4314Rights(MailboxACL.Right.Lookup))); }
@Override protected void doEncode(ImapMessage acceptableMessage, ImapResponseComposer composer, ImapSession session) throws IOException { final ListRightsResponse listRightsResponse = (ListRightsResponse) acceptableMessage; composer.untagged(); composer.commandName(ImapConstants.LISTRIGHTS_RESPONSE_NAME); String mailboxName = listRightsResponse.getMailboxName(); composer.mailbox(mailboxName == null ? "" : mailboxName); String identifier = listRightsResponse.getIdentifier(); composer.quote(identifier); Rfc4314Rights[] rights = listRightsResponse.getRights(); for (Rfc4314Rights entry : rights) { composer.quote(entry.serialize()); } composer.end(); }
@Test public void fullRightsShouldContainsAllRights() { assertThat(full.list()).containsOnly( Administer, PerformExpunge, Insert, CreateMailbox, Lookup, Post, Read, WriteSeenFlag, DeleteMessages, Write, DeleteMailbox); }
private boolean checkSeenFlag(Rfc4314Rights rights, Flags sharedPermanentFlags) { return sharedPermanentFlags.contains(Flags.Flag.SEEN) && rights.contains(Right.WriteSeenFlag); }
public boolean isReadWrite(MailboxSession session, Mailbox mailbox, Flags sharedPermanentFlags) throws UnsupportedRightException { Rfc4314Rights rights = myRights(mailbox, session); /* * then go through shared flags. RFC 4314 section 4: * Changing flags: STORE * - the server MUST check if the user has "t" (expunge) right * - when the user modifies \Deleted flag "s" (seen) right * - when the user modifies \Seen flag "w" (write) - for all other message flags. */ return rights.contains(Right.Insert) || rights.contains(Right.PerformExpunge) || checkDeleteFlag(rights, sharedPermanentFlags) || checkSeenFlag(rights, sharedPermanentFlags) || checkWriteFlag(rights, sharedPermanentFlags); }
private boolean checkDeleteFlag(Rfc4314Rights rights, Flags sharedPermanentFlags) { return sharedPermanentFlags.contains(Flags.Flag.DELETED) && rights.contains(Right.DeleteMessages); }
public static Rfc4314Rights deserialize(String serialized) throws UnsupportedRightException { return new Rfc4314Rights(serialized); }
public String toString() { return serialize(); }
@Test void twoConcurrentUpdatesWhenStoredShouldReturnACEWithTwoEntries(CassandraCluster cassandra) throws Exception { CountDownLatch countDownLatch = new CountDownLatch(2); MailboxACL.EntryKey keyBenwa = new MailboxACL.EntryKey("benwa", MailboxACL.NameType.user, false); MailboxACL.Rfc4314Rights rights = new MailboxACL.Rfc4314Rights(MailboxACL.Right.Read); cassandraACLMapper.updateACL(MAILBOX_ID, MailboxACL.command().key(keyBenwa).rights(rights).asAddition()); MailboxACL.EntryKey keyBob = new MailboxACL.EntryKey("bob", MailboxACL.NameType.user, false); MailboxACL.EntryKey keyAlice = new MailboxACL.EntryKey("alice", MailboxACL.NameType.user, false); Future<Boolean> future1 = performACLUpdateInExecutor(cassandra, executor, keyBob, rights, countDownLatch::countDown); Future<Boolean> future2 = performACLUpdateInExecutor(cassandra, executor, keyAlice, rights, countDownLatch::countDown); awaitAll(future1, future2); assertThat(cassandraACLMapper.getACL(MAILBOX_ID).join()) .isEqualTo(new MailboxACL().union(keyBob, rights).union(keyAlice, rights).union(keyBenwa, rights)); }
@Test public void allExceptShouldReturnAllButProvidedRight() throws UnsupportedRightException { assertThat(Rfc4314Rights.allExcept(Lookup)) .isEqualTo(new Rfc4314Rights( DeleteMessages, Insert, Read, Administer, Write, WriteSeenFlag, PerformExpunge, CreateMailbox, Post, DeleteMailbox)); }
public Entry(String key, Right... rights) throws UnsupportedRightException { this(EntryKey.deserialize(key), new Rfc4314Rights(rights)); }
public static Rfc4314Rights fromSerializedRfc4314Rights(String serializedRfc4314Rights) throws UnsupportedRightException { return new Rfc4314Rights(rightListFromSerializedRfc4314Rights(serializedRfc4314Rights)); }
@Test public void containsShouldReturnTrueWhenNonRightsPresent() throws UnsupportedRightException { assertThat(lprs.contains()).isTrue(); }
@Test public void containsShouldReturnFalseWhenAtLeastOneRightNotPresent() throws UnsupportedRightException { assertThat(lprs.contains(Lookup, Write)).isFalse(); }