This is an automated email from the ASF dual-hosted git repository. chibenwa pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 167b726c04450e70134ce58dca9ac1a92c1722ec Author: Quan Tran <[email protected]> AuthorDate: Mon Jul 13 22:58:40 2026 +0700 [BUILD] WebPushContract: isolate using different users --- .../distributed/DistributedWebPushTest.java | 1 + .../jmap/rfc8621/contract/WebPushContract.scala | 71 ++++++++++++++-------- .../jmap/rfc8621/memory/MemoryWebPushTest.java | 1 + .../jmap/rfc8621/postgres/PostgresWebPushTest.java | 1 + 4 files changed, 48 insertions(+), 26 deletions(-) diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedWebPushTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedWebPushTest.java index c194d5c187..d946d583ee 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedWebPushTest.java +++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedWebPushTest.java @@ -59,6 +59,7 @@ class DistributedWebPushTest implements WebPushContract { .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration) .overrideWith(new TestJMAPServerModule(), new PushSubscriptionProbeModule()) .overrideWith(binder -> binder.bind(PushClientConfiguration.class).toInstance(PushClientConfiguration.UNSAFE_DEFAULT()))) + .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS) .build(); @RegisterExtension diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/WebPushContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/WebPushContract.scala index ce99b1f0a3..c6a897e54d 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/WebPushContract.scala +++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/WebPushContract.scala @@ -24,10 +24,12 @@ import java.security.KeyPair import java.security.interfaces.{ECPrivateKey, ECPublicKey} import java.time.temporal.ChronoUnit import java.util.Base64 +import java.util.UUID import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicReference import java.util.function.Consumer +import com.google.common.hash.Hashing import com.google.crypto.tink.apps.webpush.WebPushHybridDecrypt import com.google.crypto.tink.subtle.EllipticCurves import com.google.crypto.tink.subtle.EllipticCurves.CurveType @@ -38,9 +40,10 @@ import net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson import org.apache.http.HttpStatus import org.apache.http.HttpStatus.SC_OK import org.apache.james.GuiceJamesServer +import org.apache.james.core.Username import org.apache.james.jmap.core.ResponseObject.SESSION_STATE import org.apache.james.jmap.http.UserCredential -import org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER, ACCOUNT_ID, ANDRE, ANDRE_PASSWORD, BOB, BOB_PASSWORD, DOMAIN, authScheme, baseRequestSpecBuilder} +import org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER, ANDRE_PASSWORD, BOB_PASSWORD, DOMAIN, authScheme, baseRequestSpecBuilder} import org.apache.james.jmap.rfc8621.contract.tags.CategoryTags import org.apache.james.mailbox.DefaultMailboxes import org.apache.james.mailbox.MessageManager.AppendCommand @@ -66,7 +69,18 @@ import play.api.libs.json.{JsObject, JsString, Json} import scala.jdk.CollectionConverters._ +object WebPushContractContext { + case class TestContext(bobUsername: Username, bobAccountId: String, andreUsername: Username) + val currentContext: java.util.concurrent.atomic.AtomicReference[TestContext] = new java.util.concurrent.atomic.AtomicReference[TestContext]() +} + trait WebPushContract { + import WebPushContractContext.currentContext + + def bobUsername: Username = currentContext.get().bobUsername + def bobAccountId: String = currentContext.get().bobAccountId + def andreUsername: Username = currentContext.get().andreUsername + private lazy val awaitAtMostTenSeconds: ConditionFactory = Awaitility.`with` .pollInterval(ONE_HUNDRED_MILLISECONDS) .and.`with`.pollDelay(ONE_HUNDRED_MILLISECONDS) @@ -76,17 +90,22 @@ trait WebPushContract { @BeforeEach def setUp(server: GuiceJamesServer): Unit = { + val uniqueSuffix = UUID.randomUUID().toString.replace("-", "").take(8) + val bob = Username.fromLocalPartWithDomain(s"bob$uniqueSuffix", DOMAIN) + val andre = Username.fromLocalPartWithDomain(s"andre$uniqueSuffix", DOMAIN) + currentContext.set(WebPushContractContext.TestContext( + bob, Hashing.sha256().hashString(bob.asString(), StandardCharsets.UTF_8).toString, andre)) server.getProbe(classOf[DataProbeImpl]) .fluent() .addDomain(DOMAIN.asString()) - .addUser(BOB.asString(), BOB_PASSWORD) - .addUser(ANDRE.asString(), ANDRE_PASSWORD) + .addUser(bobUsername.asString(), BOB_PASSWORD) + .addUser(andreUsername.asString(), ANDRE_PASSWORD) server.getProbe(classOf[MailboxProbeImpl]) - .createMailbox(MailboxPath.inbox(BOB)) + .createMailbox(MailboxPath.inbox(bobUsername)) requestSpecification = baseRequestSpecBuilder(server) - .setAuth(authScheme(UserCredential(BOB, BOB_PASSWORD))) + .setAuth(authScheme(UserCredential(bobUsername, BOB_PASSWORD))) .addHeader(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER) .build() } @@ -155,8 +174,8 @@ trait WebPushContract { private def sendEmailToBob(server: GuiceJamesServer): Unit = { val smtpMessageSender: SMTPMessageSender = new SMTPMessageSender(DOMAIN.asString()) smtpMessageSender.connect("127.0.0.1", server.getProbe(classOf[SmtpGuiceProbe]).getSmtpPort) - .authenticate(ANDRE.asString, ANDRE_PASSWORD) - .sendMessage(ANDRE.asString, BOB.asString()) + .authenticate(andreUsername.asString, ANDRE_PASSWORD) + .sendMessage(andreUsername.asString, bobUsername.asString()) smtpMessageSender.close() awaitAtMostTenSeconds.until(() => server.getProbe(classOf[SpoolerProbe]).processingFinished()) @@ -238,7 +257,7 @@ trait WebPushContract { s"""{ | "@type": "StateChange", | "changed": { - | "$ACCOUNT_ID": { + | "$bobAccountId": { | "Mailbox": "$${json-unit.any-string}" | } | } @@ -264,7 +283,7 @@ trait WebPushContract { s"""{ | "@type": "StateChange", | "changed": { - | "$ACCOUNT_ID": { + | "$bobAccountId": { | "EmailDelivery": "$${json-unit.any-string}" | } | } @@ -281,20 +300,20 @@ trait WebPushContract { setupPushSubscriptionForBob(pushServer) // WHEN bob create a draft mail - val mailboxId = server.getProbe(classOf[MailboxProbeImpl]).getMailboxId("#private", BOB.asString(), MailboxConstants.INBOX) + val mailboxId = server.getProbe(classOf[MailboxProbeImpl]).getMailboxId("#private", bobUsername.asString(), MailboxConstants.INBOX) val request = s"""{ | "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"], | "methodCalls": [ | ["Email/set", { - | "accountId": "$ACCOUNT_ID", + | "accountId": "$bobAccountId", | "create": { | "aaaaaa":{ | "mailboxIds": { | "${mailboxId.serialize}": true | }, | "to": [{"email": "[email protected]"}, {"email": "[email protected]"}], - | "from": [{"email": "${BOB.asString}"}] + | "from": [{"email": "${bobUsername.asString}"}] | } | } | }, "c1"]] @@ -315,7 +334,7 @@ trait WebPushContract { s"""{ | "@type": "StateChange", | "changed": { - | "$ACCOUNT_ID": { + | "$bobAccountId": { | "EmailDelivery": "$${json-unit.any-string}" | } | } @@ -337,13 +356,13 @@ trait WebPushContract { | "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail", "urn:ietf:params:jmap:submission"], | "methodCalls": [ | ["EmailSubmission/set", { - | "accountId": "$ACCOUNT_ID", + | "accountId": "$bobAccountId", | "create": { | "k1490": { | "emailId": "${messageId.serialize}", | "envelope": { - | "mailFrom": {"email": "${BOB.asString}"}, - | "rcptTo": [{"email": "${ANDRE.asString}"}] + | "mailFrom": {"email": "${bobUsername.asString}"}, + | "rcptTo": [{"email": "${andreUsername.asString}"}] | } | } | } @@ -365,7 +384,7 @@ trait WebPushContract { s"""{ | "@type": "StateChange", | "changed": { - | "$ACCOUNT_ID": { + | "$bobAccountId": { | "EmailDelivery": "$${json-unit.any-string}" | } | } @@ -438,7 +457,7 @@ trait WebPushContract { s"""{ | "@type": "StateChange", | "changed": { - | "$ACCOUNT_ID": { + | "$bobAccountId": { | "Mailbox": "$${json-unit.any-string}" | } | } @@ -529,7 +548,7 @@ trait WebPushContract { s"""{ | "@type": "StateChange", | "changed": { - | "$ACCOUNT_ID": { + | "$bobAccountId": { | "Mailbox": "$${json-unit.any-string}" | } | } @@ -558,7 +577,7 @@ trait WebPushContract { s"""{ | "@type": "StateChange", | "changed": { - | "$ACCOUNT_ID": { + | "$bobAccountId": { | "Mailbox": "$${json-unit.any-string}" | } | } @@ -672,7 +691,7 @@ trait WebPushContract { s"""{ | "@type": "StateChange", | "changed": { - | "$ACCOUNT_ID": { + | "$bobAccountId": { | "Mailbox": "$${json-unit.ignore}" | } | } @@ -683,14 +702,14 @@ trait WebPushContract { val message: Message = Message.Builder .of .setSubject("test") - .setSender(BOB.asString) - .setFrom(BOB.asString) - .setTo(ANDRE.asString) + .setSender(bobUsername.asString) + .setFrom(bobUsername.asString) + .setTo(andreUsername.asString) .setBody("testmail", StandardCharsets.UTF_8) .build - val bobDraftsPath = MailboxPath.forUser(BOB, DefaultMailboxes.DRAFTS) + val bobDraftsPath = MailboxPath.forUser(bobUsername, DefaultMailboxes.DRAFTS) server.getProbe(classOf[MailboxProbeImpl]).createMailbox(bobDraftsPath) - val messageId: MessageId = server.getProbe(classOf[MailboxProbeImpl]).appendMessage(BOB.asString(), bobDraftsPath, AppendCommand.builder() + val messageId: MessageId = server.getProbe(classOf[MailboxProbeImpl]).appendMessage(bobUsername.asString(), bobDraftsPath, AppendCommand.builder() .build(message)) .getMessageId messageId diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryWebPushTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryWebPushTest.java index 6327c5fde0..ab6cbc0ba3 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryWebPushTest.java +++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryWebPushTest.java @@ -46,6 +46,7 @@ public class MemoryWebPushTest implements WebPushContract { .overrideWith(new TestJMAPServerModule(), new PushSubscriptionProbeModule()) .overrideWith(binder -> binder.bind(PushClientConfiguration.class).toInstance(PushClientConfiguration.UNSAFE_DEFAULT()))) .extension(new ClockExtension()) + .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS) .build(); @RegisterExtension diff --git a/server/protocols/jmap-rfc-8621-integration-tests/postgres-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/postgres/PostgresWebPushTest.java b/server/protocols/jmap-rfc-8621-integration-tests/postgres-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/postgres/PostgresWebPushTest.java index 919bb3fecd..846554922f 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/postgres-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/postgres/PostgresWebPushTest.java +++ b/server/protocols/jmap-rfc-8621-integration-tests/postgres-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/postgres/PostgresWebPushTest.java @@ -59,6 +59,7 @@ public class PostgresWebPushTest implements WebPushContract { .overrideWith(new TestJMAPServerModule()) .overrideWith(new PushSubscriptionProbeModule()) .overrideWith(binder -> binder.bind(PushClientConfiguration.class).toInstance(PushClientConfiguration.UNSAFE_DEFAULT()))) + .lifeCycle(JamesServerExtension.Lifecycle.PER_CLASS) .build(); @RegisterExtension --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
