From 3d952841777501367de6754bc1195d881635ada6 Mon Sep 17 00:00:00 2001 From: macacia Date: Fri, 8 Nov 2024 17:00:12 +0100 Subject: [PATCH] P4ADEV-788 applied requested changes --- .../A2ALegacyClaims2UserInfoMapper.java | 14 +-- .../security/JwtAuthenticationFilter.java | 15 ++- .../service/AccessTokenBuilderService.java | 34 ++++--- .../a2a/legacy/A2AClientLegacyPropConfig.java | 31 +++++- .../A2ALegacySecretsRetrieverService.java | 43 --------- .../a2a/legacy/A2ALegacySecretsService.java | 21 ++++ .../a2a/legacy/ValidateJWTLegacyService.java | 20 +--- .../user/IamUserInfoDTO2UserInfoMapper.java | 1 + .../payhub/auth/utils/JWTValidator.java | 16 ++-- src/main/resources/application.yml | 9 +- .../auth/controller/AuthnControllerTest.java | 42 +++++--- ...ntrollerNoOrganizzationAccessModeTest.java | 45 +++++---- .../auth/controller/AuthzControllerTest.java | 95 +++++++++++-------- .../A2ALegacyClaims2UserInfoMapperTest.java | 16 ++-- .../AccessTokenBuilderServiceTest.java | 12 ++- .../legacy/A2AClientLegacyPropConfigTest.java | 33 +++++++ .../A2ALegacySecretsRetrieverServiceTest.java | 67 ------------- .../legacy/A2ALegacySecretsServiceTest.java | 44 +++++++++ .../legacy/JWTLegacyHandlerServiceTest.java | 4 +- .../legacy/ValidateJWTLegacyServiceTest.java | 65 +++++-------- .../payhub/auth/utils/JWTValidatorTest.java | 6 +- 21 files changed, 342 insertions(+), 291 deletions(-) delete mode 100644 src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsRetrieverService.java create mode 100644 src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsService.java create mode 100644 src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2AClientLegacyPropConfigTest.java delete mode 100644 src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsRetrieverServiceTest.java create mode 100644 src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsServiceTest.java diff --git a/src/main/java/it/gov/pagopa/payhub/auth/mapper/A2ALegacyClaims2UserInfoMapper.java b/src/main/java/it/gov/pagopa/payhub/auth/mapper/A2ALegacyClaims2UserInfoMapper.java index 91ffa5e..91f4f1d 100644 --- a/src/main/java/it/gov/pagopa/payhub/auth/mapper/A2ALegacyClaims2UserInfoMapper.java +++ b/src/main/java/it/gov/pagopa/payhub/auth/mapper/A2ALegacyClaims2UserInfoMapper.java @@ -12,15 +12,15 @@ public class A2ALegacyClaims2UserInfoMapper { private static final String A2A_PREFIX = "A2A-"; - public UserInfo map(String subject) { + public UserInfo map(String issuer) { return UserInfo.builder() - .issuer(subject) - .userId(A2A_PREFIX + subject) - .name(subject) - .familyName(subject) - .fiscalCode(A2A_PREFIX + subject) + .issuer(issuer) + .userId(A2A_PREFIX + issuer) + .name(issuer) + .familyName(issuer) + .fiscalCode(A2A_PREFIX + issuer) .organizations(Collections.singletonList(UserOrganizationRoles.builder() - .organizationIpaCode(subject) + .organizationIpaCode(issuer) .roles(Collections.singletonList(Constants.ROLE_ADMIN)) .build())) .build(); diff --git a/src/main/java/it/gov/pagopa/payhub/auth/security/JwtAuthenticationFilter.java b/src/main/java/it/gov/pagopa/payhub/auth/security/JwtAuthenticationFilter.java index e6a7425..ee2dad3 100644 --- a/src/main/java/it/gov/pagopa/payhub/auth/security/JwtAuthenticationFilter.java +++ b/src/main/java/it/gov/pagopa/payhub/auth/security/JwtAuthenticationFilter.java @@ -1,8 +1,5 @@ package it.gov.pagopa.payhub.auth.security; -import com.auth0.jwt.JWT; -import com.auth0.jwt.RegisteredClaims; -import com.auth0.jwt.interfaces.DecodedJWT; import it.gov.pagopa.payhub.auth.exception.custom.InvalidAccessTokenException; import it.gov.pagopa.payhub.auth.service.AccessTokenBuilderService; import it.gov.pagopa.payhub.auth.service.AuthnService; @@ -34,11 +31,13 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { private final AuthnService authnService; private final ValidateTokenService validateTokenService; private final JWTLegacyHandlerService jwtLegacyHandlerService; + private final AccessTokenBuilderService accessTokenBuilderService; - public JwtAuthenticationFilter(AuthnService authnService, ValidateTokenService validateTokenService, JWTLegacyHandlerService jwtLegacyHandlerService) { + public JwtAuthenticationFilter(AuthnService authnService, ValidateTokenService validateTokenService, JWTLegacyHandlerService jwtLegacyHandlerService, AccessTokenBuilderService accessTokenBuilderService) { this.authnService = authnService; this.validateTokenService = validateTokenService; this.jwtLegacyHandlerService = jwtLegacyHandlerService; + this.accessTokenBuilderService = accessTokenBuilderService; } @Override @@ -47,7 +46,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse String authorization = request.getHeader(HttpHeaders.AUTHORIZATION); if (StringUtils.hasText(authorization)) { String token = authorization.replace("Bearer ", ""); - UserInfo userInfo = getUserInfoByTokenHeaderClaim(token); + UserInfo userInfo = validateToken(token); Collection authorities = null; if (userInfo.getOrganizationAccess() != null) { authorities = userInfo.getOrganizations().stream() @@ -65,13 +64,11 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse } catch (Exception e){ log.error("Something gone wrong while retrieving UserInfo", e); } - filterChain.doFilter(request, response); } - private UserInfo getUserInfoByTokenHeaderClaim(String token) { - DecodedJWT jwt = JWT.decode(token); - if (!AccessTokenBuilderService.ISSUER.equalsIgnoreCase(jwt.getHeaderClaim(RegisteredClaims.ISSUER).asString())) + private UserInfo validateToken(String token) { + if (!token.startsWith(accessTokenBuilderService.getHeaderPrefix())) return jwtLegacyHandlerService.handleLegacyToken(token); validateTokenService.validate(token); diff --git a/src/main/java/it/gov/pagopa/payhub/auth/service/AccessTokenBuilderService.java b/src/main/java/it/gov/pagopa/payhub/auth/service/AccessTokenBuilderService.java index e838b98..9e1ed7b 100644 --- a/src/main/java/it/gov/pagopa/payhub/auth/service/AccessTokenBuilderService.java +++ b/src/main/java/it/gov/pagopa/payhub/auth/service/AccessTokenBuilderService.java @@ -1,12 +1,10 @@ package it.gov.pagopa.payhub.auth.service; +import com.auth0.jwt.HeaderParams; import com.auth0.jwt.JWT; -import com.auth0.jwt.RegisteredClaims; import com.auth0.jwt.algorithms.Algorithm; import it.gov.pagopa.payhub.auth.utils.CertUtils; import it.gov.pagopa.payhub.model.generated.AccessToken; -import java.util.HashMap; -import java.util.Map; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -16,28 +14,33 @@ import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.time.Instant; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; @Service public class AccessTokenBuilderService { - public static final String ISSUER = "p4pa-auth"; public static final String ACCESS_TOKEN_TYPE = "at+JWT"; private final String allowedAudience; private final int expireIn; - private final RSAPublicKey rsaPublicKey; private final RSAPrivateKey rsaPrivateKey; + private final String kid; + private final DataCipherService dataCipherService; public AccessTokenBuilderService( - @Value("${jwt.audience}") String allowedAudience, - @Value("${jwt.access-token.expire-in}") int expireIn, - @Value("${jwt.access-token.private-key}") String privateKey, - @Value("${jwt.access-token.public-key}") String publicKey - ) { + @Value("${jwt.audience}") String allowedAudience, + @Value("${jwt.access-token.expire-in}") int expireIn, + @Value("${jwt.access-token.private-key}") String privateKey, + @Value("${jwt.access-token.public-key}") String publicKey, DataCipherService dataCipherService) { this.allowedAudience = allowedAudience; this.expireIn = expireIn; + this.dataCipherService = dataCipherService; + byte[] hashed = dataCipherService.hash(publicKey); + this.kid = UUID.nameUUIDFromBytes(hashed).toString(); - try { + try { rsaPrivateKey = CertUtils.pemKey2PrivateKey(privateKey); rsaPublicKey = CertUtils.pemPub2PublicKey(publicKey); } catch (InvalidKeySpecException | NoSuchAlgorithmException | IOException e) { @@ -48,11 +51,11 @@ public AccessTokenBuilderService( public AccessToken build(){ Algorithm algorithm = Algorithm.RSA512(rsaPublicKey, rsaPrivateKey); Map headerClaims = new HashMap<>(); - headerClaims.put(RegisteredClaims.ISSUER, ISSUER); + headerClaims.put(HeaderParams.KEY_ID, kid); headerClaims.put("typ", ACCESS_TOKEN_TYPE); String tokenType = "bearer"; String token = JWT.create() - .withHeader(headerClaims) + .withHeader(headerClaims) .withClaim("typ", tokenType) .withIssuer(allowedAudience) .withJWTId(UUID.randomUUID().toString()) @@ -61,4 +64,9 @@ public AccessToken build(){ .sign(algorithm); return new AccessToken(token, tokenType, expireIn); } + + public String getHeaderPrefix() { + var prefix = String.format("{\"kid\":\"%s\"", kid); + return Base64.getEncoder().encodeToString(prefix.getBytes()); + } } diff --git a/src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2AClientLegacyPropConfig.java b/src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2AClientLegacyPropConfig.java index 07d061c..d03ef19 100644 --- a/src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2AClientLegacyPropConfig.java +++ b/src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2AClientLegacyPropConfig.java @@ -1,14 +1,41 @@ package it.gov.pagopa.payhub.auth.service.a2a.legacy; +import it.gov.pagopa.payhub.auth.exception.custom.InvalidTokenException; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; +import java.security.KeyFactory; +import java.security.PublicKey; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; @Component -@ConfigurationProperties(prefix = "m2m.legacy.public") +@ConfigurationProperties(prefix = "m2m.legacy") @Data public class A2AClientLegacyPropConfig { - private Map secrets; + private Map publicKeys; + + public Map getPublicKeysAsMap() { + return Optional.ofNullable(publicKeys) + .orElse(Map.of()) + .entrySet().stream() + .collect(Collectors.toUnmodifiableMap( + Map.Entry::getKey, + entry -> getPublicKeyFromString(entry.getKey(), entry.getValue()) + )); + } + + private PublicKey getPublicKeyFromString(String keyName, String encodedKey) { + try { + X509EncodedKeySpec publicKeyX509 = new X509EncodedKeySpec(Base64.getDecoder().decode(encodedKey)); + KeyFactory kf = KeyFactory.getInstance("RSA"); + return kf.generatePublic(publicKeyX509); + } catch (Exception e){ + throw new InvalidTokenException("invalid public key for: " + keyName); + } + } } diff --git a/src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsRetrieverService.java b/src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsRetrieverService.java deleted file mode 100644 index ef8ea86..0000000 --- a/src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsRetrieverService.java +++ /dev/null @@ -1,43 +0,0 @@ -package it.gov.pagopa.payhub.auth.service.a2a.legacy; - -import io.jsonwebtoken.io.Decoders; -import it.gov.pagopa.payhub.auth.exception.custom.InvalidTokenException; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import java.security.KeyFactory; -import java.security.PublicKey; -import java.security.spec.X509EncodedKeySpec; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; - -@Service -@Slf4j -public class A2ALegacySecretsRetrieverService { - private final A2AClientLegacyPropConfig a2AClientLegacyPropConfig; - - public A2ALegacySecretsRetrieverService(A2AClientLegacyPropConfig a2AClientLegacyPropConfig) { - this.a2AClientLegacyPropConfig = a2AClientLegacyPropConfig; - } - - public Map envToMap() { - return Optional.ofNullable(a2AClientLegacyPropConfig.getSecrets()) - .orElse(Map.of()) - .entrySet().stream() - .collect(Collectors.toUnmodifiableMap( - Map.Entry::getKey, - entry -> getPublicKeyFromString(entry.getValue()) - )); - } - - private PublicKey getPublicKeyFromString(String encodedKey) { - try { - X509EncodedKeySpec publicKeyX509 = new X509EncodedKeySpec(Decoders.BASE64.decode(encodedKey)); - KeyFactory kf = KeyFactory.getInstance("RSA"); - return kf.generatePublic(publicKeyX509); - } catch (Exception e){ - throw new InvalidTokenException("invalid public key"); - } - } -} diff --git a/src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsService.java b/src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsService.java new file mode 100644 index 0000000..1807520 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsService.java @@ -0,0 +1,21 @@ +package it.gov.pagopa.payhub.auth.service.a2a.legacy; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.security.PublicKey; +import java.util.Map; + +@Service +@Slf4j +public class A2ALegacySecretsService { + private final A2AClientLegacyPropConfig a2AClientLegacyPropConfig; + + public A2ALegacySecretsService(A2AClientLegacyPropConfig a2AClientLegacyPropConfig) { + this.a2AClientLegacyPropConfig = a2AClientLegacyPropConfig; + } + + public Map getLegacySecrets() { + return a2AClientLegacyPropConfig.getPublicKeysAsMap(); + } +} diff --git a/src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/ValidateJWTLegacyService.java b/src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/ValidateJWTLegacyService.java index 468b56c..7ab2eb1 100644 --- a/src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/ValidateJWTLegacyService.java +++ b/src/main/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/ValidateJWTLegacyService.java @@ -6,31 +6,28 @@ import it.gov.pagopa.payhub.auth.utils.JWTValidator; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.springframework.stereotype.Service; import java.security.PublicKey; import java.time.Instant; import java.util.Map; -import java.util.Objects; @Service @Slf4j public class ValidateJWTLegacyService { public static final String TOKEN_TYPE_A2A = "a2a"; - private final A2ALegacySecretsRetrieverService a2ALegacySecretsRetrieverService; + private final A2ALegacySecretsService a2ALegacySecretsService; private final JWTValidator jwtValidator; - public ValidateJWTLegacyService(A2ALegacySecretsRetrieverService a2ALegacySecretsRetrieverService, JWTValidator jwtValidator) { - this.a2ALegacySecretsRetrieverService = a2ALegacySecretsRetrieverService; + public ValidateJWTLegacyService(A2ALegacySecretsService a2ALegacySecretsService, JWTValidator jwtValidator) { + this.a2ALegacySecretsService = a2ALegacySecretsService; this.jwtValidator = jwtValidator; } public Pair> validate(String token) { - Map clientApplicationsPublicKeyMap = a2ALegacySecretsRetrieverService.envToMap(); - verifyEnvMap(clientApplicationsPublicKeyMap); + Map clientApplicationsPublicKeyMap = a2ALegacySecretsService.getLegacySecrets(); Pair> claims = validateToken(clientApplicationsPublicKeyMap, token); validateM2MType(claims.getRight()); validateClaims(claims.getRight()); @@ -38,11 +35,6 @@ public Pair> validate(String token) { return claims; } - private void verifyEnvMap(Map clientApplicationsPublicKeyMap) { - if (clientApplicationsPublicKeyMap.isEmpty()){ - throw new InvalidTokenException("The PublicKey is not present"); - } - } private void validateM2MType(Map claims){ if (!TOKEN_TYPE_A2A.equals(claims.get("type").asString())) @@ -63,9 +55,7 @@ private void validateClaims(Map claims) { private Pair> validateToken(Map clientApplicationsPublicKeyMap, String token) { return clientApplicationsPublicKeyMap.keySet().stream() - .map(key -> new ImmutablePair<>(key, clientApplicationsPublicKeyMap.get(key))) - .map(pair -> jwtValidator.validateLegacyToken(pair.getLeft(), token, pair.getRight())) - .filter(Objects::nonNull) + .map(key -> Pair.of(key, jwtValidator.validate(token, clientApplicationsPublicKeyMap.get(key)))) .findFirst() .orElseThrow(() -> new InvalidTokenException("Invalid token for A2A call")); } diff --git a/src/main/java/it/gov/pagopa/payhub/auth/service/user/IamUserInfoDTO2UserInfoMapper.java b/src/main/java/it/gov/pagopa/payhub/auth/service/user/IamUserInfoDTO2UserInfoMapper.java index 239528a..37bf52c 100644 --- a/src/main/java/it/gov/pagopa/payhub/auth/service/user/IamUserInfoDTO2UserInfoMapper.java +++ b/src/main/java/it/gov/pagopa/payhub/auth/service/user/IamUserInfoDTO2UserInfoMapper.java @@ -20,6 +20,7 @@ public class IamUserInfoDTO2UserInfoMapper implements Function { private static final String WS_USER_SUFFIX = "-WS_USER"; + private final UsersRepository usersRepository; private final OperatorsRepository operatorsRepository; diff --git a/src/main/java/it/gov/pagopa/payhub/auth/utils/JWTValidator.java b/src/main/java/it/gov/pagopa/payhub/auth/utils/JWTValidator.java index cd40d57..4c494e7 100644 --- a/src/main/java/it/gov/pagopa/payhub/auth/utils/JWTValidator.java +++ b/src/main/java/it/gov/pagopa/payhub/auth/utils/JWTValidator.java @@ -12,17 +12,14 @@ import com.auth0.jwt.interfaces.DecodedJWT; import it.gov.pagopa.payhub.auth.exception.custom.InvalidTokenException; import it.gov.pagopa.payhub.auth.exception.custom.TokenExpiredException; -import java.io.IOException; -import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; -import java.security.spec.InvalidKeySpecException; - -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; import java.util.Map; @@ -94,14 +91,13 @@ public void validateInternalToken(String token) { /** * Validates JWT signature with publickey. * - * @param applicationName the application name for which to validate the token * @param token the JWT to validate * @param publicKey the key to use in the verify instance. * @throws TokenExpiredException if the token has expired. * @throws InvalidTokenException if the token is invalid for any other reason * (e.g., signature verification failure). */ - public Pair> validateLegacyToken(String applicationName, String token, PublicKey publicKey) { + public Map validate(String token, PublicKey publicKey) { try{ DecodedJWT jwt = JWT.decode(token); @@ -109,7 +105,7 @@ public Pair> validateLegacyToken(String applicationNa JWTVerifier verifier = JWT.require(algorithm).build(); verifier.verify(jwt); - return new ImmutablePair<>(applicationName, jwt.getClaims()); + return jwt.getClaims(); } catch (com.auth0.jwt.exceptions.TokenExpiredException e){ throw new TokenExpiredException(e.getMessage()); } catch (JWTVerificationException ex) { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 36478e2..c204e82 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -70,5 +70,10 @@ data-chiper: m2m: piattaforma-unitaria-client-secret: "\${PIATTAFORMA_UNITARIA_CLIENT_SECRET:SECRET}" -# list here the keys used to identify external apps -# for example if an app is called "acme" then you should define its public key in the property "m2m.legacy.public.acme" +# legacy: +# public-keys: +# foo: "\${FOO_APPLICATION_PUBLIC_KEY:FOO_PUCLIC_KEY}" +# bar: "\${BAR_APPLICATION_PUBLIC_KEY:BAR_PUCLIC_KEY}" +# list here the keys/values used to identify external apps +# the key naming is mandatory to be the value of the organization IPA code +# you should define its public key in the property like this for example --> "m2m.legacy.public-keys.IPACODE" diff --git a/src/test/java/it/gov/pagopa/payhub/auth/controller/AuthnControllerTest.java b/src/test/java/it/gov/pagopa/payhub/auth/controller/AuthnControllerTest.java index e63cada..69a3240 100644 --- a/src/test/java/it/gov/pagopa/payhub/auth/controller/AuthnControllerTest.java +++ b/src/test/java/it/gov/pagopa/payhub/auth/controller/AuthnControllerTest.java @@ -5,6 +5,7 @@ import it.gov.pagopa.payhub.auth.exception.custom.*; import it.gov.pagopa.payhub.auth.security.JwtAuthenticationFilter; import it.gov.pagopa.payhub.auth.security.WebSecurityConfig; +import it.gov.pagopa.payhub.auth.service.AccessTokenBuilderService; import it.gov.pagopa.payhub.auth.service.AuthnService; import it.gov.pagopa.payhub.auth.service.ValidateTokenService; import it.gov.pagopa.payhub.auth.service.a2a.legacy.JWTLegacyHandlerService; @@ -37,8 +38,7 @@ @WebMvcTest(AuthnControllerImpl.class) @Import({AuthExceptionHandler.class, WebSecurityConfig.class, JwtAuthenticationFilter.class}) class AuthnControllerTest { - - private static final String TOKEN = "eyJpc3MiOiJwNHBhLWF1dGgiLCJ0eXAiOiJhdCtKV1QiLCJhbGciOiJSUzUxMiJ9.eyJ0eXAiOiJiZWFyZXIiLCJpc3MiOiJBUFBMSUNBVElPTl9BVURJRU5DRSIsImp0aSI6ImM2ZTQwZjI2LTBlYjktNDIwMy04YzBkLTFiYjgwMjdiYzQwYiIsImlhdCI6MTczMDg5NjM1MSwiZXhwIjoxNzMwODk5OTUxfQ.hdP7P3hINFmLALMgz8z4j-0RAXcYjkJF8AIPt_Cda-x49huwzsnnQfrXUHOCh1Gsa_K0LLyNkZbVaq9IAd7wsUtFKTJ6sNn57VT_OY7ss4P3lZX3r1NTX25nLp_Kv37yIcsyc-3SwDnLWJOYajJ5heljCZUwsuVr1_7Y5IiR2YeIhj3nHwX_JvEAYYKhloE9vowSd4LObEYnhvl5XRBZpS2N97luycklig-NAeqDDFTp5ZirFLTRDlls8_Mbbx4QuF9ka_2Zz5KywDWcd33uO-Uuji4wsdnwW3wdvt42ei6aVhCfoLJrME3bZQfhINg1XDoJIueJPTgtX2rlXeLtcQ"; + @Autowired private MockMvc mockMvc; @@ -52,7 +52,10 @@ class AuthnControllerTest { private ValidateTokenService validateTokenServiceMock; @MockBean - private JWTLegacyHandlerService jwtLegacyHandlerService; + private JWTLegacyHandlerService jwtLegacyHandlerServiceMock; + + @MockBean + private AccessTokenBuilderService accessTokenBuilderServiceMock; //region desc=postToken tests @Test @@ -162,12 +165,13 @@ void givenRequestWitAuthorizationWhenGetUserInfoThenOk() throws Exception { .build())) .build(); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(expectedUser); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); mockMvc.perform( get("/payhub/auth/userinfo") - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isOk()) .andExpect(content().json("{\"userId\":\"USERID\"}")); } @@ -176,35 +180,36 @@ void givenRequestWitAuthorizationWhenGetUserInfoThenOk() throws Exception { void givenRequestWitAuthorizationAndNotOrganizationAccessWhenGetUserInfoThenOk() throws Exception { UserInfo expectedUser = UserInfo.builder().userId("USERID").build(); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(expectedUser); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); mockMvc.perform( get("/payhub/auth/userinfo") - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isOk()) .andExpect(content().json("{\"userId\":\"USERID\"}")); } @Test void givenRequestWithInvalidAuthorizationWhenGetUserInfoThenForbidden() throws Exception { - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenThrow(new InvalidAccessTokenException("")); mockMvc.perform( get("/payhub/auth/userinfo") - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isForbidden()); } @Test void givenRequestWithUserNotFoundWhenGetUserInfoThenForbidden() throws Exception { - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenThrow(new UserNotFoundException("")); mockMvc.perform( get("/payhub/auth/userinfo") - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isForbidden()); } //endregion @@ -245,5 +250,20 @@ void givenCompleteRequestWhenLogoutThenInvalidClientError() throws Exception { assertEquals(AuthErrorDTO.ErrorEnum.INVALID_CLIENT, actual.getError()); assertEquals("", actual.getErrorDescription()); } + + @Test + void givenM2MLegacyRequestWhenGetUserInfoThenOk() throws Exception { + + UserInfo expectedUser = UserInfo.builder().userId("USERID").build(); + + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("legacy"); + Mockito.when(jwtLegacyHandlerServiceMock.handleLegacyToken("accessToken")).thenReturn(expectedUser); + + mockMvc.perform( + get("/payhub/auth/userinfo") + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") + ).andExpect(status().isOk()) + .andExpect(content().json("{\"userId\":\"USERID\"}")); + } //end region } diff --git a/src/test/java/it/gov/pagopa/payhub/auth/controller/AuthzControllerNoOrganizzationAccessModeTest.java b/src/test/java/it/gov/pagopa/payhub/auth/controller/AuthzControllerNoOrganizzationAccessModeTest.java index dfb82c1..84844d6 100644 --- a/src/test/java/it/gov/pagopa/payhub/auth/controller/AuthzControllerNoOrganizzationAccessModeTest.java +++ b/src/test/java/it/gov/pagopa/payhub/auth/controller/AuthzControllerNoOrganizzationAccessModeTest.java @@ -4,6 +4,7 @@ import it.gov.pagopa.payhub.auth.exception.AuthExceptionHandler; import it.gov.pagopa.payhub.auth.security.JwtAuthenticationFilter; import it.gov.pagopa.payhub.auth.security.WebSecurityConfig; +import it.gov.pagopa.payhub.auth.service.AccessTokenBuilderService; import it.gov.pagopa.payhub.auth.service.AuthnService; import it.gov.pagopa.payhub.auth.service.AuthzService; import it.gov.pagopa.payhub.auth.service.ValidateTokenService; @@ -38,7 +39,6 @@ @Import({AuthExceptionHandler.class, WebSecurityConfig.class, JwtAuthenticationFilter.class}) @TestPropertySource(properties = { "app.enable-access-organization-mode=false" }) class AuthzControllerNoOrganizzationAccessModeTest { - private static final String TOKEN = "eyJpc3MiOiJwNHBhLWF1dGgiLCJ0eXAiOiJhdCtKV1QiLCJhbGciOiJSUzUxMiJ9.eyJ0eXAiOiJiZWFyZXIiLCJpc3MiOiJBUFBMSUNBVElPTl9BVURJRU5DRSIsImp0aSI6ImM2ZTQwZjI2LTBlYjktNDIwMy04YzBkLTFiYjgwMjdiYzQwYiIsImlhdCI6MTczMDg5NjM1MSwiZXhwIjoxNzMwODk5OTUxfQ.hdP7P3hINFmLALMgz8z4j-0RAXcYjkJF8AIPt_Cda-x49huwzsnnQfrXUHOCh1Gsa_K0LLyNkZbVaq9IAd7wsUtFKTJ6sNn57VT_OY7ss4P3lZX3r1NTX25nLp_Kv37yIcsyc-3SwDnLWJOYajJ5heljCZUwsuVr1_7Y5IiR2YeIhj3nHwX_JvEAYYKhloE9vowSd4LObEYnhvl5XRBZpS2N97luycklig-NAeqDDFTp5ZirFLTRDlls8_Mbbx4QuF9ka_2Zz5KywDWcd33uO-Uuji4wsdnwW3wdvt42ei6aVhCfoLJrME3bZQfhINg1XDoJIueJPTgtX2rlXeLtcQ"; @Autowired private MockMvc mockMvc; @@ -53,7 +53,10 @@ class AuthzControllerNoOrganizzationAccessModeTest { private ValidateTokenService validateTokenServiceMock; @MockBean - private JWTLegacyHandlerService jwtLegacyHandlerService; + private JWTLegacyHandlerService jwtLegacyHandlerServiceMock; + + @MockBean + private AccessTokenBuilderService accessTokenBuilderServiceMock; // createOperator region @Test @@ -63,16 +66,18 @@ void givenUnauthorizedUserWhenCreateOrganizationOperatorThenOk() throws Exceptio request.setExternalUserId("EXTERNALUSERID"); Gson gson = new Gson(); String body = gson.toJson(request); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode("ORG2") .roles(List.of(Constants.ROLE_ADMIN)) .build())) .build()); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); + mockMvc.perform( post("/payhub/am/operators/{organizationIpaCode}", organizationIpaCode) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") .contentType(MediaType.APPLICATION_JSON) .content(String.valueOf((body))) ).andExpect(status().isUnauthorized()); @@ -92,17 +97,18 @@ void givenAuthorizedUserWhenCreateOrganizationOperatorThenOk() throws Exception String body = gson.toJson(createOperatorRequest); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode(organizationIpaCode) .roles(List.of(Constants.ROLE_ADMIN)) .build())) .build()); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); mockMvc.perform( post("/payhub/am/operators/{organizationIpaCode}", organizationIpaCode) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") .contentType(MediaType.APPLICATION_JSON) .content(body) ).andExpect(status().isOk()); @@ -119,17 +125,18 @@ void givenAuthorizedUserWhenCreateUserThenOk() throws Exception { Gson gson = new Gson(); String body = gson.toJson(user); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode("IPA_TEST_2") .roles(List.of(Constants.ROLE_ADMIN)) .build())) .build()); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); mockMvc.perform( post("/payhub/am/users") - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") .contentType(MediaType.APPLICATION_JSON) .content(body) ).andExpect(status().isOk()); @@ -141,16 +148,18 @@ void givenUnauthorizedUserWhenCreateUserThenOk() throws Exception { request.setExternalUserId("EXTERNALUSERID"); Gson gson = new Gson(); String body = gson.toJson(request); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode("IPA_TEST_2") .roles(List.of(Constants.ROLE_OPER)) .build())) .build()); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); + mockMvc.perform( post("/payhub/am/users") - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") .contentType(MediaType.APPLICATION_JSON) .content(String.valueOf((body))) ).andExpect(status().isUnauthorized()); @@ -164,16 +173,18 @@ void givenUnauthorizedUserWhenRegisterClientThenUnauthorizedException() throws E request.setClientName("CLIENTNAME"); Gson gson = new Gson(); String body = gson.toJson(request); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode("ORG2") .roles(List.of(Constants.ROLE_OPER)) .build())) .build()); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); + mockMvc.perform( post("/payhub/auth/clients/{organizationIpaCode}", organizationIpaCode) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") .contentType(MediaType.APPLICATION_JSON) .content(String.valueOf((body))) ).andExpect(status().isUnauthorized()); @@ -197,15 +208,16 @@ void givenAuthorizedUserWhenRegisterClientThenOk() throws Exception { .build())) .build(); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(expectedUser); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); doReturn(new ClientDTO(organizationIpaCode + createClientRequest.getClientName(), createClientRequest.getClientName(), organizationIpaCode, uuidRandomForSecret)) .when(authzServiceMock).registerClient(organizationIpaCode, createClientRequest); MvcResult result = mockMvc.perform( post("/payhub/auth/clients/{organizationIpaCode}", organizationIpaCode) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") .contentType(MediaType.APPLICATION_JSON) .content(new Gson().toJson(createClientRequest)) ).andExpect(status().isOk()) @@ -236,15 +248,16 @@ void givenAuthorizedUserWhenGetClientSecretThenOk() throws Exception { .build())) .build(); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(expectedUser); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); doReturn(uuidRandomForClientSecret) .when(authzServiceMock).getClientSecret(organizationIpaCode, clientId); MvcResult result = mockMvc.perform( get("/payhub/auth/clients/{organizationIpaCode}/{clientId}", organizationIpaCode, clientId) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isOk()) .andReturn(); diff --git a/src/test/java/it/gov/pagopa/payhub/auth/controller/AuthzControllerTest.java b/src/test/java/it/gov/pagopa/payhub/auth/controller/AuthzControllerTest.java index 7b78bb7..172dd23 100644 --- a/src/test/java/it/gov/pagopa/payhub/auth/controller/AuthzControllerTest.java +++ b/src/test/java/it/gov/pagopa/payhub/auth/controller/AuthzControllerTest.java @@ -7,6 +7,7 @@ import it.gov.pagopa.payhub.auth.exception.custom.OperatorNotFoundException; import it.gov.pagopa.payhub.auth.security.JwtAuthenticationFilter; import it.gov.pagopa.payhub.auth.security.WebSecurityConfig; +import it.gov.pagopa.payhub.auth.service.AccessTokenBuilderService; import it.gov.pagopa.payhub.auth.service.AuthnService; import it.gov.pagopa.payhub.auth.service.AuthzService; import it.gov.pagopa.payhub.auth.service.ValidateTokenService; @@ -44,7 +45,7 @@ @WebMvcTest(AuthzControllerImpl.class) @Import({AuthExceptionHandler.class, WebSecurityConfig.class, JwtAuthenticationFilter.class}) class AuthzControllerTest { - private static final String TOKEN = "eyJpc3MiOiJwNHBhLWF1dGgiLCJ0eXAiOiJhdCtKV1QiLCJhbGciOiJSUzUxMiJ9.eyJ0eXAiOiJiZWFyZXIiLCJpc3MiOiJBUFBMSUNBVElPTl9BVURJRU5DRSIsImp0aSI6ImM2ZTQwZjI2LTBlYjktNDIwMy04YzBkLTFiYjgwMjdiYzQwYiIsImlhdCI6MTczMDg5NjM1MSwiZXhwIjoxNzMwODk5OTUxfQ.hdP7P3hINFmLALMgz8z4j-0RAXcYjkJF8AIPt_Cda-x49huwzsnnQfrXUHOCh1Gsa_K0LLyNkZbVaq9IAd7wsUtFKTJ6sNn57VT_OY7ss4P3lZX3r1NTX25nLp_Kv37yIcsyc-3SwDnLWJOYajJ5heljCZUwsuVr1_7Y5IiR2YeIhj3nHwX_JvEAYYKhloE9vowSd4LObEYnhvl5XRBZpS2N97luycklig-NAeqDDFTp5ZirFLTRDlls8_Mbbx4QuF9ka_2Zz5KywDWcd33uO-Uuji4wsdnwW3wdvt42ei6aVhCfoLJrME3bZQfhINg1XDoJIueJPTgtX2rlXeLtcQ"; + @Autowired private MockMvc mockMvc; @Autowired @@ -60,7 +61,10 @@ class AuthzControllerTest { private ValidateTokenService validateTokenServiceMock; @MockBean - private JWTLegacyHandlerService jwtLegacyHandlerService; + private JWTLegacyHandlerService jwtLegacyHandlerServiceMock; + + @MockBean + private AccessTokenBuilderService accessTokenBuilderServiceMock; //region desc=getOrganizationOperators tests @Test @@ -68,7 +72,7 @@ void givenAuthorizedUserwhenGetOrganizationOperatorsThenOk() throws Exception { String organizationIpaCode = "IPACODE"; Pageable pageRequest = PageRequest.of(4, 1); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode(organizationIpaCode) @@ -83,7 +87,7 @@ void givenAuthorizedUserwhenGetOrganizationOperatorsThenOk() throws Exception { pageRequest, 100 ); - + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); Mockito.when(authzServiceMock.getOrganizationOperators(organizationIpaCode, pageRequest)) .thenReturn(expectedResult); @@ -91,7 +95,7 @@ void givenAuthorizedUserwhenGetOrganizationOperatorsThenOk() throws Exception { get("/payhub/am/operators/{organizationIpaCode}", organizationIpaCode) .param("page", "4") .param("size", "1") - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isOk()) .andExpect(content().json("{\"content\":[{\"userId\":\"USER1\"}],\"pageNo\":4,\"pageSize\":1,\"totalElements\":1,\"totalPages\":100}")); } @@ -104,7 +108,7 @@ void givenAuthorizedUserWhenGetOrganizationOperatorsWithQueryParamsThenOk() thro String firstName = "FIRSTNAME"; String lastName = "LASTNAME"; - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode(organizationIpaCode) @@ -122,7 +126,7 @@ void givenAuthorizedUserWhenGetOrganizationOperatorsWithQueryParamsThenOk() thro pageRequest, 100 ); - + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); Mockito.when(authzServiceMock.getOrganizationOperators(organizationIpaCode, fiscalCode, firstName, lastName, pageRequest)) .thenReturn(expectedResult); @@ -134,7 +138,7 @@ void givenAuthorizedUserWhenGetOrganizationOperatorsWithQueryParamsThenOk() thro .param("lastName", lastName) .param("page", "4") .param("size", "1") - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isOk()) .andExpect(content().json("{\"content\":[{\"userId\":\"USER1\"}],\"pageNo\":4,\"pageSize\":1,\"totalElements\":1,\"totalPages\":100}")); } @@ -143,19 +147,20 @@ void givenAuthorizedUserWhenGetOrganizationOperatorsWithQueryParamsThenOk() thro void givenUnauthorizedUserwhenGetOrganizationOperatorsThenOk() throws Exception { String organizationIpaCode = "IPACODE"; - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode("ORG2") .roles(List.of(Constants.ROLE_ADMIN)) .build())) .build()); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); mockMvc.perform( get("/payhub/am/operators/{organizationIpaCode}", organizationIpaCode) .param("page", "4") .param("size", "1") - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isUnauthorized()); } //end region @@ -165,7 +170,7 @@ void givenAuthorizedUserWhenGetOrganizationOperatorThenOk() throws Exception { String organizationIpaCode = "IPACODE"; String mappedExternalUserId = "MAPPEDEXTERNALUSERID"; - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode(organizationIpaCode) @@ -179,11 +184,12 @@ void givenAuthorizedUserWhenGetOrganizationOperatorThenOk() throws Exception { .organizationIpaCode(organizationIpaCode) .build(); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); Mockito.when(authzServiceMock.getOrganizationOperator(organizationIpaCode, mappedExternalUserId)).thenReturn(expectedResult); mockMvc.perform( get("/payhub/am/operators/{organizationIpaCode}/{mappedExternalUserId}", organizationIpaCode, mappedExternalUserId) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isOk()); } @@ -192,7 +198,7 @@ void givenOperatorNotFoundWhenGetOrganizationOperatorThenException() throws Exce String organizationIpaCode = "IPACODE"; String mappedExternalUserId = "MAPPEDEXTERNALUSERID"; - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode(organizationIpaCode) @@ -202,11 +208,12 @@ void givenOperatorNotFoundWhenGetOrganizationOperatorThenException() throws Exce OperatorNotFoundException exception = new OperatorNotFoundException(""); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); Mockito.when(authzServiceMock.getOrganizationOperator(organizationIpaCode, mappedExternalUserId)).thenThrow(exception); mockMvc.perform( get("/payhub/am/operators/{organizationIpaCode}/{mappedExternalUserId}", organizationIpaCode, mappedExternalUserId) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isNotFound()) .andExpect(result -> Assertions.assertInstanceOf(OperatorNotFoundException.class, result.getResolvedException())); @@ -220,17 +227,18 @@ void givenIsNotImplementedWhenCreateOrganizationOperatorThenOk() throws Exceptio CreateOperatorRequest request = new CreateOperatorRequest(); request.setExternalUserId("EXTERNALUSERID"); String body = objectMapper.writeValueAsString(request); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode("ORG2") .roles(List.of(Constants.ROLE_ADMIN)) .build())) .build()); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); mockMvc.perform( post("/payhub/am/operators/{organizationIpaCode}", organizationIpaCode) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") .contentType(MediaType.APPLICATION_JSON) .content(body) ).andExpect(status().isNotImplemented()); @@ -242,17 +250,18 @@ void givenIsNotImplementedWhenCreateUserThenError() throws Exception { UserDTO request = new UserDTO(); request.setExternalUserId("EXTERNALUSERID"); String body = objectMapper.writeValueAsString(request); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode("ORG2") .roles(List.of(Constants.ROLE_ADMIN)) .build())) .build()); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); mockMvc.perform( post("/payhub/am/users") - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") .contentType(MediaType.APPLICATION_JSON) .content(body) ).andExpect(status().isNotImplemented()); @@ -273,13 +282,14 @@ void givenRequestWitAuthorizationWhenGetUserInfoThenOk() throws Exception { .build())) .build(); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode("ORG") .roles(List.of(Constants.ROLE_ADMIN)) .build())) .build()); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); //When Mockito.when(authzServiceMock.getUserInfoFromMappedExternalUserId(mappedExternalUserId)) @@ -288,7 +298,7 @@ void givenRequestWitAuthorizationWhenGetUserInfoThenOk() throws Exception { //Then mockMvc.perform( get("/payhub/auth/userinfo/{mappedExternalUserId}", mappedExternalUserId) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isOk()) .andExpect(content().json("{\"userId\":\"USERID\"}")); } @@ -307,13 +317,14 @@ void givenRequestUnauthorizedWhenGetUserInfoThenException() throws Exception { .build())) .build(); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode("ORG") .roles(List.of(Constants.ROLE_OPER)) .build())) .build()); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); //When Mockito.when(authzServiceMock.getUserInfoFromMappedExternalUserId(mappedExternalUserId)) @@ -322,7 +333,7 @@ void givenRequestUnauthorizedWhenGetUserInfoThenException() throws Exception { //Then mockMvc.perform( get("/payhub/auth/userinfo/{mappedExternalUserId}", mappedExternalUserId) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isUnauthorized()); } //end region @@ -343,15 +354,15 @@ void givenAuthorizedUserWhenGetClientSecretThenOk() throws Exception { .build())) .build(); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(expectedUser); - doReturn(uuidRandomForClientSecret) .when(authzServiceMock).getClientSecret(organizationIpaCode, clientId); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); MvcResult result = mockMvc.perform( get("/payhub/auth/clients/{organizationIpaCode}/{clientId}", organizationIpaCode, clientId) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isOk()) .andReturn(); @@ -365,18 +376,19 @@ void givenRequestUnauthorizedWhenGetClientSecretThenException() throws Exception String clientId = "CLIENTID"; //When - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode("ORG") .roles(List.of(Constants.ROLE_OPER)) .build())) .build()); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); //Then mockMvc.perform( get("/payhub/auth/clients/{organizationIpaCode}/{clientId}", organizationIpaCode, clientId) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isUnauthorized()); } //end region @@ -409,15 +421,15 @@ void givenAuthorizedUserWhenGetClientsThenOk() throws Exception { .build(); List expectedDTOList = List.of(dto1, dto2); //When - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(expectedUser); - + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); doReturn(expectedDTOList) .when(authzServiceMock).getClients(organizationIpaCode); //Then MvcResult result = mockMvc.perform( get("/payhub/auth/clients/{organizationIpaCode}", organizationIpaCode) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isOk()) .andReturn(); @@ -432,18 +444,19 @@ void givenRequestUnauthorizedWhenGetClientsThenException() throws Exception { String organizationIpaCode = "IPA_TEST_2"; //When - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode("ORG") .roles(List.of(Constants.ROLE_OPER)) .build())) .build()); + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); //Then mockMvc.perform( get("/payhub/auth/clients/{organizationIpaCode}", organizationIpaCode) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isUnauthorized()); } //end region @@ -453,14 +466,14 @@ void givenRequestUnauthorizedWhenGetClientsThenException() throws Exception { void givenAlreadyExistentClientWhenRegisterClientThenConflict() throws Exception { String organizationIpaCode = "IPACODE"; - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode(organizationIpaCode) .roles(List.of(Constants.ROLE_ADMIN)) .build())) .build()); - + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); CreateClientRequest createClientRequest = new CreateClientRequest(); createClientRequest.setClientName("CLIENTNAME"); Mockito.when(authzServiceMock.registerClient(organizationIpaCode, createClientRequest)) @@ -468,7 +481,7 @@ void givenAlreadyExistentClientWhenRegisterClientThenConflict() throws Exception mockMvc.perform( post("/payhub/auth/clients/{organizationIpaCode}", organizationIpaCode) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(createClientRequest)) ).andExpect(status().isConflict()); @@ -490,14 +503,14 @@ void givenAuthorizedUserWhenRevokeClientThenOk() throws Exception { .build())) .build(); - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(expectedUser); - + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); willDoNothing().given(authzServiceMock).revokeClient(organizationIpaCode, clientId); mockMvc.perform( delete("/payhub/auth/clients/{organizationIpaCode}/{clientId}", organizationIpaCode, clientId) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isOk()) .andDo(print()); } @@ -509,18 +522,18 @@ void givenUnauthorizedUserWhenRevokeClientThenException() throws Exception { String clientId = "CLIENTID"; //When - Mockito.when(authnServiceMock.getUserInfo(TOKEN)) + Mockito.when(authnServiceMock.getUserInfo("accessToken")) .thenReturn(UserInfo.builder() .organizations(List.of(UserOrganizationRoles.builder() .organizationIpaCode("ORG") .roles(List.of(Constants.ROLE_OPER)) .build())) .build()); - + Mockito.when(accessTokenBuilderServiceMock.getHeaderPrefix()).thenReturn("accessToken"); //Then mockMvc.perform( delete("/payhub/auth/clients/{organizationIpaCode}/{clientId}", organizationIpaCode, clientId) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + TOKEN) + .header(HttpHeaders.AUTHORIZATION, "Bearer accessToken") ).andExpect(status().isUnauthorized()); } //end region diff --git a/src/test/java/it/gov/pagopa/payhub/auth/mapper/A2ALegacyClaims2UserInfoMapperTest.java b/src/test/java/it/gov/pagopa/payhub/auth/mapper/A2ALegacyClaims2UserInfoMapperTest.java index d86e3c4..dd4c5af 100644 --- a/src/test/java/it/gov/pagopa/payhub/auth/mapper/A2ALegacyClaims2UserInfoMapperTest.java +++ b/src/test/java/it/gov/pagopa/payhub/auth/mapper/A2ALegacyClaims2UserInfoMapperTest.java @@ -21,21 +21,21 @@ class A2ALegacyClaims2UserInfoMapperTest { void WhenMapThenGetUserInfoMapped() { //Given String prefix = "A2A-"; - String subject = "subject"; + String issuer = "issuer"; UserInfo expected = UserInfo.builder() - .issuer(subject) - .userId(prefix + subject) - .name(subject) - .familyName(subject) - .fiscalCode(prefix + subject) + .issuer(issuer) + .userId(prefix + issuer) + .name(issuer) + .familyName(issuer) + .fiscalCode(prefix + issuer) .organizations(Collections.singletonList(UserOrganizationRoles.builder() - .organizationIpaCode(subject) + .organizationIpaCode(issuer) .roles(Collections.singletonList(Constants.ROLE_ADMIN)) .build())) .build(); //When - UserInfo result = mapper.map(subject); + UserInfo result = mapper.map(issuer); //Then Assertions.assertEquals(expected, result); } diff --git a/src/test/java/it/gov/pagopa/payhub/auth/service/AccessTokenBuilderServiceTest.java b/src/test/java/it/gov/pagopa/payhub/auth/service/AccessTokenBuilderServiceTest.java index 0295b34..30efee1 100644 --- a/src/test/java/it/gov/pagopa/payhub/auth/service/AccessTokenBuilderServiceTest.java +++ b/src/test/java/it/gov/pagopa/payhub/auth/service/AccessTokenBuilderServiceTest.java @@ -2,6 +2,7 @@ import com.auth0.jwt.JWT; import com.auth0.jwt.interfaces.DecodedJWT; +import com.fasterxml.jackson.databind.ObjectMapper; import it.gov.pagopa.payhub.model.generated.AccessToken; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -58,16 +59,19 @@ public class AccessTokenBuilderServiceTest { private AccessTokenBuilderService accessTokenBuilderService; + private DataCipherService dataCipherService; + @BeforeEach void init(){ - accessTokenBuilderService = new AccessTokenBuilderService("APPLICATION_AUDIENCE", EXPIRE_IN, PRIVATE_KEY, PUBLIC_KEY); + dataCipherService = new DataCipherService("PSW","PEPPER", new ObjectMapper()); + accessTokenBuilderService = new AccessTokenBuilderService("APPLICATION_AUDIENCE", EXPIRE_IN, PRIVATE_KEY, PUBLIC_KEY, dataCipherService); } @Test void test(){ // When AccessToken result = accessTokenBuilderService.build(); - + String prefix = accessTokenBuilderService.getHeaderPrefix(); // Then Assertions.assertEquals("bearer", result.getTokenType()); Assertions.assertEquals(EXPIRE_IN, result.getExpiresIn()); @@ -75,9 +79,11 @@ void test(){ DecodedJWT decodedAccessToken = JWT.decode(result.getAccessToken()); String decodedHeader = new String(Base64.getDecoder().decode(decodedAccessToken.getHeader())); String decodedPayload = new String(Base64.getDecoder().decode(decodedAccessToken.getPayload())); + String decodedprefix = new String(Base64.getDecoder().decode(prefix)); - Assertions.assertEquals("{\"iss\":\"p4pa-auth\",\"typ\":\"at+JWT\",\"alg\":\"RS512\"}", decodedHeader); + Assertions.assertEquals(decodedprefix +",\"typ\":\"at+JWT\",\"alg\":\"RS512\"}", decodedHeader); Assertions.assertEquals(EXPIRE_IN, (decodedAccessToken.getExpiresAtAsInstant().toEpochMilli() - decodedAccessToken.getIssuedAtAsInstant().toEpochMilli()) / 1_000); Assertions.assertTrue(Pattern.compile("\\{\"typ\":\"bearer\",\"iss\":\"APPLICATION_AUDIENCE\",\"jti\":\"[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}\",\"iat\":[0-9]+,\"exp\":[0-9]+}").matcher(decodedPayload).matches(), "Payload not matches requested pattern: " + decodedPayload); + Assertions.assertTrue(Pattern.compile("\\{\"kid\":\"[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}\"").matcher(decodedprefix).matches(), "key identifier not matches requested pattern: " + decodedprefix); } } diff --git a/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2AClientLegacyPropConfigTest.java b/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2AClientLegacyPropConfigTest.java new file mode 100644 index 0000000..bf10085 --- /dev/null +++ b/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2AClientLegacyPropConfigTest.java @@ -0,0 +1,33 @@ +package it.gov.pagopa.payhub.auth.service.a2a.legacy; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.security.PublicKey; +import java.util.Map; + +@ExtendWith(SpringExtension.class) +@EnableConfigurationProperties(value = A2AClientLegacyPropConfig.class) +@TestPropertySource(properties = { + "m2m.legacy.public-keys.A2A-IPA_TEST_1=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuximAPn5uRE55OHqGB/wQneUlQSNQEe6VJMzRCr1Mml5J0Zo7y857DyB+teY38vN1lWMwKyt77yOsrMQyRX3TlD2gSxEXLEhJmqWEmcLm2TXMIhGv/TboL40gsEcI5flubFYqUThbk5fJR/vYkocj7E7Jw0JAKZnav3aS2Gx4cmIlaAarXwHjpM0T+0c8RA3QQB2eZ38gjA1MA6wpqg/avUcgn6+xpv3NNj7KqV6jxDpqKN42vucBtNAtsaP0q3O2s0PbkrOUY+ogOGUxuFfgIbq0nNizZypsN9w/B6coFr5rLkwZgsCTCL/AlAqX6r+/017XHRX8fUiRXQsIux7Xp1u45Rr0ZH1RWDMcoRNJQcHz410PnQqXb7TQCHNV5G6sqmSVKJOj8CLHkqYW0R5VhjvQDzdK62nmSp7lSXQiQOwNpIPK4ijLeU8SnEhCi3+o1Khtq9X6z3XxRh3XbP2n67mJ7EGgVz2Z/zLMuph4k/Cg7o62cCYfCpsqVE96gq10xj+UUfg5ONRoyOZEYYflVpRlrUjhy+wcB4z9YWcjm3gQ5FJXBthTWq47aQqjzhs6uKmJEcwDrJf+lXhQyv+j5lZ4ybPC+s7dknUnHUAw8fXdY5cwYxHdnhJ7dlf6IQJOCcBR1xgmqGUj+iwHmvNnk8jPa3NNaMUc8ruPfU8AX0CAwEAAQ==", + "m2m.legacy.public-keys.A2A-IPA_TEST_2=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAj/PKsMVKq8SWIhnDl0/pJT9BS5JfXesTllDTunDMjh5wkj97LR4wbGUXJjkf4auZzNJU/NN7muER2qlJjiTA3+OpfqndnVFmHLVG5hwQf6Pjy9fYv+FLTbR8l/O6giKfoGpMmLOVd+mS/QA7aBZMWoSyb9p0pxDg4Wb4MHjSQksXDSBdW/zRqVqiHNuILxpYr98WDactpsVhLyAuBRSvnuSMUat5XpNZFQt0qW5ZunTr8ctNIRIYVMaz5nWo3ker6YGWfU1CJxXV2vT2sFi60G4ngy3TrAX7OAy1vCk144pkDkGZc+6zSfZE1EuZvcq1q+Li3PD1TQ8J81n9tZ1X1xJT5xBBeFy1fExa+WyJGZorc5YkwNvq6HdCsTp3vtqszMvqHNz8xXk5VskbSICxKEdqdyV2FdkmbEl16pkm4UJZgiwRYlzs6THJ+wVUzuDaJZVMOcGB9Uv3kEVsXgagfHP6CITNrVJgixUBc92pgNCc11E6HOVdxsklNZ2m/PfBjiqk+sX31CFfTV2kKHdujs7E4e18etqLWVVt+ygG7PYD5r6ZB0tZVT4Vadowh4+R2/aAsrxGFzW5tHm0GDyu0e7ahK0ltdgK5slyLIEWa8cf6F0dX3JFDOtg3Iawllje4nPvOK8h8WDr2TMI1sHy3XEMvCY8eHcg0izjdI3uGJ8CAwEAAQ==" +}) +class A2AClientLegacyPropConfigTest { + + @Autowired + private A2AClientLegacyPropConfig propConfig; + + @Test + void testGetPublicKeysAsMap() { + Map publicKeyMap = propConfig.getPublicKeysAsMap(); + + Assertions.assertTrue(publicKeyMap.containsKey("A2A-IPA_TEST_1")); + Assertions.assertTrue(publicKeyMap.containsKey("A2A-IPA_TEST_2")); + Assertions.assertEquals(2, publicKeyMap.size()); + } +} diff --git a/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsRetrieverServiceTest.java b/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsRetrieverServiceTest.java deleted file mode 100644 index 11e2eac..0000000 --- a/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsRetrieverServiceTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package it.gov.pagopa.payhub.auth.service.a2a.legacy; - -import io.jsonwebtoken.io.Encoders; -import it.gov.pagopa.payhub.auth.exception.custom.InvalidTokenException; -import it.gov.pagopa.payhub.auth.utils.JWTValidatorUtils; -import org.junit.jupiter.api.Assertions; -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.junit.jupiter.MockitoExtension; - -import java.security.KeyPair; -import java.security.PublicKey; -import java.util.HashMap; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -class A2ALegacySecretsRetrieverServiceTest { - - @Mock - private A2AClientLegacyPropConfig a2aClientLegacyPropConfigMock; - - private A2ALegacySecretsRetrieverService service; - - private KeyPair keyPair; - - @BeforeEach - void setUp() throws Exception { - service = new A2ALegacySecretsRetrieverService(a2aClientLegacyPropConfigMock); - keyPair = JWTValidatorUtils.generateKeyPair(); - } - - @Test - void givenEnvPropWhenEnvToMapThenInvokeA2ALegacySecretsRetrieverService() { - //Given - PublicKey publicKey = keyPair.getPublic(); - String publicKeyEncoded = Encoders.BASE64.encode(publicKey.getEncoded()); - Map envMapProps = Map.of("acme", publicKeyEncoded); - when(a2aClientLegacyPropConfigMock.getSecrets()).thenReturn(envMapProps); - //When - - Map result = service.envToMap(); - - //Then - assertNotNull(result); - assertEquals(publicKey, result.get("acme")); - } - - @Test - void GivenInvalidPropsWhenEnvToMapThenInvalidTokenException() { - //Given - Map envMapProps = new HashMap<>(); - envMapProps.put("nullProperty", null); - envMapProps.put("emptyProperty", ""); - envMapProps.put("invalidBase64", "not_base64"); - when(a2aClientLegacyPropConfigMock.getSecrets()).thenReturn(envMapProps); - //When Then - Assertions.assertThrows(InvalidTokenException.class, () -> service.envToMap()); - } - - -} diff --git a/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsServiceTest.java b/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsServiceTest.java new file mode 100644 index 0000000..731a9c5 --- /dev/null +++ b/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/A2ALegacySecretsServiceTest.java @@ -0,0 +1,44 @@ +package it.gov.pagopa.payhub.auth.service.a2a.legacy; + +import it.gov.pagopa.payhub.auth.utils.JWTValidatorUtils; +import org.junit.jupiter.api.Assertions; +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.junit.jupiter.MockitoExtension; + +import java.security.KeyPair; +import java.security.PublicKey; +import java.util.Map; + +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class A2ALegacySecretsServiceTest { + + @Mock + private A2AClientLegacyPropConfig a2aClientLegacyPropConfigMock; + + private A2ALegacySecretsService service; + + private KeyPair keyPair; + + @BeforeEach + void setUp() throws Exception { + service = new A2ALegacySecretsService(a2aClientLegacyPropConfigMock); + keyPair = JWTValidatorUtils.generateKeyPair(); + } + + @Test + void testGetLegacySecrets() { + //Given + PublicKey publicKey = keyPair.getPublic(); + when(a2aClientLegacyPropConfigMock.getPublicKeysAsMap()).thenReturn(Map.of("A2A-IPA_TEST_1", publicKey)); + //When + Map publicKeyMap = service.getLegacySecrets(); + //Then + Assertions.assertTrue(publicKeyMap.containsKey("A2A-IPA_TEST_1")); + Assertions.assertEquals(publicKey, publicKeyMap.get("A2A-IPA_TEST_1")); + } +} diff --git a/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/JWTLegacyHandlerServiceTest.java b/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/JWTLegacyHandlerServiceTest.java index 82c2c41..e33416e 100644 --- a/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/JWTLegacyHandlerServiceTest.java +++ b/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/JWTLegacyHandlerServiceTest.java @@ -40,9 +40,9 @@ void givenValidTokenWhenHandleLegacyTokenThenSuccess() { UserInfo userInfo = new UserInfo(); Mockito.when(a2ALegacyClaims2UserInfoMapperMock.map("subject")).thenReturn(userInfo); //When - service.handleLegacyToken(token); + UserInfo result = service.handleLegacyToken(token); //Then - Assertions.assertDoesNotThrow(() -> service.handleLegacyToken(token)); + Assertions.assertEquals(userInfo, result); } private Pair> createJWKClaims(){ diff --git a/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/ValidateJWTLegacyServiceTest.java b/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/ValidateJWTLegacyServiceTest.java index 370c3db..052a206 100644 --- a/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/ValidateJWTLegacyServiceTest.java +++ b/src/test/java/it/gov/pagopa/payhub/auth/service/a2a/legacy/ValidateJWTLegacyServiceTest.java @@ -5,7 +5,6 @@ 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.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -17,18 +16,18 @@ import java.security.KeyPair; import java.security.PublicKey; import java.time.Instant; -import java.util.HashMap; import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class ValidateJWTLegacyServiceTest { @Mock - private A2ALegacySecretsRetrieverService a2ALegacySecretsRetrieverServiceMock; + private A2ALegacySecretsService a2ALegacySecretsServiceMock; @Mock private JWTValidator jwtValidatorMock; private ValidateJWTLegacyService service; @@ -37,85 +36,73 @@ class ValidateJWTLegacyServiceTest { @BeforeEach void setup() throws Exception { - service = new ValidateJWTLegacyService(a2ALegacySecretsRetrieverServiceMock, jwtValidatorMock); + service = new ValidateJWTLegacyService(a2ALegacySecretsServiceMock, jwtValidatorMock); keyPair = JWTValidatorUtils.generateKeyPair(); } @Test void GivenValidTokenThenOk() { - String appName = "APPLICATION_NAME"; + String appName = "A2A-IPA_TEST_1"; + PublicKey publicKey = keyPair.getPublic(); String token = JWTValidatorUtils.generateLegacyToken(keyPair, "a2a", Instant.now(), Instant.now().plusSeconds(3_600L), "jti"); + when(a2ALegacySecretsServiceMock.getLegacySecrets()).thenReturn(Map.of(appName, publicKey)); - Map clientApplicationsPublicKeyMap = Map.of(appName, keyPair.getPublic()); - Mockito.when(a2ALegacySecretsRetrieverServiceMock.envToMap()).thenReturn(clientApplicationsPublicKeyMap); - - Pair> claimsMap = new ImmutablePair<>(appName, JWT.decode(token).getClaims()); - Mockito.when(jwtValidatorMock.validateLegacyToken(appName, token, keyPair.getPublic())).thenReturn(claimsMap); + Map claimsMap = JWT.decode(token).getClaims(); + Mockito.when(jwtValidatorMock.validate(token, publicKey)).thenReturn(claimsMap); Pair> result = service.validate(token); - assertEquals(claimsMap, result); - } - - @Test - void GivenEmptyMapThenInvalidTokenException() { - Map clientApplicationsPublicKeyMap = new HashMap<>(); - Mockito.when(a2ALegacySecretsRetrieverServiceMock.envToMap()).thenReturn(clientApplicationsPublicKeyMap); - assertThrows(InvalidTokenException.class, () -> service.validate("token")); + assertEquals(Pair.of(appName, claimsMap), result); } @Test void GivenNonM2MAuthTokenThenInvalidTokenException() { - String appName = "APPLICATION_NAME"; + PublicKey publicKey = keyPair.getPublic(); String token = JWTValidatorUtils.generateLegacyToken(keyPair, "notA2A", Instant.now(), Instant.now().plusSeconds(3_600L), "jwtId"); + when(a2ALegacySecretsServiceMock.getLegacySecrets()).thenReturn(Map.of("A2A-IPA_TEST_1", publicKey)); - Map clientApplicationsPublicKeyMap = Map.of(appName, keyPair.getPublic()); - Mockito.when(a2ALegacySecretsRetrieverServiceMock.envToMap()).thenReturn(clientApplicationsPublicKeyMap); - - Pair> claimsMap = new ImmutablePair<>(appName, JWT.decode(token).getClaims()); - Mockito.when(jwtValidatorMock.validateLegacyToken(appName, token, keyPair.getPublic())).thenReturn(claimsMap); + Map claimsMap = JWT.decode(token).getClaims(); + Mockito.when(jwtValidatorMock.validate(token, publicKey)).thenReturn(claimsMap); assertThrows(InvalidTokenException.class, () -> service.validate(token), "Invalid token type"); } @Test void GivenInvalidIatThenInvalidTokenException() { - String appName = "APPLICATION_NAME"; + PublicKey publicKey = keyPair.getPublic(); String token = JWTValidatorUtils.generateLegacyToken(keyPair, "a2a", Instant.now().minusSeconds(3_600L * 48), Instant.now().plusSeconds(3_600_000L), "jwtId"); - Map clientApplicationsPublicKeyMap = Map.of(appName, keyPair.getPublic()); - Mockito.when(a2ALegacySecretsRetrieverServiceMock.envToMap()).thenReturn(clientApplicationsPublicKeyMap); - Pair> claimsMap = new ImmutablePair<>(appName, JWT.decode(token).getClaims()); - Mockito.when(jwtValidatorMock.validateLegacyToken(appName, token, keyPair.getPublic())).thenReturn(claimsMap); + when(a2ALegacySecretsServiceMock.getLegacySecrets()).thenReturn(Map.of("A2A-IPA_TEST_1", publicKey)); + + Map claimsMap = JWT.decode(token).getClaims(); + Mockito.when(jwtValidatorMock.validate(token, publicKey)).thenReturn(claimsMap); assertThrows(InvalidTokenException.class, () -> service.validate(token), "Invalid field iat"); } @Test void GivenInvalidExpThenInvalidTokenException() { - String appName = "APPLICATION_NAME"; + PublicKey publicKey = keyPair.getPublic(); String token = JWTValidatorUtils.generateLegacyToken(keyPair, "a2a", Instant.now(), Instant.now().plusSeconds(3_600L * 48), "jwtId"); - Map clientApplicationsPublicKeyMap = Map.of(appName, keyPair.getPublic()); - Mockito.when(a2ALegacySecretsRetrieverServiceMock.envToMap()).thenReturn(clientApplicationsPublicKeyMap); + when(a2ALegacySecretsServiceMock.getLegacySecrets()).thenReturn(Map.of("A2A-IPA_TEST_1", publicKey)); - Pair> claimsMap = new ImmutablePair<>(appName, JWT.decode(token).getClaims()); - Mockito.when(jwtValidatorMock.validateLegacyToken(appName, token, keyPair.getPublic())).thenReturn(claimsMap); + Map claimsMap = JWT.decode(token).getClaims(); + Mockito.when(jwtValidatorMock.validate(token, publicKey)).thenReturn(claimsMap); assertThrows(InvalidTokenException.class, () -> service.validate(token), "Invalid field exp"); } @Test void GivenInvalidJtiThenInvalidTokenException() { - String appName = "APPLICATION_NAME"; + PublicKey publicKey = keyPair.getPublic(); String token = JWTValidatorUtils.generateLegacyToken(keyPair, "a2a", Instant.now(), Instant.now().plusSeconds(3_600L), ""); - Map clientApplicationsPublicKeyMap = Map.of(appName, keyPair.getPublic()); - Mockito.when(a2ALegacySecretsRetrieverServiceMock.envToMap()).thenReturn(clientApplicationsPublicKeyMap); + when(a2ALegacySecretsServiceMock.getLegacySecrets()).thenReturn(Map.of("A2A-IPA_TEST_1", publicKey)); - Pair> claimsMap = new ImmutablePair<>(appName, JWT.decode(token).getClaims()); - Mockito.when(jwtValidatorMock.validateLegacyToken(appName, token, keyPair.getPublic())).thenReturn(claimsMap); + Map claimsMap = JWT.decode(token).getClaims(); + Mockito.when(jwtValidatorMock.validate(token, publicKey)).thenReturn(claimsMap); assertThrows(InvalidTokenException.class, () -> service.validate(token), "Invalid field jti"); } diff --git a/src/test/java/it/gov/pagopa/payhub/auth/utils/JWTValidatorTest.java b/src/test/java/it/gov/pagopa/payhub/auth/utils/JWTValidatorTest.java index 0d56fec..e08da2f 100644 --- a/src/test/java/it/gov/pagopa/payhub/auth/utils/JWTValidatorTest.java +++ b/src/test/java/it/gov/pagopa/payhub/auth/utils/JWTValidatorTest.java @@ -94,20 +94,20 @@ void givenTokenExpiredThenTokenExpiredException() { @Test void givenValidLegacyJWTThenOk() { String validToken = utils.generateLegacyToken(keyPair, "a2a", Instant.now(), Instant.now().plusSeconds(3_600_000L), "jwtId"); - Assertions.assertDoesNotThrow(() -> jwtValidator.validateLegacyToken("app", validToken, keyPair.getPublic())); + Assertions.assertDoesNotThrow(() -> jwtValidator.validate(validToken, keyPair.getPublic())); } @Test void givenInvalidTokenWhenValidateLegacyTokenThenThrowInvalidTokenException() { String invalidToken = "your_invalid_token_here"; PublicKey publicKey = keyPair.getPublic(); - assertThrows(InvalidTokenException.class, () ->jwtValidator.validateLegacyToken("app", invalidToken, publicKey)); + assertThrows(InvalidTokenException.class, () ->jwtValidator.validate(invalidToken, publicKey)); } @Test void givenInvalidTokenWhenValidateLegacyTokenThenThrowTokenExpiredException() { String invalidToken = utils.generateLegacyToken(keyPair, "a2a", Instant.now(), Instant.now().minusSeconds(3_600_000L), "jwtId"); PublicKey publicKey = keyPair.getPublic(); - assertThrows(TokenExpiredException.class, () ->jwtValidator.validateLegacyToken("app", invalidToken, publicKey)); + assertThrows(TokenExpiredException.class, () ->jwtValidator.validate(invalidToken, publicKey)); } }