Skip to content

Commit

Permalink
added authorization tests
Browse files Browse the repository at this point in the history
  • Loading branch information
petretiandrea committed Nov 20, 2024
1 parent 658f8e3 commit 3db7bbc
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 16 deletions.
7 changes: 6 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,21 @@ 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",
"useSwaggerUI" : "false",
"reactive" : "true",
"swaggerAnnotations" : "false",
"skipDefaultInterface" : "true",
"openApiNullable" : "true",
])
typeMappings.set([
"DateTime" : "java.time.LocalDateTime",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package it.gov.pagopa.rtp.activator.controller;

import java.net.URI;
import java.util.UUID;

import org.springframework.http.ResponseEntity;
Expand All @@ -16,16 +17,16 @@
@Validated
public class ActivationAPIControllerImpl implements CreateApi {

@PreAuthorize("hasRole('write_rtp_activations')")
@Override
@PreAuthorize("hasRole('write_rtp_activations')")
public Mono<ResponseEntity<Void>> activate(
UUID requestId,
String version,
Mono<ActivationReqDto> activationReqDto,
ServerWebExchange exchange
) {
return activationReqDto.flatMap(
request -> Mono.just(ResponseEntity.ok().build())
request -> Mono.just(ResponseEntity.created(URI.create("http://localhost")).build())
);
}
}
Original file line number Diff line number Diff line change
@@ -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));
}
}

Original file line number Diff line number Diff line change
@@ -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"));
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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
Expand All @@ -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();
}

Expand Down
17 changes: 17 additions & 0 deletions src/test/java/it/gov/pagopa/rtp/activator/utils/Users.java
Original file line number Diff line number Diff line change
@@ -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 { }
}
2 changes: 1 addition & 1 deletion src/test/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
logging.level.org.springframework.security=DEBUG
logging.level.org.springframework.security=DEBUG

0 comments on commit 3db7bbc

Please sign in to comment.