From 599269c5170147f6d0acc637377d8ef10e49400b Mon Sep 17 00:00:00 2001 From: ase-101 Date: Fri, 18 Oct 2024 01:32:49 +0530 Subject: [PATCH 1/2] ES-1807 Signed-off-by: ase-101 --- docker-compose/docker-compose.yml | 3 +- .../services/AuthorizationServiceImpl.java | 7 ++- .../esignet/services/ClaimsHelperService.java | 3 +- .../services/AuthorizationServiceTest.java | 55 ++++++++++++++++++- 4 files changed, 60 insertions(+), 8 deletions(-) diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml index 5ba0eb65f..29d93bc9f 100644 --- a/docker-compose/docker-compose.yml +++ b/docker-compose/docker-compose.yml @@ -20,11 +20,12 @@ services: - SPRING_DATASOURCE_URL=jdbc:postgresql://database:5432/mosip_mockidentitysystem?currentSchema=mockidentitysystem - SPRING_DATASOURCE_USERNAME=postgres - SPRING_DATASOURCE_PASSWORD=postgres + - MOSIP_MOCK_IDA_KYC_TRANSACTION_TIMEOUT_SECS=900 depends_on: - database esignet: - image: mosipdev/esignet:release-1.5.x + image: 'mosipdev/esignet:release-1.5.x' user: root ports: - 8088:8088 diff --git a/oidc-service-impl/src/main/java/io/mosip/esignet/services/AuthorizationServiceImpl.java b/oidc-service-impl/src/main/java/io/mosip/esignet/services/AuthorizationServiceImpl.java index b6a7dde57..6292e24a3 100644 --- a/oidc-service-impl/src/main/java/io/mosip/esignet/services/AuthorizationServiceImpl.java +++ b/oidc-service-impl/src/main/java/io/mosip/esignet/services/AuthorizationServiceImpl.java @@ -277,12 +277,13 @@ public ClaimDetailResponse getClaimDetails(String transactionId) { } //Profile update is mandated only if any essential verified claim is requested - boolean isEssentialVerifiedClaimRequested = transaction.getResolvedClaims().getUserinfo() + boolean unverifiedEssentialClaimsExists = transaction.getResolvedClaims().getUserinfo() .entrySet() .stream() .anyMatch( entry -> entry.getValue().stream() - .anyMatch(m -> (boolean) m.getOrDefault("essential", false) && m.get("verification") != null )); - claimDetailResponse.setProfileUpdateRequired(isEssentialVerifiedClaimRequested); + .anyMatch(m -> (boolean) m.getOrDefault("essential", false) && m.get("verification") != null && + transaction.getClaimMetadata().getOrDefault(entry.getKey(), Collections.EMPTY_LIST).isEmpty() )); + claimDetailResponse.setProfileUpdateRequired(unverifiedEssentialClaimsExists); claimDetailResponse.setClaimStatus(list); auditWrapper.logAudit(Action.CLAIM_DETAILS, ActionStatus.SUCCESS, AuditHelper.buildAuditDto(transactionId, transaction), null); diff --git a/oidc-service-impl/src/main/java/io/mosip/esignet/services/ClaimsHelperService.java b/oidc-service-impl/src/main/java/io/mosip/esignet/services/ClaimsHelperService.java index 446875ec4..e3cce84b6 100644 --- a/oidc-service-impl/src/main/java/io/mosip/esignet/services/ClaimsHelperService.java +++ b/oidc-service-impl/src/main/java/io/mosip/esignet/services/ClaimsHelperService.java @@ -164,7 +164,8 @@ protected ClaimStatus getClaimStatus(String claim, List> cla //if the claim is requested without any verification metadata if(CollectionUtils.isEmpty(claimDetails) || claimDetails.stream().allMatch( m -> m.get("verification") == null)) - return new ClaimStatus(claim, false, storedVerificationMetadata.containsKey(claim)); + return new ClaimStatus(claim, !storedVerificationMetadata.getOrDefault(claim, Collections.emptyList()).isEmpty(), + storedVerificationMetadata.containsKey(claim)); log.info("Request to fetch verification metadata for {} with filter criteria : {}", claim, claimDetails); List storedVerificationDetails = storedVerificationMetadata.get(claim); diff --git a/oidc-service-impl/src/test/java/io/mosip/esignet/services/AuthorizationServiceTest.java b/oidc-service-impl/src/test/java/io/mosip/esignet/services/AuthorizationServiceTest.java index 3de60b0ce..c982a6ac9 100644 --- a/oidc-service-impl/src/test/java/io/mosip/esignet/services/AuthorizationServiceTest.java +++ b/oidc-service-impl/src/test/java/io/mosip/esignet/services/AuthorizationServiceTest.java @@ -19,6 +19,7 @@ import io.mosip.esignet.api.spi.AuditPlugin; import io.mosip.esignet.api.spi.Authenticator; import io.mosip.esignet.api.util.ConsentAction; +import io.mosip.esignet.api.util.FilterCriteriaMatcher; import io.mosip.esignet.core.constants.Constants; import io.mosip.esignet.core.dto.*; import io.mosip.esignet.core.exception.EsignetException; @@ -102,9 +103,14 @@ public void setUp() { claims.put("profile", Arrays.asList("given_name", "profile_picture", "name", "phone_number", "email")); claims.put("email", Arrays.asList("email","email_verified")); claims.put("phone", Arrays.asList("phone_number","phone_number_verified")); + + FilterCriteriaMatcher filterCriteriaMatcher = new FilterCriteriaMatcher(); + ReflectionTestUtils.setField(filterCriteriaMatcher,"objectMapper", new ObjectMapper()); + ClaimsHelperService claimsHelperService = new ClaimsHelperService(); ReflectionTestUtils.setField(claimsHelperService,"claims", claims); ReflectionTestUtils.setField(claimsHelperService,"objectMapper", new ObjectMapper()); + ReflectionTestUtils.setField(claimsHelperService,"filterCriteriaMatcher", filterCriteriaMatcher); ReflectionTestUtils.setField(authorizationHelperService, "credentialScopes", Arrays.asList("sample_ldp_vc")); ReflectionTestUtils.setField(authorizationHelperService, "authorizeScopes", Arrays.asList("resident-service")); @@ -1371,24 +1377,67 @@ public void getAuthCode_withInValidTransactionId_thenFail() { } @Test - public void getClaimDetails_withValidTransaction_thenPass(){ + public void getClaimDetails_withUnVerifiedClaimsRequest_thenPass(){ OIDCTransaction transaction=new OIDCTransaction(); Claims resolvedClaims = new Claims(); resolvedClaims.setUserinfo(new HashMap<>()); Map map = new HashMap<>(); map.put("essential", true); - map.put("verification", new HashMap<>()); resolvedClaims.getUserinfo().put("name", Arrays.asList(map)); - transaction.setResolvedClaims(resolvedClaims); transaction.setEssentialClaims(List.of("name", "email")); transaction.setVoluntaryClaims(List.of("phone_number")); + + Map> claimMetadata = new HashMap<>(); + transaction.setClaimMetadata(claimMetadata); transaction.setConsentAction(ConsentAction.NOCAPTURE); Mockito.when(cacheUtilService.getAuthenticatedTransaction(Mockito.anyString())).thenReturn(transaction); ClaimDetailResponse claimDetailResponse = authorizationServiceImpl.getClaimDetails("transactionId"); Assert.assertEquals(claimDetailResponse.getConsentAction(),ConsentAction.NOCAPTURE); Assert.assertEquals(claimDetailResponse.getTransactionId(),"transactionId"); + Assert.assertFalse(claimDetailResponse.isProfileUpdateRequired()); + } + + @Test + public void getClaimDetails_withVerifiedClaimsRequest_thenPass() throws JsonProcessingException { + OIDCTransaction transaction=new OIDCTransaction(); + Claims resolvedClaims = new Claims(); + resolvedClaims.setUserinfo(new HashMap<>()); + Map map = new HashMap<>(); + map.put("essential", true); + Map requestedVerification = new HashMap<>(); + requestedVerification.put("trust_framework", null); + map.put("verification", requestedVerification); + resolvedClaims.getUserinfo().put("name", Arrays.asList(map)); + transaction.setResolvedClaims(resolvedClaims); + transaction.setEssentialClaims(List.of("name", "email")); + transaction.setVoluntaryClaims(List.of("phone_number")); + + Map> claimMetadata = new HashMap<>(); + transaction.setClaimMetadata(claimMetadata); + transaction.setConsentAction(ConsentAction.CAPTURE); + Mockito.when(cacheUtilService.getAuthenticatedTransaction(Mockito.anyString())).thenReturn(transaction); + + ClaimDetailResponse claimDetailResponse = authorizationServiceImpl.getClaimDetails("transactionId"); + Assert.assertEquals(claimDetailResponse.getConsentAction(),ConsentAction.CAPTURE); + Assert.assertEquals(claimDetailResponse.getTransactionId(),"transactionId"); + Assert.assertTrue(claimDetailResponse.getClaimStatus().stream().allMatch(cs -> !cs.isVerified() && !cs.isAvailable())); + Assert.assertTrue(claimDetailResponse.isProfileUpdateRequired()); + + Map emailMap = new HashMap<>(); + emailMap.put("essential", true); + resolvedClaims.getUserinfo().put("email", Arrays.asList(emailMap)); + Map phoneMap = new HashMap<>(); + phoneMap.put("essential", false); + resolvedClaims.getUserinfo().put("phone_number", Arrays.asList(phoneMap)); + claimMetadata.put("name", Arrays.asList(objectMapper.readTree("{\"verification\": {\"trust_framework\": \"XYZ TF\"}}"))); + claimMetadata.put("phone_number", Arrays.asList()); + claimDetailResponse = authorizationServiceImpl.getClaimDetails("transactionId"); + Assert.assertTrue(claimDetailResponse.getClaimStatus().stream().anyMatch(cs -> cs.getClaim().equals("name") && cs.isVerified() && cs.isAvailable())); + Assert.assertTrue(claimDetailResponse.getClaimStatus().stream().anyMatch(cs -> cs.getClaim().equals("email") && !cs.isVerified() && !cs.isAvailable())); + Assert.assertTrue(claimDetailResponse.getClaimStatus().stream().anyMatch(cs -> cs.getClaim().equals("phone_number") && !cs.isVerified() && cs.isAvailable())); + Assert.assertFalse(claimDetailResponse.isProfileUpdateRequired()); } @Test From ef3b5f4b219559c988e4b3351c6d100edd748179 Mon Sep 17 00:00:00 2001 From: ase-101 Date: Fri, 18 Oct 2024 01:35:34 +0530 Subject: [PATCH 2/2] Updated postman collection Signed-off-by: ase-101 --- .../eSignet.postman_collection.json | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/postman-collection/eSignet.postman_collection.json b/postman-collection/eSignet.postman_collection.json index 7e047571d..7d32a8f8d 100644 --- a/postman-collection/eSignet.postman_collection.json +++ b/postman-collection/eSignet.postman_collection.json @@ -192,7 +192,8 @@ "const publicKeyPem = pmlib.rs.KEYUTIL.getPEM(kp.pubKeyObj, \"PKCS8PUB\");", "// Convert the PEM format to a simple Base64 string (removing PEM headers)", "const publicKeyBase64 = publicKeyPem.replace(/-----BEGIN PUBLIC KEY-----|-----END PUBLIC KEY-----|\\n/g, '');", - "pm.environment.set(\"client_id\", publicKeyBase64.substring(2, 50));", + "let updatedStr = publicKeyBase64.replace(/\\//g, \"_\");", + "pm.environment.set(\"client_id\", updatedStr.substring(2, 50));", "", "// Log the result to Postman's console (option);", "pm.environment.set(\"client_private_key\", JSON.stringify(privateKey_jwk));", @@ -255,7 +256,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"requestTime\": \"{{$isoTimestamp}}\",\n \"request\": {\n \"logoUri\": \"{{$randomImageUrl}}\",\n \"redirectUris\": [\n \"{{redirection_url}}\",\n \"io.mosip.residentapp://oauth\",\n \"http://loclahost:3000/**\",\n \"http://loclahost:5000/registration/*\"\n ],\n \"userClaims\": [\n \"name\",\n \"email\",\n \"gender\",\n \"phone_number\",\n \"birthdate\",\n \"picture\",\n \"address\"\n ],\n \"authContextRefs\": [\n \"mosip:idp:acr:generated-code\",\n \"mosip:idp:acr:password\",\n \"mosip:idp:acr:linked-wallet\",\n \"mosip:idp:acr:biometrics\"\n ],\n \"status\": \"ACTIVE\",\n \"grantTypes\": [\n \"authorization_code\"\n ],\n \"clientName\": \"{{$randomCompanyName}}\",\n \"clientAuthMethods\": [\n \"private_key_jwt\"\n ]\n }\n}", + "raw": "{\n \"requestTime\": \"{{$isoTimestamp}}\",\n \"request\": {\n \"logoUri\": \"{{$randomImageUrl}}\",\n \"redirectUris\": [\n \"{{redirection_url}}\",\n \"io.mosip.residentapp://oauth\",\n \"http://loclahost:3000/**\",\n \"http://loclahost:5000/registration/*\"\n ],\n \"userClaims\": [\n \"name\",\n \"email\",\n \"gender\",\n \"phone_number\",\n \"birthdate\",\n \"picture\",\n \"address\"\n ],\n \"authContextRefs\": [\n \"mosip:idp:acr:generated-code\",\n \"mosip:idp:acr:password\",\n \"mosip:idp:acr:linked-wallet\",\n \"mosip:idp:acr:biometrics\",\n \"mosip:idp:acr:static-code\"\n ],\n \"status\": \"ACTIVE\",\n \"grantTypes\": [\n \"authorization_code\"\n ],\n \"clientName\": \"{{$randomCompanyName}}\",\n \"clientAuthMethods\": [\n \"private_key_jwt\"\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -1092,7 +1093,7 @@ "pm.test(\"Validate linkTransactionId\", function () {", " var jsonData = pm.response.json();", " pm.expect(jsonData.response.linkTransactionId).not.equals(null);", - " pm.environment.set(\"linkTransactionId\", jsonData.response.linkTransactionId);", + " pm.environment.set(\"link_transaction_id\", jsonData.response.linkTransactionId);", "});" ], "type": "text/javascript", @@ -1210,7 +1211,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"requestTime\": \"{{$isoTimestamp}}\",\n \"request\": {\n \"linkedTransactionId\": \"{{linkTransactionId}}\",\n \"individualId\": \"{{individual_id}}\",\n \"challengeList\" : [\n {\n \"authFactorType\" : \"WLA\",\n \"challenge\" : \"{{wla_challenge}}\",\n \"format\" : \"jwt\"\n }\n ]\n }\n}", + "raw": "{\n \"requestTime\": \"{{$isoTimestamp}}\",\n \"request\": {\n \"linkedTransactionId\": \"{{link_transaction_id}}\",\n \"individualId\": \"{{individual_id}}\",\n \"challengeList\" : [\n {\n \"authFactorType\" : \"WLA\",\n \"challenge\" : \"{{wla_challenge}}\",\n \"format\" : \"jwt\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -1278,7 +1279,7 @@ "pm.test(\"Validate code\", function () {", " var jsonData = pm.response.json();", " pm.expect(jsonData.response.code).not.equals(null);", - " pm.environment.set(\"code\", jsonData.response.code);", + " pm.collectionVariables.set(\"code\", jsonData.response.code);", "});" ], "type": "text/javascript", @@ -1299,7 +1300,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"requestTime\": \"{{$isoTimestamp}}\",\n \"request\": {\n \"linkedTransactionId\": \"{{linkTransactionId}}\",\n \"acceptedClaims\": {{accepted_claims}},\n \"signature\": \"{{detachedSignature}}\"\n }\n}", + "raw": "{\n \"requestTime\": \"{{$isoTimestamp}}\",\n \"request\": {\n \"linkedTransactionId\": \"{{link_transaction_id}}\",\n \"acceptedClaims\": {{accepted_claims}},\n \"signature\": \"{{detachedSignature}}\"\n }\n}", "options": { "raw": { "language": "json" @@ -1874,7 +1875,7 @@ "response": [] }, { - "name": "Complete the verification process & Resume Halted Transaction", + "name": "Complete Signup Redirect", "request": { "method": "POST", "header": [ @@ -1970,7 +1971,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"requestTime\": \"{{$isoTimestamp}}\",\n \"request\": {\n \"transactionId\": \"{{transaction_id}}\",\n \"acceptedClaims\": {{accepted_claims}},\n \"permittedAuthorizeScopes\" : {{permitted_authorized_scopes}}\n }\n}", + "raw": "{\n \"requestTime\": \"{{$isoTimestamp}}\",\n \"request\": {\n \"transactionId\": \"{{transaction_id}}\",\n \"acceptedClaims\": [\"name\",\"phone_number\"],\n \"permittedAuthorizeScopes\" : {{permitted_authorized_scopes}}\n }\n}", "options": { "raw": { "language": "json"