Skip to content

Commit

Permalink
[ES-313] Fixed blank attribute issue & language not available issue. (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
mahammedtaheer authored Oct 3, 2023
1 parent 1d42341 commit e8281e3
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -31,29 +32,19 @@
* @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;

@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 {

Expand Down Expand Up @@ -131,49 +122,4 @@ private void validateToken(KycTokenData kycTokenData, String oidcClientId, Strin
IdAuthenticationErrorConstants.KYC_TOKEN_EXPIRED.getErrorMessage());
}
}

public void mapConsentedAttributesToIdSchemaAttributes(List<String> consentAttributes, Set<String> filterAttributes,
List<String> policyAllowedKycAttribs) throws IdAuthenticationBusinessException {

if(consentAttributes != null && !consentAttributes.isEmpty()) {
for (String attrib : consentAttributes) {
Collection<? extends String> 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<String> filterByPolicyAllowedAttributes(Set<String> filterAttributes, List<String> 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<String> filterAllowedUserClaims(String oidcClientId, List<String> consentAttributes) {
mosipLogger.info(IdAuthCommonConstants.IDA, this.getClass().getSimpleName(), "filterAllowedUserClaims",
"Checking for OIDC client allowed userclaims");
Optional<OIDCClientData> oidcClientData = oidcClientDataRepo.findByClientId(oidcClientId);

List<String> 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());

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -133,6 +134,9 @@ public class KycFacadeImpl implements KycFacade {
@Autowired
private TokenValidationHelper tokenValidationHelper;

@Autowired
private ExchangeDataAttributesUtil exchangeDataAttributesUtil;

/*
* (non-Javadoc)
*
Expand Down Expand Up @@ -399,15 +403,15 @@ public KycExchangeResponseDTO processKycExchange(KycExchangeRequestDTO kycExchan
}

List<String> consentAttributes = kycExchangeRequestDTO.getConsentObtained();
List<String> allowedConsentAttributes = tokenValidationHelper.filterAllowedUserClaims(oidcClientId, consentAttributes);
List<String> allowedConsentAttributes = exchangeDataAttributesUtil.filterAllowedUserClaims(oidcClientId, consentAttributes);

PolicyDTO policyDto = policyDtoOpt.get();
List<String> policyAllowedKycAttribs = Optional.ofNullable(policyDto.getAllowedKycAttributes()).stream()
.flatMap(Collection::stream).map(KYCAttributes::getAttributeName).collect(Collectors.toList());

Set<String> filterAttributes = new HashSet<>();
tokenValidationHelper.mapConsentedAttributesToIdSchemaAttributes(allowedConsentAttributes, filterAttributes, policyAllowedKycAttribs);
Set<String> policyAllowedAttributes = tokenValidationHelper.filterByPolicyAllowedAttributes(filterAttributes, policyAllowedKycAttribs);
exchangeDataAttributesUtil.mapConsentedAttributesToIdSchemaAttributes(allowedConsentAttributes, filterAttributes, policyAllowedKycAttribs);
Set<String> policyAllowedAttributes = exchangeDataAttributesUtil.filterByPolicyAllowedAttributes(filterAttributes, policyAllowedKycAttribs);

boolean isBioRequired = false;
if (filterAttributes.contains(CbeffDocType.FACE.getType().value().toLowerCase()) ||
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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<String, Object> metadata, ObjectWithMetadata requestWithMetadata) throws IdAuthenticationBusinessException {
Expand Down Expand Up @@ -133,15 +137,15 @@ public VciExchangeResponseDTO processVciExchange(VciExchangeRequestDTO vciExchan

// Will implement later the consent claims based on credential definition input
List<String> consentAttributes = Collections.emptyList();
List<String> allowedConsentAttributes = tokenValidationHelper.filterAllowedUserClaims(oidcClientId, consentAttributes);
List<String> allowedConsentAttributes = exchangeDataAttributesUtil.filterAllowedUserClaims(oidcClientId, consentAttributes);

PolicyDTO policyDto = policyDtoOpt.get();
List<String> policyAllowedKycAttribs = Optional.ofNullable(policyDto.getAllowedKycAttributes()).stream()
.flatMap(Collection::stream).map(KYCAttributes::getAttributeName).collect(Collectors.toList());

Set<String> filterAttributes = new HashSet<>();
tokenValidationHelper.mapConsentedAttributesToIdSchemaAttributes(allowedConsentAttributes, filterAttributes, policyAllowedKycAttribs);
Set<String> policyAllowedAttributes = tokenValidationHelper.filterByPolicyAllowedAttributes(filterAttributes, policyAllowedKycAttribs);
exchangeDataAttributesUtil.mapConsentedAttributesToIdSchemaAttributes(allowedConsentAttributes, filterAttributes, policyAllowedKycAttribs);
Set<String> policyAllowedAttributes = exchangeDataAttributesUtil.filterByPolicyAllowedAttributes(filterAttributes, policyAllowedKycAttribs);

boolean isBioRequired = false;
if (filterAttributes.contains(CbeffDocType.FACE.getType().value().toLowerCase()) ||
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,15 +399,21 @@ private Map<String, Object> getCredSubjectMap(String credSubjectId, Map<String,
continue;
if (idInfoList.size() == 1) {
IdentityInfoDTO identityInfo = idInfoList.get(0);
if (Objects.isNull(identityInfo.getLanguage()))
credSubjectMap.put(idSchemaAttribute, idInfoList.get(0).getValue());
if (Objects.isNull(identityInfo.getLanguage())) {
String value = identityInfo.getValue();
if (Objects.nonNull(value) && (value.trim().length() > 0))
credSubjectMap.put(idSchemaAttribute, value);
}
else {
Map<String, String> 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;
Expand All @@ -417,12 +423,16 @@ private Map<String, Object> getCredSubjectMap(String credSubjectId, Map<String,
Map<String, String> 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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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<String> consentAttributes, Set<String> filterAttributes,
List<String> policyAllowedKycAttribs) throws IdAuthenticationBusinessException {

if(consentAttributes != null && !consentAttributes.isEmpty()) {
for (String attrib : consentAttributes) {
Collection<? extends String> 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<String> filterByPolicyAllowedAttributes(Set<String> filterAttributes, List<String> 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<String> filterAllowedUserClaims(String oidcClientId, List<String> consentAttributes) {
mosipLogger.info(IdAuthCommonConstants.IDA, this.getClass().getSimpleName(), "filterAllowedUserClaims",
"Checking for OIDC client allowed userclaims");
Optional<OIDCClientData> oidcClientData = oidcClientDataRepo.findByClientId(oidcClientId);

List<String> 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());

}

}

0 comments on commit e8281e3

Please sign in to comment.