This is an automated email from the ASF dual-hosted git repository. rcordier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 9239b2f838b11978082fa2807fbb07db4952d913 Author: duc91 <[email protected]> AuthorDate: Fri May 29 14:20:55 2020 +0700 JAMES-3093 Organize AuthenticationContract and implementations --- ...est.java => DistributedAuthenticationTest.java} | 4 +- .../DistributedBasicAuthenticationTest.java | 51 ----- .../rfc8621/contract/AuthenticationContract.scala | 232 +++++++++++++++++++++ .../contract/BasicAuthenticationContract.scala | 123 ----------- .../james/jmap/rfc8621/contract/Fixture.scala | 8 + .../contract/JWTAuthenticationContract.scala | 107 ---------- .../rfc8621/memory/MemoryAuthenticationTest.java | 4 +- server/protocols/jmap/pom.xml | 4 - 8 files changed, 244 insertions(+), 289 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/DistributedJWTAuthenticationTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedAuthenticationTest.java similarity index 94% rename from server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedJWTAuthenticationTest.java rename to server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedAuthenticationTest.java index 0a8787b..8ab8ee8 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedJWTAuthenticationTest.java +++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedAuthenticationTest.java @@ -25,14 +25,14 @@ import org.apache.james.CassandraRabbitMQJamesServerMain; import org.apache.james.DockerElasticSearchExtension; import org.apache.james.JamesServerBuilder; import org.apache.james.JamesServerExtension; -import org.apache.james.jmap.rfc8621.contract.JWTAuthenticationContract; +import org.apache.james.jmap.rfc8621.contract.AuthenticationContract; import org.apache.james.modules.AwsS3BlobStoreExtension; import org.apache.james.modules.RabbitMQExtension; import org.apache.james.modules.TestJMAPServerModule; import org.apache.james.modules.blobstore.BlobStoreConfiguration; import org.junit.jupiter.api.extension.RegisterExtension; -public class DistributedJWTAuthenticationTest implements JWTAuthenticationContract { +class DistributedAuthenticationTest implements AuthenticationContract { @RegisterExtension static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir -> CassandraRabbitMQJamesConfiguration.builder() 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/DistributedBasicAuthenticationTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedBasicAuthenticationTest.java deleted file mode 100644 index d4f2151..0000000 --- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedBasicAuthenticationTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - -package org.apache.james.jmap.rfc8621.distributed; - -import org.apache.james.CassandraExtension; -import org.apache.james.CassandraRabbitMQJamesConfiguration; -import org.apache.james.CassandraRabbitMQJamesServerMain; -import org.apache.james.DockerElasticSearchExtension; -import org.apache.james.GuiceJamesServer; -import org.apache.james.JamesServerBuilder; -import org.apache.james.JamesServerExtension; -import org.apache.james.jmap.rfc8621.contract.BasicAuthenticationContract; -import org.apache.james.modules.AwsS3BlobStoreExtension; -import org.apache.james.modules.RabbitMQExtension; -import org.apache.james.modules.TestJMAPServerModule; -import org.apache.james.modules.blobstore.BlobStoreConfiguration; -import org.junit.jupiter.api.extension.RegisterExtension; - -public class DistributedBasicAuthenticationTest implements BasicAuthenticationContract { - @RegisterExtension - static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir -> - CassandraRabbitMQJamesConfiguration.builder() - .workingDirectory(tmpDir) - .configurationFromClasspath() - .blobStore(BlobStoreConfiguration.objectStorage().disableCache()) - .build()) - .extension(new DockerElasticSearchExtension()) - .extension(new CassandraExtension()) - .extension(new RabbitMQExtension()) - .extension(new AwsS3BlobStoreExtension()) - .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration) - .overrideWith(new TestJMAPServerModule())) - .build(); -} 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/AuthenticationContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/AuthenticationContract.scala new file mode 100644 index 0000000..6d2b766 --- /dev/null +++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/AuthenticationContract.scala @@ -0,0 +1,232 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.jmap.rfc8621.contract + +import io.netty.handler.codec.http.HttpHeaderNames.ACCEPT +import io.restassured.RestAssured.{`given`, requestSpecification} +import io.restassured.authentication.NoAuthScheme +import io.restassured.http.Header +import org.apache.http.HttpStatus.{SC_OK, SC_UNAUTHORIZED} +import org.apache.james.GuiceJamesServer +import org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER, ALICE, ALICE_PASSWORD, AUTHORIZATION_HEADER, BOB, BOB_BASIC_AUTH_HEADER, BOB_PASSWORD, DOMAIN, DOMAIN_WITH_SPACE, ECHO_REQUEST_OBJECT, INVALID_JWT_TOKEN, UNKNOWN_USER_TOKEN, USER_TOKEN, getHeadersWith, toBase64, _} +import org.apache.james.jmap.rfc8621.contract.tags.CategoryTags +import org.apache.james.utils.DataProbeImpl +import org.junit.jupiter.api.{BeforeEach, Nested, Tag, Test} + + +trait AuthenticationContract { + @BeforeEach + def setup(server: GuiceJamesServer): Unit = { + server.getProbe(classOf[DataProbeImpl]) + .fluent + .addDomain(DOMAIN.asString) + .addDomain(_2_DOT_DOMAIN.asString) + .addUser(USER.asString, USER_PASSWORD) + .addUser(ALICE.asString, ALICE_PASSWORD) + .addUser(BOB.asString, BOB_PASSWORD) + + requestSpecification = baseRequestSpecBuilder(server) + .setAuth(new NoAuthScheme) + .build + } + + @Nested + class BothAuthenticationMechanisms { + @Tag(CategoryTags.BASIC_FEATURE) + @Test + def shouldRespond200WhenBasicAuthValidAndJWTInvalid(): Unit = { + `given` + .headers(getHeadersWith(BOB_BASIC_AUTH_HEADER)) + .header(new Header(AUTHORIZATION_HEADER, s"Bearer $UNKNOWN_USER_TOKEN")) + .body(ECHO_REQUEST_OBJECT) + .when + .post + .`then` + .statusCode(SC_OK) + } + + @Tag(CategoryTags.BASIC_FEATURE) + @Test + def shouldRespond200WhenJWTAuthValidAndBasicAuthInvalid(): Unit = { + `given` + .headers(getHeadersWith(new Header(AUTHORIZATION_HEADER, s"Basic ${toBase64(s"this-thing-wrong")}"))) + .header(new Header(AUTHORIZATION_HEADER, s"Bearer $USER_TOKEN")) + .body(ECHO_REQUEST_OBJECT) + .when + .post + .`then` + .statusCode(SC_OK) + } + + @Tag(CategoryTags.BASIC_FEATURE) + @Test + def shouldRespond200WhenBothAuthenticationValid(): Unit = { + `given` + .headers(getHeadersWith(BOB_BASIC_AUTH_HEADER)) + .header(new Header(AUTHORIZATION_HEADER, s"Bearer $USER_TOKEN")) + .body(ECHO_REQUEST_OBJECT) + .when + .post + .`then` + .statusCode(SC_OK) + } + + @Tag(CategoryTags.BASIC_FEATURE) + @Test + def shouldRespond401WhenNoneAuthenticationValid(): Unit = { + `given` + .headers(getHeadersWith(new Header(AUTHORIZATION_HEADER, s"Basic ${toBase64(s"this-one-wrong")}"))) + .header(new Header(AUTHORIZATION_HEADER, s"Bearer $UNKNOWN_USER_TOKEN")) + .body(ECHO_REQUEST_OBJECT) + .when + .post + .`then` + .statusCode(SC_UNAUTHORIZED) + } + } + + @Nested + class BasicAuth { + @Test + def postShouldRespond401WhenNoAuthorizationHeader(): Unit = { + given() + .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER) + .body(ECHO_REQUEST_OBJECT) + .when + .post + .`then` + .statusCode(SC_UNAUTHORIZED) + } + + @Test + @Tag(CategoryTags.BASIC_FEATURE) + def postShouldRespond200WhenHasCredentials(): Unit = { + `given` + .headers(getHeadersWith(BOB_BASIC_AUTH_HEADER)) + .body(ECHO_REQUEST_OBJECT) + .when + .post + .`then` + .statusCode(SC_OK) + } + + @Test + def postShouldRespond401WhenCredentialsWithInvalidUser(): Unit = { + val authHeader: Header = new Header(AUTHORIZATION_HEADER, s"Basic ${toBase64(s"${BOB.getLocalPart}@@$DOMAIN:$BOB_PASSWORD")}") + `given` + .headers(getHeadersWith(authHeader)) + .body(ECHO_REQUEST_OBJECT) + .when + .post + .`then` + .statusCode(SC_UNAUTHORIZED) + } + + @Test + def postShouldRespond200WhenCredentialsWith2DotDomain(): Unit = { + val authHeader: Header = new Header(AUTHORIZATION_HEADER, s"Basic ${toBase64(s"${ALICE.asString}:$ALICE_PASSWORD")}") + `given` + .headers(getHeadersWith(authHeader)) + .body(ECHO_REQUEST_OBJECT) + .when + .post + .`then` + .statusCode(SC_OK) + } + + @Test + def postShouldRespond401WhenCredentialsWithSpaceDomain(): Unit = { + val authHeader: Header = new Header(AUTHORIZATION_HEADER, s"Basic ${toBase64(s"${BOB.getLocalPart}@$DOMAIN_WITH_SPACE:$BOB_PASSWORD")}") + `given` + .headers(getHeadersWith(authHeader)) + .body(ECHO_REQUEST_OBJECT) + .when + .post + .`then` + .statusCode(SC_UNAUTHORIZED) + } + + @Test + def postShouldRespond401WhenUserNotFound(): Unit = { + val authHeader: Header = new Header(AUTHORIZATION_HEADER, s"Basic ${toBase64(s"usernotfound@$DOMAIN:$BOB_PASSWORD")}") + `given` + .headers(getHeadersWith(authHeader)) + .body(ECHO_REQUEST_OBJECT) + .when + .post + .`then` + .statusCode(SC_UNAUTHORIZED) + } + + @Test + @Tag(CategoryTags.BASIC_FEATURE) + def postShouldRespond401WhenWrongPassword(): Unit = { + val authHeader: Header = new Header(AUTHORIZATION_HEADER, s"Basic ${toBase64(s"${BOB.asString}:WRONG_PASSWORD")}") + `given` + .headers(getHeadersWith(authHeader)) + .body(ECHO_REQUEST_OBJECT) + .when + .post + .`then` + .statusCode(SC_UNAUTHORIZED) + } + } + + @Nested + class JWTAuth { + @Tag(CategoryTags.BASIC_FEATURE) + @Test + def postShouldReturn200WhenValidJwtAuthorizationHeader(): Unit = { + `given` + .headers(getHeadersWith(new Header(AUTHORIZATION_HEADER, s"Bearer $USER_TOKEN"))) + .body(ECHO_REQUEST_OBJECT) + .when + .post + .`then` + .statusCode(SC_OK) + } + + @Test + @Tag(CategoryTags.BASIC_FEATURE) + def postShouldReturn401WhenValidUnknownUserJwtAuthorizationHeader(): Unit = { + val authHeader: Header = new Header(AUTHORIZATION_HEADER, s"Bearer $UNKNOWN_USER_TOKEN") + `given` + .headers(getHeadersWith(authHeader)) + .body(ECHO_REQUEST_OBJECT) + .when + .post + .`then` + .statusCode(SC_UNAUTHORIZED) + } + + @Test + @Tag(CategoryTags.BASIC_FEATURE) + def postShouldReturn401WhenInvalidJwtAuthorizationHeader(): Unit = { + `given` + .headers(getHeadersWith(new Header(AUTHORIZATION_HEADER, s"Bearer $INVALID_JWT_TOKEN"))) + .body(ECHO_REQUEST_OBJECT) + .when + .post + .`then` + .statusCode(SC_UNAUTHORIZED) + } + } +} + 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/BasicAuthenticationContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/BasicAuthenticationContract.scala deleted file mode 100644 index f257bbf..0000000 --- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/BasicAuthenticationContract.scala +++ /dev/null @@ -1,123 +0,0 @@ -package org.apache.james.jmap.rfc8621.contract - -import java.nio.charset.StandardCharsets.UTF_8 -import java.util.Base64 - -import io.netty.handler.codec.http.HttpHeaderNames.ACCEPT -import io.restassured.RestAssured.{`given`, requestSpecification} -import io.restassured.authentication.NoAuthScheme -import io.restassured.http.Header -import org.apache.http.HttpStatus.{SC_OK, SC_UNAUTHORIZED} -import org.apache.james.GuiceJamesServer -import org.apache.james.jmap.rfc8621.contract.BasicAuthenticationContract._ -import org.apache.james.jmap.rfc8621.contract.Fixture._ -import org.apache.james.jmap.rfc8621.contract.tags.CategoryTags -import org.apache.james.utils.DataProbeImpl -import org.junit.jupiter.api.{BeforeEach, Tag, Test} - -object BasicAuthenticationContract { - private def toBase64(stringValue: String): String = { - Base64.getEncoder.encodeToString(stringValue.getBytes(UTF_8)) - } -} - -trait BasicAuthenticationContract { - @BeforeEach - def setUp(server: GuiceJamesServer): Unit = { - server.getProbe(classOf[DataProbeImpl]) - .fluent() - .addDomain(DOMAIN.asString()) - .addUser(BOB.asString(), BOB_PASSWORD) - .addDomain(_2_DOT_DOMAIN.asString()) - .addUser(ALICE.asString(), ALICE_PASSWORD) - - requestSpecification = baseRequestSpecBuilder(server) - .setAuth(new NoAuthScheme()) - .build - } - - @Test - def postShouldRespondUnauthorizedWhenNoAuthorizationHeader(): Unit = { - given() - .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER) - .body(ECHO_REQUEST_OBJECT) - .when() - .post() - .then - .statusCode(SC_UNAUTHORIZED) - } - - @Test - @Tag(CategoryTags.BASIC_FEATURE) - def postShouldRespond200WhenHasCredentials(): Unit = { - val authHeader: Header = new Header(AUTHORIZATION_HEADER, s"Basic ${toBase64(s"${BOB.asString}:$BOB_PASSWORD")}") - `given`() - .headers(getHeadersWith(authHeader)) - .body(ECHO_REQUEST_OBJECT) - .when() - .post() - .then - .statusCode(SC_OK) - } - - @Test - def postShouldRespond401WhenCredentialsWithInvalidUser(): Unit = { - val authHeader: Header = new Header(AUTHORIZATION_HEADER, s"Basic ${toBase64(s"${BOB.getLocalPart}@@$DOMAIN:$BOB_PASSWORD")}") - `given`() - .headers(getHeadersWith(authHeader)) - .body(ECHO_REQUEST_OBJECT) - .when() - .post() - .then - .statusCode(SC_UNAUTHORIZED) - } - - @Test - def postShouldRespondOKWhenCredentialsWith2DotDomain(): Unit = { - val authHeader: Header = new Header(AUTHORIZATION_HEADER, s"Basic ${toBase64(s"${ALICE.asString}:$ALICE_PASSWORD")}") - `given`() - .headers(getHeadersWith(authHeader)) - .body(ECHO_REQUEST_OBJECT) - .when() - .post() - .then - .statusCode(SC_OK) - } - - @Test - def postShouldRespond401WhenCredentialsWithSpaceDomain(): Unit = { - val authHeader: Header = new Header(AUTHORIZATION_HEADER, s"Basic ${toBase64(s"${BOB.getLocalPart}@$DOMAIN_WITH_SPACE:$BOB_PASSWORD")}") - `given`() - .headers(getHeadersWith(authHeader)) - .body(ECHO_REQUEST_OBJECT) - .when() - .post() - .then - .statusCode(SC_UNAUTHORIZED) - } - - @Test - def postShouldRespond401WhenUserNotFound(): Unit = { - val authHeader: Header = new Header(AUTHORIZATION_HEADER, s"Basic ${toBase64(s"usernotfound@$DOMAIN:$BOB_PASSWORD")}") - `given`() - .headers(getHeadersWith(authHeader)) - .body(ECHO_REQUEST_OBJECT) - .when() - .post() - .then - .statusCode(SC_UNAUTHORIZED) - } - - @Test - @Tag(CategoryTags.BASIC_FEATURE) - def postShouldRespond401WhenWrongPassword(): Unit = { - val authHeader: Header = new Header(AUTHORIZATION_HEADER, s"Basic ${toBase64(s"${BOB.asString}:WRONG_PASSWORD")}") - `given`() - .headers(getHeadersWith(authHeader)) - .body(ECHO_REQUEST_OBJECT) - .when() - .post() - .then - .statusCode(SC_UNAUTHORIZED) - } -} 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/Fixture.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/Fixture.scala index be44b77..7d22579 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/Fixture.scala +++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/Fixture.scala @@ -20,6 +20,8 @@ package org.apache.james.jmap.rfc8621.contract import java.nio.charset.StandardCharsets +import java.nio.charset.StandardCharsets.UTF_8 +import java.util.Base64 import io.netty.handler.codec.http.HttpHeaderNames.ACCEPT import io.restassured.authentication.PreemptiveBasicAuthScheme @@ -51,6 +53,10 @@ object Fixture { authScheme } + def toBase64(stringValue: String): String = { + Base64.getEncoder.encodeToString(stringValue.getBytes(UTF_8)) + } + def getHeadersWith(authHeader: Header): Headers = { new Headers( new Header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER), @@ -67,6 +73,8 @@ object Fixture { val BOB_PASSWORD: String = "bobpassword" val ALICE_PASSWORD: String = "alicepassword" + val BOB_BASIC_AUTH_HEADER: Header = new Header(AUTHORIZATION_HEADER, s"Basic ${toBase64(s"${BOB.asString}:$BOB_PASSWORD")}") + val ECHO_REQUEST_OBJECT: String = """{ | "using": [ 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/JWTAuthenticationContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/JWTAuthenticationContract.scala deleted file mode 100644 index 5fbad90..0000000 --- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/JWTAuthenticationContract.scala +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ -package org.apache.james.jmap.rfc8621.contract - -import io.restassured.RestAssured.{`given`, requestSpecification} -import io.restassured.authentication.NoAuthScheme -import io.restassured.http.Header -import org.apache.http.HttpStatus._ -import org.apache.james.GuiceJamesServer -import org.apache.james.core.Username -import org.apache.james.jmap.rfc8621.contract.Fixture._ -import org.apache.james.jmap.rfc8621.contract.JWTAuthenticationContract._ -import org.apache.james.jmap.rfc8621.contract.tags.CategoryTags -import org.apache.james.utils.DataProbeImpl -import org.junit.jupiter.api.{BeforeEach, Tag, Test} - -object JWTAuthenticationContract { - private val USER_TOKEN: String = - "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyQGRvbWFpbi50bGQifQ.U-dUPv6OU6KO5N7CooHUfMkCd" + - "FJHx2F3H4fm7Q79g1BPfBSkifPj5xyVlZ0JwEGXypC4zBw9ay3l4DxzX7D_6p1Hx_ihXsoLx1Ca-WUo44x-XRSpPfgxiZjHCJkGBLMV3RZlA" + - "jip-d18mxkcX3JGplX_sCQkFisduAOAHuKSUg9wI6VBgUQi_0B35FYv6tP_bD6eFtvaAUN9QyXXh8UQjEp8CO12lRz6enfLx_V6BG_fEMkee" + - "6vRqdEqx_F9OF3eWTe1giMp_JhQ7_l1OXXtbd4TndVvTeuVy4irPbsRc-M8x_-qTDpFp6saRRsyOcFspxPp5n3yIhEK7B3UZiseXw" - - private val UNKNOWN_USER_TOKEN: String = - "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.T04BTk" + - "LXkJj24coSZkK13RfG25lpvmSl2MJ7N10KpBk9_-95EGYZdog-BDAn3PJzqVw52z-Bwjh4VOj1-j7cURu0cT4jXehhUrlCxS4n7QHZD" + - "N_bsEYGu7KzjWTpTsUiHe-rN7izXVFxDGG1TGwlmBCBnPW-EFCf9ylUsJi0r2BKNdaaPRfMIrHptH1zJBkkUziWpBN1RNLjmvlAUf49" + - "t1Tbv21ZqYM5Ht2vrhJWczFbuC-TD-8zJkXhjTmA1GVgomIX5dx1cH-dZX1wANNmshUJGHgepWlPU-5VIYxPEhb219RMLJIELMY2qN" + - "OR8Q31ydinyqzXvCSzVJOf6T60-w" - - private val INVALID_JWT_TOKEN: String = - "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbkBvcGVu" + - "thispartiscompletelywrong.reQc3DiVvbQHF08oW1qOUyDJyv3tfzDNk8jhVZequiCdOI9vXnRlOe" + - "-yDYktd4WT8MYhqY7MgS-wR0vO9jZFv8ZCgd_MkKCvCO0HmMjP5iQPZ0kqGkgWUH7X123tfR38MfbCVAdPDba-K3MfkogV1xvDhlkPScFr_6MxE" + - "xtedOK2JnQZn7t9sUzSrcyjWverm7gZkPptkIVoS8TsEeMMME5vFXe_nqkEG69q3kuBUm_33tbR5oNS0ZGZKlG9r41lHBjyf9J1xN4UYV8n866d" + - "a7RPPCzshIWUtO0q9T2umWTnp-6OnOdBCkndrZmRR6pPxsD5YL0_77Wq8KT_5__fGA" - - private val USER: Username = Username.fromLocalPartWithDomain("user", DOMAIN) - private val USER_PASSWORD: String = "user" -} - -trait JWTAuthenticationContract { - @BeforeEach - def setUp(server: GuiceJamesServer): Unit = { - server.getProbe(classOf[DataProbeImpl]) - .fluent() - .addDomain(DOMAIN.asString()) - .addUser(USER.asString(), USER_PASSWORD) - - requestSpecification = baseRequestSpecBuilder(server) - .setAuth(new NoAuthScheme) - .build - } - - @Tag(CategoryTags.BASIC_FEATURE) - @Test - def getMustReturnEndpointsWhenValidJwtAuthorizationHeader(): Unit = { - `given` - .headers(getHeadersWith(new Header(AUTHORIZATION_HEADER, s"Bearer $USER_TOKEN"))) - .body(ECHO_REQUEST_OBJECT) - .when - .post() - .`then` - .statusCode(SC_OK) - } - - @Test - @Tag(CategoryTags.BASIC_FEATURE) - def getMustReturnOKWhenValidUnknownUserJwtAuthorizationHeader(): Unit = { - val authHeader: Header = new Header(AUTHORIZATION_HEADER, s"Bearer $UNKNOWN_USER_TOKEN") - `given`() - .headers(getHeadersWith(authHeader)) - .body(ECHO_REQUEST_OBJECT) - .when() - .post() - .then - .statusCode(SC_UNAUTHORIZED) - } - - @Test - @Tag(CategoryTags.BASIC_FEATURE) - def getMustReturnBadCredentialsWhenInvalidJwtAuthorizationHeader(): Unit = { - `given` - .headers(getHeadersWith(new Header(AUTHORIZATION_HEADER, s"Bearer $INVALID_JWT_TOKEN"))) - .body(ECHO_REQUEST_OBJECT) - .when - .post() - .`then` - .statusCode(SC_UNAUTHORIZED) - } -} 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/MemoryAuthenticationTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryAuthenticationTest.java index 5fd5b42..74163fd 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryAuthenticationTest.java +++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryAuthenticationTest.java @@ -24,11 +24,11 @@ import static org.apache.james.MemoryJamesServerMain.IN_MEMORY_SERVER_AGGREGATE_ import org.apache.james.GuiceJamesServer; import org.apache.james.JamesServerBuilder; import org.apache.james.JamesServerExtension; -import org.apache.james.jmap.rfc8621.contract.BasicAuthenticationContract; +import org.apache.james.jmap.rfc8621.contract.AuthenticationContract; import org.apache.james.modules.TestJMAPServerModule; import org.junit.jupiter.api.extension.RegisterExtension; -public class MemoryAuthenticationTest implements BasicAuthenticationContract { +class MemoryAuthenticationTest implements AuthenticationContract { @RegisterExtension static JamesServerExtension testExtension = new JamesServerBuilder<>(JamesServerBuilder.defaultConfigurationProvider()) .server(configuration -> GuiceJamesServer.forConfiguration(configuration) diff --git a/server/protocols/jmap/pom.xml b/server/protocols/jmap/pom.xml index 37cc3db..33e0e04 100644 --- a/server/protocols/jmap/pom.xml +++ b/server/protocols/jmap/pom.xml @@ -81,10 +81,6 @@ <artifactId>javax.annotation-api</artifactId> </dependency> <dependency> - <groupId>javax.annotation</groupId> - <artifactId>javax.annotation-api</artifactId> - </dependency> - <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.13</version> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
