Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package io.mosip.esignet.api.validator;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.mosip.esignet.api.dto.AuthChallenge;
import io.mosip.esignet.api.util.ErrorConstants;
import io.mosip.esignet.api.validator.AuthChallengeFactorFormat;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -12,7 +14,11 @@

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

@Component
public class AuthChallengeFactorFormatValidator implements ConstraintValidator<AuthChallengeFactorFormat, AuthChallenge> {
Expand All @@ -24,6 +30,12 @@ public class AuthChallengeFactorFormatValidator implements ConstraintValidator<A
@Autowired
private Environment environment;

@Autowired
private ObjectMapper objectMapper;

@Value("#{${mosip.esignet.authenticator.default.auth-factor.kba.field-details}}")
private List<Map<String, String>> fieldDetailList;

@Override
public boolean isValid(AuthChallenge authChallenge, ConstraintValidatorContext context) {
String authFactor = authChallenge.getAuthFactorType();
Expand All @@ -42,7 +54,32 @@ public boolean isValid(AuthChallenge authChallenge, ConstraintValidatorContext c
int min = environment.getProperty(String.format(MIN_LENGTH_KEY_PREFIX, authFactor), Integer.TYPE, 50);
int max = environment.getProperty(String.format(MAX_LENGTH_KEY_PREFIX, authFactor), Integer.TYPE, 50);
String challenge = authChallenge.getChallenge();
int length = StringUtils.hasText(challenge)? challenge.length():0 ;
return length>=min && length<=max;
int length = StringUtils.hasText(challenge) ? challenge.length() : 0;
if (!(length >= min && length <= max)) {
return false;
}
if (authFactor.equals("KBA")) {
return validateChallenge(authChallenge.getChallenge());
}
return length >= min && length <= max;
}

private boolean validateChallenge(String challenge) {
byte[] decodedBytes = Base64.getDecoder().decode(challenge);
String decodedString = new String(decodedBytes, StandardCharsets.UTF_8);
Map<String, String> challengeMap;
try {
challengeMap = objectMapper.readValue(decodedString, new TypeReference<Map<String, String>>() {
});
} catch (JsonProcessingException e) {
return false;
}
for (Map<String, String> fieldDetail : fieldDetailList) {
String id=fieldDetail.get("id");
if(fieldDetail.containsKey("regex") && challengeMap.containsKey(id) && !Pattern.compile(fieldDetail.get("regex")).matcher(challengeMap.get(id)).matches()) {
return false;
}
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.*;

import static io.mosip.esignet.api.util.ErrorConstants.INVALID_AUTH_FACTOR_TYPE_FORMAT;
import static io.mosip.esignet.api.util.ErrorConstants.INVALID_CHALLENGE_LENGTH;
Expand Down Expand Up @@ -819,6 +816,88 @@ public void authenticateEndUser_withInvalidFormat_returnErrorResponse() throws E
.andExpect(jsonPath("$.errors[0].errorCode").value("invalid_challenge_format"));
}

@Test
public void authenticateEndUser_withValidKBADetails_returnSuccessResponse() throws Exception {
AuthRequest authRequest = new AuthRequest();
authRequest.setIndividualId("1234567890");
authRequest.setTransactionId("1234567890");

AuthChallenge authChallenge = new AuthChallenge();
authChallenge.setChallenge("eyJmdWxsTmFtZSI6IkthaWYgU2lkZGlxdWUiLCJkb2IiOiIyMDAwLTA3LTI2In0\u003d");
authChallenge.setAuthFactorType("KBA");
authChallenge.setFormat("base64url-encoded-json");

List<AuthChallenge> authChallengeList = new ArrayList<>();
authChallengeList.add(authChallenge);

authRequest.setChallengeList(authChallengeList);

RequestWrapper wrapper = new RequestWrapper<>();
wrapper.setRequestTime(IdentityProviderUtil.getUTCDateTime());
wrapper.setRequest(authRequest);
when(authorizationService.authenticateUserV2(authRequest)).thenReturn(new AuthResponseV2());
mockMvc.perform(post("/authorization/v2/authenticate")
.content(objectMapper.writeValueAsString(wrapper))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}

@Test
public void authenticateEndUser_withInvalidChallenge_returnErrorResponse() throws Exception {
AuthRequest authRequest = new AuthRequest();
authRequest.setIndividualId("1234567890");
authRequest.setTransactionId("1234567890");

AuthChallenge authChallenge = new AuthChallenge();
authChallenge.setChallenge("eyJmdWxsTmFtZSI6IjEyMyIsImRvYiI6IjIwMDAtMDctMjYifQ==");
authChallenge.setAuthFactorType("KBA");
authChallenge.setFormat("base64url-encoded-json");

List<AuthChallenge> authChallengeList = new ArrayList<>();
authChallengeList.add(authChallenge);

authRequest.setChallengeList(authChallengeList);

RequestWrapper wrapper = new RequestWrapper<>();
wrapper.setRequestTime(IdentityProviderUtil.getUTCDateTime());
wrapper.setRequest(authRequest);
when(authorizationService.authenticateUserV2(authRequest)).thenReturn(new AuthResponseV2());
mockMvc.perform(post("/authorization/v2/authenticate")
.content(objectMapper.writeValueAsString(wrapper))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.errors").isNotEmpty())
.andExpect(jsonPath("$.errors[0].errorCode").value("invalid_challenge"));
}

@Test
public void authenticateEndUser_withInvalidChallengeJson_returnErrorResponse() throws Exception {
AuthRequest authRequest = new AuthRequest();
authRequest.setIndividualId("1234567890");
authRequest.setTransactionId("1234567890");

AuthChallenge authChallenge = new AuthChallenge();
authChallenge.setChallenge("abc");
authChallenge.setAuthFactorType("KBA");
authChallenge.setFormat("base64url-encoded-json");

List<AuthChallenge> authChallengeList = new ArrayList<>();
authChallengeList.add(authChallenge);

authRequest.setChallengeList(authChallengeList);

RequestWrapper wrapper = new RequestWrapper<>();
wrapper.setRequestTime(IdentityProviderUtil.getUTCDateTime());
wrapper.setRequest(authRequest);
when(authorizationService.authenticateUserV2(authRequest)).thenReturn(new AuthResponseV2());
mockMvc.perform(post("/authorization/v2/authenticate")
.content(objectMapper.writeValueAsString(wrapper))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.errors").isNotEmpty())
.andExpect(jsonPath("$.errors[0].errorCode").value("invalid_challenge"));
}

@Test
public void authenticateEndUser_withNullAuthFactorType_returnErrorResponse() throws Exception {
AuthRequest authRequest = new AuthRequest();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ mosip.esignet.ui.config.key-values={'sbi.env': 'Developer', 'sbi.timeout.DISC':
'sbi.timeout.DINFO': 30, 'sbi.timeout.CAPTURE': 30, 'sbi.capture.count.face': 1, 'sbi.capture.count.finger': 2, \
'sbi.capture.count.iris': 1, 'sbi.capture.score.face': 70, 'sbi.capture.score.finger':70, 'sbi.capture.score.iris':70 }

mosip.esignet.authenticator.default.auth-factor.kba.field-details={{'id':'policyNumber', 'type':'text', 'format':'', 'maxLength': 50, 'regex': '^\\s*[+-]?(\\d+|\\d*\\.\\d+|\\d+\\.\\d*)([Ee][+-]?\\d*)?\\s*$'},{'id':'fullName', 'type':'text', 'format':'', 'maxLength': 50, 'regex': '^[A-Za-z\\s]{1,}[\\.]{0,1}[A-Za-z\\s]{0,}$'},{'id':'dob', 'type':'date', 'format':'dd/mm/yyyy'}}

##----------------------------------------------------------------------------------------------------------------------
spring.autoconfigure.exclude[0]=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration

Expand Down