From 0361977dc452ca16e25714feb2877f98c9741d71 Mon Sep 17 00:00:00 2001 From: antoniotarricone Date: Wed, 8 Jan 2025 09:33:43 +0100 Subject: [PATCH 1/3] Removed Terraform script to deploy by means of ARM. --- src/main/terraform/container_app_arm.off | 189 ----------------------- 1 file changed, 189 deletions(-) delete mode 100644 src/main/terraform/container_app_arm.off diff --git a/src/main/terraform/container_app_arm.off b/src/main/terraform/container_app_arm.off deleted file mode 100644 index 97785ce..0000000 --- a/src/main/terraform/container_app_arm.off +++ /dev/null @@ -1,189 +0,0 @@ -resource "azurerm_resource_group_template_deployment" "auth_arm" { - name = "${local.project}-auth-ca-arm" - resource_group_name = data.azurerm_container_app_environment.mil.resource_group_name - deployment_mode = "Incremental" - tags = local.tags - - template_content = <<-EOT - { - "$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion":"1.0.0.0", - "parameters":{}, - "variables":{}, - "resources":[ - { - "name":"${local.project}-auth-ca-arm", - "type":"Microsoft.App/containerApps", - "apiVersion": "2024-10-02-preview", - "location":"${var.location}", - "properties":{ - "managedEnvironmentId":"${data.azurerm_container_app_environment.mil.id}", - "environmentId":"${data.azurerm_container_app_environment.mil.id}", - "configuration":{ - "secrets":[ - { - "name":"cosmosdb-account-mil-primary-mongodb-connection-string", - "keyVaultUrl":"${data.azurerm_key_vault.general.vault_uri}secrets/${var.cosmosdb_account_primary_mongodb_connection_string_kv_secret}", - "identity":"${data.azurerm_user_assigned_identity.auth.id}" - }, - { - "name":"cosmosdb-account-mil-secondary-mongodb-connection-string", - "keyVaultUrl":"${data.azurerm_key_vault.general.vault_uri}secrets/${var.cosmosdb_account_secondary_mongodb_connection_string_kv_secret}", - "identity":"${data.azurerm_user_assigned_identity.auth.id}" - }, - { - "name":"identity-client-id", - "value":"${data.azurerm_user_assigned_identity.auth.client_id}" - }, - { - "name":"key-vault-auth-vault-uri", - "keyVaultUrl":"${data.azurerm_key_vault.general.vault_uri}secrets/${var.key_vault_auth_vault_uri_kv_secret}", - "identity":"${data.azurerm_user_assigned_identity.auth.id}" - }, - { - "name":"application-insigths-mil-connection-string", - "keyVaultUrl":"${data.azurerm_key_vault.general.vault_uri}secrets/${var.application_insigths_connection_string_kv_secret}", - "identity":"${data.azurerm_user_assigned_identity.auth.id}" - } - ], - "activeRevisionsMode":"Single", - "ingress":{ - "external":true, - "targetPort":8080, - "transport":"Http", - "traffic":[ - { - "weight":100, - "latestRevision":true - } - ] - }, - "maxInactiveRevisions":5 - }, - "template":{ - "containers":[ - { - "image":"${var.mil_auth_image}", - "imageType":"ContainerImage", - "name":"mil-auth", - "env":[ - { - "name":"TZ", - "value":"Europe/Rome" - }, - { - "name":"auth.quarkus-log-level", - "value":"${var.mil_auth_quarkus_log_level}" - }, - { - "name":"auth.quarkus-rest-client-logging-scope", - "value":"${var.mil_auth_quarkus_rest_client_logging_scope}" - }, - { - "name":"auth.app-log-level", - "value":"${var.mil_auth_app_log_level}" - }, - { - "name":"auth.cryptoperiod", - "value":"${var.mil_auth_cryptoperiod}" - }, - { - "name":"auth.keysize", - "value":"${var.mil_auth_keysize}" - }, - { - "name":"auth.access.duration", - "value":"${var.mil_auth_access_duration}" - }, - { - "name":"auth.refresh.duration", - "value":"${var.mil_auth_refresh_duration}" - }, - { - "name":"auth.keyvault.url", - "secretRef":"key-vault-auth-vault-uri" - }, - { - "name":"auth.base-url", - "value":"${var.mil_auth_base_url}" - }, - { - "name":"application-insights.connection-string", - "secretRef":"application-insigths-mil-connection-string" - }, - { - "name":"auth.json-log", - "value":"${var.mil_auth_json_log}" - }, - { - "name":"auth.keyvault.maxresults", - "value":"${var.mil_auth_keyvault_maxresults}" - }, - { - "name":"auth.keyvault.backoff.number-of-attempts", - "value":"${var.mil_auth_keyvault_backoff_num_of_attempts}" - }, - { - "name":"jwt-publickey-location", - "value":"http://127.0.0.1:8080/.well-known/jwks.json" - }, - { - "name":"mongodb.connect-timeout", - "value":"${var.mil_auth_mongodb_connect_timeout}" - }, - { - "name":"mongodb.read-timeout", - "value":"${var.mil_auth_mongodb_read_timeout}" - }, - { - "name":"mongodb.server-selection-timeout", - "value":"${var.mil_auth_mongodb_server_selection_timeout}" - }, - { - "name":"mongodb.connection-string-1", - "secretRef":"cosmosdb-account-mil-primary-mongodb-connection-string" - }, - { - "name":"mongodb.connection-string-2", - "secretRef":"cosmosdb-account-mil-secondary-mongodb-connection-string" - }, - { - "name":"IDENTITY_CLIENT_ID", - "secretRef":"identity-client-id" - } - ], - "resources":{ - "cpu":"${var.mil_auth_cpu}", - "memory":"${var.mil_auth_memory}" - } - } - ], - "scale":{ - "minReplicas":"${var.mil_auth_min_replicas}", - "maxReplicas":"${var.mil_auth_max_replicas}", - "cooldownPeriod":120, - "pollingInterval":5, - "rules":[ - { - "name":"http-requests", - "http":{ - "metadata":{ - "concurrentRequests":"25" - } - } - } - ] - } - } - }, - "identity":{ - "type":"UserAssigned", - "userAssignedIdentities":{ - "${data.azurerm_user_assigned_identity.auth.id}":{} - } - } - } - ] - } - EOT -} From dd63e04bde557979ebe9841ff76e1d26ca7b0fb3 Mon Sep 17 00:00:00 2001 From: antoniotarricone Date: Wed, 8 Jan 2025 09:34:37 +0100 Subject: [PATCH 2/3] Probes switched off waiting to understand why they don't work! --- src/main/terraform/container_app.tf | 60 ++++++++++++++--------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/main/terraform/container_app.tf b/src/main/terraform/container_app.tf index 607f723..06147b0 100644 --- a/src/main/terraform/container_app.tf +++ b/src/main/terraform/container_app.tf @@ -119,36 +119,36 @@ resource "azurerm_container_app" "auth" { secret_name = "identity-client-id" } - liveness_probe { - path = "/q/health/live" - port = 8080 - transport = "HTTP" - initial_delay = 0 - interval_seconds = 10 - failure_count_threshold = 3 - timeout = 1 - } - - readiness_probe { - path = "/q/health/ready" - port = 8080 - transport = "HTTP" - initial_delay = 0 - interval_seconds = 10 - failure_count_threshold = 3 - success_count_threshold = 1 - timeout = 1 - } - - startup_probe { - path = "/q/health/started" - port = 8080 - transport = "HTTP" - initial_delay = 0 - interval_seconds = 10 - failure_count_threshold = 3 - timeout = 1 - } + #liveness_probe { + # path = "/q/health/live" + # port = 8080 + # transport = "HTTP" + # initial_delay = 0 + # interval_seconds = 10 + # failure_count_threshold = 3 + # timeout = 1 + #} + + #readiness_probe { + # path = "/q/health/ready" + # port = 8080 + # transport = "HTTP" + # initial_delay = 0 + # interval_seconds = 10 + # failure_count_threshold = 3 + # success_count_threshold = 1 + # timeout = 1 + #} + + #startup_probe { + # path = "/q/health/started" + # port = 8080 + # transport = "HTTP" + # initial_delay = 0 + # interval_seconds = 10 + # failure_count_threshold = 3 + # timeout = 1 + #} } max_replicas = var.mil_auth_max_replicas From 0542c77127854be8699b5fb0ab5961dc1e73e63e Mon Sep 17 00:00:00 2001 From: antoniotarricone Date: Wed, 8 Jan 2025 10:59:45 +0100 Subject: [PATCH 3/3] Added SignedJWT deserializer. --- .../mil/auth/util/SignedJWTDeserializer.java | 59 ++++++++++++++++ .../auth/util/SignedJWTParamConverter.java | 8 +-- .../pagopa/swclient/mil/auth/util/Sample.java | 37 ++++++++++ .../auth/util/SignedJWTDeserializerTest.java | 69 +++++++++++++++++++ .../util/SignedJWTParamConverterTest.java | 35 ++++++++++ 5 files changed, 202 insertions(+), 6 deletions(-) create mode 100644 src/main/java/it/pagopa/swclient/mil/auth/util/SignedJWTDeserializer.java create mode 100644 src/test/java/it/pagopa/swclient/mil/auth/util/Sample.java create mode 100644 src/test/java/it/pagopa/swclient/mil/auth/util/SignedJWTDeserializerTest.java create mode 100644 src/test/java/it/pagopa/swclient/mil/auth/util/SignedJWTParamConverterTest.java diff --git a/src/main/java/it/pagopa/swclient/mil/auth/util/SignedJWTDeserializer.java b/src/main/java/it/pagopa/swclient/mil/auth/util/SignedJWTDeserializer.java new file mode 100644 index 0000000..eaa7edb --- /dev/null +++ b/src/main/java/it/pagopa/swclient/mil/auth/util/SignedJWTDeserializer.java @@ -0,0 +1,59 @@ +/* + * SignedJWTDeserializer.java + * + * 8 jan 2025 + */ +package it.pagopa.swclient.mil.auth.util; + +import java.io.IOException; +import java.text.ParseException; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.nimbusds.jwt.SignedJWT; + +import io.quarkus.logging.Log; +import it.pagopa.swclient.mil.auth.AuthErrorCode; +import it.pagopa.swclient.mil.bean.Errors; +import jakarta.ws.rs.BadRequestException; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +/** + *

