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
Expand Up @@ -10,11 +10,13 @@
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.*;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.networknt.schema.JsonSchema;
import com.networknt.schema.JsonSchemaFactory;
import com.networknt.schema.SpecVersion;
import com.networknt.schema.ValidationMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
Expand Down Expand Up @@ -50,30 +52,26 @@ public class MockProfileRegistryPluginImpl implements ProfileRegistryPlugin {

private static final String UTC_DATETIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
private static final List<String> ACTIONS = Arrays.asList("CREATE", "UPDATE");

@Value("${mosip.signup.mock.username.field:phone}")
private String usernameField;

@Value("#{'${mosip.signup.mock.mandatory-attributes.CREATE:}'.split(',')}")
private List<String> requiredFieldsOnCreate;

@Value("#{'${mosip.signup.mock.mandatory-attributes.UPDATE:}'.split(',')}")
private List<String> requiredFieldsOnUpdate;

@Value("#{'${mosip.signup.mock.lang-based-attributes:}'.split(',')}")
private List<String> langBasedFields;
@Value("${mosip.signup.identifier.name:phone}")
private String identifierField;

//Endpoint to add/update identity data
@Value("${mosip.signup.mock.identity.endpoint}")
private String identityEndpoint;

//Endpoint to fetch identity data
@Value("${mosip.signup.mock.get-identity.endpoint}")
private String getIdentityEndpoint;

@Value("${mosip.signup.mock.add-verified-claims.endpoint}")
private String addVerifiedClaimsEndpoint;

@Value("${mosip.signup.mock.get-schema.endpoint}")
private String getSchemaEndpoint;
@Value("${mosip.signup.mock.identity-schema.endpoint}")
private String identitySchemaEndpoint;

@Value("${mosip.signup.mock.ui-schema.endpoint}")
private String uiSchemaEndpoint;

@Value("${mosip.signup.mock.face.biometric.field-name:encodedPhoto}")
private String faceBiometricFieldName;
Expand All @@ -91,26 +89,46 @@ public class MockProfileRegistryPluginImpl implements ProfileRegistryPlugin {
@Autowired
private ResourceLoader resourceLoader;

private volatile JsonSchema schema;

@Override
public void validate(String action, ProfileDto profileDto) throws InvalidProfileException {
if (!ACTIONS.contains(action)) {

if(schema == null) {
synchronized (this) {
ResponseWrapper<JsonNode> responseWrapper = request(identitySchemaEndpoint, HttpMethod.GET, null,
new ParameterizedTypeReference<ResponseWrapper<JsonNode>>() {
});
JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012);
schema = jsonSchemaFactory.getSchema(responseWrapper.getResponse());
}
}

if(!ACTIONS.contains(action)) {
log.error("Invalid action value : {}. Allowed values are CREATE and UPDATE", action);
throw new InvalidProfileException(ErrorConstants.INVALID_ACTION);
}

JsonNode inputJson = profileDto.getIdentity();
List<String> requiredFields = action.equals("CREATE") ? requiredFieldsOnCreate : requiredFieldsOnUpdate;
for (String fieldName : requiredFields) {
if (!fieldName.isEmpty() && (!inputJson.hasNonNull(fieldName) || (inputJson.get(fieldName).isArray() && inputJson.get(fieldName).isEmpty()))) {
log.error("Null value found in the required field of {}, required: {}", fieldName, requiredFields);
throw new InvalidProfileException("invalid_".concat(fieldName.toLowerCase()));
Set<ValidationMessage> errors = schema.validate(profileDto.getIdentity());

for(ValidationMessage error : errors) {
log.error("Validation error for field {} with message {}", error.getInstanceLocation(), error.getMessage());
String fieldName = error.getInstanceLocation().getNameCount() > 0 ? error.getInstanceLocation().getName(0) :
error.getProperty();
if(action.equals("UPDATE") && error.getCode().equals("1028")) {
//Ignore required field validation errors for update action as in an update scenario, not all fields are mandatory
continue;
}
throw new InvalidProfileException(fieldName != null ? "invalid_".concat(fieldName.toLowerCase()) :
"unknown_field");
}
}

@Override
public ProfileResult createProfile(String requestId, ProfileDto profileDto) throws ProfileException {
if(usernameField != null && !profileDto.getIndividualId().equalsIgnoreCase(profileDto.getIdentity().get(usernameField).asText())) {
log.error("{} and userName mismatch", usernameField);
if(identifierField != null && (profileDto.getIdentity().hasNonNull(identifierField)
&& !profileDto.getIndividualId().equalsIgnoreCase(profileDto.getIdentity().get(identifierField).asText()))) {
log.error("{} and userName mismatch", identifierField);
throw new InvalidProfileException(ErrorConstants.IDENTIFIER_MISMATCH);
}
ObjectNode inputJson = (ObjectNode) profileDto.getIdentity();
Expand Down Expand Up @@ -253,9 +271,8 @@ private String getUTCDateTime() {

@Override
public JsonNode getUISpecification() {
ResponseWrapper<JsonNode> responseWrapper = request(getSchemaEndpoint, HttpMethod.GET ,null,
ResponseWrapper<JsonNode> responseWrapper = request(uiSchemaEndpoint, HttpMethod.GET ,null,
new ParameterizedTypeReference<ResponseWrapper<JsonNode>>() {});
return responseWrapper.getResponse();
}

}
7 changes: 2 additions & 5 deletions mock-plugin/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,11 @@ mosip.signup.mock.identity-verification.story-name=mock-idv-user-story.json

## File defined in the property `mosip.signup.mock.identity-verification.story-name` is loaded with below defined URL
mosip.signup.mock.config-server-url=classpath:
mosip.signup.mock.get-schema.endpoint=${mosip.esignet.mock.domain.url}/v1/mock-identity-system/identity/ui-spec

mosip.signup.mock.mandatory-attributes.CREATE=fullName,phone,password,preferredLang
mosip.signup.mock.mandatory-attributes.UPDATE=
mosip.signup.mock.username.field=phone

mosip.signup.mock.identity.endpoint=${mosip.esignet.mock.domain.url}/v1/mock-identity-system/identity
mosip.signup.mock.get-identity.endpoint=${mosip.esignet.mock.domain.url}/v1/mock-identity-system/identity/
mosip.signup.mock.identity-schema.endpoint=${mosip.esignet.mock.domain.url}/v1/mock-identity-system/identity/identity-schema
mosip.signup.mock.ui-schema.endpoint=${mosip.esignet.mock.domain.url}/v1/mock-identity-system/identity/ui-spec
mosip.signup.mock.add-verified-claims.endpoint=${mosip.esignet.mock.domain.url}/v1/mock-identity-system/identity/add-verified-claim

## Disable authz & authn with mock-plugin
Expand Down
Loading
Loading