From dadc7699a05107c337bea1454e047597617125c1 Mon Sep 17 00:00:00 2001 From: "jagadeesh.t" Date: Wed, 3 Dec 2025 13:44:56 +0530 Subject: [PATCH 01/10] added new feature digital-id-card --- admin/admin-service/pom.xml | 16 ++ .../entity/ApplicantUserDetailsEntity.java | 29 +++ .../ApplicantUserDetailsRepository.java | 18 ++ .../constant/ApplicantDetailErrorCode.java | 32 +++ .../ApplicantDetailsController.java | 66 ++++++ .../mosip/admin/dto/ApplicantDetailsDto.java | 15 ++ .../admin/dto/ApplicantUserDetailsDto.java | 11 + .../dto/DigitalCardStatusResponseDto.java | 17 ++ .../packetstatusupdater/constant/ApiName.java | 2 +- .../packetstatusupdater/util/EventEnum.java | 22 +- .../packetstatusupdater/util/RestClient.java | 169 +++++++++++++- .../admin/service/ApplicantDetailService.java | 13 ++ .../impl/ApplicantDetailServiceImpl.java | 215 ++++++++++++++++++ .../admin/util/CbeffToBiometricUtil.java | 135 +++++++++++ .../java/io/mosip/admin/util/Utility.java | 77 +++++++ 15 files changed, 827 insertions(+), 10 deletions(-) create mode 100644 admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java create mode 100644 admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsRepository.java create mode 100644 admin/admin-service/src/main/java/io/mosip/admin/constant/ApplicantDetailErrorCode.java create mode 100644 admin/admin-service/src/main/java/io/mosip/admin/controller/ApplicantDetailsController.java create mode 100644 admin/admin-service/src/main/java/io/mosip/admin/dto/ApplicantDetailsDto.java create mode 100644 admin/admin-service/src/main/java/io/mosip/admin/dto/ApplicantUserDetailsDto.java create mode 100644 admin/admin-service/src/main/java/io/mosip/admin/dto/DigitalCardStatusResponseDto.java create mode 100644 admin/admin-service/src/main/java/io/mosip/admin/service/ApplicantDetailService.java create mode 100644 admin/admin-service/src/main/java/io/mosip/admin/service/impl/ApplicantDetailServiceImpl.java create mode 100644 admin/admin-service/src/main/java/io/mosip/admin/util/CbeffToBiometricUtil.java create mode 100644 admin/admin-service/src/main/java/io/mosip/admin/util/Utility.java diff --git a/admin/admin-service/pom.xml b/admin/admin-service/pom.xml index b5dc1da0591..19014fe21dd 100644 --- a/admin/admin-service/pom.xml +++ b/admin/admin-service/pom.xml @@ -186,6 +186,22 @@ + + io.mosip.kernel + kernel-cbeffutil-api + 1.2.0 + + + io.mosip.biometric.util + biometrics-util + 1.2.0 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + + + diff --git a/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java b/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java new file mode 100644 index 00000000000..c5b79bc2c5e --- /dev/null +++ b/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java @@ -0,0 +1,29 @@ +package io.mosip.admin.bulkdataupload.entity; + +import lombok.Data; +import org.hibernate.annotations.GenericGenerator; + +import jakarta.persistence.*; +import java.io.Serializable; +import java.time.LocalDate; + +@Data +@Entity +@Table(name = "applicant_login_detail", schema = "master") +public class ApplicantUserDetailsEntity extends BaseEntity implements Serializable { + + private static final long serialVersionUID = -8541947587557590379L; + + @Id + @GeneratedValue(generator = "uuid") + @GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator") + @Column(name = "id", nullable = false, length = 64) + private String id; + + @Column(name = "usr_id", nullable = false, length = 64) + private String userId; + + @Column(name = "login_date") + private LocalDate loginDate; + +} \ No newline at end of file diff --git a/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsRepository.java b/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsRepository.java new file mode 100644 index 00000000000..c2d5ab97f42 --- /dev/null +++ b/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsRepository.java @@ -0,0 +1,18 @@ +package io.mosip.admin.bulkdataupload.entity; + +import io.mosip.kernel.core.dataaccess.spi.repository.BaseRepository; +import org.springframework.stereotype.Repository; + +import java.time.LocalDate; + +/** + * @author Dhanendra + * + */ +@Repository +public interface ApplicantUserDetailsRepository extends BaseRepository { + + + long countByUserIdAndLoginDate(String userId, LocalDate loginDate); + +} \ No newline at end of file diff --git a/admin/admin-service/src/main/java/io/mosip/admin/constant/ApplicantDetailErrorCode.java b/admin/admin-service/src/main/java/io/mosip/admin/constant/ApplicantDetailErrorCode.java new file mode 100644 index 00000000000..5861f11759f --- /dev/null +++ b/admin/admin-service/src/main/java/io/mosip/admin/constant/ApplicantDetailErrorCode.java @@ -0,0 +1,32 @@ +package io.mosip.admin.constant; + +public enum ApplicantDetailErrorCode { + + UNABLE_TO_RETRIEVE_RID_DETAILS("ADM-AVD-001", "A technical error occurred while retrieving the data, please try again after some time."), + RID_INVALID("ADM-AVD-002","RID is invalid"), + RID_NOT_FOUND("ADM-AVD-003","The card for this request ID is not generated. Please check the status of the ID."), + DATA_NOT_FOUND("ADM-AVD-004","Applicant Photo Not Found"), + DIGITAL_CARD_RID_NOT_FOUND("ADM-AVD-005", "Digital card not found for the RID, please try after few days"), + DIGITAL_CARD_NOT_ACKNOWLEDGED("ADM-AVD-006", "Please acknowledge the details before downloading digital card"), + REQ_ID_NOT_FOUND("ADM-AVD-007","Request id not found"), + + LIMIT_EXCEEDED("ADM-AVD-008","Your daily search limit has exceeded. Please try searching again tomorrow."), + + DATA_SHARE_EXPIRED_EXCEPTION("ADM-AVD-008", "Data share usuage expired"); + + private final String errorCode; + private final String errorMessage; + + private ApplicantDetailErrorCode(final String errorCode, final String errorMessage) { + this.errorCode = errorCode; + this.errorMessage = errorMessage; + } + + public String getErrorCode() { + return errorCode; + } + + public String getErrorMessage() { + return errorMessage; + } +} \ No newline at end of file diff --git a/admin/admin-service/src/main/java/io/mosip/admin/controller/ApplicantDetailsController.java b/admin/admin-service/src/main/java/io/mosip/admin/controller/ApplicantDetailsController.java new file mode 100644 index 00000000000..4a51ca7ee5f --- /dev/null +++ b/admin/admin-service/src/main/java/io/mosip/admin/controller/ApplicantDetailsController.java @@ -0,0 +1,66 @@ +package io.mosip.admin.controller; + +import io.mosip.admin.dto.ApplicantDetailsDto; +import io.mosip.admin.dto.ApplicantUserDetailsDto; +import io.mosip.admin.packetstatusupdater.util.AuditUtil; +import io.mosip.admin.packetstatusupdater.util.EventEnum; +import io.mosip.admin.service.ApplicantDetailService; +import io.mosip.kernel.core.http.ResponseWrapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.InputStreamResource; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.io.ByteArrayInputStream; + +@RestController +public class ApplicantDetailsController { + + @Autowired + AuditUtil auditUtil; + + @Autowired + ApplicantDetailService applicantDetailService; + + //@PreAuthorize("hasRole(''ZONAL_ADMIN','GLOBAL_ADMIN'')") + @PreAuthorize("hasAnyRole(@authorizedRoles.getGetpacketstatusupdate())") + @GetMapping("/applicantDetails/{rid}") + public ResponseWrapper getApplicantDetails(@PathVariable("rid") String rid) throws Exception { + auditUtil.setAuditRequestDto(EventEnum.APPLICANT_VERIFICATION_API_CALLED,null); + ResponseWrapper responseWrapper = new ResponseWrapper<>(); + responseWrapper.setResponse(applicantDetailService.getApplicantDetails(rid)); + auditUtil.setAuditRequestDto(EventEnum.APPLICANT_VERIFICATION_SUCCESS,null); + return responseWrapper; + } + + // @PreAuthorize("hasRole(''ZONAL_ADMIN','GLOBAL_ADMIN'')") + @PreAuthorize("hasAnyRole(@authorizedRoles.getGetpacketstatusupdate())") + @GetMapping("/applicantDetails/getLoginDetails") + public ResponseWrapper getApplicantUserDetails() throws Exception { + auditUtil.setAuditRequestDto(EventEnum.APPLICANT_LOGIN_DETAILS_API_CALLED,null); + ResponseWrapper responseWrapper = new ResponseWrapper<>(); + responseWrapper.setResponse(applicantDetailService.getApplicantUserDetails()); + auditUtil.setAuditRequestDto(EventEnum.APPLICANT_LOGIN_DETAILS_SUCCESS,null); + return responseWrapper; + } + + // @PreAuthorize("hasRole(''ZONAL_ADMIN','GLOBAL_ADMIN'')") + @PreAuthorize("hasAnyRole(@authorizedRoles.getGetpacketstatusupdate())") + @GetMapping("/rid-digital-card/{rid}") + public ResponseEntity getRIDDigitalCard( + @PathVariable("rid") String rid,@RequestParam("isAcknowledged") boolean isAcknowledged) throws Exception { + auditUtil.setAuditRequestDto(EventEnum.RID_DIGITAL_CARD_REQ,null); + byte[] pdfBytes = applicantDetailService.getRIDDigitalCard(rid,isAcknowledged); + InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(pdfBytes)); + auditUtil.setAuditRequestDto(EventEnum.RID_DIGITAL_CARD_REQ_SUCCESS,null); + return ResponseEntity.ok().contentType(MediaType.parseMediaType("application/pdf")) + .header("Content-Disposition", "attachment; filename=\"" + + rid + ".pdf\"") + .body((Object) resource); + } +} \ No newline at end of file diff --git a/admin/admin-service/src/main/java/io/mosip/admin/dto/ApplicantDetailsDto.java b/admin/admin-service/src/main/java/io/mosip/admin/dto/ApplicantDetailsDto.java new file mode 100644 index 00000000000..3185ff42b5e --- /dev/null +++ b/admin/admin-service/src/main/java/io/mosip/admin/dto/ApplicantDetailsDto.java @@ -0,0 +1,15 @@ +package io.mosip.admin.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +import java.util.HashMap; +import java.util.Map; + +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class ApplicantDetailsDto { + + Map applicantDataMap=new HashMap<>(); + +} \ No newline at end of file diff --git a/admin/admin-service/src/main/java/io/mosip/admin/dto/ApplicantUserDetailsDto.java b/admin/admin-service/src/main/java/io/mosip/admin/dto/ApplicantUserDetailsDto.java new file mode 100644 index 00000000000..35e6c9f9ad6 --- /dev/null +++ b/admin/admin-service/src/main/java/io/mosip/admin/dto/ApplicantUserDetailsDto.java @@ -0,0 +1,11 @@ +package io.mosip.admin.dto; + +import lombok.Data; + +@Data +public class ApplicantUserDetailsDto { + + private int maxCount; + + private int count; +} \ No newline at end of file diff --git a/admin/admin-service/src/main/java/io/mosip/admin/dto/DigitalCardStatusResponseDto.java b/admin/admin-service/src/main/java/io/mosip/admin/dto/DigitalCardStatusResponseDto.java new file mode 100644 index 00000000000..97de952191e --- /dev/null +++ b/admin/admin-service/src/main/java/io/mosip/admin/dto/DigitalCardStatusResponseDto.java @@ -0,0 +1,17 @@ +package io.mosip.admin.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DigitalCardStatusResponseDto { + + private String id; + + private String statusCode; + + private String url; +} \ No newline at end of file diff --git a/admin/admin-service/src/main/java/io/mosip/admin/packetstatusupdater/constant/ApiName.java b/admin/admin-service/src/main/java/io/mosip/admin/packetstatusupdater/constant/ApiName.java index 14788bdd01f..72f9f18f82d 100644 --- a/admin/admin-service/src/main/java/io/mosip/admin/packetstatusupdater/constant/ApiName.java +++ b/admin/admin-service/src/main/java/io/mosip/admin/packetstatusupdater/constant/ApiName.java @@ -7,6 +7,6 @@ */ public enum ApiName { - LOST_RID_API,CRYPTOMANAGERDECRYPT_API,MACHINE_GET_API; + LOST_RID_API,CRYPTOMANAGERDECRYPT_API,MACHINE_GET_API,RETRIEVE_IDENTITY_API,DIGITAL_CARD_STATUS_URL; } diff --git a/admin/admin-service/src/main/java/io/mosip/admin/packetstatusupdater/util/EventEnum.java b/admin/admin-service/src/main/java/io/mosip/admin/packetstatusupdater/util/EventEnum.java index a021636c443..f5855f33691 100644 --- a/admin/admin-service/src/main/java/io/mosip/admin/packetstatusupdater/util/EventEnum.java +++ b/admin/admin-service/src/main/java/io/mosip/admin/packetstatusupdater/util/EventEnum.java @@ -83,7 +83,27 @@ public enum EventEnum { ADMIN_PROXY_ERROR("ADM-MSD-411",AuditConstant.AUDIT_SYSTEM,"Request for Admin Proxy","Failed to call Rest api - %s","ADM-MSD","Admin Proxy service","NO_ID","NO_ID_TYPE",AuditConstant.APPLICATION_ID,AuditConstant.APPLICATION_NAME), KEYMANAGER_PROXY_API_CALLED("ADM-MSD-410", AuditConstant.AUDIT_SYSTEM, "Request for KeyManager proxy API", "API called for KeyManager proxy", "ADM-MSD", "Admin Proxy service", "NO_ID", "NO_ID_TYPE", - AuditConstant.APPLICATION_ID, AuditConstant.APPLICATION_NAME ); + AuditConstant.APPLICATION_ID, AuditConstant.APPLICATION_NAME ), + APPLICANT_VERIFICATION_API_CALLED("ADM-AVD-501", AuditConstant.AUDIT_SYSTEM, "Request for Applicant Verification API", + "API called for Applicant Verification request", "ADM-AVD", "Admin service", "NO_ID", "NO_ID_TYPE", + AuditConstant.APPLICATION_ID, AuditConstant.APPLICATION_NAME), + APPLICANT_VERIFICATION_SUCCESS("ADM-AVD-502", AuditConstant.AUDIT_SYSTEM, "Request for Applicant Verification API", + "successfully return the applicantPhoto and dob", "ADM-AVD", "admin service", "NO_ID", "NO_ID_TYPE", + AuditConstant.APPLICATION_ID, AuditConstant.APPLICATION_NAME), + APPLICANT_VERIFICATION_ERROR("ADM-AVD-503",AuditConstant.AUDIT_SYSTEM,"Request for Applicant Verification","Failed to call Rest api - %s","ADM-AVD","admin service","NO_ID","NO_ID_TYPE",AuditConstant.APPLICATION_ID,AuditConstant.APPLICATION_NAME), + RID_DIGITAL_CARD_REQ_EXCEPTION("ADM-AVD-504",AuditConstant.AUDIT_SYSTEM,"Request for Digital Card","Downloading digital card based on RID failed - %s","ADM-AVD","admin service","NO_ID","NO_ID_TYPE",AuditConstant.APPLICATION_ID,AuditConstant.APPLICATION_NAME), + RID_DIGITAL_CARD_REQ("ADM-AVD-505", AuditConstant.AUDIT_SYSTEM, "Request for Digital Card", + "API called for Digital card", "ADM-AVD", "Admin service", "NO_ID", "NO_ID_TYPE", + AuditConstant.APPLICATION_ID, AuditConstant.APPLICATION_NAME), + RID_DIGITAL_CARD_REQ_SUCCESS("ADM-AVD-506", AuditConstant.AUDIT_SYSTEM, "Request for Digital Card", + "successfully returned the digital card", "ADM-AVD", "admin service", "NO_ID", "NO_ID_TYPE", + AuditConstant.APPLICATION_ID, AuditConstant.APPLICATION_NAME), + APPLICANT_LOGIN_DETAILS_API_CALLED("ADM-AVD-507", AuditConstant.AUDIT_SYSTEM, "Request for Applicant Login Details API", + "API called for Applicant Login Details", "ADM-AVD", "Admin service", "NO_ID", "NO_ID_TYPE", + AuditConstant.APPLICATION_ID, AuditConstant.APPLICATION_NAME), + APPLICANT_LOGIN_DETAILS_SUCCESS("ADM-AVD-508", AuditConstant.AUDIT_SYSTEM, "Request for Applicant Login Details API", + "successfully return the login details", "ADM-AVD", "admin service", "NO_ID", "NO_ID_TYPE", + AuditConstant.APPLICATION_ID, AuditConstant.APPLICATION_NAME); private final String eventId; diff --git a/admin/admin-service/src/main/java/io/mosip/admin/packetstatusupdater/util/RestClient.java b/admin/admin-service/src/main/java/io/mosip/admin/packetstatusupdater/util/RestClient.java index ffa4f7594ff..57c12d679d5 100644 --- a/admin/admin-service/src/main/java/io/mosip/admin/packetstatusupdater/util/RestClient.java +++ b/admin/admin-service/src/main/java/io/mosip/admin/packetstatusupdater/util/RestClient.java @@ -1,21 +1,21 @@ package io.mosip.admin.packetstatusupdater.util; -import java.io.IOException; -import java.util.Iterator; -import java.util.List; - +import io.mosip.admin.constant.ApplicantDetailErrorCode; +import io.mosip.admin.packetstatusupdater.constant.ApiName; +import io.mosip.admin.packetstatusupdater.exception.MasterDataServiceException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; +import org.springframework.http.*; import org.springframework.stereotype.Component; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; -import io.mosip.admin.packetstatusupdater.constant.ApiName; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; @@ -63,6 +63,159 @@ public T postApi(ApiName apiName, MediaType mediaType, Object requestType, C return result; } + /** + * Post api. + * + * @param the generic type + * @param apiName the api name + * @param pathsegments the pathsegments + * @param queryParamName the query param name + * @param queryParamValue the query param value + * @param mediaType the media type + * @param requestType the request type + * @param responseClass the response class + * @return the t + * @throws Exception + */ + @SuppressWarnings("unchecked") + public T postApi(ApiName apiName, List pathsegments, String queryParamName, String queryParamValue, + MediaType mediaType, Object requestType, Class responseClass) throws Exception { + T result = null; + String apiHostIpPort = environment.getProperty(apiName.name()); + UriComponentsBuilder builder = null; + if (apiHostIpPort != null) + builder = UriComponentsBuilder.fromUriString(apiHostIpPort); + if (builder != null) { + + if (!((pathsegments == null) || (pathsegments.isEmpty()))) { + for (String segment : pathsegments) { + if (!((segment == null) || (("").equals(segment)))) { + builder.pathSegment(segment); + } + } + + } + if (!((queryParamName == null) || (("").equals(queryParamName)))) { + String[] queryParamNameArr = queryParamName.split(","); + String[] queryParamValueArr = queryParamValue.split(","); + + for (int i = 0; i < queryParamNameArr.length; i++) { + builder.queryParam(queryParamNameArr[i], queryParamValueArr[i]); + } + } + try { + result = (T) restTemplate.postForObject(builder.toUriString(), setRequestHeader(requestType, mediaType), + responseClass); + } catch (Exception e) { + throw new Exception(e); + } + } + return result; + } + + /** + * Gets the api. + * + * @param the generic type + * @param apiName the api name + * @param pathsegments the pathsegments + * @param queryParamName the query param name + * @param queryParamValue the query param value + * @param responseType the response type + * @return the api + * @throws Exception + */ + @SuppressWarnings("unchecked") + public T getApi(ApiName apiName, List pathsegments, String queryParamName, String queryParamValue, + Class responseType) throws Exception { + + String apiHostIpPort = environment.getProperty(apiName.name()); + T result = null; + UriComponentsBuilder builder = null; + UriComponents uriComponents = null; + if (apiHostIpPort != null) { + + builder = UriComponentsBuilder.fromUriString(apiHostIpPort); + if (!((pathsegments == null) || (pathsegments.isEmpty()))) { + for (String segment : pathsegments) { + if (!((segment == null) || (("").equals(segment)))) { + builder.pathSegment(segment); + } + } + } + if (!((queryParamName == null) || (("").equals(queryParamName)))) { + + String[] queryParamNameArr = queryParamName.split(","); + String[] queryParamValueArr = queryParamValue.split(","); + for (int i = 0; i < queryParamNameArr.length; i++) { + builder.queryParam(queryParamNameArr[i], queryParamValueArr[i]); + } + } + uriComponents = builder.build(false).encode(); + try { + result = (T) restTemplate + .exchange(uriComponents.toUri(), HttpMethod.GET, setRequestHeader(null, null), responseType) + .getBody(); + } catch (Exception e) { + throw new Exception(e); + } + + } + return result; + } +/* *//** + * Gets the Object. + * + * @param the generic type + * @param url the url + * @param responseType the response type + * @return the api + * @throws Exception + *//* + @SuppressWarnings("unchecked") + public T getForObject(String url, + Class responseType) throws Exception { + + T result = null; + try { + result= (T) restTemplate + .getForObject(url, responseType); + } catch (Exception e) { + throw new Exception(e); + } + return result; + }*/ + + /** + * Gets the Object. + * + * @param the generic type + * @param url the url + * @param responseType the response type + * @return the api + * @throws Exception + */ + @SuppressWarnings("unchecked") + public T getApi(String url, + Class responseType) throws Exception { + + T result = null; + try { + ResponseEntity responseEntity= restTemplate + .exchange(url, HttpMethod.GET, setRequestHeader(null, null), responseType); + if (url != null && url.contains("datashare") && responseEntity != null) { + MediaType contentType = responseEntity.getHeaders().getContentType(); + if (contentType != null && contentType.equals(MediaType.APPLICATION_JSON)){ + throw new MasterDataServiceException(ApplicantDetailErrorCode.DATA_SHARE_EXPIRED_EXCEPTION.getErrorCode(), + ApplicantDetailErrorCode.DATA_SHARE_EXPIRED_EXCEPTION.getErrorMessage()); + } + } + result= (T) responseEntity.getBody(); + } catch (Exception e) { + throw new Exception(e); + } + return result; + } /** * Sets the request header. * diff --git a/admin/admin-service/src/main/java/io/mosip/admin/service/ApplicantDetailService.java b/admin/admin-service/src/main/java/io/mosip/admin/service/ApplicantDetailService.java new file mode 100644 index 00000000000..99c896a20a6 --- /dev/null +++ b/admin/admin-service/src/main/java/io/mosip/admin/service/ApplicantDetailService.java @@ -0,0 +1,13 @@ +package io.mosip.admin.service; + +import io.mosip.admin.dto.ApplicantDetailsDto; +import io.mosip.admin.dto.ApplicantUserDetailsDto; + +public interface ApplicantDetailService { + + ApplicantDetailsDto getApplicantDetails(String rid) throws Exception; + + byte[] getRIDDigitalCard(String rid, boolean isAcknowledged) throws Exception; + + ApplicantUserDetailsDto getApplicantUserDetails(); +} \ No newline at end of file diff --git a/admin/admin-service/src/main/java/io/mosip/admin/service/impl/ApplicantDetailServiceImpl.java b/admin/admin-service/src/main/java/io/mosip/admin/service/impl/ApplicantDetailServiceImpl.java new file mode 100644 index 00000000000..73be291a308 --- /dev/null +++ b/admin/admin-service/src/main/java/io/mosip/admin/service/impl/ApplicantDetailServiceImpl.java @@ -0,0 +1,215 @@ +package io.mosip.admin.service.impl; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.mosip.admin.bulkdataupload.entity.ApplicantUserDetailsEntity; +import io.mosip.admin.bulkdataupload.entity.ApplicantUserDetailsRepository; +import io.mosip.admin.constant.ApplicantDetailErrorCode; +import io.mosip.admin.dto.ApplicantDetailsDto; +import io.mosip.admin.dto.ApplicantUserDetailsDto; +import io.mosip.admin.dto.DigitalCardStatusResponseDto; +import io.mosip.admin.packetstatusupdater.constant.ApiName; +import io.mosip.admin.packetstatusupdater.exception.DataNotFoundException; +import io.mosip.admin.packetstatusupdater.exception.MasterDataServiceException; +import io.mosip.admin.packetstatusupdater.exception.RequestException; +import io.mosip.admin.packetstatusupdater.util.AuditUtil; +import io.mosip.admin.packetstatusupdater.util.EventEnum; +import io.mosip.admin.packetstatusupdater.util.RestClient; +import io.mosip.admin.service.ApplicantDetailService; +import io.mosip.admin.util.CbeffToBiometricUtil; +import io.mosip.admin.util.Utility; +import io.mosip.biometrics.util.ConvertRequestDto; +import io.mosip.biometrics.util.face.FaceDecoder; +import io.mosip.kernel.core.idvalidator.exception.InvalidIDException; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.binary.StringUtils; +import org.json.JSONException; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Service; +import org.springframework.web.client.ResourceAccessException; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.*; + +@Service +public class ApplicantDetailServiceImpl implements ApplicantDetailService { + + private static final String FACE = "Face"; + + private static final Logger log = LoggerFactory.getLogger(ApplicantDetailServiceImpl.class); + + @Autowired + RestClient restClient; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private AuditUtil auditUtil; + + @Autowired + CbeffToBiometricUtil cbeffToBiometricUtil; + + + @Autowired + Utility utility; + + @Autowired + private ApplicantUserDetailsRepository applicantUserDetailsRepository; + + private static final String IDENTITY = "identity"; + + private static final String RESPONSE = "response"; + + private static final String AVAILABLE = "available"; + + private static final String DOCUMENTS="documents"; + + private static final String APPLICANTPHOTO = "applicantPhoto"; + + private static final String VALUE = "value"; + private static final String DOB = "dob"; + + @Value("${mosip.admin.applicant-details.exposed-identity-fields}") + private String[] applicantDetails; + + @Value("${mosip.admin.applicant-details.max.login.count:15}") + private int maxcount; + + + @Override + public ApplicantDetailsDto getApplicantDetails(String rid) throws Exception { + ApplicantDetailsDto applicantDetailsDto =new ApplicantDetailsDto(); + Map applicantDataMap=new HashMap<>(); + List pathsegments=new ArrayList<>(); + String individualBiometrics=null; + pathsegments.add(rid); + String imageData=null; + try { + String userId = ((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername(); + long count=applicantUserDetailsRepository.countByUserIdAndLoginDate(userId, LocalDate.now()); + if((int)count>=maxcount){ + throw new RequestException(ApplicantDetailErrorCode.LIMIT_EXCEEDED.getErrorCode(), + ApplicantDetailErrorCode.LIMIT_EXCEEDED.getErrorMessage()); + } + String response = restClient.getApi(ApiName.RETRIEVE_IDENTITY_API,pathsegments,"type","bio",String.class); + JSONObject responseObj= objectMapper.readValue(response,JSONObject.class); + if(response!=null && responseObj.get("response")==null) { + throw new RequestException(ApplicantDetailErrorCode.RID_NOT_FOUND.getErrorCode(), + ApplicantDetailErrorCode.RID_NOT_FOUND.getErrorMessage()); + } + JSONObject responseJsonObj= utility.getJSONObject(responseObj,RESPONSE); + JSONObject identityObj=utility.getJSONObject(responseJsonObj,IDENTITY); + JSONArray documents=utility.getJSONArray(responseJsonObj,DOCUMENTS); + String idenitityJson=utility.getMappingJson(); + JSONObject idenitityJsonObject=objectMapper.readValue(idenitityJson,JSONObject.class); + JSONObject mapperIdentity=utility.getJSONObject(idenitityJsonObject,IDENTITY); + List mapperJsonKeys = new ArrayList<>(mapperIdentity.keySet()); + for(String valueObj: applicantDetails){ + if (valueObj == null) { + log.warn("Encountered null value in applicantDetails list"); + continue; + } + if(!valueObj.equalsIgnoreCase(APPLICANTPHOTO)){ + LinkedHashMap jsonObject = utility.getJSONValue(mapperIdentity, valueObj); + if (jsonObject != null && VALUE != null && jsonObject.containsKey(VALUE)) { + String value = jsonObject.get(VALUE); + applicantDataMap.put(value, identityObj.get(value).toString()); + } + } else { + getImageData(documents,applicantDataMap); + } + } + saveApplicantLoginDetails(); + applicantDetailsDto.setApplicantDataMap(applicantDataMap); + } catch (ResourceAccessException | JSONException e) { + auditUtil.setAuditRequestDto(EventEnum.APPLICANT_VERIFICATION_ERROR,null); + throw new RequestException(ApplicantDetailErrorCode.UNABLE_TO_RETRIEVE_RID_DETAILS.getErrorCode(), + ApplicantDetailErrorCode.UNABLE_TO_RETRIEVE_RID_DETAILS.getErrorMessage(),e); + }catch (InvalidIDException | DataNotFoundException e){ + auditUtil.setAuditRequestDto(EventEnum.APPLICANT_VERIFICATION_ERROR,null); + throw new RequestException(e.getErrorCode(), e.getErrorText()); + } + return applicantDetailsDto; + } + + @Override + public byte[] getRIDDigitalCard(String rid, boolean isAcknowledged) throws Exception { + if(!isAcknowledged){ + throw new MasterDataServiceException( + ApplicantDetailErrorCode.DIGITAL_CARD_NOT_ACKNOWLEDGED.getErrorCode(), + ApplicantDetailErrorCode.DIGITAL_CARD_NOT_ACKNOWLEDGED.getErrorMessage()); + } + DigitalCardStatusResponseDto digitalCardStatusResponseDto =getDigitialCardStatus(rid); + if(!digitalCardStatusResponseDto.getStatusCode().equalsIgnoreCase(AVAILABLE)) { + auditUtil.setAuditRequestDto(EventEnum.RID_DIGITAL_CARD_REQ_EXCEPTION,null); + throw new MasterDataServiceException( + ApplicantDetailErrorCode.DIGITAL_CARD_RID_NOT_FOUND.getErrorCode(), + ApplicantDetailErrorCode.DIGITAL_CARD_RID_NOT_FOUND.getErrorMessage()); + } + return restClient.getApi(digitalCardStatusResponseDto.getUrl(), byte[].class); + } + + @Override + public ApplicantUserDetailsDto getApplicantUserDetails() { + String userId = ((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername(); + ApplicantUserDetailsDto applicantUserDetailsDto=new ApplicantUserDetailsDto(); + applicantUserDetailsDto.setMaxCount(maxcount); + long count=applicantUserDetailsRepository.countByUserIdAndLoginDate(userId,LocalDate.now()); + applicantUserDetailsDto.setCount((int)count); + return applicantUserDetailsDto; + } + + private DigitalCardStatusResponseDto getDigitialCardStatus(String rid) + throws Exception { + + List pathsegments=new ArrayList<>(); + pathsegments.add(rid); + String response = restClient.getApi(ApiName.DIGITAL_CARD_STATUS_URL,pathsegments,"","",String.class); + JSONObject responseObj= objectMapper.readValue(response,JSONObject.class); + if(responseObj.containsKey("response") && responseObj.get("response")==null) { + throw new MasterDataServiceException(ApplicantDetailErrorCode.REQ_ID_NOT_FOUND.getErrorCode(), + ApplicantDetailErrorCode.REQ_ID_NOT_FOUND.getErrorMessage()); + } + JSONObject responseJsonObj= utility.getJSONObject(responseObj,RESPONSE); + DigitalCardStatusResponseDto digitalCardStatusResponseDto = objectMapper.readValue( + responseJsonObj.toJSONString(), DigitalCardStatusResponseDto.class); + return digitalCardStatusResponseDto; + } + + private void getImageData(JSONArray documents, Map applicantDataMap) throws Exception { + ConvertRequestDto convertRequestDto = new ConvertRequestDto(); + JSONObject documentObj=utility.getJSONObjectFromArray(documents,0); + String individualBiometrics = utility.getJSONValue(documentObj, VALUE); + List subtype = new ArrayList<>(); + byte[] photoByte = cbeffToBiometricUtil.getImageBytes(individualBiometrics, FACE, subtype); + if (photoByte != null) { + convertRequestDto.setVersion("ISO19794_5_2011"); + convertRequestDto.setInputBytes(photoByte); + byte[] data = FaceDecoder.convertFaceISOToImageBytes(convertRequestDto); + String encodedBytes = StringUtils.newStringUtf8(Base64.encodeBase64(data, false)); + String imageData = "data:image/png;base64," + encodedBytes; + applicantDataMap.put(APPLICANTPHOTO, imageData); + } else { + throw new DataNotFoundException(ApplicantDetailErrorCode.DATA_NOT_FOUND.getErrorCode(), ApplicantDetailErrorCode.DATA_NOT_FOUND.getErrorMessage()); + } + } + public void saveApplicantLoginDetails(){ + String userId = ((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername(); + ApplicantUserDetailsEntity applicantUserDetailsEntity=new ApplicantUserDetailsEntity(); + applicantUserDetailsEntity.setUserId(userId); + applicantUserDetailsEntity.setLoginDate(LocalDate.now()); + applicantUserDetailsEntity.setCreatedBy(SecurityContextHolder.getContext().getAuthentication().getName()); + applicantUserDetailsEntity.setCreatedDateTime(LocalDateTime.now()); + applicantUserDetailsEntity.setIsActive(true); + applicantUserDetailsRepository.save(applicantUserDetailsEntity); + } + +} \ No newline at end of file diff --git a/admin/admin-service/src/main/java/io/mosip/admin/util/CbeffToBiometricUtil.java b/admin/admin-service/src/main/java/io/mosip/admin/util/CbeffToBiometricUtil.java new file mode 100644 index 00000000000..41d2f48a86d --- /dev/null +++ b/admin/admin-service/src/main/java/io/mosip/admin/util/CbeffToBiometricUtil.java @@ -0,0 +1,135 @@ +package io.mosip.admin.util; + +import io.mosip.admin.constant.ApplicantDetailErrorCode; +import io.mosip.admin.packetstatusupdater.exception.DataNotFoundException; +import io.mosip.kernel.biometrics.constant.BiometricType; +import io.mosip.kernel.biometrics.entities.BIR; +import io.mosip.kernel.biometrics.spi.CbeffUtil; +import io.mosip.kernel.cbeffutil.impl.CbeffImpl; +import org.apache.commons.codec.binary.Base64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * The Class CbeffToBiometricUtil. + * + * @author M1048358 Alok + * @author M1030448 Jyoti + */ +@Component +public class CbeffToBiometricUtil { + + /** The print logger. */ + private static final Logger logger = LoggerFactory.getLogger(CbeffToBiometricUtil.class); + + + /** The cbeffutil. */ + private CbeffUtil cbeffutil = new CbeffImpl(); + + /** + * Instantiates biometric util + * + */ + public CbeffToBiometricUtil() { + + } + + /** + * Gets the photo. + * + * @param cbeffFileString the cbeff file string + * @param type the type + * @param subType the sub type + * @return the photo + * @throws Exception the exception + */ + public byte[] getImageBytes(String cbeffFileString, String type, List subType) { + logger.debug("CbeffToBiometricUtil::getImageBytes()::entry"); + byte[] photoBytes = null; + if (cbeffFileString != null) { + List bIRTypeList = null; + try { + bIRTypeList = getBIRTypeList(cbeffFileString); + photoBytes = getPhotoByTypeAndSubType(bIRTypeList, type, subType); + } catch (Exception e) { + throw new DataNotFoundException(ApplicantDetailErrorCode.DATA_NOT_FOUND.getErrorCode(),ApplicantDetailErrorCode.DATA_NOT_FOUND.getErrorMessage()); + } + } + logger.debug("CbeffToBiometricUtil::getImageBytes()::exit"); + return photoBytes; + } + + /** + * Gets the photo by type and sub type. + * + * @param type the type + * @param subType the sub type + * @return the photo by type and sub type + */ + private byte[] getPhotoByTypeAndSubType(List bIRList, String type, List subType) { + byte[] photoBytes = null; + for (BIR bir : bIRList) { + if (bir.getBdbInfo() != null) { + List singleTypeList = bir.getBdbInfo().getType(); + List subTypeList = bir.getBdbInfo().getSubtype(); + + boolean isType = isBiometricType(type, singleTypeList); + boolean isSubType = isSubType(subType, subTypeList); + + if (isType && isSubType) { + photoBytes = bir.getBdb(); + break; + } + } + } + return photoBytes; + } + + /** + * Checks if is sub type. + * + * @param subType the sub type + * @param subTypeList the sub type list + * @return true, if is sub type + */ + private boolean isSubType(List subType, List subTypeList) { + return subTypeList.equals(subType) ? Boolean.TRUE : Boolean.FALSE; + } + + private boolean isBiometricType(String type, List biometricTypeList) { + boolean isType = false; + for (BiometricType biometricType : biometricTypeList) { + if (biometricType.value().equalsIgnoreCase(type)) { + isType = true; + } + } + return isType; + } + + + /** + * Gets the BIR type list. + * + * @param cbeffFileString the cbeff file string + * @return the BIR type list + * @throws Exception the exception + */ + + public List getBIRTypeList(String cbeffFileString) throws Exception { + return cbeffutil.getBIRDataFromXML(Base64.decodeBase64(cbeffFileString)); + } + + /** + * Gets the BIR type list. + * + * @param xmlBytes byte array of XML data + * @return the BIR type list + * @throws Exception the exception + */ + public List getBIRDataFromXML(byte[] xmlBytes) throws Exception { + return cbeffutil.getBIRDataFromXML(xmlBytes); + } +} diff --git a/admin/admin-service/src/main/java/io/mosip/admin/util/Utility.java b/admin/admin-service/src/main/java/io/mosip/admin/util/Utility.java new file mode 100644 index 00000000000..17ecf8db26d --- /dev/null +++ b/admin/admin-service/src/main/java/io/mosip/admin/util/Utility.java @@ -0,0 +1,77 @@ +package io.mosip.admin.util; + +import io.mosip.admin.packetstatusupdater.util.RestClient; +import io.mosip.kernel.core.util.StringUtils; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.LinkedHashMap; + +@Component +public class Utility { + + private static final Logger logger = LoggerFactory.getLogger(Utility.class); + + @Value("${mosip.kernel.config.server.file.storage.uri}") + private String configServerFileStorageURL; + + @Value("${mosip.admin.identityMappingJson}") + private String identityJson; + + @Autowired + private RestClient restClient; + + @Autowired + private Environment env; + + private static final String IDENTITY = "identity"; + private static final String VALUE = "value"; + + private static String regProcessorIdentityJson = ""; + + public String getMappingJson() throws Exception { + if (StringUtils.isBlank(regProcessorIdentityJson)) { + regProcessorIdentityJson=restClient.getApi(configServerFileStorageURL + identityJson, String.class); + } + return regProcessorIdentityJson; + } + + @SuppressWarnings("unchecked") + public JSONObject getJSONObject(JSONObject jsonObject, Object key) { + if(jsonObject == null) + return null; + LinkedHashMap identity = (LinkedHashMap) jsonObject.get(key); + return identity != null ? new JSONObject(identity) : null; + } + @SuppressWarnings("unchecked") + public T getJSONValue(JSONObject jsonObject, Object key) { + T value = (T) jsonObject.get(key); + return value; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public JSONArray getJSONArray(JSONObject jsonObject, Object key) { + ArrayList value = (ArrayList) jsonObject.get(key); + if (value == null) + return null; + JSONArray jsonArray = new JSONArray(); + jsonArray.addAll(value); + + return jsonArray; + + } + @SuppressWarnings("rawtypes") + public JSONObject getJSONObjectFromArray(JSONArray jsonObject, int key) { + LinkedHashMap identity = (LinkedHashMap) jsonObject.get(key); + return identity != null ? new JSONObject(identity) : null; + } + + +} From be58cdc88e2c1cca552372af06594a1661dd015f Mon Sep 17 00:00:00 2001 From: Jagadeesh-T440 Date: Wed, 3 Dec 2025 13:47:57 +0530 Subject: [PATCH 02/10] Update push-trigger.yml --- .github/workflows/push-trigger.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/push-trigger.yml b/.github/workflows/push-trigger.yml index 399a7952235..c2e7dcb3794 100644 --- a/.github/workflows/push-trigger.yml +++ b/.github/workflows/push-trigger.yml @@ -21,6 +21,7 @@ on: - develop - MOSIP* - tf_nira_dev + - digital_card jobs: build-maven-admin-services: From 739922edc8e5bf3cbb46221554355eef81ff0b88 Mon Sep 17 00:00:00 2001 From: "jagadeesh.t" Date: Wed, 3 Dec 2025 14:24:32 +0530 Subject: [PATCH 03/10] updated --- .../entity/ApplicantUserDetailsEntity.java | 29 ------------------- .../impl/ApplicantDetailServiceImpl.java | 12 +------- 2 files changed, 1 insertion(+), 40 deletions(-) delete mode 100644 admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java diff --git a/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java b/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java deleted file mode 100644 index c5b79bc2c5e..00000000000 --- a/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.mosip.admin.bulkdataupload.entity; - -import lombok.Data; -import org.hibernate.annotations.GenericGenerator; - -import jakarta.persistence.*; -import java.io.Serializable; -import java.time.LocalDate; - -@Data -@Entity -@Table(name = "applicant_login_detail", schema = "master") -public class ApplicantUserDetailsEntity extends BaseEntity implements Serializable { - - private static final long serialVersionUID = -8541947587557590379L; - - @Id - @GeneratedValue(generator = "uuid") - @GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator") - @Column(name = "id", nullable = false, length = 64) - private String id; - - @Column(name = "usr_id", nullable = false, length = 64) - private String userId; - - @Column(name = "login_date") - private LocalDate loginDate; - -} \ No newline at end of file diff --git a/admin/admin-service/src/main/java/io/mosip/admin/service/impl/ApplicantDetailServiceImpl.java b/admin/admin-service/src/main/java/io/mosip/admin/service/impl/ApplicantDetailServiceImpl.java index 73be291a308..946d8869b5c 100644 --- a/admin/admin-service/src/main/java/io/mosip/admin/service/impl/ApplicantDetailServiceImpl.java +++ b/admin/admin-service/src/main/java/io/mosip/admin/service/impl/ApplicantDetailServiceImpl.java @@ -127,7 +127,6 @@ public ApplicantDetailsDto getApplicantDetails(String rid) throws Exception { getImageData(documents,applicantDataMap); } } - saveApplicantLoginDetails(); applicantDetailsDto.setApplicantDataMap(applicantDataMap); } catch (ResourceAccessException | JSONException e) { auditUtil.setAuditRequestDto(EventEnum.APPLICANT_VERIFICATION_ERROR,null); @@ -201,15 +200,6 @@ private void getImageData(JSONArray documents, Map applicantData throw new DataNotFoundException(ApplicantDetailErrorCode.DATA_NOT_FOUND.getErrorCode(), ApplicantDetailErrorCode.DATA_NOT_FOUND.getErrorMessage()); } } - public void saveApplicantLoginDetails(){ - String userId = ((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername(); - ApplicantUserDetailsEntity applicantUserDetailsEntity=new ApplicantUserDetailsEntity(); - applicantUserDetailsEntity.setUserId(userId); - applicantUserDetailsEntity.setLoginDate(LocalDate.now()); - applicantUserDetailsEntity.setCreatedBy(SecurityContextHolder.getContext().getAuthentication().getName()); - applicantUserDetailsEntity.setCreatedDateTime(LocalDateTime.now()); - applicantUserDetailsEntity.setIsActive(true); - applicantUserDetailsRepository.save(applicantUserDetailsEntity); - } + } \ No newline at end of file From bf9a6e53c8d95ab71d077610ac0aa1bedd2599dd Mon Sep 17 00:00:00 2001 From: "jagadeesh.t" Date: Wed, 3 Dec 2025 19:14:19 +0530 Subject: [PATCH 04/10] Updated --- .../entity/ApplicantUserDetailsEntity.java | 35 +++++++++++++++++++ .../impl/ApplicantDetailServiceImpl.java | 14 ++++++++ 2 files changed, 49 insertions(+) create mode 100644 admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java diff --git a/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java b/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java new file mode 100644 index 00000000000..ca2d8df8287 --- /dev/null +++ b/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java @@ -0,0 +1,35 @@ +package io.mosip.admin.bulkdataupload.entity; + +import lombok.Data; +import org.hibernate.annotations.GenericGenerator; + +import jakarta.persistence.*; +import java.io.Serializable; +import java.time.LocalDate; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +@Data +@Entity +@Table(name = "applicant_login_detail", schema = "master") +public class ApplicantUserDetailsEntity extends BaseEntity implements Serializable { + + private static final long serialVersionUID = -8541947587557590379L; + + @Id + @GeneratedValue(generator = "uuid") + @GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator") + @Column(name = "id", nullable = false, length = 64) + private String id; + + @Column(name = "usr_id", nullable = false, length = 64) + private String userId; + + @Column(name = "login_date") + private LocalDate loginDate; + +} \ No newline at end of file diff --git a/admin/admin-service/src/main/java/io/mosip/admin/service/impl/ApplicantDetailServiceImpl.java b/admin/admin-service/src/main/java/io/mosip/admin/service/impl/ApplicantDetailServiceImpl.java index 946d8869b5c..596cf345b7b 100644 --- a/admin/admin-service/src/main/java/io/mosip/admin/service/impl/ApplicantDetailServiceImpl.java +++ b/admin/admin-service/src/main/java/io/mosip/admin/service/impl/ApplicantDetailServiceImpl.java @@ -1,6 +1,7 @@ package io.mosip.admin.service.impl; import com.fasterxml.jackson.databind.ObjectMapper; + import io.mosip.admin.bulkdataupload.entity.ApplicantUserDetailsEntity; import io.mosip.admin.bulkdataupload.entity.ApplicantUserDetailsRepository; import io.mosip.admin.constant.ApplicantDetailErrorCode; @@ -127,6 +128,7 @@ public ApplicantDetailsDto getApplicantDetails(String rid) throws Exception { getImageData(documents,applicantDataMap); } } + saveApplicantLoginDetails(); applicantDetailsDto.setApplicantDataMap(applicantDataMap); } catch (ResourceAccessException | JSONException e) { auditUtil.setAuditRequestDto(EventEnum.APPLICANT_VERIFICATION_ERROR,null); @@ -202,4 +204,16 @@ private void getImageData(JSONArray documents, Map applicantData } + public void saveApplicantLoginDetails(){ + String userId = ((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername(); + ApplicantUserDetailsEntity applicantUserDetailsEntity=new ApplicantUserDetailsEntity(); + applicantUserDetailsEntity.setUserId(userId); + applicantUserDetailsEntity.setLoginDate(LocalDate.now()); + applicantUserDetailsEntity.setCreatedBy(SecurityContextHolder.getContext().getAuthentication().getName()); + applicantUserDetailsEntity.setCreatedDateTime(LocalDateTime.now()); + applicantUserDetailsEntity.setIsActive(true); + applicantUserDetailsRepository.save(applicantUserDetailsEntity); + } + + } \ No newline at end of file From dc6bc19287900aa5d86d1ea8b729ce68d3f52c71 Mon Sep 17 00:00:00 2001 From: "jagadeesh.t" Date: Wed, 3 Dec 2025 19:14:59 +0530 Subject: [PATCH 05/10] updated --- .../admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java | 1 - 1 file changed, 1 deletion(-) diff --git a/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java b/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java index ca2d8df8287..e8040751528 100644 --- a/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java +++ b/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java @@ -3,7 +3,6 @@ import lombok.Data; import org.hibernate.annotations.GenericGenerator; -import jakarta.persistence.*; import java.io.Serializable; import java.time.LocalDate; From 62e022312c90c157f882c05f249c11b501698517 Mon Sep 17 00:00:00 2001 From: "jagadeesh.t" Date: Thu, 4 Dec 2025 12:15:14 +0530 Subject: [PATCH 06/10] Updated property --- .../bulkdataupload/entity/ApplicantUserDetailsEntity.java | 8 +------- .../admin-service/src/test/resources/bootstrap.properties | 4 +++- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java b/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java index e8040751528..7d31deb6f18 100644 --- a/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java +++ b/admin/admin-service/src/main/java/io/mosip/admin/bulkdataupload/entity/ApplicantUserDetailsEntity.java @@ -2,16 +2,10 @@ import lombok.Data; import org.hibernate.annotations.GenericGenerator; - +import javax.persistence.*; import java.io.Serializable; import java.time.LocalDate; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Table; - @Data @Entity @Table(name = "applicant_login_detail", schema = "master") diff --git a/admin/admin-service/src/test/resources/bootstrap.properties b/admin/admin-service/src/test/resources/bootstrap.properties index 87a2773c770..87600c68e44 100644 --- a/admin/admin-service/src/test/resources/bootstrap.properties +++ b/admin/admin-service/src/test/resources/bootstrap.properties @@ -26,4 +26,6 @@ openapi.service.servers[0].description=Admin Masterdata url openapi.group.name=${openapi.info.title} openapi.group.paths[0]=/** springdoc.swagger-ui.disable-swagger-default-url=true -spring.mvc.servlet.path=${server.servlet.context-path} \ No newline at end of file +spring.mvc.servlet.path=${server.servlet.context-path} + +mosip.kernel.config.server.file.storage.uri=${spring.cloud.config.uri}/${spring.application.name}/${spring.profiles.active}/${spring.cloud.config.label}/ \ No newline at end of file From 1ebdb61d037e9a71945488807e9c5c42e5cb34d2 Mon Sep 17 00:00:00 2001 From: "jagadeesh.t" Date: Thu, 4 Dec 2025 12:28:29 +0530 Subject: [PATCH 07/10] Updated property --- .../src/main/resources/application-local1.properties | 5 ++++- .../src/test/resources/application-test.properties | 5 ++++- admin/admin-service/src/test/resources/bootstrap.properties | 4 +--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/admin/admin-service/src/main/resources/application-local1.properties b/admin/admin-service/src/main/resources/application-local1.properties index d7374455e94..608b9773de1 100644 --- a/admin/admin-service/src/main/resources/application-local1.properties +++ b/admin/admin-service/src/main/resources/application-local1.properties @@ -371,4 +371,7 @@ mosip.admin.base.url=https://dev.mosip.net mosip.service.end-points=/**/masterdata/**,/**/keymanager/** auth.allowed.urls=http://localhost:5000/ mosip.iam.certs_endpoint=http://localhost:5000/auth/realms/mosip/protocol/openid-connect/certs -mosip.kernel.masterdata.name.validate.regex=[^A-Za-z] \ No newline at end of file +mosip.kernel.masterdata.name.validate.regex=[^A-Za-z] + +mosip.kernel.config.server.file.storage.uri=https://dev.mosip.net/config/admin/mz/develop2-v2 +mosip.admin.identityMappingJson=identity-mapping.json \ No newline at end of file diff --git a/admin/admin-service/src/test/resources/application-test.properties b/admin/admin-service/src/test/resources/application-test.properties index 9d74b2b2324..79259983fc4 100644 --- a/admin/admin-service/src/test/resources/application-test.properties +++ b/admin/admin-service/src/test/resources/application-test.properties @@ -457,4 +457,7 @@ mosip.admin.base.url=https://dev.mosip.net mosip.service.end-points=/**/masterdata/**,/**/keymanager/** auth.allowed.urls=http://localhost:5000/ -mosip.kernel.masterdata.name.validate.regex=[^A-Za-z] \ No newline at end of file +mosip.kernel.masterdata.name.validate.regex=[^A-Za-z] + +mosip.kernel.config.server.file.storage.uri=${spring.cloud.config.uri}/${spring.application.name}/${spring.profiles.active}/${spring.cloud.config.label}/ +mosip.admin.identityMappingJson=identity-mapping.json \ No newline at end of file diff --git a/admin/admin-service/src/test/resources/bootstrap.properties b/admin/admin-service/src/test/resources/bootstrap.properties index 87600c68e44..87a2773c770 100644 --- a/admin/admin-service/src/test/resources/bootstrap.properties +++ b/admin/admin-service/src/test/resources/bootstrap.properties @@ -26,6 +26,4 @@ openapi.service.servers[0].description=Admin Masterdata url openapi.group.name=${openapi.info.title} openapi.group.paths[0]=/** springdoc.swagger-ui.disable-swagger-default-url=true -spring.mvc.servlet.path=${server.servlet.context-path} - -mosip.kernel.config.server.file.storage.uri=${spring.cloud.config.uri}/${spring.application.name}/${spring.profiles.active}/${spring.cloud.config.label}/ \ No newline at end of file +spring.mvc.servlet.path=${server.servlet.context-path} \ No newline at end of file From 5ff207fa3590372e3ed07b3cb32c7c9a6888ab44 Mon Sep 17 00:00:00 2001 From: "jagadeesh.t" Date: Thu, 4 Dec 2025 12:40:43 +0530 Subject: [PATCH 08/10] Updated --- .../src/main/resources/application-local1.properties | 3 ++- .../src/test/resources/application-test.properties | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/admin/admin-service/src/main/resources/application-local1.properties b/admin/admin-service/src/main/resources/application-local1.properties index 608b9773de1..1aaa2df06ea 100644 --- a/admin/admin-service/src/main/resources/application-local1.properties +++ b/admin/admin-service/src/main/resources/application-local1.properties @@ -374,4 +374,5 @@ mosip.iam.certs_endpoint=http://localhost:5000/auth/realms/mosip/protocol/openid mosip.kernel.masterdata.name.validate.regex=[^A-Za-z] mosip.kernel.config.server.file.storage.uri=https://dev.mosip.net/config/admin/mz/develop2-v2 -mosip.admin.identityMappingJson=identity-mapping.json \ No newline at end of file +mosip.admin.identityMappingJson=identity-mapping.json +mosip.admin.applicant-details.exposed-identity-fields=dob,applicantPhoto, NIN \ No newline at end of file diff --git a/admin/admin-service/src/test/resources/application-test.properties b/admin/admin-service/src/test/resources/application-test.properties index 79259983fc4..f0d1009ed4c 100644 --- a/admin/admin-service/src/test/resources/application-test.properties +++ b/admin/admin-service/src/test/resources/application-test.properties @@ -460,4 +460,5 @@ auth.allowed.urls=http://localhost:5000/ mosip.kernel.masterdata.name.validate.regex=[^A-Za-z] mosip.kernel.config.server.file.storage.uri=${spring.cloud.config.uri}/${spring.application.name}/${spring.profiles.active}/${spring.cloud.config.label}/ -mosip.admin.identityMappingJson=identity-mapping.json \ No newline at end of file +mosip.admin.identityMappingJson=identity-mapping.json +mosip.admin.applicant-details.exposed-identity-fields=dob,applicantPhoto, NIN \ No newline at end of file From 93a54c27f000e140667adbd4efcd22953138a92d Mon Sep 17 00:00:00 2001 From: "jagadeesh.t" Date: Thu, 4 Dec 2025 12:58:46 +0530 Subject: [PATCH 09/10] updated docker file --- admin/hotlist-service/Dockerfile | 3 ++- admin/kernel-masterdata-service/Dockerfile | 3 ++- admin/kernel-syncdata-service/Dockerfile | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/admin/hotlist-service/Dockerfile b/admin/hotlist-service/Dockerfile index 0b3732ee5c0..4499d13a559 100644 --- a/admin/hotlist-service/Dockerfile +++ b/admin/hotlist-service/Dockerfile @@ -1,4 +1,5 @@ -FROM openjdk:11 +#FROM openjdk:11 +FROM eclipse-temurin:11-jdk ARG SOURCE ARG COMMIT_HASH diff --git a/admin/kernel-masterdata-service/Dockerfile b/admin/kernel-masterdata-service/Dockerfile index 82d759f6eb5..cae8fbd4fad 100644 --- a/admin/kernel-masterdata-service/Dockerfile +++ b/admin/kernel-masterdata-service/Dockerfile @@ -1,4 +1,5 @@ -FROM openjdk:11 +#FROM openjdk:11 +FROM eclipse-temurin:11-jdk ARG SOURCE ARG COMMIT_HASH diff --git a/admin/kernel-syncdata-service/Dockerfile b/admin/kernel-syncdata-service/Dockerfile index 9e8e3f96593..0f4d29ef44c 100644 --- a/admin/kernel-syncdata-service/Dockerfile +++ b/admin/kernel-syncdata-service/Dockerfile @@ -1,4 +1,5 @@ -FROM openjdk:11 +#FROM openjdk:11 +FROM eclipse-temurin:11-jdk ARG SOURCE ARG COMMIT_HASH From 0f543637a333122e6e7b3e12c5b7fe30806a77b9 Mon Sep 17 00:00:00 2001 From: Jagadeesh-T440 Date: Mon, 8 Dec 2025 15:32:39 +0530 Subject: [PATCH 10/10] Update push-trigger.yml --- .github/workflows/push-trigger.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/push-trigger.yml b/.github/workflows/push-trigger.yml index c2e7dcb3794..399a7952235 100644 --- a/.github/workflows/push-trigger.yml +++ b/.github/workflows/push-trigger.yml @@ -21,7 +21,6 @@ on: - develop - MOSIP* - tf_nira_dev - - digital_card jobs: build-maven-admin-services: