Skip to content

Commit

Permalink
fix: P4ADEV-398 refactor design (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
antonioT90 authored May 29, 2024
1 parent 3fa3732 commit a64f7f5
Show file tree
Hide file tree
Showing 10 changed files with 228 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public AuthControllerImpl(AuthService authService) {

@Override
public ResponseEntity<AccessToken> postToken(String clientId, String grantType, String subjectToken, String subjectIssuer, String subjectTokenType, String scope) {
authService.authToken(subjectToken);
authService.postToken(subjectToken);
return new ResponseEntity<>(HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

public interface AuthService {

void authToken(String token);
void postToken(String token);
}
Original file line number Diff line number Diff line change
@@ -1,38 +1,20 @@
package it.gov.pagopa.payhub.auth.service;

import io.jsonwebtoken.Claims;
import it.gov.pagopa.payhub.auth.exception.custom.InvalidTokenException;
import it.gov.pagopa.payhub.auth.utils.JWTValidator;
import it.gov.pagopa.payhub.auth.service.exchange.ExchangeTokenService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Map;

@Slf4j
@Service
public class AuthServiceImpl implements AuthService{
private final String audience;
private final String issuer;
private final String urlJwkProvider;
private final JWTValidator jwtValidator;
private final ExchangeTokenService exchangeTokenService;

public AuthServiceImpl(@Value("${jwt.token.audience:}")String audience,
@Value("${jwt.token.issuer:}")String issuer,
@Value("${jwt.token.jwk:}")String urlJwkProvider,
JWTValidator jwtValidator) {
this.audience = audience;
this.issuer = issuer;
this.urlJwkProvider = urlJwkProvider;
this.jwtValidator = jwtValidator;
public AuthServiceImpl(ExchangeTokenService exchangeTokenService) {
this.exchangeTokenService = exchangeTokenService;
}

@Override
public void authToken(String token) {
Map<String, String> data = jwtValidator.validate(token, urlJwkProvider);
if (!(data.get(Claims.AUDIENCE).equals(audience) && data.get(Claims.ISSUER).equals(issuer))){
throw new InvalidTokenException("Invalid audience or issuer in the token");
}
log.info("Token validated successfully");
public void postToken(String token) {
exchangeTokenService.postToken(token);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package it.gov.pagopa.payhub.auth.service.exchange;

public interface ExchangeTokenService {
void postToken(String token);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package it.gov.pagopa.payhub.auth.service.exchange;

import org.springframework.stereotype.Service;

@Service
public class ExchangeTokenServiceImpl implements ExchangeTokenService{

private final ValidateTokenService validateTokenService;

public ExchangeTokenServiceImpl(ValidateTokenService validateTokenService) {
this.validateTokenService = validateTokenService;
}

@Override
public void postToken(String token) {
validateTokenService.validate(token);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package it.gov.pagopa.payhub.auth.service.exchange;

import io.jsonwebtoken.Claims;
import it.gov.pagopa.payhub.auth.exception.custom.InvalidTokenException;
import it.gov.pagopa.payhub.auth.utils.JWTValidator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Map;

@Service
@Slf4j
class ValidateTokenService {
private final String audience;
private final String issuer;
private final String urlJwkProvider;
private final JWTValidator jwtValidator;

public ValidateTokenService(@Value("${jwt.token.audience:}")String audience,
@Value("${jwt.token.issuer:}")String issuer,
@Value("${jwt.token.jwk:}")String urlJwkProvider,
JWTValidator jwtValidator) {
this.audience = audience;
this.issuer = issuer;
this.urlJwkProvider = urlJwkProvider;
this.jwtValidator = jwtValidator;
}

public void validate(String token) {
Map<String, String> data = jwtValidator.validate(token, urlJwkProvider);
if (!(data.get(Claims.AUDIENCE).equals(audience) && data.get(Claims.ISSUER).equals(issuer))){
throw new InvalidTokenException("Invalid audience or issuer in the token");
}
log.info("Token validated successfully");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class AuthControllerTest {

@Test
void givenExpectedAuthTokenThenOk() throws Exception {
doNothing().when(authServiceMock).authToken("token");
doNothing().when(authServiceMock).postToken("token");

MvcResult result = mockMvc.perform(
post("/payhub/auth/token")
Expand All @@ -49,7 +49,7 @@ void givenExpectedAuthTokenThenOk() throws Exception {

@Test
void givenRequestWithoutAuthTokenThenBadRequest() throws Exception {
doNothing().when(authServiceMock).authToken("token");
doNothing().when(authServiceMock).postToken("token");

MvcResult result = mockMvc.perform(
post("/payhub/auth/token")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,96 +1,43 @@
package it.gov.pagopa.payhub.auth.service;

import com.github.tomakehurst.wiremock.WireMockServer;
import it.gov.pagopa.payhub.auth.exception.custom.InvalidTokenException;
import it.gov.pagopa.payhub.auth.utils.JWTValidator;
import it.gov.pagopa.payhub.auth.utils.JWTValidatorUtils;
import it.gov.pagopa.payhub.auth.service.exchange.ExchangeTokenService;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;

@ExtendWith(SpringExtension.class)
public class AuthServiceTest {

public static final Date EXPIRES_AT = new Date(System.currentTimeMillis() + 3600000);
private static final String AUD = "AUD";
private static final String ISS = "ISS";

private AuthService authService;
private WireMockServer wireMockServer;
private JWTValidatorUtils utils;
@ExtendWith(MockitoExtension.class)
class AuthServiceTest {

@Mock
private JWTValidator jwtValidator;
private ExchangeTokenService exchangeTokenServiceMock;

private AuthService service;

@BeforeEach
void setup(){
wireMockServer = new WireMockServer(wireMockConfig().dynamicPort());
wireMockServer.start();
utils = new JWTValidatorUtils(wireMockServer);
authService = new AuthServiceImpl(AUD, ISS, utils.getUrlJwkProvider(), jwtValidator);
void init(){
service = new AuthServiceImpl(exchangeTokenServiceMock);
}

@AfterEach
void clean(){
wireMockServer.stop();
}
@Test
void authTokenOk() throws Exception {
String token = utils.generateJWK(EXPIRES_AT);
Map<String, String> claimsMap = createJWKClaims(ISS, AUD);

String wireMockUrl = utils.getUrlJwkProvider();
when(jwtValidator.validate(token, wireMockUrl)).thenReturn(claimsMap);

authService.authToken(token);
Mockito.verify(jwtValidator, times(1)).validate(token, wireMockUrl);
void verifyNotMoreInteractions(){
Mockito.verifyNoMoreInteractions(
exchangeTokenServiceMock
);
}

@Test
void authTokenWrongIss() throws Exception {
String token = utils.generateJWK(EXPIRES_AT);
Map<String, String> claimsMap = createJWKClaims("ISS_FAKE", AUD);
void whenPostTokenThenCallExchangeService(){
// Given
String token = "TOKEN";

String wireMockUrl = utils.getUrlJwkProvider();
when(jwtValidator.validate(token, wireMockUrl)).thenReturn(claimsMap);

assertThrows(InvalidTokenException.class, () ->
authService.authToken(token));

}

@Test
void authTokenWrongAud() throws Exception {
String token = utils.generateJWK(EXPIRES_AT);
Map<String, String> claimsMap = createJWKClaims(ISS, "AUD_FAKE");

String wireMockUrl = utils.getUrlJwkProvider();
when(jwtValidator.validate(token, wireMockUrl)).thenReturn(claimsMap);

assertThrows(InvalidTokenException.class, () ->
authService.authToken(token));

}
// When
service.postToken(token);

private Map<String, String> createJWKClaims (String iss, String aud){
Map<String, String> claims = new HashMap<>();
claims.put("iss", iss);
claims.put("aud", aud);
claims.put("exp", "1715267318");
claims.put("jti", "my-key-id");
return claims;
// Then
Mockito.verify(exchangeTokenServiceMock).postToken(token);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package it.gov.pagopa.payhub.auth.service.exchange;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
class ExchangeTokenServiceTest {

@Mock
private ValidateTokenService validateTokenServiceMock;

private ExchangeTokenService service;

@BeforeEach
void init(){
service = new ExchangeTokenServiceImpl(validateTokenServiceMock);
}

@AfterEach
void verifyNotMoreInteractions(){
Mockito.verifyNoMoreInteractions(
validateTokenServiceMock
);
}

@Test
void givenValidTokenWhenPostTokenThenSuccess(){
// Given
String token = "TOKEN";

// When
service.postToken(token);

// Then
Mockito.verify(validateTokenServiceMock).validate(token);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package it.gov.pagopa.payhub.auth.service.exchange;

import com.github.tomakehurst.wiremock.WireMockServer;
import it.gov.pagopa.payhub.auth.exception.custom.InvalidTokenException;
import it.gov.pagopa.payhub.auth.utils.JWTValidator;
import it.gov.pagopa.payhub.auth.utils.JWTValidatorUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;

@ExtendWith(SpringExtension.class)
class ValidateTokenServiceTest {

public static final Date EXPIRES_AT = new Date(System.currentTimeMillis() + 3600000);
private static final String AUD = "AUD";
private static final String ISS = "ISS";

private ValidateTokenService validateTokenService;
private WireMockServer wireMockServer;
private JWTValidatorUtils utils;

@Mock
private JWTValidator jwtValidator;

@BeforeEach
void setup(){
wireMockServer = new WireMockServer(wireMockConfig().dynamicPort());
wireMockServer.start();
utils = new JWTValidatorUtils(wireMockServer);
validateTokenService = new ValidateTokenService(AUD, ISS, utils.getUrlJwkProvider(), jwtValidator);
}

@AfterEach
void clean(){
wireMockServer.stop();
}
@Test
void authTokenOk() throws Exception {
String token = utils.generateJWK(EXPIRES_AT);
Map<String, String> claimsMap = createJWKClaims(ISS, AUD);

String wireMockUrl = utils.getUrlJwkProvider();
when(jwtValidator.validate(token, wireMockUrl)).thenReturn(claimsMap);

validateTokenService.validate(token);
Mockito.verify(jwtValidator, times(1)).validate(token, wireMockUrl);
}

@Test
void authTokenWrongIss() throws Exception {
String token = utils.generateJWK(EXPIRES_AT);
Map<String, String> claimsMap = createJWKClaims("ISS_FAKE", AUD);

String wireMockUrl = utils.getUrlJwkProvider();
when(jwtValidator.validate(token, wireMockUrl)).thenReturn(claimsMap);

assertThrows(InvalidTokenException.class, () ->
validateTokenService.validate(token));

}

@Test
void authTokenWrongAud() throws Exception {
String token = utils.generateJWK(EXPIRES_AT);
Map<String, String> claimsMap = createJWKClaims(ISS, "AUD_FAKE");

String wireMockUrl = utils.getUrlJwkProvider();
when(jwtValidator.validate(token, wireMockUrl)).thenReturn(claimsMap);

assertThrows(InvalidTokenException.class, () ->
validateTokenService.validate(token));

}

private Map<String, String> createJWKClaims (String iss, String aud){
Map<String, String> claims = new HashMap<>();
claims.put("iss", iss);
claims.put("aud", aud);
claims.put("exp", "1715267318");
claims.put("jti", "my-key-id");
return claims;
}
}

0 comments on commit a64f7f5

Please sign in to comment.