You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2020/04/13 02:53:32 UTC
[james-project] 05/13: JAMES-2891 AccountId should have its own type
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 3a53fafad2b6d6a7bf7039759f0c13611fa1ca1a
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Tue Mar 31 21:13:18 2020 +0700
JAMES-2891 AccountId should have its own type
---
.../org/apache/james/jmap/http/SessionRoutes.scala | 4 +-
.../apache/james/jmap/http/SessionSupplier.scala | 74 +++++++---------------
.../org/apache/james/jmap/json/Serializer.scala | 17 +++--
.../org/apache/james/jmap/model/Capability.scala | 4 +-
.../org/apache/james/jmap/model/Invocation.scala | 6 +-
.../org/apache/james/jmap/model/Session.scala | 54 ++++++++++++----
.../apache/james/jmap/http/SessionRoutesTest.scala | 38 +----------
.../james/jmap/http/SessionSupplierTest.scala | 10 ++-
.../james/jmap/json/SessionSerializationTest.scala | 36 ++++++-----
9 files changed, 111 insertions(+), 132 deletions(-)
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/SessionRoutes.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/SessionRoutes.scala
index 79bfb45..75a280b 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/SessionRoutes.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/SessionRoutes.scala
@@ -46,10 +46,10 @@ object SessionRoutes {
@Inject
class SessionRoutes(val authFilter: Authenticator,
val sessionSupplier: SessionSupplier = new SessionSupplier(),
- val serializer: Serializer = new Serializer) extends JMAPRoutes {
+ val serializer: Serializer = new Serializer()) extends JMAPRoutes {
val logger: Logger = SessionRoutes.LOGGER
- val generateSession: BiFunction[HttpServerRequest, HttpServerResponse, Publisher[Void]] =
+ private val generateSession: BiFunction[HttpServerRequest, HttpServerResponse, Publisher[Void]] =
(request, response) => SMono.fromPublisher(authFilter.authenticate(request))
.map(_.getUser)
.flatMap(sessionSupplier.generate)
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/SessionSupplier.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/SessionSupplier.scala
index c7fb076..231617a 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/SessionSupplier.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/SessionSupplier.scala
@@ -21,16 +21,12 @@ package org.apache.james.jmap.http
import java.net.URL
-import com.google.common.annotations.VisibleForTesting
import eu.timepit.refined.auto._
-import eu.timepit.refined.refineV
import org.apache.james.core.Username
-import org.apache.james.jmap.http.SessionSupplier.{CORE_CAPABILITY, MAIL_CAPABILITY}
+import org.apache.james.jmap.http.SessionSupplier.{CORE_CAPABILITY, HARD_CODED_URL_PREFIX, MAIL_CAPABILITY}
import org.apache.james.jmap.model.CapabilityIdentifier.CapabilityIdentifier
-import org.apache.james.jmap.model.Id.Id
import org.apache.james.jmap.model._
-import reactor.core.publisher.Mono
-import reactor.core.scala.publisher.{SFlux, SMono}
+import reactor.core.scala.publisher.SMono
object SessionSupplier {
private val CORE_CAPABILITY = CoreCapability(
@@ -53,56 +49,30 @@ object SessionSupplier {
emailQuerySortOptions = List("receivedAt", "cc", "from", "to", "subject", "size", "sentAt", "hasKeyword", "uid", "Id"),
MayCreateTopLevelMailbox(true)
))
+
+ private val HARD_CODED_URL_PREFIX = "http://this-url-is-hardcoded.org"
}
class SessionSupplier {
- def generate(username: Username): SMono[Session] =
- SMono.fromPublisher(
- Mono.zip(
- accounts(username).asJava(),
- primaryAccounts(username).asJava()))
- .map(tuple => generate(username, tuple.getT1, tuple.getT2))
-
- private def accounts(username: Username): SMono[Map[Id, Account]] =
- getId(username)
- .map(id => Map(
- id -> Account(
- username,
- IsPersonal(true),
- IsReadOnly(false),
- accountCapabilities = Set(CORE_CAPABILITY, MAIL_CAPABILITY))))
-
- private def primaryAccounts(username: Username): SMono[Map[CapabilityIdentifier, Id]] =
- SFlux.just(CORE_CAPABILITY, MAIL_CAPABILITY)
- .flatMap(capability => getId(username)
- .map(id => (capability.identifier, id)))
- .collectMap(getIdentifier, getId)
- private def getIdentifier(tuple : (CapabilityIdentifier, Id)): CapabilityIdentifier = tuple._1
- private def getId(tuple : (CapabilityIdentifier, Id)): Id = tuple._2
-
- private def getId(username: Username): SMono[Id] = {
- SMono.fromCallable(() => refineId(username))
- .flatMap {
- case Left(errorMessage: String) => SMono.raiseError(new IllegalStateException(errorMessage))
- case Right(id) => SMono.just(id)
- }
+ def generate(username: Username): SMono[Session] = {
+ accounts(username)
+ .map(account => Session(
+ Capabilities(CORE_CAPABILITY, MAIL_CAPABILITY),
+ List(account),
+ primaryAccounts(account.accountId),
+ username,
+ apiUrl = new URL(s"$HARD_CODED_URL_PREFIX/jmap"),
+ downloadUrl = new URL(s"$HARD_CODED_URL_PREFIX/download"),
+ uploadUrl = new URL(s"$HARD_CODED_URL_PREFIX/upload"),
+ eventSourceUrl = new URL(s"$HARD_CODED_URL_PREFIX/eventSource")))
}
- private def refineId(username: Username): Either[String, Id] = refineV(usernameHashCode(username))
- @VisibleForTesting def usernameHashCode(username: Username) = username.asString().hashCode.toOctalString
+ private def accounts(username: Username): SMono[Account] = SMono.defer(() =>
+ Account.from(username, IsPersonal(true), IsReadOnly(false), Set(CORE_CAPABILITY, MAIL_CAPABILITY)) match {
+ case Left(ex: IllegalArgumentException) => SMono.raiseError(ex)
+ case Right(account: Account) => SMono.just(account)
+ })
- private def generate(username: Username,
- accounts: Map[Id, Account],
- primaryAccounts: Map[CapabilityIdentifier, Id]): Session = {
- Session(
- Capabilities(CORE_CAPABILITY, MAIL_CAPABILITY),
- accounts,
- primaryAccounts,
- username,
- apiUrl = new URL("http://this-url-is-hardcoded.org/jmap"),
- downloadUrl = new URL("http://this-url-is-hardcoded.org/download"),
- uploadUrl = new URL("http://this-url-is-hardcoded.org/upload"),
- eventSourceUrl = new URL("http://this-url-is-hardcoded.org/eventSource"),
- state = "000001")
- }
+ private def primaryAccounts(accountId: AccountId): Map[CapabilityIdentifier, AccountId] =
+ Map(CORE_CAPABILITY.identifier -> accountId, MAIL_CAPABILITY.identifier -> accountId)
}
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
index ebf9985..2189af9 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
@@ -24,7 +24,6 @@ import java.net.URL
import org.apache.james.core.Username
import org.apache.james.jmap.model
import org.apache.james.jmap.model.CapabilityIdentifier.CapabilityIdentifier
-import org.apache.james.jmap.model.Id.Id
import org.apache.james.jmap.model.Invocation.{Arguments, MethodCallId, MethodName}
import org.apache.james.jmap.model.{Account, Invocation, Session, _}
import play.api.libs.functional.syntax._
@@ -103,17 +102,27 @@ class Serializer {
private implicit val capabilitiesWrites: Writes[Capabilities] = capabilities => setCapabilityWrites.writes(Set(capabilities.coreCapability, capabilities.mailCapability))
- private implicit def identifierMapWrite[Any](implicit idWriter: Writes[Id]): Writes[Map[CapabilityIdentifier, Any]] =
+ private implicit val accountIdWrites: Format[AccountId] = Json.valueFormat[AccountId]
+ private implicit def identifierMapWrite[Any](implicit idWriter: Writes[AccountId]): Writes[Map[CapabilityIdentifier, Any]] =
(m: Map[CapabilityIdentifier, Any]) => {
m.foldLeft(JsObject.empty)((jsObject, kv) => {
- val (identifier: CapabilityIdentifier, id: Id) = kv
+ val (identifier: CapabilityIdentifier, id: AccountId) = kv
jsObject.+(identifier.value, idWriter.writes(id))
})
}
private implicit val isPersonalFormat: Format[IsPersonal] = Json.valueFormat[IsPersonal]
private implicit val isReadOnlyFormat: Format[IsReadOnly] = Json.valueFormat[IsReadOnly]
- private implicit val accountWrites: Writes[Account] = Json.writes[Account]
+ private implicit val accountWrites: Writes[Account] = (
+ (JsPath \ Account.NAME).write[Username] and
+ (JsPath \ Account.IS_PERSONAL).write[IsPersonal] and
+ (JsPath \ Account.IS_READ_ONLY).write[IsReadOnly] and
+ (JsPath \ Account.ACCOUNT_CAPABILITIES).write[Set[_ <: Capability]]
+ ) (unlift(Account.unapplyIgnoreAccountId))
+
+ private implicit def accountListWrites(implicit accountWrites: Writes[Account]): Writes[List[Account]] =
+ (list: List[Account]) => JsObject(list.map(account => (account.accountId.id.value, accountWrites.writes(account))))
+
private implicit val sessionWrites: Writes[Session] = Json.writes[Session]
def serialize(session: Session): JsValue = {
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Capability.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Capability.scala
index 8e35c7d..17517fe 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Capability.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Capability.scala
@@ -30,8 +30,8 @@ import org.apache.james.jmap.model.UnsignedInt.UnsignedInt
object CapabilityIdentifier {
type CapabilityIdentifier = String Refined Uri
- val JMAP_CORE: CapabilityIdentifier = "urn:ietf:params:jmap:core"
- val JMAP_MAIL: CapabilityIdentifier = "urn:ietf:params:jmap:mail"
+ private[model] val JMAP_CORE: CapabilityIdentifier = "urn:ietf:params:jmap:core"
+ private[model] val JMAP_MAIL: CapabilityIdentifier = "urn:ietf:params:jmap:mail"
}
sealed trait CapabilityProperties
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Invocation.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Invocation.scala
index 7ad8e5c..c46d95b 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Invocation.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Invocation.scala
@@ -25,9 +25,9 @@ import play.api.libs.json._
case class Invocation(methodName: MethodName, arguments: Arguments, methodCallId: MethodCallId)
object Invocation {
- val METHOD_NAME: Int = 0
- val ARGUMENTS: Int = 1
- val METHOD_CALL: Int = 2
+ private[jmap] val METHOD_NAME: Int = 0
+ private[jmap] val ARGUMENTS: Int = 1
+ private[jmap] val METHOD_CALL: Int = 2
case class MethodName(value: NonEmptyString)
case class Arguments(value: JsObject) extends AnyVal
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Session.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Session.scala
index 5d85fca..0bb733d 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Session.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Session.scala
@@ -20,44 +20,76 @@
package org.apache.james.jmap.model
import java.net.URL
+import java.nio.charset.StandardCharsets
+import com.google.common.hash.Hashing
import eu.timepit.refined.api.Refined
+import eu.timepit.refined.auto._
import eu.timepit.refined.collection.NonEmpty
+import eu.timepit.refined.refineV
import org.apache.james.core.Username
import org.apache.james.jmap.model.CapabilityIdentifier.CapabilityIdentifier
import org.apache.james.jmap.model.Id.Id
-import org.apache.james.jmap.model.State.State
+import org.apache.james.jmap.model.State.{INSTANCE, State}
case class IsPersonal(value: Boolean)
case class IsReadOnly(value: Boolean)
-object Account {
- def apply(name: Username,
- isPersonal: IsPersonal,
- isReadOnly: IsReadOnly,
- accountCapabilities: Set[_ <: Capability]): Account = {
+object AccountId {
+ def from(username: Username): Either[IllegalArgumentException, AccountId] = {
+ val sha256String = Hashing.sha256()
+ .hashString(username.asString(), StandardCharsets.UTF_8)
+ .toString
+ val refinedId: Either[String, Id] = refineV(sha256String)
- new Account(name, isPersonal, isReadOnly, accountCapabilities)
+ refinedId match {
+ case Left(errorMessage: String) => Left(new IllegalArgumentException(errorMessage))
+ case Right(id) => Right(AccountId(id))
+ }
}
}
-final case class Account private(name: Username,
+final case class AccountId(id: Id)
+
+object Account {
+ private[jmap] val NAME = "name";
+ private[jmap] val IS_PERSONAL = "isPersonal"
+ private[jmap] val IS_READ_ONLY = "isReadOnly"
+ private[jmap] val ACCOUNT_CAPABILITIES = "accountCapabilities"
+
+ def from(name: Username,
+ isPersonal: IsPersonal,
+ isReadOnly: IsReadOnly,
+ accountCapabilities: Set[_ <: Capability]): Either[IllegalArgumentException, Account] =
+ AccountId.from(name) match {
+ case Left(ex: IllegalArgumentException) => Left(ex)
+ case Right(accountId) => Right(new Account(accountId, name, isPersonal, isReadOnly, accountCapabilities))
+ }
+
+ def unapplyIgnoreAccountId(account: Account): Some[(Username, IsPersonal, IsReadOnly, Set[_ <: Capability])] =
+ Some(account.name, account.isPersonal, account.isReadOnly, account.accountCapabilities)
+}
+
+final case class Account private(accountId: AccountId,
+ name: Username,
isPersonal: IsPersonal,
isReadOnly: IsReadOnly,
accountCapabilities: Set[_ <: Capability])
object State {
+ private[model] val INSTANCE: State = "000001"
+
type State = String Refined NonEmpty
}
case class Capabilities(coreCapability: CoreCapability, mailCapability: MailCapability)
final case class Session(capabilities: Capabilities,
- accounts: Map[Id, Account],
- primaryAccounts: Map[CapabilityIdentifier, Id],
+ accounts: List[Account],
+ primaryAccounts: Map[CapabilityIdentifier, AccountId],
username: Username,
apiUrl: URL,
downloadUrl: URL,
uploadUrl: URL,
eventSourceUrl: URL,
- state: State)
+ state: State = INSTANCE)
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionRoutesTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionRoutesTest.scala
index 6ff561d..a7b3e9c 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionRoutesTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionRoutesTest.scala
@@ -31,7 +31,6 @@ import org.apache.james.core.Username
import org.apache.james.jmap.http.SessionRoutesTest.{BOB, TEST_CONFIGURATION}
import org.apache.james.jmap.{JMAPConfiguration, JMAPRoutes, JMAPServer}
import org.apache.james.mailbox.MailboxSession
-import org.hamcrest.CoreMatchers.is
import org.mockito.ArgumentMatchers.any
import org.mockito.Mockito._
import org.scalatest.BeforeAndAfter
@@ -120,7 +119,7 @@ class SessionRoutesTest extends AnyFlatSpec with BeforeAndAfter with Matchers {
| }
| },
| "accounts" : {
- | "25742733157" : {
+ | "0fe275bf13ff761407c17f64b1dfae2f4b3186feea223d7267b79f873a105401" : {
| "name" : "bob@james.org",
| "isPersonal" : true,
| "isReadOnly" : false,
@@ -147,8 +146,8 @@ class SessionRoutesTest extends AnyFlatSpec with BeforeAndAfter with Matchers {
| }
| },
| "primaryAccounts" : {
- | "urn:ietf:params:jmap:core" : "25742733157",
- | "urn:ietf:params:jmap:mail" : "25742733157"
+ | "urn:ietf:params:jmap:core" : "0fe275bf13ff761407c17f64b1dfae2f4b3186feea223d7267b79f873a105401",
+ | "urn:ietf:params:jmap:mail" : "0fe275bf13ff761407c17f64b1dfae2f4b3186feea223d7267b79f873a105401"
| },
| "username" : "bob@james.org",
| "apiUrl" : "http://this-url-is-hardcoded.org/jmap",
@@ -160,35 +159,4 @@ class SessionRoutesTest extends AnyFlatSpec with BeforeAndAfter with Matchers {
Json.parse(sessionJson) should equal(Json.parse(expectedJson))
}
-
- "get" should "return 500 when unexpected Id serialization" in {
- when(sessionSupplier.usernameHashCode(BOB))
- .thenReturn("INVALID_JMAP_ID_()*&*$(#*")
-
- RestAssured.when()
- .get
- .then
- .statusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR)
- }
-
- "get" should "return empty content type when unexpected Id serialization" in {
- when(sessionSupplier.usernameHashCode(BOB))
- .thenReturn("INVALID_JMAP_ID_()*&*$(#*")
-
- RestAssured.when()
- .get
- .then
- .contentType(is(""))
- }
-
- "get" should "return empty body when unexpected Id serialization" in {
- when(sessionSupplier.usernameHashCode(BOB))
- .thenReturn("INVALID_JMAP_ID_()*&*$(#*")
-
- RestAssured.`with`()
- .get
- .thenReturn()
- .getBody
- .asString() should equal("")
- }
}
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionSupplierTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionSupplierTest.scala
index 1b2bb0b..11bd415 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionSupplierTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionSupplierTest.scala
@@ -19,10 +19,8 @@
package org.apache.james.jmap.http
-import eu.timepit.refined.auto._
import org.apache.james.core.Username
import org.apache.james.jmap.http.SessionSupplierTest.USERNAME
-import org.apache.james.jmap.model.Id.Id
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
@@ -45,12 +43,12 @@ class SessionSupplierTest extends AnyWordSpec with Matchers {
}
"has name" in {
- accounts.view.mapValues(_.name).values.toList should equal(List(USERNAME))
+ accounts.map(_.name) should equal(List(USERNAME))
}
- "has id" in {
- val usernameHashCode: Id = "22267206120"
- accounts.keys.toList should equal(List(usernameHashCode))
+ "has accountId being hash of username in string" in {
+ accounts.map(_.accountId)
+ .map(_.id.value) should equal(List("0cb33e029628ea603d1b988f0f81b069d89b6c5a093e12b275ecdc626bd7458c"))
}
}
}
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/SessionSerializationTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/SessionSerializationTest.scala
index 8f6f228..98e3f81 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/SessionSerializationTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/SessionSerializationTest.scala
@@ -50,9 +50,7 @@ object SessionSerializationTest {
private val MAX_OBJECTS_IN_SET : MaxObjectsInSet = MaxObjectsInSet(128L)
private val COLLATION_ALGORITHMS : List[CollationAlgorithm] = List(ALGO_1, ALGO_2, ALGO_3)
private val USER_1 = Username.of("user1@james.org")
- private val USER_1_ID: Id = "user1Id"
private val USER_2 = Username.of("user2@james.org")
- private val USER_2_ID: Id = "user2Id"
private val URL = new URL("http://james.org")
private val STATE : State = "fda9342jcm"
@@ -87,28 +85,32 @@ object SessionSerializationTest {
private val IS_NOT_PERSONAL : IsPersonal = IsPersonal(false)
private val IS_NOT_READ_ONLY : IsReadOnly = IsReadOnly(false)
- private val ACCOUNT_1 = Account(
+ private val ACCOUNT_1: Account = Account.from(
name = USER_1,
isPersonal = IS_PERSONAL,
isReadOnly = IS_NOT_READ_ONLY,
- accountCapabilities = Set(CORE_CAPABILITY))
- private val ACCOUNT_2 = Account(
+ accountCapabilities = Set(CORE_CAPABILITY)) match {
+ case Left(ex: IllegalArgumentException) => throw ex
+ case Right(account: Account) => account
+ }
+
+ private val ACCOUNT_2: Account = Account.from(
name = USER_2,
isPersonal = IS_NOT_PERSONAL,
isReadOnly = IS_NOT_READ_ONLY,
- accountCapabilities = Set(CORE_CAPABILITY))
- private val ACCOUNTS = Map(
- USER_1_ID -> ACCOUNT_1,
- USER_2_ID -> ACCOUNT_2,
- )
+ accountCapabilities = Set(CORE_CAPABILITY)) match {
+ case Left(ex: IllegalArgumentException) => throw ex
+ case Right(account: Account) => account
+ }
+
private val PRIMARY_ACCOUNTS = Map(
- MAIL_IDENTIFIER -> USER_1_ID,
- CONTACT_IDENTIFIER -> USER_2_ID
+ MAIL_IDENTIFIER -> ACCOUNT_1.accountId,
+ CONTACT_IDENTIFIER -> ACCOUNT_1.accountId
)
private val SESSION = Session(
capabilities = CAPABILITIES,
- accounts = ACCOUNTS,
+ accounts = List(ACCOUNT_1, ACCOUNT_2),
primaryAccounts = PRIMARY_ACCOUNTS,
username = USER_1,
apiUrl = URL,
@@ -155,7 +157,7 @@ class SessionSerializationTest extends AnyWordSpec with Matchers {
| }
| },
| "accounts": {
- | "user1Id": {
+ | "807a5306ccb4527af7790a0f9b48a776514bdbfba064e355461a76bcffbf2c90": {
| "name": "user1@james.org",
| "isPersonal": true,
| "isReadOnly": false,
@@ -176,7 +178,7 @@ class SessionSerializationTest extends AnyWordSpec with Matchers {
| }
| }
| },
- | "user2Id": {
+ | "a9b46834e106ff73268a40a34ffba9fcfeee8bdb601939d1a96ef9199dc2695c": {
| "name": "user2@james.org",
| "isPersonal": false,
| "isReadOnly": false,
@@ -199,8 +201,8 @@ class SessionSerializationTest extends AnyWordSpec with Matchers {
| }
| },
| "primaryAccounts": {
- | "urn:ietf:params:jmap:mail": "user1Id",
- | "urn:ietf:params:jmap:contact": "user2Id"
+ | "urn:ietf:params:jmap:mail": "807a5306ccb4527af7790a0f9b48a776514bdbfba064e355461a76bcffbf2c90",
+ | "urn:ietf:params:jmap:contact": "807a5306ccb4527af7790a0f9b48a776514bdbfba064e355461a76bcffbf2c90"
| },
| "username": "user1@james.org",
| "apiUrl": "http://james.org",
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org