
io.mosip.registration.service.external.impl.PreRegZipHandlingServiceImpl Maven / Gradle / Ivy
package io.mosip.registration.service.external.impl;
import static io.mosip.registration.constants.RegistrationConstants.ZIP_FILE_EXTENSION;
import static io.mosip.registration.exception.RegistrationExceptionConstants.*;
import static java.io.File.separator;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import io.mosip.commons.packet.dto.packet.SimpleDto;
import io.mosip.kernel.clientcrypto.service.impl.ClientCryptoFacade;
import io.mosip.kernel.clientcrypto.util.ClientCryptoUtils;
import io.mosip.kernel.core.crypto.spi.CryptoCoreSpec;
import io.mosip.kernel.core.exception.ExceptionUtils;
import io.mosip.kernel.core.logger.spi.Logger;
import io.mosip.kernel.core.util.CryptoUtil;
import io.mosip.kernel.core.util.FileUtils;
import io.mosip.kernel.core.util.StringUtils;
import io.mosip.kernel.keygenerator.bouncycastle.KeyGenerator;
import io.mosip.registration.config.AppConfig;
import io.mosip.registration.constants.RegistrationConstants;
import io.mosip.registration.context.ApplicationContext;
import io.mosip.registration.dao.DocumentTypeDAO;
import io.mosip.registration.dto.PreRegistrationDTO;
import io.mosip.registration.dto.RegistrationDTO;
import io.mosip.registration.dto.packetmanager.DocumentDto;
import io.mosip.registration.dto.schema.UiFieldDTO;
import io.mosip.registration.entity.DocumentType;
import io.mosip.registration.exception.RegBaseCheckedException;
import io.mosip.registration.exception.RegBaseUncheckedException;
import io.mosip.registration.service.BaseService;
import io.mosip.registration.service.IdentitySchemaService;
import io.mosip.registration.service.external.PreRegZipHandlingService;
/**
* This implementation class to handle the pre-registration data
*
* @author balamurugan ramamoorthy
* @since 1.0.0
*
*/
@Service
public class PreRegZipHandlingServiceImpl extends BaseService implements PreRegZipHandlingService {
private static final Logger LOGGER = AppConfig.getLogger(PreRegZipHandlingServiceImpl.class);
private static final String CONTROLTYPE_DOB = "date";
private static final String CONTROLTYPE_DOB_AGE = "ageDate";
@Autowired
private DocumentTypeDAO documentTypeDAO;
@Autowired
private IdentitySchemaService identitySchemaService;
@Autowired
private ClientCryptoFacade clientCryptoFacade;
@Autowired
private KeyGenerator keyGenerator;
@Autowired
private CryptoCoreSpec cryptoCore;
@Value("${mosip.registration.prereg.packet.entires.limit:15}")
private int THRESHOLD_ENTRIES;
@Value("${mosip.registration.prereg.packet.size.limit:200000}")
private long THRESHOLD_SIZE;
@Value("${mosip.registration.prereg.packet.threshold.ratio:10}")
private int THRESHOLD_RATIO;
/*
* (non-Javadoc)
*
* @see io.mosip.registration.service.external.PreRegZipHandlingService#
* extractPreRegZipFile(byte[])
*/
@Override
public RegistrationDTO extractPreRegZipFile(byte[] preRegZipFile) throws RegBaseCheckedException {
LOGGER.debug("extractPreRegZipFile invoked");
try{
int totalEntries = 0;
long totalReadArchiveSize = 0;
try (ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream(preRegZipFile))) {
ZipEntry zipEntry;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
totalEntries++;
if (zipEntry.getName().equalsIgnoreCase("ID.json")) {
byte[] idjson = IOUtils.toByteArray(zipInputStream);
double compressionRatio = idjson.length / zipEntry.getCompressedSize();
if(compressionRatio > THRESHOLD_RATIO) {
LOGGER.error("compression ratio is more than the threshold");
throw new RegBaseCheckedException(PRE_REG_PACKET_ZIP_COMPRESSED_RATIO_EXCEEDED.getErrorCode(),
PRE_REG_PACKET_ZIP_COMPRESSED_RATIO_EXCEEDED.getErrorMessage());
}
totalReadArchiveSize = totalReadArchiveSize + idjson.length;
parseDemographicJson(new String(idjson));
break;
}
if(totalEntries > THRESHOLD_ENTRIES) {
LOGGER.error("Number of entries in the packet is more than the threshold");
throw new RegBaseCheckedException(PRE_REG_PACKET_ENTRIES_THRESHOLD_CROSSED.getErrorCode(),
PRE_REG_PACKET_ENTRIES_THRESHOLD_CROSSED.getErrorMessage());
}
if(totalReadArchiveSize > THRESHOLD_SIZE) {
LOGGER.error("Archive size read in the packet is more than the threshold");
throw new RegBaseCheckedException(PRE_REG_PACKET_ZIP_SIZE_THRESHOLD_CROSSED.getErrorCode(),
PRE_REG_PACKET_ZIP_SIZE_THRESHOLD_CROSSED.getErrorMessage());
}
}
}
totalEntries = 0;
totalReadArchiveSize = 0;
try (ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream(preRegZipFile))) {
ZipEntry zipEntry;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
totalEntries++;
String fileName = zipEntry.getName();
validateFilename(fileName, ".");
//if (zipEntry.getName().contains("_")) {
LOGGER.debug("extractPreRegZipFile zipEntry >>>> {}", fileName);
Optional> result = getRegistrationDTOFromSession().getDocuments().entrySet().stream()
.filter(e -> fileName.equals(e.getValue().getValue().concat(".").concat(e.getValue().getFormat()))).findFirst();
if(result.isPresent()) {
DocumentDto documentDto = result.get().getValue();
documentDto.setDocument(IOUtils.toByteArray(zipInputStream));
totalReadArchiveSize = totalReadArchiveSize + documentDto.getDocument().length;
double compressionRatio = documentDto.getDocument().length / zipEntry.getCompressedSize();
if(compressionRatio > THRESHOLD_RATIO) {
LOGGER.error("compression ratio is more than the threshold");
throw new RegBaseCheckedException(PRE_REG_PACKET_ZIP_COMPRESSED_RATIO_EXCEEDED.getErrorCode(),
PRE_REG_PACKET_ZIP_COMPRESSED_RATIO_EXCEEDED.getErrorMessage());
}
List documentTypes = documentTypeDAO.getDocTypeByName(documentDto.getType());
if(Objects.nonNull(documentTypes) && !documentTypes.isEmpty()) {
LOGGER.debug("{} >>>> documentTypes.get(0).getCode() >>>> {}", documentDto.getType(),
documentTypes.get(0).getCode());
documentDto.setType(documentTypes.get(0).getCode());
documentDto.setValue(documentDto.getCategory().concat("_").concat(documentDto.getType()));
}
getRegistrationDTOFromSession().addDocument(result.get().getKey(), result.get().getValue());
LOGGER.debug("Added zip entry as document for field >>>> {}", result.get().getKey());
}
//}
if(totalEntries > THRESHOLD_ENTRIES) {
LOGGER.error("Number of entries in the packet is more than the threshold", totalEntries);
throw new RegBaseCheckedException(PRE_REG_PACKET_ENTRIES_THRESHOLD_CROSSED.getErrorCode(),
PRE_REG_PACKET_ENTRIES_THRESHOLD_CROSSED.getErrorMessage());
}
if(totalReadArchiveSize > THRESHOLD_SIZE) {
LOGGER.error("Archive size read in the packet is more than the threshold", totalReadArchiveSize);
throw new RegBaseCheckedException(PRE_REG_PACKET_ZIP_SIZE_THRESHOLD_CROSSED.getErrorCode(),
PRE_REG_PACKET_ZIP_SIZE_THRESHOLD_CROSSED.getErrorMessage());
}
}
}
Iterator> entries = getRegistrationDTOFromSession().getDocuments().entrySet().iterator();
while (entries.hasNext()) {
Entry entry = entries.next();
if (entry.getValue().getDocument() == null || entry.getValue().getDocument().length == 0) {
entries.remove();
}
}
} catch (IOException exception) {
LOGGER.error(exception.getMessage(), exception);
throw new RegBaseCheckedException(REG_IO_EXCEPTION.getErrorCode(), exception.getCause().getMessage());
} catch (RuntimeException exception) {
LOGGER.error(exception.getMessage(), exception);
throw new RegBaseUncheckedException(RegistrationConstants.PACKET_ZIP_CREATION, exception.getMessage());
}
return getRegistrationDTOFromSession();
}
/**
* This method is used to parse the demographic json and converts it into
* RegistrationDto
*
* @param jsonString
* - reader for text file
* @throws RegBaseCheckedException
* - holds the cheked exceptions
*/
private void parseDemographicJson(String jsonString) throws RegBaseCheckedException {
try {
if (!StringUtils.isEmpty(jsonString) && validateDemographicInfoObject()) {
JSONObject jsonObject = (JSONObject) new JSONObject(jsonString).get("identity");
//Always use latest schema, ignoring missing / removed fields
RegistrationDTO registrationDTO = getRegistrationDTOFromSession();
List fieldList = identitySchemaService.getAllFieldSpec(registrationDTO.getProcessId(), registrationDTO.getIdSchemaVersion());
getRegistrationDTOFromSession().clearRegistrationDto();
for(UiFieldDTO field : fieldList) {
if(field.getId().equalsIgnoreCase("IDSchemaVersion"))
continue;
switch (field.getType()) {
case "documentType":
DocumentDto documentDto = new DocumentDto();
if(jsonObject.has(field.getId()) && jsonObject.get(field.getId()) != null) {
JSONObject fieldValue = jsonObject.getJSONObject(field.getId());
documentDto.setCategory(field.getSubType());
documentDto.setOwner("Applicant");
documentDto.setFormat(fieldValue.getString("format"));
documentDto.setType(fieldValue.getString("type"));
documentDto.setValue(fieldValue.getString("value"));
try {
documentDto.setRefNumber(fieldValue.has("refNumber") ? fieldValue.getString("refNumber") :
(fieldValue.has("docRefId") ? fieldValue.getString("docRefId") : null));
} catch(JSONException jsonException) {
LOGGER.error("Unable to find Document Refernce Number for Pre-Reg-Sync : ", jsonException);
}
getRegistrationDTOFromSession().addDocument(field.getId(), documentDto);
}
break;
case "biometricsType":
break;
default:
Object fieldValue = getValueFromJson(field.getId(), field.getType(), jsonObject);
if(fieldValue != null) {
switch (field.getControlType()) {
case CONTROLTYPE_DOB_AGE:
case CONTROLTYPE_DOB:
getRegistrationDTOFromSession().setDateField(field.getId(), (String)fieldValue, field.getSubType());
break;
default:
getRegistrationDTOFromSession().getDemographics().put(field.getId(), fieldValue);
}
}
break;
}
}
}
} catch (JSONException | IOException e) {
LOGGER.error(e.getMessage(), e);
throw new RegBaseCheckedException(REG_IO_EXCEPTION.getErrorCode(), e.getMessage());
}
}
private Object getValueFromJson(String key, String fieldType, JSONObject jsonObject) throws IOException, JSONException {
if(!jsonObject.has(key))
return null;
try {
switch (fieldType) {
case "string": return jsonObject.getString(key);
case "integer": return jsonObject.getInt(key);
case "number": return jsonObject.getLong(key);
case "simpleType":
List list = new ArrayList();
for(int i=0;i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy