Skip to content

Commit

Permalink
James 3945 rights positioning for subaddressing (apache#2419)
Browse files Browse the repository at this point in the history
  • Loading branch information
florentos17 authored Sep 27, 2024
1 parent 1705d89 commit 81b61ed
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public UnionMailboxACLResolver(MailboxACL userGlobalACL, MailboxACL groupGlobalA
protected static boolean applies(EntryKey aclKey, EntryKey queryKey, Username resourceOwner) {
final String aclKeyName = aclKey.getName();
final NameType aclKeyNameType = aclKey.getNameType();
if (SpecialName.anybody.name().equals(aclKeyName)) {
if (SpecialName.anyone.name().equals(aclKeyName)) {
/* this works also for unauthenticated users */
return true;
} else if (queryKey != null) {
Expand Down Expand Up @@ -208,7 +208,7 @@ protected static boolean applies(EntryKey aclKey, EntryKey queryKey, Username re
throw new IllegalStateException("Unexpected " + NameType.class.getName() + "." + queryKey.getNameType());
}
} else {
/* non-anybody ACL keys do not match non-authenticated queries */
/* non-anyone ACL keys do not match non-authenticated queries */
return false;
}
}
Expand All @@ -231,7 +231,7 @@ public MailboxACL applyGlobalACL(MailboxACL resourceACL) throws UnsupportedRight
* <li>if the given user is the owner of the given mailbox also the "owner"
* entry is included</li>
* <li>the "authenticated" entry</li>
* <li>the "anybody" entry</li>
* <li>the "anyone" entry</li>
* </ul>
*
* (2) if {@code queryKey} is a group key, the rights included come from the
Expand All @@ -241,7 +241,7 @@ public MailboxACL applyGlobalACL(MailboxACL resourceACL) throws UnsupportedRight
* <li>if the given group is the owner of the given mailbox also the "owner"
* entry is included</li>
* <li>the "authenticated" entry (*)</li>
* <li>the "anybody" entry</li>
* <li>the "anyone" entry</li>
* </ul>
*
* (3) if {@code queryKey} is a special key, the rights included come from
Expand All @@ -250,7 +250,7 @@ public MailboxACL applyGlobalACL(MailboxACL resourceACL) throws UnsupportedRight
* <li>the entry literally matching the given special name</li>
* <li>the "authenticated" entry if the {@code queryKey} is the "owner"
* query key (*)</li>
* <li>the "anybody" entry</li>
* <li>the "anyone" entry</li>
* </ul>
*
* (*) This is the most questionable case: should "authenticated" ACL
Expand All @@ -259,7 +259,7 @@ public MailboxACL applyGlobalACL(MailboxACL resourceACL) throws UnsupportedRight
* to be set explicitly for the members of "group1". And secondly the group
* rights are actually queried and applied only for authenticated users. To
* put it in other words, the hasRight(user, right, ...) call can be
* performed only either with user == null (only "anybody" rights will
* performed only either with user == null (only "anyone" rights will
* apply) or with a user name which is there only after the user was
* authenticated.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public enum NameType {
* Special name literals.
*/
public enum SpecialName {
anybody, authenticated, owner
anyone, authenticated, owner
}

/**
Expand Down Expand Up @@ -634,8 +634,8 @@ public final int hashCode() {
}
}

public static final EntryKey ANYBODY_KEY;
public static final EntryKey ANYBODY_NEGATIVE_KEY;
public static final EntryKey ANYONE_KEY;
public static final EntryKey ANYONE_NEGATIVE_KEY;
public static final EntryKey AUTHENTICATED_KEY;
public static final EntryKey AUTHENTICATED_NEGATIVE_KEY;
public static final MailboxACL EMPTY;
Expand All @@ -651,8 +651,8 @@ public final int hashCode() {

static {
try {
ANYBODY_KEY = new EntryKey(SpecialName.anybody.name(), NameType.special, false);
ANYBODY_NEGATIVE_KEY = new EntryKey(SpecialName.anybody.name(), NameType.special, true);
ANYONE_KEY = new EntryKey(SpecialName.anyone.name(), NameType.special, false);
ANYONE_NEGATIVE_KEY = new EntryKey(SpecialName.anyone.name(), NameType.special, true);
AUTHENTICATED_KEY = new EntryKey(SpecialName.authenticated.name(), NameType.special, false);
AUTHENTICATED_NEGATIVE_KEY = new EntryKey(SpecialName.authenticated.name(), NameType.special, true);
EMPTY = new MailboxACL();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ class UnionMailboxACLResolverTest {
private static final Username USER_1 = Username.of("user1");
private static final Username USER_2 = Username.of("user2");

private MailboxACL anybodyRead;
private MailboxACL anybodyReadNegative;
private MailboxACL anyoneRead;
private MailboxACL anyoneReadNegative;
private UnionMailboxACLResolver anyoneReadListGlobal;
private MailboxACL authenticatedRead;
private UnionMailboxACLResolver authenticatedReadListWriteGlobal;
Expand All @@ -57,7 +57,7 @@ void setUp() throws Exception {

MailboxACL acl = new MailboxACL(new Entry(MailboxACL.AUTHENTICATED_KEY, MailboxACL.FULL_RIGHTS));
authenticatedReadListWriteGlobal = new UnionMailboxACLResolver(acl, acl);
acl = new MailboxACL(new Entry(MailboxACL.ANYBODY_KEY, Rfc4314Rights.fromSerializedRfc4314Rights("rl")));
acl = new MailboxACL(new Entry(MailboxACL.ANYONE_KEY, Rfc4314Rights.fromSerializedRfc4314Rights("rl")));
anyoneReadListGlobal = new UnionMailboxACLResolver(acl, acl);
acl = new MailboxACL(new Entry(MailboxACL.OWNER_KEY, MailboxACL.FULL_RIGHTS));
ownerFullGlobal = new UnionMailboxACLResolver(acl, acl);
Expand All @@ -66,8 +66,8 @@ void setUp() throws Exception {
user1Read = new MailboxACL(new Entry(user1Key, Rfc4314Rights.fromSerializedRfc4314Rights("r")));
user1ReadNegative = new MailboxACL(new Entry(EntryKey.createUserEntryKey(USER_1, true), Rfc4314Rights.fromSerializedRfc4314Rights("r")));

anybodyRead = new MailboxACL(new Entry(MailboxACL.ANYBODY_KEY, Rfc4314Rights.fromSerializedRfc4314Rights("r")));
anybodyReadNegative = new MailboxACL(new Entry(MailboxACL.ANYBODY_NEGATIVE_KEY, Rfc4314Rights.fromSerializedRfc4314Rights("r")));
anyoneRead = new MailboxACL(new Entry(MailboxACL.ANYONE_KEY, Rfc4314Rights.fromSerializedRfc4314Rights("r")));
anyoneReadNegative = new MailboxACL(new Entry(MailboxACL.ANYONE_NEGATIVE_KEY, Rfc4314Rights.fromSerializedRfc4314Rights("r")));

authenticatedRead = new MailboxACL(new Entry(MailboxACL.AUTHENTICATED_KEY, Rfc4314Rights.fromSerializedRfc4314Rights("r")));
authenticatedReadNegative = new MailboxACL(new Entry(MailboxACL.AUTHENTICATED_NEGATIVE_KEY, Rfc4314Rights.fromSerializedRfc4314Rights("r")));
Expand All @@ -82,7 +82,7 @@ void testAppliesNullUser() throws UnsupportedRightException {

assertThat(UnionMailboxACLResolver.applies(user1Key, null, USER_1)).isFalse();
assertThat(UnionMailboxACLResolver.applies(user2Key, null, USER_1)).isFalse();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.ANYBODY_KEY, null, USER_1)).isTrue();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.ANYONE_KEY, null, USER_1)).isTrue();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.AUTHENTICATED_KEY, null, USER_1)).isFalse();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.OWNER_KEY, null, USER_1)).isFalse();
}
Expand All @@ -92,21 +92,21 @@ void testAppliesUser() throws UnsupportedRightException {
/* requester is the resource owner */
assertThat(UnionMailboxACLResolver.applies(user1Key, user1Key, USER_1)).isTrue();
assertThat(UnionMailboxACLResolver.applies(user2Key, user1Key, USER_1)).isFalse();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.ANYBODY_KEY, user1Key, USER_1)).isTrue();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.ANYONE_KEY, user1Key, USER_1)).isTrue();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.AUTHENTICATED_KEY, user1Key, USER_1)).isTrue();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.OWNER_KEY, user1Key, USER_1)).isTrue();