+ * Deserializes strings in signed JWT. + *

+ * + * @author Antonio Tarricone + */ +public class SignedJWTDeserializer extends JsonDeserializer { + /** + *

+ * Default constructor. + *

+ */ + public SignedJWTDeserializer() { + super(); + } + + /** + * + * @see com.fasterxml.jackson.databind.JsonDeserializer#deserialize(JsonParser, + * DeserializationContext) JsonDeserializer#deserialize(JsonParser, DeserializationContext) + */ + @Override + public SignedJWT deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + Log.trace("deserialize"); + try { + return SignedJWT.parse(p.getText()); + } catch (ParseException e) { + String message = String.format("[%s] Error parsing token", AuthErrorCode.ERROR_PARSING_TOKEN); + Log.errorf(e, message); + Response error = Response.status(Status.BAD_REQUEST) + .entity(new Errors(AuthErrorCode.ERROR_PARSING_TOKEN, message)) + .build(); + throw new BadRequestException(error); + } + } +} diff --git a/src/main/java/it/pagopa/swclient/mil/auth/util/SignedJWTParamConverter.java b/src/main/java/it/pagopa/swclient/mil/auth/util/SignedJWTParamConverter.java index e2f7417..703ca03 100644 --- a/src/main/java/it/pagopa/swclient/mil/auth/util/SignedJWTParamConverter.java +++ b/src/main/java/it/pagopa/swclient/mil/auth/util/SignedJWTParamConverter.java @@ -45,11 +45,7 @@ public SignedJWT fromString(String value) { */ @Override public String toString(SignedJWT value) { - // For now this method is not useful, so to avoid coverage checking, - // I prefer to return an exception! - // The real implementation should be: - // Log.trace("toString"); // NOSONAR - // return value.serialize(); // NOSONAR - throw new UnsupportedOperationException(); + Log.trace("toString"); + return value.serialize(); } } \ No newline at end of file diff --git a/src/test/java/it/pagopa/swclient/mil/auth/util/Sample.java b/src/test/java/it/pagopa/swclient/mil/auth/util/Sample.java new file mode 100644 index 0000000..e6679fa --- /dev/null +++ b/src/test/java/it/pagopa/swclient/mil/auth/util/Sample.java @@ -0,0 +1,37 @@ +/* + * Sample.java + * + * 8 jan 2025 + */ +package it.pagopa.swclient.mil.auth.util; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.nimbusds.jwt.SignedJWT; + +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +/** + * + * @author Antonio Tarricone + */ +@Getter +@Setter +@Accessors(chain = true) +public class Sample { + /** + * JSON keys. + */ + public static final String JWT_JK = "jwt"; + + /** + * + */ + @JsonProperty(JWT_JK) + @JsonSerialize(using = SignedJWTSerializer.class) + @JsonDeserialize(using = SignedJWTDeserializer.class) + private SignedJWT jwt; +} \ No newline at end of file diff --git a/src/test/java/it/pagopa/swclient/mil/auth/util/SignedJWTDeserializerTest.java b/src/test/java/it/pagopa/swclient/mil/auth/util/SignedJWTDeserializerTest.java new file mode 100644 index 0000000..430ac6f --- /dev/null +++ b/src/test/java/it/pagopa/swclient/mil/auth/util/SignedJWTDeserializerTest.java @@ -0,0 +1,69 @@ +/* + * SignedJWTDeserializerTest.java + * + * 8 gen 2025 + */ +package it.pagopa.swclient.mil.auth.util; + +import static org.junit.jupiter.api.Assertions.*; + +import java.text.ParseException; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nimbusds.jwt.SignedJWT; + +import io.quarkus.test.junit.QuarkusTest; + +/** + * + * @author Antonio Tarricone + */ +@QuarkusTest +class SignedJWTDeserializerTest { + /** + * + * @param testInfo + */ + @BeforeEach + void init(TestInfo testInfo) { + String frame = "*".repeat(testInfo.getDisplayName().length() + 11); + System.out.println(frame); + System.out.printf("* %s: START *%n", testInfo.getDisplayName()); + System.out.println(frame); + } + + /** + * Test method for + * {@link it.pagopa.swclient.mil.auth.util.SignedJWTDeserializer#deserialize(com.fasterxml.jackson.core.JsonParser, com.fasterxml.jackson.databind.DeserializationContext)}. + * + * @throws ParseException + * @throws JsonProcessingException + */ + @Test + void testDeserializeJsonParserDeserializationContext() throws ParseException, JsonProcessingException { + SignedJWT expected = SignedJWT.parse("eyJraWQiOiJrZXlfbmFtZS9rZXlfdmVyc2lvbiIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJjbGllbnRfaWQiLCJjbGllbnRJZCI6ImNsaWVudF9pZCIsImNoYW5uZWwiOiJjaGFubmVsIiwiaXNzIjoiaHR0cHM6Ly9taWwtYXV0aCIsImdyb3VwcyI6InJvbGUiLCJ0ZXJtaW5hbElkIjoidGVybWluYWxfaWQiLCJhdWQiOiJodHRwczovL21pbCIsIm1lcmNoYW50SWQiOiJtZXJjaGFudF9pZCIsInNjb3BlIjoic2NvcGUiLCJmaXNjYWxDb2RlIjoiZW5jX2Zpc2NhbF9jb2RlIiwiZXhwIjoxNzE3NjUyLCJhY3F1aXJlcklkIjoiYWNxdWlyZXJfaWQiLCJpYXQiOjE3MTc1OTJ9.AA"); + + String json = "{\"jwt\":\"eyJraWQiOiJrZXlfbmFtZS9rZXlfdmVyc2lvbiIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJjbGllbnRfaWQiLCJjbGllbnRJZCI6ImNsaWVudF9pZCIsImNoYW5uZWwiOiJjaGFubmVsIiwiaXNzIjoiaHR0cHM6Ly9taWwtYXV0aCIsImdyb3VwcyI6InJvbGUiLCJ0ZXJtaW5hbElkIjoidGVybWluYWxfaWQiLCJhdWQiOiJodHRwczovL21pbCIsIm1lcmNoYW50SWQiOiJtZXJjaGFudF9pZCIsInNjb3BlIjoic2NvcGUiLCJmaXNjYWxDb2RlIjoiZW5jX2Zpc2NhbF9jb2RlIiwiZXhwIjoxNzE3NjUyLCJhY3F1aXJlcklkIjoiYWNxdWlyZXJfaWQiLCJpYXQiOjE3MTc1OTJ9.AA\"}"; + + Sample sample = new ObjectMapper().readValue(json, Sample.class); + + SignedJWT actual = sample.getJwt(); + + assertEquals(expected.serialize(), actual.serialize()); + } + + /** + * Test method for + * {@link it.pagopa.swclient.mil.auth.util.SignedJWTDeserializer#deserialize(com.fasterxml.jackson.core.JsonParser, com.fasterxml.jackson.databind.DeserializationContext)}. + */ + @Test + void testDeserializeJsonParserDeserializationContextWithInvalidJwt() { + String json = "{\"jwt\":\"@.@.@\"}"; + assertThrows(JsonProcessingException.class, () -> new ObjectMapper().readValue(json, Sample.class)); + } +} \ No newline at end of file diff --git a/src/test/java/it/pagopa/swclient/mil/auth/util/SignedJWTParamConverterTest.java b/src/test/java/it/pagopa/swclient/mil/auth/util/SignedJWTParamConverterTest.java new file mode 100644 index 0000000..443b4c1 --- /dev/null +++ b/src/test/java/it/pagopa/swclient/mil/auth/util/SignedJWTParamConverterTest.java @@ -0,0 +1,35 @@ +/* + * SignedJWTParamConverterTest.java + * + * 8 gen 2025 + */ +package it.pagopa.swclient.mil.auth.util; + +import static org.junit.jupiter.api.Assertions.*; + +import java.text.ParseException; + +import org.junit.jupiter.api.Test; + +import com.nimbusds.jwt.SignedJWT; + +import io.quarkus.test.junit.QuarkusTest; + +/** + * + * @author Antonio Tarricone + */ +@QuarkusTest +class SignedJWTParamConverterTest { + /** + * Test method for + * {@link it.pagopa.swclient.mil.auth.util.SignedJWTParamConverter#toString(com.nimbusds.jwt.SignedJWT)}. + * + * @throws ParseException + */ + @Test + void testToStringSignedJWT() throws ParseException { + SignedJWT jwt = SignedJWT.parse("eyJraWQiOiJrZXlfbmFtZS9rZXlfdmVyc2lvbiIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJjbGllbnRfaWQiLCJjbGllbnRJZCI6ImNsaWVudF9pZCIsImNoYW5uZWwiOiJjaGFubmVsIiwiaXNzIjoiaHR0cHM6Ly9taWwtYXV0aCIsImdyb3VwcyI6InJvbGUiLCJ0ZXJtaW5hbElkIjoidGVybWluYWxfaWQiLCJhdWQiOiJodHRwczovL21pbCIsIm1lcmNoYW50SWQiOiJtZXJjaGFudF9pZCIsInNjb3BlIjoic2NvcGUiLCJmaXNjYWxDb2RlIjoiZW5jX2Zpc2NhbF9jb2RlIiwiZXhwIjoxNzE3NjUyLCJhY3F1aXJlcklkIjoiYWNxdWlyZXJfaWQiLCJpYXQiOjE3MTc1OTJ9.AA"); + assertEquals(jwt.serialize(), new SignedJWTParamConverter().toString(jwt)); + } +}