This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit b9e7792ca75a42241bcf495598b4c7122e80f11c
Author: Florent Azavant <fazav...@linagora.com>
AuthorDate: Wed Nov 6 10:50:12 2024 +0100

    [ISSUE-5314] refactored `Rights.scala` to use `EntryKey` instead of 
`Username`
---
 .../org/apache/james/mailbox/model/MailboxACL.java | 14 +++--
 .../apache/james/jmap/json/MailboxSerializer.scala | 12 ++--
 .../scala/org/apache/james/jmap/mail/Rights.scala  | 43 ++++++-------
 .../james/jmap/json/MailboxSerializationTest.scala |  7 ++-
 .../org/apache/james/jmap/mail/RightsTest.scala    | 73 +++++++++++-----------
 5 files changed, 78 insertions(+), 71 deletions(-)

diff --git 
a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxACL.java 
b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxACL.java
index 34204359b5..575763647e 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxACL.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxACL.java
@@ -375,15 +375,19 @@ public class MailboxACL {
         }
 
         public static EntryKey createUserEntryKey(Username name) {
-            return new EntryKey(name.asString(), NameType.user, POSITIVE_KEY);
+            return createUserEntryKey(name.asString());
         }
 
-        public static EntryKey createNegativeUserEntryKey(Username name) {
-            return new EntryKey(name.asString(), NameType.user, NEGATIVE_KEY);
+        public static EntryKey createUserEntryKey(Username name, boolean 
negative) {
+            return createUserEntryKey(name.asString(), negative);
         }
 
-        public static EntryKey createUserEntryKey(Username name, boolean 
negative) {
-            return new EntryKey(name.asString(), NameType.user, negative);
+        public static EntryKey createUserEntryKey(String name) {
+            return createUserEntryKey(name, POSITIVE_KEY);
+        }
+
+        public static EntryKey createUserEntryKey(String name, boolean 
negative) {
+            return new EntryKey(name, NameType.user, negative);
         }
 
         private final String name;
diff --git 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/MailboxSerializer.scala
 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/MailboxSerializer.scala
index d22e9c4a95..f4c027f675 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/MailboxSerializer.scala
+++ 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/MailboxSerializer.scala
@@ -22,13 +22,13 @@ package org.apache.james.jmap.json
 import eu.timepit.refined
 import eu.timepit.refined._
 import jakarta.inject.Inject
-import org.apache.james.core.{Domain, Username}
+import org.apache.james.core.Domain
 import org.apache.james.jmap.core.CapabilityIdentifier.CapabilityIdentifier
 import org.apache.james.jmap.core.Id.IdConstraint
 import org.apache.james.jmap.core.{ClientId, Properties, SetError, UuidState}
 import org.apache.james.jmap.mail.{Ids, IsSubscribed, Mailbox, 
MailboxChangesRequest, MailboxChangesResponse, MailboxCreationId, 
MailboxCreationRequest, MailboxCreationResponse, MailboxGetRequest, 
MailboxGetResponse, MailboxNamespace, MailboxPatchObject, MailboxRights, 
MailboxSetRequest, MailboxSetResponse, MailboxUpdateResponse, MayAddItems, 
MayCreateChild, MayDelete, MayReadItems, MayRemoveItems, MayRename, 
MaySetKeywords, MaySetSeen, MaySubmit, NotFound, Quota, QuotaId, QuotaRoot, Quo 
[...]
 import org.apache.james.mailbox.Role
-import org.apache.james.mailbox.model.MailboxACL.{Right => JavaRight}
+import org.apache.james.mailbox.model.MailboxACL.{EntryKey, Right => JavaRight}
 import org.apache.james.mailbox.model.{MailboxACL, MailboxId}
 import play.api.libs.json._
 
@@ -92,13 +92,13 @@ class MailboxSerializer @Inject()(mailboxIdFactory: 
MailboxId.Factory) {
   private implicit val mailboxJavaRightReads: Reads[JavaRight] = value => 
rightRead.reads(value).map(right => right.toMailboxRight)
   private implicit val mailboxRfc4314RightsReads: Reads[Rfc4314Rights] = 
Json.valueReads[Rfc4314Rights]
   private implicit val rightSeqWrites: Writes[Seq[Right]] = seq => 
JsArray(seq.map(rightWrites.writes))
-  private implicit val rightsMapWrites: Writes[Map[Username, Seq[Right]]] =
-    mapWrites[Username, Seq[Right]](_.asString(), rightSeqWrites)
+  private implicit val rightsMapWrites: Writes[Map[EntryKey, Seq[Right]]] =
+    mapWrites[EntryKey, Seq[Right]](_.toString(), rightSeqWrites)
   private implicit val rightsWrites: Writes[Rights] = Json.valueWrites[Rights]
 
-  private implicit val mapRightsReads: Reads[Map[Username, Seq[Right]]] = 
_.validate[Map[String, Seq[Right]]]
+  private implicit val mapRightsReads: Reads[Map[EntryKey, Seq[Right]]] = 
_.validate[Map[String, Seq[Right]]]
     .map(rawMap =>
-      rawMap.map(entry => (Username.of(entry._1), entry._2)))
+      rawMap.map(entry => (EntryKey.deserialize(entry._1), entry._2)))
   private implicit val rightsReads: Reads[Rights] = json => 
mapRightsReads.reads(json).map(rawMap => Rights(rawMap))
 
   private implicit val domainWrites: Writes[Domain] = domain => 
JsString(domain.asString)
diff --git 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Rights.scala
 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Rights.scala
index 5b8fe06732..ee6edd3495 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Rights.scala
+++ 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Rights.scala
@@ -19,7 +19,6 @@
 
 package org.apache.james.jmap.mail
 
-import org.apache.james.core.Username
 import org.apache.james.mailbox.model.MailboxACL.{EntryKey, Rfc4314Rights => 
JavaRfc4314Rights, Right => JavaRight}
 import org.apache.james.mailbox.model.{MailboxACL => JavaMailboxACL}
 import org.slf4j.{Logger, LoggerFactory}
@@ -87,12 +86,12 @@ object Rights {
 
   val EMPTY = Rights(Map())
 
-  def of(username: Username, right: Right): Rights = of(username, Seq(right))
+  def of(entryKey: EntryKey, right: Right): Rights = of(entryKey, Seq(right))
 
-  def of(username: Username, rights: Seq[Right]): Rights = {
+  def of(entryKey: EntryKey, rights: Seq[Right]): Rights = {
     require(rights.nonEmpty, "'rights' should not be empty")
 
-    Rights(Map(username -> rights))
+    Rights(Map(entryKey -> rights))
   }
 
   def fromACL(acl: MailboxACL): Rights = acl.entries
@@ -104,15 +103,17 @@ object Rights {
     }
     .fold(EMPTY)(_ combine _)
 
-  private def toRights(entryKey: EntryKey, aclRights: Rfc4314Rights): Rights = 
of(Username.of(entryKey.getName), aclRights.toRights)
+  private def toRights(entryKey: EntryKey, aclRights: Rfc4314Rights): Rights = 
of(entryKey, aclRights.toRights)
 
   private def isSupported(key: EntryKey): Boolean = key match {
     case k if k.isNegative =>
       LOGGER.info("Negative keys are not supported")
       false
-    case JavaMailboxACL.OWNER_KEY => false
-    case k if k.getNameType ne JavaMailboxACL.NameType.user =>
-      LOGGER.info("{} is not supported. Only 'user' is.", key.getNameType)
+    case k if k.getNameType == JavaMailboxACL.NameType.special && k.getName != 
JavaMailboxACL.SpecialName.anyone.name() =>
+      LOGGER.info("Special name {} is not supported. Only 'anyone' is.", 
key.getName)
+      false
+    case k if k.getNameType == JavaMailboxACL.NameType.group =>
+      LOGGER.info("Name type {} is not supported. Only 'user' and 
'special.anyone' are.", key.getNameType)
       false
     case _ => true
   }
@@ -123,39 +124,39 @@ case object Applicable extends RightsApplicability
 case object NotApplicable extends RightsApplicability
 case object Unsupported extends RightsApplicability
 
-case class Rights(rights: Map[Username, Seq[Right]]) {
-  def removeEntriesFor(username: Username) = copy(rights = rights - username)
+case class Rights(rights: Map[EntryKey, Seq[Right]]) {
+  def removeEntriesFor(entryKey: EntryKey) = copy(rights = rights - entryKey)
 
   def toMailboxAcl: MailboxACL = {
     val map: Map[EntryKey, Rfc4314Rights] = rights.view
       .mapValues(Rfc4314Rights.fromRights)
       .toMap
       .map {
-        case (user, rfc4314Rights) => (EntryKey.createUserEntryKey(user), 
rfc4314Rights)
+        case (entryKey, rfc4314Rights) => (entryKey, rfc4314Rights)
       }
     MailboxACL(map)
   }
 
-  def append(username: Username, right: Right): Rights = append(username, 
Seq(right))
+  def append(entryKey: EntryKey, right: Right): Rights = append(entryKey, 
Seq(right))
 
-  def append(username: Username, rights: Seq[Right]): Rights = copy(rights = 
this.rights + (username -> rights))
+  def append(entryKey: EntryKey, rights: Seq[Right]): Rights = copy(rights = 
this.rights + (entryKey -> rights))
 
   def combine(that: Rights): Rights = Rights(this.rights ++ that.rights)
 
-  def mayReadItems(username: Username): RightsApplicability = 
containsRight(username, Right.Read)
+  def mayReadItems(entryKey: EntryKey): RightsApplicability = 
containsRight(entryKey, Right.Read)
 
-  def mayAddItems(username: Username): RightsApplicability = 
containsRight(username, Right.Insert)
+  def mayAddItems(entryKey: EntryKey): RightsApplicability = 
containsRight(entryKey, Right.Insert)
 
-  def mayRemoveItems(username: Username): RightsApplicability = 
containsRight(username, Right.DeleteMessages)
+  def mayRemoveItems(entryKey: EntryKey): RightsApplicability = 
containsRight(entryKey, Right.DeleteMessages)
 
-  def mayCreateChild(username: Username): RightsApplicability = Unsupported
+  def mayCreateChild(entryKey: EntryKey): RightsApplicability = Unsupported
 
-  def mayRename(username: Username): RightsApplicability = Unsupported
+  def mayRename(entryKey: EntryKey): RightsApplicability = Unsupported
 
-  def mayDelete(username: Username): RightsApplicability = Unsupported
+  def mayDelete(entryKey: EntryKey): RightsApplicability = Unsupported
 
-  private def containsRight(username: Username, right: Right): 
RightsApplicability = {
-    val contains = rights.get(username)
+  private def containsRight(entryKey: EntryKey, right: Right): 
RightsApplicability = {
+    val contains = rights.get(entryKey)
       .map(_.contains(right))
     contains match {
       case Some(true) => Applicable
diff --git 
a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxSerializationTest.scala
 
b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxSerializationTest.scala
index c9f5891bff..f7b2c63c22 100644
--- 
a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxSerializationTest.scala
+++ 
b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxSerializationTest.scala
@@ -21,11 +21,12 @@ package org.apache.james.jmap.json
 
 import eu.timepit.refined.auto._
 import net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson
-import org.apache.james.core.{Domain, Username}
+import org.apache.james.core.Domain
 import org.apache.james.jmap.json.MailboxSerializationTest.MAILBOX
 import org.apache.james.jmap.mail.MailboxName.MailboxName
 import org.apache.james.jmap.mail.{IsSubscribed, Mailbox, MailboxNamespace, 
MailboxRights, MayAddItems, MayCreateChild, MayDelete, MayReadItems, 
MayRemoveItems, MayRename, MaySetKeywords, MaySetSeen, MaySubmit, 
PersonalNamespace, Quota, QuotaId, QuotaRoot, Quotas, Right, Rights, SortOrder, 
TotalEmails, TotalThreads, UnreadEmails, UnreadThreads, Value}
 import org.apache.james.mailbox.Role
+import org.apache.james.mailbox.model.MailboxACL.EntryKey
 import org.apache.james.mailbox.model.{MailboxId, TestId}
 import org.scalatest.matchers.should.Matchers
 import org.scalatest.wordspec.AnyWordSpec
@@ -56,8 +57,8 @@ object MailboxSerializationTest {
     maySubmit = MaySubmit(false)
   )
 
-  private val RIGHTS: Rights = Rights.of(Username.of("bob"), 
Seq(Right.Expunge, Right.Lookup))
-    .append(Username.of("alice"), Seq(Right.Read, Right.Write))
+  private val RIGHTS: Rights = Rights.of(EntryKey.createUserEntryKey("bob"), 
Seq(Right.Expunge, Right.Lookup))
+    .append(EntryKey.createUserEntryKey("alice"), Seq(Right.Read, Right.Write))
 
   private val QUOTAS = Quotas(Map(
     QuotaId(QuotaRoot("quotaRoot", None)) -> Quota(Map(
diff --git 
a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/mail/RightsTest.scala
 
b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/mail/RightsTest.scala
index cae2864741..c6f6d594b1 100644
--- 
a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/mail/RightsTest.scala
+++ 
b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/mail/RightsTest.scala
@@ -29,8 +29,9 @@ import scala.jdk.CollectionConverters._
 
 class RightsTest extends AnyWordSpec with Matchers {
   val NEGATIVE = true
-  val USERNAME: Username = Username.of("user")
-  val OTHER_USERNAME: Username = Username.of("otherUser")
+  val USER: String = "user"
+  val USER_ENTRYKEY: EntryKey = EntryKey.createUserEntryKey(USER)
+  val OTHER_USER_ENTRYKEY: EntryKey = EntryKey.createUserEntryKey("otherUser")
 
   "Right ofCharacter" should  {
     "recognise 'a'" in {
@@ -70,21 +71,21 @@ class RightsTest extends AnyWordSpec with Matchers {
     }
     "filter out negative users" in {
       val acl = new JavaMailboxACL(Map(
-        EntryKey.createUserEntryKey(USERNAME, NEGATIVE) -> 
JavaRfc4314Rights.fromSerializedRfc4314Rights("aet")).asJava)
+        EntryKey.createUserEntryKey(USER, NEGATIVE) -> 
JavaRfc4314Rights.fromSerializedRfc4314Rights("aet")).asJava)
 
       Rights.fromACL(MailboxACL.fromJava(acl)) must be(Rights.EMPTY)
     }
     "accept users" in {
       val acl = new JavaMailboxACL(Map(
-        EntryKey.createUserEntryKey(USERNAME) -> 
JavaRfc4314Rights.fromSerializedRfc4314Rights("aet")).asJava)
+        USER_ENTRYKEY -> 
JavaRfc4314Rights.fromSerializedRfc4314Rights("aet")).asJava)
 
-      Rights.fromACL(MailboxACL.fromJava(acl)) must be(Rights.of(USERNAME, 
Seq(Right.Administer, Right.Expunge, Right.DeleteMessages)))
+      Rights.fromACL(MailboxACL.fromJava(acl)) must 
be(Rights.of(USER_ENTRYKEY, Seq(Right.Administer, Right.Expunge, 
Right.DeleteMessages)))
     }
     "filter out unknown rights" in {
       val acl = new JavaMailboxACL(Map(
-        EntryKey.createUserEntryKey(USERNAME) -> 
JavaRfc4314Rights.fromSerializedRfc4314Rights("aetxk")).asJava)
+        USER_ENTRYKEY -> 
JavaRfc4314Rights.fromSerializedRfc4314Rights("aetxk")).asJava)
 
-      Rights.fromACL(MailboxACL.fromJava(acl)) must be(Rights.of(USERNAME, 
Seq(Right.Administer, Right.Expunge, Right.DeleteMessages)))
+      Rights.fromACL(MailboxACL.fromJava(acl)) must 
be(Rights.of(USER_ENTRYKEY, Seq(Right.Administer, Right.Expunge, 
Right.DeleteMessages)))
     }
   }
   "To ACL" should  {
@@ -92,11 +93,11 @@ class RightsTest extends AnyWordSpec with Matchers {
       Rights.EMPTY.toMailboxAcl.asJava must be(new JavaMailboxACL())
     }
     "return acl conversion" in {
-      val user1 = Username.of("user1")
-      val user2 = Username.of("user2")
+      val user1 = EntryKey.createUserEntryKey("user1")
+      val user2 = EntryKey.createUserEntryKey("user2")
       val expected = new JavaMailboxACL(Map(
-          EntryKey.createUserEntryKey(user1) -> new 
JavaRfc4314Rights(JavaRight.Administer, JavaRight.DeleteMessages),
-          EntryKey.createUserEntryKey(user2) -> new 
JavaRfc4314Rights(JavaRight.PerformExpunge, JavaRight.Lookup))
+          user1 -> new JavaRfc4314Rights(JavaRight.Administer, 
JavaRight.DeleteMessages),
+          user2 -> new JavaRfc4314Rights(JavaRight.PerformExpunge, 
JavaRight.Lookup))
         .asJava)
       val jmapPojo = Rights.of(user1, Seq(Right.Administer, 
Right.DeleteMessages))
         .append(user2, Seq(Right.Expunge, Right.Lookup))
@@ -106,72 +107,72 @@ class RightsTest extends AnyWordSpec with Matchers {
   }
   "Remove entries" should  {
     "return empty when empty" in {
-      Rights.EMPTY.removeEntriesFor(USERNAME) must be(Rights.EMPTY)
+      Rights.EMPTY.removeEntriesFor(USER_ENTRYKEY) must be(Rights.EMPTY)
     }
     "return empty when only user" in {
-      Rights.of(USERNAME, Right.Lookup)
-        .removeEntriesFor(USERNAME) must be(Rights.EMPTY)
+      Rights.of(USER_ENTRYKEY, Right.Lookup)
+        .removeEntriesFor(USER_ENTRYKEY) must be(Rights.EMPTY)
     }
     "only remove specified users" in {
-      val expected = Rights.of(OTHER_USERNAME, Right.Lookup)
+      val expected = Rights.of(OTHER_USER_ENTRYKEY, Right.Lookup)
 
-      Rights.of(USERNAME, Right.Lookup)
-        .append(OTHER_USERNAME, Right.Lookup)
-        .removeEntriesFor(USERNAME) must be(expected)
+      Rights.of(USER_ENTRYKEY, Right.Lookup)
+        .append(OTHER_USER_ENTRYKEY, Right.Lookup)
+        .removeEntriesFor(USER_ENTRYKEY) must be(expected)
     }
   }
   "mayAddItems" should  {
     "return empty when no user" in {
-      Rights.EMPTY.mayAddItems(USERNAME) must be(NotApplicable)
+      Rights.EMPTY.mayAddItems(USER_ENTRYKEY) must be(NotApplicable)
     }
     "return false when no insert right" in {
-      Rights.of(USERNAME, Seq(Right.Administer, Right.Expunge, Right.Lookup, 
Right.DeleteMessages, Right.Read, Right.Seen, Right.Write))
-        .mayAddItems(USERNAME) must be(NotApplicable)
+      Rights.of(USER_ENTRYKEY, Seq(Right.Administer, Right.Expunge, 
Right.Lookup, Right.DeleteMessages, Right.Read, Right.Seen, Right.Write))
+        .mayAddItems(USER_ENTRYKEY) must be(NotApplicable)
     }
     "return true when insert right" in {
-      Rights.of(USERNAME, Right.Insert)
-        .mayAddItems(USERNAME) must be(Applicable)
+      Rights.of(USER_ENTRYKEY, Right.Insert)
+        .mayAddItems(USER_ENTRYKEY) must be(Applicable)
     }
   }
   "mayReadItems" should  {
     "return empty when no user" in {
-      Rights.EMPTY.mayReadItems(USERNAME) must be(NotApplicable)
+      Rights.EMPTY.mayReadItems(USER_ENTRYKEY) must be(NotApplicable)
     }
     "return false when no read right" in {
-      Rights.of(USERNAME, Seq(Right.Administer, Right.Expunge, Right.Lookup, 
Right.DeleteMessages, Right.Administer, Right.Seen, Right.Write))
-        .mayReadItems(USERNAME) must be(NotApplicable)
+      Rights.of(USER_ENTRYKEY, Seq(Right.Administer, Right.Expunge, 
Right.Lookup, Right.DeleteMessages, Right.Administer, Right.Seen, Right.Write))
+        .mayReadItems(USER_ENTRYKEY) must be(NotApplicable)
     }
     "return true when read right" in {
-      Rights.of(USERNAME, Right.Read)
-        .mayReadItems(USERNAME) must be(Applicable)
+      Rights.of(USER_ENTRYKEY, Right.Read)
+        .mayReadItems(USER_ENTRYKEY) must be(Applicable)
     }
   }
   "mayRemoveItems" should  {
     "return empty when no user" in {
-      Rights.EMPTY.mayRemoveItems(USERNAME) must be(NotApplicable)
+      Rights.EMPTY.mayRemoveItems(USER_ENTRYKEY) must be(NotApplicable)
     }
     "return false when no delete right" in {
-      Rights.of(USERNAME, Seq(Right.Administer, Right.Expunge, Right.Lookup, 
Right.Read, Right.Administer, Right.Seen, Right.Write))
-        .mayRemoveItems(USERNAME) must be(NotApplicable)
+      Rights.of(USER_ENTRYKEY, Seq(Right.Administer, Right.Expunge, 
Right.Lookup, Right.Read, Right.Administer, Right.Seen, Right.Write))
+        .mayRemoveItems(USER_ENTRYKEY) must be(NotApplicable)
     }
     "return true when delete right" in {
-      Rights.of(USERNAME, Right.DeleteMessages)
-        .mayRemoveItems(USERNAME) must be(Applicable)
+      Rights.of(USER_ENTRYKEY, Right.DeleteMessages)
+        .mayRemoveItems(USER_ENTRYKEY) must be(Applicable)
     }
   }
   "mayRename" should  {
     "return unsupported" in {
-      Rights.EMPTY.mayRename(USERNAME) must be(Unsupported)
+      Rights.EMPTY.mayRename(USER_ENTRYKEY) must be(Unsupported)
     }
   }
   "mayDelete" should  {
     "return unsupported" in {
-      Rights.EMPTY.mayDelete(USERNAME) must be(Unsupported)
+      Rights.EMPTY.mayDelete(USER_ENTRYKEY) must be(Unsupported)
     }
   }
   "mayCreateChild" should  {
     "return unsupported" in {
-      Rights.EMPTY.mayCreateChild(USERNAME) must be(Unsupported)
+      Rights.EMPTY.mayCreateChild(USER_ENTRYKEY) must be(Unsupported)
     }
   }
 }


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

Reply via email to