/* requester is not the resource user */
assertThat(UnionMailboxACLResolver.applies(user1Key, user1Key, USER_2)).isTrue();
assertThat(UnionMailboxACLResolver.applies(user2Key, user1Key, USER_2)).isFalse();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.ANYBODY_KEY, user1Key, USER_2)).isTrue();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.ANYONE_KEY, user1Key, USER_2)).isTrue();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.AUTHENTICATED_KEY, user1Key, USER_2)).isTrue();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.OWNER_KEY, user1Key, USER_2)).isFalse();

/* owner query */
assertThat(UnionMailboxACLResolver.applies(user1Key, MailboxACL.OWNER_KEY, USER_1)).isFalse();
assertThat(UnionMailboxACLResolver.applies(user2Key, MailboxACL.OWNER_KEY, USER_1)).isFalse();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.ANYBODY_KEY, MailboxACL.OWNER_KEY, USER_1)).isTrue();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.ANYONE_KEY, MailboxACL.OWNER_KEY, USER_1)).isTrue();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.AUTHENTICATED_KEY, MailboxACL.OWNER_KEY, USER_1)).isTrue();
assertThat(UnionMailboxACLResolver.applies(MailboxACL.OWNER_KEY, MailboxACL.OWNER_KEY, USER_1)).isTrue();
}
Expand Down Expand Up @@ -156,38 +156,38 @@ void testResolveRightsNullUser() throws UnsupportedRightException {
.isFalse();

assertThat(
anyoneReadListGlobal.resolveRights(null, anybodyRead, USER_1)
anyoneReadListGlobal.resolveRights(null, anyoneRead, USER_1)
.contains(MailboxACL.Right.Read))
.isTrue();
assertThat(
anyoneReadListGlobal.resolveRights(null, anybodyReadNegative, USER_1)
anyoneReadListGlobal.resolveRights(null, anyoneReadNegative, USER_1)
.contains(MailboxACL.Right.Read))
.isFalse();

assertThat(
authenticatedReadListWriteGlobal.resolveRights(null, anybodyRead, USER_1)
authenticatedReadListWriteGlobal.resolveRights(null, anyoneRead, USER_1)
.contains(MailboxACL.Right.Read))
.isTrue();
assertThat(
authenticatedReadListWriteGlobal.resolveRights(null, anybodyReadNegative, USER_1)
authenticatedReadListWriteGlobal.resolveRights(null, anyoneReadNegative, USER_1)
.contains(MailboxACL.Right.Read))
.isFalse();

assertThat(
ownerFullGlobal.resolveRights(null, anybodyRead, USER_1)
ownerFullGlobal.resolveRights(null, anyoneRead, USER_1)
.contains(MailboxACL.Right.Read))
.isTrue();
assertThat(
ownerFullGlobal.resolveRights(null, anybodyReadNegative, USER_1)
ownerFullGlobal.resolveRights(null, anyoneReadNegative, USER_1)
.contains(MailboxACL.Right.Read))
.isFalse();

assertThat(
noGlobals.resolveRights(null, anybodyRead, USER_1)
noGlobals.resolveRights(null, anyoneRead, USER_1)
.contains(MailboxACL.Right.Read))
.isTrue();
assertThat(
noGlobals.resolveRights(null, anybodyReadNegative, USER_1)
noGlobals.resolveRights(null, anyoneReadNegative, USER_1)
.contains(MailboxACL.Right.Read))
.isFalse();

Expand Down Expand Up @@ -326,38 +326,38 @@ void testResolveRightsUserSelfOwner() throws UnsupportedRightException {
.isFalse();

assertThat(
anyoneReadListGlobal.resolveRights(USER_1, anybodyRead, USER_1)
anyoneReadListGlobal.resolveRights(USER_1, anyoneRead, USER_1)
.contains(MailboxACL.Right.Read))
.isTrue();
assertThat(
anyoneReadListGlobal.resolveRights(USER_1, anybodyReadNegative, USER_1)
anyoneReadListGlobal.resolveRights(USER_1, anyoneReadNegative, USER_1)
.contains(MailboxACL.Right.Read))
.isFalse();

assertThat(
authenticatedReadListWriteGlobal.resolveRights(USER_1, anybodyRead, USER_1)
authenticatedReadListWriteGlobal.resolveRights(USER_1, anyoneRead, USER_1)
.contains(MailboxACL.Right.Read))
.isTrue();
assertThat(
authenticatedReadListWriteGlobal.resolveRights(USER_1, anybodyReadNegative, USER_1)
authenticatedReadListWriteGlobal.resolveRights(USER_1, anyoneReadNegative, USER_1)
.contains(MailboxACL.Right.Read))
.isFalse();

assertThat(
ownerFullGlobal.resolveRights(USER_1, anybodyRead, USER_1)
ownerFullGlobal.resolveRights(USER_1, anyoneRead, USER_1)
.contains(MailboxACL.Right.Read))
.isTrue();
assertThat(
ownerFullGlobal.resolveRights(USER_1, anybodyReadNegative, USER_1)
ownerFullGlobal.resolveRights(USER_1, anyoneReadNegative, USER_1)
.contains(MailboxACL.Right.Read))
.isFalse();

assertThat(
noGlobals.resolveRights(USER_1, anybodyRead, USER_1)
noGlobals.resolveRights(USER_1, anyoneRead, USER_1)
.contains(MailboxACL.Right.Read))
.isTrue();
assertThat(
noGlobals.resolveRights(USER_1, anybodyReadNegative, USER_1)
noGlobals.resolveRights(USER_1, anyoneReadNegative, USER_1)
.contains(MailboxACL.Right.Read))
.isFalse();

Expand Down Expand Up @@ -476,38 +476,38 @@ void testResolveRightsUserNotOwner() throws UnsupportedRightException {
.isFalse();

assertThat(
anyoneReadListGlobal.resolveRights(USER_1, anybodyRead, USER_2)
anyoneReadListGlobal.resolveRights(USER_1, anyoneRead, USER_2)
.contains(MailboxACL.Right.Read))
.isTrue();
assertThat(
anyoneReadListGlobal.resolveRights(USER_1, anybodyReadNegative, USER_2)
anyoneReadListGlobal.resolveRights(USER_1, anyoneReadNegative, USER_2)
.contains(MailboxACL.Right.Read))
.isFalse();

assertThat(
authenticatedReadListWriteGlobal.resolveRights(USER_1, anybodyRead, USER_2)
authenticatedReadListWriteGlobal.resolveRights(USER_1, anyoneRead, USER_2)
.contains(MailboxACL.Right.Read))
.isTrue();
assertThat(
authenticatedReadListWriteGlobal.resolveRights(USER_1, anybodyReadNegative, USER_2)
authenticatedReadListWriteGlobal.resolveRights(USER_1, anyoneReadNegative, USER_2)
.contains(MailboxACL.Right.Read))
.isFalse();

assertThat(
ownerFullGlobal.resolveRights(USER_1, anybodyRead, USER_2)
ownerFullGlobal.resolveRights(USER_1, anyoneRead, USER_2)
.contains(MailboxACL.Right.Read))
.isTrue();
assertThat(
ownerFullGlobal.resolveRights(USER_1, anybodyReadNegative, USER_2)
ownerFullGlobal.resolveRights(USER_1, anyoneReadNegative, USER_2)
.contains(MailboxACL.Right.Read))
.isFalse();

assertThat(
noGlobals.resolveRights(USER_1, anybodyRead, USER_2)
noGlobals.resolveRights(USER_1, anyoneRead, USER_2)
.contains(MailboxACL.Right.Read))
.isTrue();
assertThat(
noGlobals.resolveRights(USER_1, anybodyReadNegative, USER_2)
noGlobals.resolveRights(USER_1, anyoneReadNegative, USER_2)
.contains(MailboxACL.Right.Read))
.isFalse();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ void testNegativeOwner() {
}

@Test
void testAnybody() {
assertThat(EntryKey.deserialize(SpecialName.anybody.toString()))
.isEqualTo(new EntryKey(SpecialName.anybody.toString(), NameType.special, false));
void testAnyone() {
assertThat(EntryKey.deserialize(SpecialName.anyone.toString()))
.isEqualTo(new EntryKey(SpecialName.anyone.toString(), NameType.special, false));
}

@Test
void testNegativeAnybody() {
assertThat(EntryKey.deserialize(MailboxACL.DEFAULT_NEGATIVE_MARKER + SpecialName.anybody.toString()))
.isEqualTo(new EntryKey(SpecialName.anybody.toString(), NameType.special, true));
void testNegativeAnyone() {
assertThat(EntryKey.deserialize(MailboxACL.DEFAULT_NEGATIVE_MARKER + SpecialName.anyone.toString()))
.isEqualTo(new EntryKey(SpecialName.anyone.toString(), NameType.special, true));
}

@Test
Expand Down Expand Up @@ -128,15 +128,15 @@ void testSerializeNegativeOwner() {
}

@Test
void testSerializeAnybody() {
assertThat(new EntryKey(SpecialName.anybody.toString(), NameType.special, false).serialize())
.isEqualTo(SpecialName.anybody.toString());
void testSerializeAnyone() {
assertThat(new EntryKey(SpecialName.anyone.toString(), NameType.special, false).serialize())
.isEqualTo(SpecialName.anyone.toString());
}

@Test
void testSerializeNegativeAnybody() {
assertThat(new EntryKey(SpecialName.anybody.toString(), NameType.special, true).serialize())
.isEqualTo(MailboxACL.DEFAULT_NEGATIVE_MARKER + SpecialName.anybody.toString());
void testSerializeNegativeAnyone() {
assertThat(new EntryKey(SpecialName.anyone.toString(), NameType.special, true).serialize())
.isEqualTo(MailboxACL.DEFAULT_NEGATIVE_MARKER + SpecialName.anyone.toString());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,41 @@ S: a5 OK DELETEACL completed.
C: a6 DELETEACL BAD bob
S: a6 NO DELETEACL failed. Mailbox not found.

C: a7 SETACL INBOX bob lr
S: a7 OK SETACL completed.
C: a7 GETACL INBOX
S: \* ACL "INBOX" "owner" "aeiklprstwx"
S: a7 OK GETACL completed.

C: a8 SETACL INBOX bob l
S: a8 OK SETACL completed.

C: a9 GETACL INBOX
S: \* ACL "INBOX" "bob" "l" "owner" "aeiklprstwx"
S: a9 OK GETACL completed.

C: a10 SETACL INBOX anyone r
S: a10 OK SETACL completed.

C: a11 GETACL INBOX
S: \* ACL "INBOX" "bob" "l" "anyone" "r" "owner" "aeiklprstwx"|\* ACL "INBOX" "anyone" "r" "bob" "l" "owner" "aeiklprstwx"
S: a11 OK GETACL completed.

C: a12 SETACL INBOX -bob r
S: a12 OK SETACL completed.

C: a13 GETACL INBOX
S: \* ACL "INBOX" "bob" "l" "anyone" "r" "-bob" "r" "owner" "aeiklprstwx"|\* ACL "INBOX" "-bob" "r" "anyone" "r" "bob" "l" "owner" "aeiklprstwx"
S: a13 OK GETACL completed.

C: a14 SETACL INBOX -bob -r
S: a14 OK SETACL completed.

C: a15 GETACL INBOX
S: \* ACL "INBOX" "bob" "l" "anyone" "r" "owner" "aeiklprstwx"|\* ACL "INBOX" "anyone" "r" "bob" "l" "owner" "aeiklprstwx"
S: a15 OK GETACL completed.

C: a16 SETACL INBOX anyone -r
S: a16 OK SETACL completed.

C: a17 GETACL INBOX
S: \* ACL "INBOX" "bob" "l" "owner" "aeiklprstwx"
S: a17 OK GETACL completed.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import org.apache.james.mpt.api.ImapHostSystem;
import org.apache.james.mpt.imapmailbox.jpa.host.JPAHostSystemExtension;
import org.apache.james.mpt.imapmailbox.suite.AuthenticatedState;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

public class JpaAuthenticatedStateTest extends AuthenticatedState {
Expand All @@ -32,4 +34,10 @@ public class JpaAuthenticatedStateTest extends AuthenticatedState {
protected ImapHostSystem createImapHostSystem() {
return hostSystemExtension.getHostSystem();
}

@Disabled("Jpa does not implement right storing for mailboxes so this test can be ignored")
@Test
@Override
public void rightsCommandsShouldBeSupported() {
}
}
Loading

0 comments on commit 81b61ed

Please sign in to comment.