From e8281e39a4d7ade9d074a55ab2b2f009f4c4213d Mon Sep 17 00:00:00 2001 From: mahammedtaheer <57249563+mahammedtaheer@users.noreply.github.com> Date: Tue, 3 Oct 2023 14:50:58 +0530 Subject: [PATCH] [ES-313] Fixed blank attribute issue & language not available issue. (#1105) --- .../service/helper/TokenValidationHelper.java | 58 +----------- .../service/kyc/facade/KycFacadeImpl.java | 12 ++- .../service/kyc/facade/VciFacadeImpl.java | 12 ++- .../service/kyc/impl/KycServiceImpl.java | 5 +- .../service/kyc/impl/VciServiceImpl.java | 28 ++++-- .../kyc/util/ExchangeDataAttributesUtil.java | 90 +++++++++++++++++++ 6 files changed, 131 insertions(+), 74 deletions(-) create mode 100644 authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/util/ExchangeDataAttributesUtil.java diff --git a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/helper/TokenValidationHelper.java b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/helper/TokenValidationHelper.java index b3a56eba064..e8298042e80 100644 --- a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/helper/TokenValidationHelper.java +++ b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/helper/TokenValidationHelper.java @@ -9,6 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; import io.mosip.authentication.common.service.entity.KycTokenData; import io.mosip.authentication.common.service.entity.OIDCClientData; @@ -31,15 +32,12 @@ * @author Mahammed Taheer */ +@Component public class TokenValidationHelper { /** The mosip logger. */ private static Logger mosipLogger = IdaLogger.getLogger(TokenValidationHelper.class); - @Value("${ida.idp.consented.individual_id.attribute.name:individual_id}") - private String consentedIndividualIdAttributeName; - - /** The Kyc Service */ @Autowired private KycService kycService; @@ -47,13 +45,6 @@ public class TokenValidationHelper { @Autowired private KycTokenDataRepository kycTokenDataRepo; - @Autowired - private IdInfoHelper idInfoHelper; - - @Autowired - private OIDCClientDataRepository oidcClientDataRepo; - - public KycTokenData findAndValidateIssuedToken(String tokenData, String oidcClientId, String reqTransactionId, String idvidHash) throws IdAuthenticationBusinessException { @@ -131,49 +122,4 @@ private void validateToken(KycTokenData kycTokenData, String oidcClientId, Strin IdAuthenticationErrorConstants.KYC_TOKEN_EXPIRED.getErrorMessage()); } } - - public void mapConsentedAttributesToIdSchemaAttributes(List consentAttributes, Set filterAttributes, - List policyAllowedKycAttribs) throws IdAuthenticationBusinessException { - - if(consentAttributes != null && !consentAttributes.isEmpty()) { - for (String attrib : consentAttributes) { - Collection idSchemaAttribute = idInfoHelper.getIdentityAttributesForIdName(attrib); - filterAttributes.addAll(idSchemaAttribute); - } - // removing individual id from consent if the claim is not allowed in policy. - if (!policyAllowedKycAttribs.contains(consentedIndividualIdAttributeName)) { - consentAttributes.remove(consentedIndividualIdAttributeName); - } - } - } - - public Set filterByPolicyAllowedAttributes(Set filterAttributes, List policyAllowedKycAttribs) { - return policyAllowedKycAttribs.stream() - .filter(attribute -> filterAttributes.contains(attribute)) - .collect(Collectors.toSet()); - } - - public String getKycExchangeResponseTime(BaseRequestDTO authRequestDTO) { - String dateTimePattern = EnvUtil.getDateTimePattern(); - return IdaRequestResponsConsumerUtil.getResponseTime(authRequestDTO.getRequestTime(), dateTimePattern); - } - - public List filterAllowedUserClaims(String oidcClientId, List consentAttributes) { - mosipLogger.info(IdAuthCommonConstants.IDA, this.getClass().getSimpleName(), "filterAllowedUserClaims", - "Checking for OIDC client allowed userclaims"); - Optional oidcClientData = oidcClientDataRepo.findByClientId(oidcClientId); - - List oidcClientAllowedUserClaims = List.of(oidcClientData.get().getUserClaims()) - .stream() - .map(String::toLowerCase) - .collect(Collectors.toList()); - if (consentAttributes.isEmpty()) { - return oidcClientAllowedUserClaims; - } - - return consentAttributes.stream() - .filter(claim -> oidcClientAllowedUserClaims.contains(claim.toLowerCase())) - .collect(Collectors.toList()); - - } } diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/KycFacadeImpl.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/KycFacadeImpl.java index 7e3582f9732..4f3a6f4d508 100644 --- a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/KycFacadeImpl.java +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/KycFacadeImpl.java @@ -70,6 +70,7 @@ import io.mosip.authentication.core.spi.indauth.match.IdInfoFetcher; import io.mosip.authentication.core.spi.indauth.service.KycService; import io.mosip.authentication.core.spi.partner.service.PartnerService; +import io.mosip.authentication.service.kyc.util.ExchangeDataAttributesUtil; import io.mosip.kernel.core.logger.spi.Logger; import reactor.util.function.Tuple3; @@ -133,6 +134,9 @@ public class KycFacadeImpl implements KycFacade { @Autowired private TokenValidationHelper tokenValidationHelper; + @Autowired + private ExchangeDataAttributesUtil exchangeDataAttributesUtil; + /* * (non-Javadoc) * @@ -399,15 +403,15 @@ public KycExchangeResponseDTO processKycExchange(KycExchangeRequestDTO kycExchan } List consentAttributes = kycExchangeRequestDTO.getConsentObtained(); - List allowedConsentAttributes = tokenValidationHelper.filterAllowedUserClaims(oidcClientId, consentAttributes); + List allowedConsentAttributes = exchangeDataAttributesUtil.filterAllowedUserClaims(oidcClientId, consentAttributes); PolicyDTO policyDto = policyDtoOpt.get(); List policyAllowedKycAttribs = Optional.ofNullable(policyDto.getAllowedKycAttributes()).stream() .flatMap(Collection::stream).map(KYCAttributes::getAttributeName).collect(Collectors.toList()); Set filterAttributes = new HashSet<>(); - tokenValidationHelper.mapConsentedAttributesToIdSchemaAttributes(allowedConsentAttributes, filterAttributes, policyAllowedKycAttribs); - Set policyAllowedAttributes = tokenValidationHelper.filterByPolicyAllowedAttributes(filterAttributes, policyAllowedKycAttribs); + exchangeDataAttributesUtil.mapConsentedAttributesToIdSchemaAttributes(allowedConsentAttributes, filterAttributes, policyAllowedKycAttribs); + Set policyAllowedAttributes = exchangeDataAttributesUtil.filterByPolicyAllowedAttributes(filterAttributes, policyAllowedKycAttribs); boolean isBioRequired = false; if (filterAttributes.contains(CbeffDocType.FACE.getType().value().toLowerCase()) || @@ -438,7 +442,7 @@ public KycExchangeResponseDTO processKycExchange(KycExchangeRequestDTO kycExchan kycExchangeResponseDTO.setId(kycExchangeRequestDTO.getId()); kycExchangeResponseDTO.setTransactionID(kycExchangeRequestDTO.getTransactionID()); kycExchangeResponseDTO.setVersion(kycExchangeRequestDTO.getVersion()); - kycExchangeResponseDTO.setResponseTime(tokenValidationHelper.getKycExchangeResponseTime(kycExchangeRequestDTO)); + kycExchangeResponseDTO.setResponseTime(exchangeDataAttributesUtil.getKycExchangeResponseTime(kycExchangeRequestDTO)); EncryptedKycRespDTO encryptedKycRespDTO = new EncryptedKycRespDTO(); encryptedKycRespDTO.setEncryptedKyc(respJson); diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/VciFacadeImpl.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/VciFacadeImpl.java index 19b7b49ef92..f677f60044c 100644 --- a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/VciFacadeImpl.java +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/VciFacadeImpl.java @@ -52,6 +52,7 @@ import io.mosip.authentication.core.spi.indauth.match.IdInfoFetcher; import io.mosip.authentication.core.spi.partner.service.PartnerService; import io.mosip.authentication.service.kyc.impl.VciServiceImpl; +import io.mosip.authentication.service.kyc.util.ExchangeDataAttributesUtil; import io.mosip.kernel.core.logger.spi.Logger; /** @@ -104,6 +105,9 @@ public class VciFacadeImpl implements VciFacade { @Autowired private KycTokenDataRepository kycTokenDataRepo; + @Autowired + private ExchangeDataAttributesUtil exchangeDataAttributesUtil; + @Override public VciExchangeResponseDTO processVciExchange(VciExchangeRequestDTO vciExchangeRequestDTO, String partnerId, String oidcClientId, Map metadata, ObjectWithMetadata requestWithMetadata) throws IdAuthenticationBusinessException { @@ -133,15 +137,15 @@ public VciExchangeResponseDTO processVciExchange(VciExchangeRequestDTO vciExchan // Will implement later the consent claims based on credential definition input List consentAttributes = Collections.emptyList(); - List allowedConsentAttributes = tokenValidationHelper.filterAllowedUserClaims(oidcClientId, consentAttributes); + List allowedConsentAttributes = exchangeDataAttributesUtil.filterAllowedUserClaims(oidcClientId, consentAttributes); PolicyDTO policyDto = policyDtoOpt.get(); List policyAllowedKycAttribs = Optional.ofNullable(policyDto.getAllowedKycAttributes()).stream() .flatMap(Collection::stream).map(KYCAttributes::getAttributeName).collect(Collectors.toList()); Set filterAttributes = new HashSet<>(); - tokenValidationHelper.mapConsentedAttributesToIdSchemaAttributes(allowedConsentAttributes, filterAttributes, policyAllowedKycAttribs); - Set policyAllowedAttributes = tokenValidationHelper.filterByPolicyAllowedAttributes(filterAttributes, policyAllowedKycAttribs); + exchangeDataAttributesUtil.mapConsentedAttributesToIdSchemaAttributes(allowedConsentAttributes, filterAttributes, policyAllowedKycAttribs); + Set policyAllowedAttributes = exchangeDataAttributesUtil.filterByPolicyAllowedAttributes(filterAttributes, policyAllowedKycAttribs); boolean isBioRequired = false; if (filterAttributes.contains(CbeffDocType.FACE.getType().value().toLowerCase()) || @@ -178,7 +182,7 @@ public VciExchangeResponseDTO processVciExchange(VciExchangeRequestDTO vciExchan vciExchangeResponseDTO.setId(vciExchangeRequestDTO.getId()); vciExchangeResponseDTO.setTransactionID(vciExchangeRequestDTO.getTransactionID()); vciExchangeResponseDTO.setVersion(vciExchangeRequestDTO.getVersion()); - vciExchangeResponseDTO.setResponseTime(tokenValidationHelper.getKycExchangeResponseTime(vciExchangeRequestDTO)); + vciExchangeResponseDTO.setResponseTime(exchangeDataAttributesUtil.getKycExchangeResponseTime(vciExchangeRequestDTO)); vciExchangeResponseDTO.setResponse(vcResponseDTO); saveToTxnTable(vciExchangeRequestDTO, false, true, partnerId, token, vciExchangeResponseDTO, requestWithMetadata); auditHelper.audit(AuditModules.VCI_EXCHANGE, AuditEvents.VCI_EXCHANGE_REQUEST_RESPONSE, diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/impl/KycServiceImpl.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/impl/KycServiceImpl.java index 5bd9d2579e3..614f904f65c 100644 --- a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/impl/KycServiceImpl.java +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/impl/KycServiceImpl.java @@ -4,6 +4,7 @@ import java.nio.ByteBuffer; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; +import java.time.temporal.ValueRange; import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.HashMap; @@ -441,9 +442,11 @@ public boolean isKycTokenExpire(LocalDateTime tokenIssuedDateTime, String kycTok LocalDateTime currentTime = LocalDateTime.now(); long diffSeconds = ChronoUnit.SECONDS.between(tokenIssuedDateTime, currentTime); + long adjustmentSeconds = EnvUtil.getKycTokenExpireTimeAdjustmentSeconds(); + ValueRange valueRange = ValueRange.of(0, adjustmentSeconds); - if (tokenIssuedDateTime != null && adjustmentSeconds < diffSeconds) { + if (tokenIssuedDateTime != null && !valueRange.isValidIntValue(diffSeconds)) { return true; } return false; diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/impl/VciServiceImpl.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/impl/VciServiceImpl.java index 73095681daf..e7271893149 100644 --- a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/impl/VciServiceImpl.java +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/impl/VciServiceImpl.java @@ -399,15 +399,21 @@ private Map getCredSubjectMap(String credSubjectId, Map 0)) + credSubjectMap.put(idSchemaAttribute, value); + } else { Map valueMap = new HashMap<>(); String lang = identityInfo.getLanguage(); if (locales.contains(lang)) { - valueMap.put(IdAuthCommonConstants.LANGUAGE_STRING, lang); - valueMap.put(IdAuthCommonConstants.VALUE_STRING, identityInfo.getValue()); - credSubjectMap.put(idSchemaAttribute, valueMap); + String value = identityInfo.getValue(); + if (Objects.nonNull(value) && (value.trim().length() > 0)) { + valueMap.put(IdAuthCommonConstants.LANGUAGE_STRING, lang); + valueMap.put(IdAuthCommonConstants.VALUE_STRING, value); + credSubjectMap.put(idSchemaAttribute, valueMap); + } } } continue; @@ -417,12 +423,16 @@ private Map getCredSubjectMap(String credSubjectId, Map valueMap = new HashMap<>(); String lang = identityInfo.getLanguage(); if (locales.contains(lang)) { - valueMap.put(IdAuthCommonConstants.LANGUAGE_STRING, identityInfo.getLanguage()); - valueMap.put(IdAuthCommonConstants.VALUE_STRING, identityInfo.getValue()); - valueList.add(valueMap); + String value = identityInfo.getValue(); + if (Objects.nonNull(value) && (value.trim().length() > 0)) { + valueMap.put(IdAuthCommonConstants.LANGUAGE_STRING, identityInfo.getLanguage()); + valueMap.put(IdAuthCommonConstants.VALUE_STRING, identityInfo.getValue()); + valueList.add(valueMap); + } } } - credSubjectMap.put(idSchemaAttribute, valueList); + if (valueList.size() > 0) + credSubjectMap.put(idSchemaAttribute, valueList); } } return credSubjectMap; diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/util/ExchangeDataAttributesUtil.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/util/ExchangeDataAttributesUtil.java new file mode 100644 index 00000000000..0497cbc9ca5 --- /dev/null +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/util/ExchangeDataAttributesUtil.java @@ -0,0 +1,90 @@ +package io.mosip.authentication.service.kyc.util; + +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import io.mosip.authentication.common.service.entity.OIDCClientData; +import io.mosip.authentication.common.service.helper.IdInfoHelper; +import io.mosip.authentication.common.service.repository.OIDCClientDataRepository; +import io.mosip.authentication.common.service.util.EnvUtil; +import io.mosip.authentication.common.service.util.IdaRequestResponsConsumerUtil; +import io.mosip.authentication.core.constant.IdAuthCommonConstants; +import io.mosip.authentication.core.exception.IdAuthenticationBusinessException; +import io.mosip.authentication.core.indauth.dto.BaseRequestDTO; +import io.mosip.authentication.core.logger.IdaLogger; +import io.mosip.kernel.core.logger.spi.Logger; + +/** + * Utility class to filter the consented attribute and policy allowed attributes. + * + * @author Mahammed Taheer + */ + +@Component +public class ExchangeDataAttributesUtil { + + /** The mosip logger. */ + private static Logger mosipLogger = IdaLogger.getLogger(ExchangeDataAttributesUtil.class); + + @Value("${ida.idp.consented.individual_id.attribute.name:individual_id}") + private String consentedIndividualIdAttributeName; + + @Autowired + private IdInfoHelper idInfoHelper; + + @Autowired + private OIDCClientDataRepository oidcClientDataRepo; + + public void mapConsentedAttributesToIdSchemaAttributes(List consentAttributes, Set filterAttributes, + List policyAllowedKycAttribs) throws IdAuthenticationBusinessException { + + if(consentAttributes != null && !consentAttributes.isEmpty()) { + for (String attrib : consentAttributes) { + Collection idSchemaAttribute = idInfoHelper.getIdentityAttributesForIdName(attrib); + filterAttributes.addAll(idSchemaAttribute); + } + // removing individual id from consent if the claim is not allowed in policy. + if (!policyAllowedKycAttribs.contains(consentedIndividualIdAttributeName)) { + consentAttributes.remove(consentedIndividualIdAttributeName); + } + } + } + + public Set filterByPolicyAllowedAttributes(Set filterAttributes, List policyAllowedKycAttribs) { + return policyAllowedKycAttribs.stream() + .filter(attribute -> filterAttributes.contains(attribute)) + .collect(Collectors.toSet()); + } + + public String getKycExchangeResponseTime(BaseRequestDTO authRequestDTO) { + String dateTimePattern = EnvUtil.getDateTimePattern(); + return IdaRequestResponsConsumerUtil.getResponseTime(authRequestDTO.getRequestTime(), dateTimePattern); + } + + public List filterAllowedUserClaims(String oidcClientId, List consentAttributes) { + mosipLogger.info(IdAuthCommonConstants.IDA, this.getClass().getSimpleName(), "filterAllowedUserClaims", + "Checking for OIDC client allowed userclaims"); + Optional oidcClientData = oidcClientDataRepo.findByClientId(oidcClientId); + + List oidcClientAllowedUserClaims = List.of(oidcClientData.get().getUserClaims()) + .stream() + .map(String::toLowerCase) + .collect(Collectors.toList()); + if (consentAttributes.isEmpty()) { + return oidcClientAllowedUserClaims; + } + + return consentAttributes.stream() + .filter(claim -> oidcClientAllowedUserClaims.contains(claim.toLowerCase())) + .collect(Collectors.toList()); + + } + +}