From 3db7bbc2c01506244b36d899eac29c12bd8d7dc3 Mon Sep 17 00:00:00 2001 From: petretiandrea Date: Wed, 20 Nov 2024 17:59:27 +0100 Subject: [PATCH] added authorization tests --- build.gradle | 7 +- .../configuration/SecurityConfig.java | 2 +- .../ActivationAPIControllerImpl.java | 5 +- .../NoSignatureJwtDecoderTest.java | 13 +++- .../ActivationAPIControllerImplTest.java | 71 +++++++++++++++++++ .../JwtUtils.java} | 11 +-- .../gov/pagopa/rtp/activator/utils/Users.java | 17 +++++ src/test/resources/application.properties | 2 +- 8 files changed, 112 insertions(+), 16 deletions(-) create mode 100644 src/test/java/it/gov/pagopa/rtp/activator/controller/ActivationAPIControllerImplTest.java rename src/test/java/it/gov/pagopa/rtp/activator/{JwtTestUtils.java => utils/JwtUtils.java} (83%) create mode 100644 src/test/java/it/gov/pagopa/rtp/activator/utils/Users.java diff --git a/build.gradle b/build.gradle index 3d3cf19..1d35c96 100644 --- a/build.gradle +++ b/build.gradle @@ -75,9 +75,13 @@ openApiGenerate { apiPackage.set("it.gov.pagopa.rtp.activator.controller.generated") modelPackage.set("it.gov.pagopa.rtp.activator.model.generated") modelNameSuffix.set("Dto") + generateApiTests.set(false) + generateApiDocumentation.set(false) + generateApiTests.set(false) + generateModelTests.set(false) + library.set("spring-boot") configOptions.set([ "dateLibrary" : "java8", - "requestMappingMode" : "api_interface", "useSpringBoot3" : "true", "interfaceOnly" : "true", "useTags" : "true", @@ -85,6 +89,7 @@ openApiGenerate { "reactive" : "true", "swaggerAnnotations" : "false", "skipDefaultInterface" : "true", + "openApiNullable" : "true", ]) typeMappings.set([ "DateTime" : "java.time.LocalDateTime", diff --git a/src/main/java/it/gov/pagopa/rtp/activator/configuration/SecurityConfig.java b/src/main/java/it/gov/pagopa/rtp/activator/configuration/SecurityConfig.java index b51373c..ffb7a17 100644 --- a/src/main/java/it/gov/pagopa/rtp/activator/configuration/SecurityConfig.java +++ b/src/main/java/it/gov/pagopa/rtp/activator/configuration/SecurityConfig.java @@ -15,7 +15,7 @@ @Configuration @EnableWebFluxSecurity -@EnableReactiveMethodSecurity // allows to use @PreAuthorize with roles +@EnableReactiveMethodSecurity(proxyTargetClass = true) // allows to use @PreAuthorize with roles public class SecurityConfig { @Bean diff --git a/src/main/java/it/gov/pagopa/rtp/activator/controller/ActivationAPIControllerImpl.java b/src/main/java/it/gov/pagopa/rtp/activator/controller/ActivationAPIControllerImpl.java index 558b867..7ee2e15 100644 --- a/src/main/java/it/gov/pagopa/rtp/activator/controller/ActivationAPIControllerImpl.java +++ b/src/main/java/it/gov/pagopa/rtp/activator/controller/ActivationAPIControllerImpl.java @@ -1,5 +1,6 @@ package it.gov.pagopa.rtp.activator.controller; +import java.net.URI; import java.util.UUID; import org.springframework.http.ResponseEntity; @@ -16,8 +17,8 @@ @Validated public class ActivationAPIControllerImpl implements CreateApi { - @PreAuthorize("hasRole('write_rtp_activations')") @Override + @PreAuthorize("hasRole('write_rtp_activations')") public Mono> activate( UUID requestId, String version, @@ -25,7 +26,7 @@ public Mono> activate( ServerWebExchange exchange ) { return activationReqDto.flatMap( - request -> Mono.just(ResponseEntity.ok().build()) + request -> Mono.just(ResponseEntity.created(URI.create("http://localhost")).build()) ); } } diff --git a/src/test/java/it/gov/pagopa/rtp/activator/configuration/NoSignatureJwtDecoderTest.java b/src/test/java/it/gov/pagopa/rtp/activator/configuration/NoSignatureJwtDecoderTest.java index 4429bfe..d55a84e 100644 --- a/src/test/java/it/gov/pagopa/rtp/activator/configuration/NoSignatureJwtDecoderTest.java +++ b/src/test/java/it/gov/pagopa/rtp/activator/configuration/NoSignatureJwtDecoderTest.java @@ -1,21 +1,28 @@ package it.gov.pagopa.rtp.activator.configuration; import com.nimbusds.jose.JOSEException; -import it.gov.pagopa.rtp.activator.JwtTestUtils; +import it.gov.pagopa.rtp.activator.utils.JwtUtils; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; +import org.springframework.security.oauth2.jwt.JwtValidationException; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; class NoSignatureJwtDecoderTest { - @Test void givenSignedTokenMustDecodeWithoutVerifySignature() throws JOSEException { final var decoder = new NoSignatureJwtDecoder(); - final var token = JwtTestUtils.generateToken("me", "none"); + final var token = JwtUtils.generateToken("me", "none"); assertThat(decoder.decode(token), Matchers.notNullValue()); } + @Test + void givenExpiredTokenMustThrowError() throws JOSEException { + final var decoder = new NoSignatureJwtDecoder(); + final var token = JwtUtils.generateExpiredToken("me", "none"); + assertThrows(JwtValidationException.class, () -> decoder.decode(token)); + } } diff --git a/src/test/java/it/gov/pagopa/rtp/activator/controller/ActivationAPIControllerImplTest.java b/src/test/java/it/gov/pagopa/rtp/activator/controller/ActivationAPIControllerImplTest.java new file mode 100644 index 0000000..8e754e7 --- /dev/null +++ b/src/test/java/it/gov/pagopa/rtp/activator/controller/ActivationAPIControllerImplTest.java @@ -0,0 +1,71 @@ +package it.gov.pagopa.rtp.activator.controller; + +import it.gov.pagopa.rtp.activator.configuration.SecurityConfig; +import it.gov.pagopa.rtp.activator.model.generated.ActivationReqDto; +import it.gov.pagopa.rtp.activator.model.generated.PayerDto; +import it.gov.pagopa.rtp.activator.utils.Users; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Import; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.reactive.server.WebTestClient; + +import java.util.UUID; + +import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.springSecurity; + + +@ExtendWith(SpringExtension.class) +@WebFluxTest(controllers = {ActivationAPIControllerImpl.class}) +@Import(SecurityConfig.class) +class ActivationAPIControllerImplTest { + @Autowired + ApplicationContext context; + + WebTestClient web; + + @BeforeEach + public void setup() { + web = WebTestClient + .bindToApplicationContext(this.context) + .apply(springSecurity()) + .configureClient() + .build(); + } + + @Test + @Users.RtpWriter + void shouldCreateNewActivation() { + web.post() + .uri("/activations") + .header("RequestId", UUID.randomUUID().toString()) + .header("Version", "v1") + .bodyValue(generateActivationRequest()) + .exchange() + .expectStatus().isEqualTo(HttpStatus.CREATED) + .expectHeader().exists(HttpHeaders.LOCATION); + } + + @Test + @WithMockUser + void userWithoutEnoughPermissionShouldNotCreateNewActivation() { + web.post() + .uri("/activations") + .header("RequestId", UUID.randomUUID().toString()) + .header("Version", "v1") + .bodyValue(generateActivationRequest()) + .exchange() + .expectStatus().isEqualTo(HttpStatus.FORBIDDEN); + } + + private ActivationReqDto generateActivationRequest() { + return new ActivationReqDto(new PayerDto("RSSMRA85T10A562S", "134")); + } +} \ No newline at end of file diff --git a/src/test/java/it/gov/pagopa/rtp/activator/JwtTestUtils.java b/src/test/java/it/gov/pagopa/rtp/activator/utils/JwtUtils.java similarity index 83% rename from src/test/java/it/gov/pagopa/rtp/activator/JwtTestUtils.java rename to src/test/java/it/gov/pagopa/rtp/activator/utils/JwtUtils.java index e0d1ab6..951cbb5 100644 --- a/src/test/java/it/gov/pagopa/rtp/activator/JwtTestUtils.java +++ b/src/test/java/it/gov/pagopa/rtp/activator/utils/JwtUtils.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.rtp.activator; +package it.gov.pagopa.rtp.activator.utils; import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.JWSAlgorithm; @@ -12,7 +12,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -public final class JwtTestUtils { +public final class JwtUtils { public static String generateToken(String subject, String... roles) throws JOSEException { return generateToken(subject, new Date(new Date().getTime() + 60 * 60 * 1000), roles); // 1 hour @@ -23,27 +23,22 @@ public static String generateExpiredToken(String subject, String... roles) throw } private static String generateToken(String subject, Date expirationTime, String... roles) throws JOSEException { - // Create HMAC signer JWSSigner signer = new MACSigner( IntStream.range(0, 256).mapToObj(Integer::toString).collect(Collectors.joining()) ); - // Prepare JWT with claims set JWTClaimsSet claimsSet = new JWTClaimsSet.Builder() .subject(subject) .claim("groups", roles) .issuer("pagopa.it") - .expirationTime(expirationTime) // 1 hour expiration + .expirationTime(expirationTime) .build(); SignedJWT signedJWT = new SignedJWT( new JWSHeader(JWSAlgorithm.HS256), claimsSet); - // Apply the HMAC signature signedJWT.sign(signer); - - // Serialize to compact form return signedJWT.serialize(); } diff --git a/src/test/java/it/gov/pagopa/rtp/activator/utils/Users.java b/src/test/java/it/gov/pagopa/rtp/activator/utils/Users.java new file mode 100644 index 0000000..bdabc68 --- /dev/null +++ b/src/test/java/it/gov/pagopa/rtp/activator/utils/Users.java @@ -0,0 +1,17 @@ +package it.gov.pagopa.rtp.activator.utils; + +import org.springframework.security.test.context.support.WithMockUser; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +public class Users { + + @Retention(RetentionPolicy.RUNTIME) + @WithMockUser(value = "writer", roles = "write_rtp_activations") + public @interface RtpWriter { } + + @Retention(RetentionPolicy.RUNTIME) + @WithMockUser(value = "reader", roles = "read_rtp_activations") + public @interface RtpReader { } +} diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 1060f52..cf39e7e 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -1 +1 @@ -logging.level.org.springframework.security=DEBUG \ No newline at end of file +logging.level.org.springframework.security=DEBUG