Skip to content

Commit

Permalink
ES-473 and ES-474 (#73)
Browse files Browse the repository at this point in the history
* config spring security and create endpoint to get csrf token

* add unit-test for new endpoint

* fix coding style

* audit trasaction

* fix code smells

* resolve comment

* remove PropertySource from AuditTransactionRequest.java

* add endline in some file

* replace url with mosip.api.internal.url in properties file

* add auditTransactionHelper to everyendpoint

* fix bug

* add auditTransactionHelper with GENERATE_CHALLENGE SUCCESS

* fix bug with DTO

* update test case

* resolve comment

* rename auditEvent

* remove covert request DTO

* remove audit transaction

* rename some var

* add audit transaction in reset password endpoint

* move set response time inside try catch

---------

Co-authored-by: Mengleang <[email protected]>
Signed-off-by: Sreang Rathanak <[email protected]>
  • Loading branch information
2 people authored and Sreang Rathanak committed Jan 15, 2024
1 parent cc26692 commit bd32f9e
Show file tree
Hide file tree
Showing 11 changed files with 293 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
import io.mosip.esignet.core.util.IdentityProviderUtil;
import io.mosip.signup.dto.*;
import io.mosip.signup.exception.SignUpException;
import io.mosip.signup.helper.AuditHelper;
import io.mosip.signup.services.RegistrationService;
import io.mosip.signup.util.AuditEventType;
import io.mosip.signup.util.ErrorConstants;
import io.mosip.signup.util.SignUpConstants;
import io.mosip.signup.util.AuditEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
Expand All @@ -27,13 +30,24 @@ public class RegistrationController {
@Autowired
RegistrationService registrationService;

@Autowired
AuditHelper auditHelper;

@PostMapping("/generate-challenge")
public ResponseWrapper<GenerateChallengeResponse> generateChallenge (@Valid @RequestBody RequestWrapper<GenerateChallengeRequest> requestWrapper,
@CookieValue(name = SignUpConstants.TRANSACTION_ID, defaultValue = EMTPY) String transactionId)
throws SignUpException {
ResponseWrapper<GenerateChallengeResponse> responseWrapper = new ResponseWrapper<>();
responseWrapper.setResponse(registrationService.generateChallenge(requestWrapper.getRequest(), transactionId));
responseWrapper.setResponseTime(IdentityProviderUtil.getUTCDateTime());
try{
responseWrapper.setResponse(registrationService.generateChallenge(requestWrapper.getRequest(), transactionId));
}catch (SignUpException signUpException){
auditHelper.sendAuditTransaction(AuditEvent.GENERATE_CHALLENGE, AuditEventType.ERROR,
transactionId, signUpException);
throw signUpException;
}
auditHelper.sendAuditTransaction(AuditEvent.GENERATE_CHALLENGE, AuditEventType.SUCCESS,
transactionId, null);
return responseWrapper;
}

Expand All @@ -44,7 +58,15 @@ public ResponseWrapper<VerifyChallengeResponse> verifyChallenge(@Valid @RequestB
throws SignUpException {
ResponseWrapper<VerifyChallengeResponse> responseWrapper = new ResponseWrapper<>();
responseWrapper.setResponseTime(IdentityProviderUtil.getUTCDateTime());
responseWrapper.setResponse(registrationService.verifyChallenge(requestWrapper.getRequest(),transactionId));
try{
responseWrapper.setResponse(registrationService.verifyChallenge(requestWrapper.getRequest(),transactionId));
}catch (SignUpException signUpException){
auditHelper.sendAuditTransaction(AuditEvent.VERIFY_CHALLENGE, AuditEventType.ERROR,
transactionId, signUpException);
throw signUpException;
}
auditHelper.sendAuditTransaction(AuditEvent.VERIFY_CHALLENGE, AuditEventType.SUCCESS,
transactionId, null);
return responseWrapper;
}

Expand All @@ -54,8 +76,14 @@ public ResponseWrapper<RegisterResponse> register(@Valid @RequestBody RequestWra
@CookieValue(value = SignUpConstants.VERIFIED_TRANSACTION_ID, defaultValue = EMTPY) String transactionId)
throws SignUpException {
ResponseWrapper<RegisterResponse> responseWrapper = new ResponseWrapper<>();
responseWrapper.setResponse(registrationService.register(requestWrapper.getRequest(), transactionId));
responseWrapper.setResponseTime(IdentityProviderUtil.getUTCDateTime());
try {
responseWrapper.setResponse(registrationService.register(requestWrapper.getRequest(), transactionId));
}catch (SignUpException signUpException){
auditHelper.sendAuditTransaction(AuditEvent.REGISTER, AuditEventType.ERROR, transactionId, signUpException);
throw signUpException;
}
auditHelper.sendAuditTransaction(AuditEvent.REGISTER, AuditEventType.SUCCESS, transactionId, null);
return responseWrapper;
}

Expand All @@ -65,9 +93,17 @@ public ResponseWrapper<RegistrationStatusResponse> getRegistrationStatus(
@CookieValue(value = SignUpConstants.VERIFIED_TRANSACTION_ID, defaultValue = EMTPY) String transactionId) {
//TODO Need to change the response to List<RegistrationStatusResponse>
//As it will be easier to give out credential issuance status for each handle type.
ResponseWrapper<RegistrationStatusResponse> responseWrapper = new ResponseWrapper<RegistrationStatusResponse>();
responseWrapper.setResponse(registrationService.getRegistrationStatus(transactionId));
responseWrapper.setResponseTime(IdentityProviderUtil.getUTCDateTime());
ResponseWrapper<RegistrationStatusResponse> responseWrapper = new ResponseWrapper<>();
try {
responseWrapper.setResponse(registrationService.getRegistrationStatus(transactionId));
responseWrapper.setResponseTime(IdentityProviderUtil.getUTCDateTime());
}catch (SignUpException signUpException){
auditHelper.sendAuditTransaction(AuditEvent.REGISTER_STATUS_CHECK, AuditEventType.ERROR,
transactionId, signUpException);
throw signUpException;
}
auditHelper.sendAuditTransaction(AuditEvent.REGISTER_STATUS_CHECK, AuditEventType.SUCCESS,
transactionId, null);
return responseWrapper;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
import io.mosip.esignet.core.dto.ResponseWrapper;
import io.mosip.esignet.core.util.IdentityProviderUtil;
import io.mosip.signup.dto.*;
import io.mosip.signup.exception.SignUpException;
import io.mosip.signup.helper.AuditHelper;
import io.mosip.signup.services.RegistrationService;
import io.mosip.signup.util.ErrorConstants;
import io.mosip.signup.util.RegistrationStatus;
import io.mosip.signup.util.SignUpConstants;
import io.mosip.signup.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -27,6 +27,9 @@ public class SignUpController {
@Autowired
RegistrationService registrationService;

@Autowired
AuditHelper auditHelper;

@Value("#{${mosip.signup.ui.config.key-values}}")
private Map<String, Object> signUpUIConfigMap;

Expand All @@ -45,7 +48,13 @@ public ResponseWrapper<RegistrationStatusResponse> resetPassword(@Valid @Request
@Valid @NotBlank(message = ErrorConstants.INVALID_TRANSACTION)
@CookieValue(value = SignUpConstants.VERIFIED_TRANSACTION_ID, defaultValue = EMTPY) String transactionId){
ResponseWrapper<RegistrationStatusResponse> responseWrapper = new ResponseWrapper<>();
responseWrapper.setResponse(registrationService.updatePassword(requestWrapper.getRequest(), transactionId));
try{
responseWrapper.setResponse(registrationService.updatePassword(requestWrapper.getRequest(), transactionId));
}catch (SignUpException signUpException){
auditHelper.sendAuditTransaction(AuditEvent.RESET_PASSWORD, AuditEventType.ERROR, transactionId, signUpException);
throw signUpException;
}
auditHelper.sendAuditTransaction(AuditEvent.RESET_PASSWORD, AuditEventType.SUCCESS, transactionId, null);
responseWrapper.setResponseTime(IdentityProviderUtil.getUTCDateTime());
return responseWrapper;
}
Expand Down
48 changes: 48 additions & 0 deletions signup-service/src/main/java/io/mosip/signup/dto/AuditRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.mosip.signup.dto;

import io.mosip.esignet.core.util.IdentityProviderUtil;
import io.mosip.signup.util.AuditEventType;
import io.mosip.signup.util.AuditEvent;
import lombok.Data;

@Data
public class AuditRequest {

private AuditEventType eventType;
private AuditEvent eventId;
private AuditEvent eventName;
private String actionTimeStamp;
private String hostName;
private String hostIp;
private String applicationId;
private String applicationName;
private String createdBy;
private String sessionUserId;
private String sessionUserName;
private String id;
private String idType;
private String moduleName;
private String moduleId;
private String description;

public AuditRequest(AuditEvent auditEvent, AuditEventType auditEventType, String applicationName, String sessionUserId,
String id, String moduleName, String description){

this.eventId = auditEvent;
this.eventName = auditEvent;
this.eventType = auditEventType;
this.actionTimeStamp = IdentityProviderUtil.getUTCDateTime();
this.hostName = "localhost";
this.hostIp = "localhost";
this.sessionUserId = sessionUserId;
this.sessionUserName = sessionUserId;
this.id = id;
this.idType = "transaction";
this.moduleName = moduleName;
this.moduleId = moduleName;
this.description = description;
this.applicationId = applicationName;
this.applicationName = applicationName;
this.createdBy = applicationName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.mosip.signup.dto;

import com.fasterxml.jackson.annotation.JsonProperty;

public class AuditResponse {

@JsonProperty("status")
private boolean status;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.mosip.signup.helper;

import io.mosip.signup.dto.AuditRequest;
import io.mosip.signup.dto.AuditResponse;
import io.mosip.signup.dto.RestRequestWrapper;
import io.mosip.signup.dto.RestResponseWrapper;
import io.mosip.signup.exception.SignUpException;
import io.mosip.signup.util.AuditEvent;
import io.mosip.signup.util.AuditEventType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import static io.mosip.esignet.core.util.IdentityProviderUtil.getUTCDateTime;

@Slf4j
@Component
public class AuditHelper {

@Autowired
@Qualifier("selfTokenRestTemplate")
private RestTemplate selfTokenRestTemplate;

@Value("${spring.application.name}")
private String applicationName;

@Value("${mosip.signup.audit-endpoint}")
String sendAuditTransactionsUrl;

@Value("${mosip.signup.audit.description.max-length}")
Integer auditDescriptionMaxLength;

public void sendAuditTransaction(AuditEvent auditEvent, AuditEventType eventType, String transactionId,
SignUpException signUpException){

RestRequestWrapper<AuditRequest> restRequestWrapper = new RestRequestWrapper<>();
restRequestWrapper.setRequesttime(getUTCDateTime());

String description = signUpException != null ?
ExceptionUtils.getStackTrace(signUpException) : null;
if (description != null && description.length() > auditDescriptionMaxLength) {
description = description.substring(0, auditDescriptionMaxLength);
}
AuditRequest auditRequest = new AuditRequest(auditEvent, eventType, applicationName, "no-user",
transactionId, "EsignetSignUpService", description);
restRequestWrapper.setRequest(auditRequest);

try{
selfTokenRestTemplate.exchange(sendAuditTransactionsUrl, HttpMethod.POST, new HttpEntity<>(restRequestWrapper),
new ParameterizedTypeReference<RestResponseWrapper<AuditResponse>>(){}).getBody();
}catch (RestClientException restClientException){
log.error("An error occurred in sendAuditTransaction", restClientException);
}
}
}
11 changes: 11 additions & 0 deletions signup-service/src/main/java/io/mosip/signup/util/AuditEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.mosip.signup.util;

public enum AuditEvent {

GENERATE_CHALLENGE,
VERIFY_CHALLENGE,
REGISTER,
REGISTER_STATUS_CHECK,
RESET_PASSWORD,
RESET_PASSWORD_STATUS_CHECK
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.mosip.signup.util;

public enum AuditEventType {

SUCCESS,
ERROR
}
36 changes: 23 additions & 13 deletions signup-service/src/main/resources/application-default.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ mosip.signup.identifier.prefix=+855
mosip.signup.supported-languages={'khm','eng'}
mosip.signup.password.pattern=^(?=.{8,20}$)(?=.*[A-Za-z])(?=.*\\d).*$
mosip.signup.password.max-length=20
## Application Name
spring.application.name=signup

server.port=8088
server.servlet.path=/
spring.mvc.servlet.path=${server.servlet.path}
server.servlet.context-path=/v1/signup
server.env.url=https://api-internal.camdgc-dev.mosip.net
mosip.signup.password.min-length=8
mosip.signup.fullname.pattern=^[\\u1780-\\u17FF\\u19E0-\\u19FF\\u1A00-\\u1A9F\\u0020]{1,30}$

Expand All @@ -14,8 +22,6 @@ mosip.signup.fullname.pattern=^[\\u1780-\\u17FF\\u19E0-\\u19FF\\u1A00-\\u1A9F\\u
## Adding 10 seconds buffer to default 180 seconds = 190 seconds.
## so 190 seconds is the Generate and verify cookie max age.
mosip.signup.unauthenticated.txn.timeout=190
mosip.signup.challenge.resend-attempt=3
mosip.signup.challenge.resend-delay=60

## Time given to complete registration and get back the status of the registration in seconds.
## Considering 5 minutes(300 seconds) to complete registration form and submit.
Expand Down Expand Up @@ -49,10 +55,10 @@ mosip.esignet.cache.expire-in-seconds={'challenge-generated': ${mosip.signup.una
'status-check': ${mosip.signup.status-check.txn.timeout} }

## ------------------------------------- Auth adapter ------------------------------------------------------------------
mosip.kernel.authmanager.url=https://api-internal.camdgc-dev.mosip.net
mosip.api.internal.url=https://api-internal.camdgc-dev.mosip.net
keycloak.external.url=https://iam.camdgc-dev.mosip.net
keycloak.internal.url=https://iam.camdgc-dev.mosip.net
auth.server.validate.url=${mosip.kernel.authmanager.url}/v1/authmanager/authorize/admin/validateToken
auth.server.validate.url=${mosip.api.internal.url}/v1/authmanager/authorize/admin/validateToken
auth.server.admin.issuer.uri=${keycloak.external.url}/auth/realms/
auth-token-generator.rest.issuerUrl=${keycloak.internal.url}/auth/realms/mosip
mosip.keycloak.issuerUrl=${keycloak.internal.url}/auth/realms/mosip
Expand All @@ -65,7 +71,7 @@ mosip.iam.adapter.clientid=mosip-signup-client
mosip.iam.adapter.clientsecret=LBIZwf0IGrFlkuXi
mosip.iam.adapter.appid=signup
mosip.iam.adapter.issuerURL=${keycloak.external.url}/auth/realms/mosip
mosip.authmanager.client-token-endpoint=${mosip.kernel.authmanager.url}/v1/authmanager/authenticate/clientidsecretkey
mosip.authmanager.client-token-endpoint=${mosip.api.internal.url}/v1/authmanager/authenticate/clientidsecretkey
mosip.iam.adapter.validate-expiry-check-rate=15
mosip.iam.adapter.renewal-before-expiry-interval=15
mosip.iam.adapter.self-token-renewal-enable=true
Expand All @@ -78,13 +84,14 @@ mosip.security.csrf-enable=true
mosip.security.cors-enable=true

## -------------------------- External endpoints -----------------------------------------------------------------------
mosip.signup.generate-challenge.endpoint=${mosip.kernel.authmanager.url}/v1/otpmanager/otp/generate
mosip.signup.get-identity.endpoint=https://api-internal.camdgc-dev.mosip.net/idrepository/v1/identity/idvid/%s@phone?type=demo&idType=HANDLE
mosip.signup.identity.endpoint=https://api-internal.camdgc-dev.mosip.net/idrepository/v1/identity/
mosip.signup.generate-hash.endpoint=https://api-internal.camdgc-dev.mosip.net/v1/keymanager/generateArgon2Hash
mosip.signup.get-uin.endpoint=https://api-internal.camdgc-dev.mosip.net/v1/idgenerator/uin
mosip.signup.send-notification.endpoint=https://api-internal.camdgc-dev.mosip.net/v1/notifier/sms/send
mosip.signup.get-registration-status.endpoint=https://api-internal.camdgc-dev.mosip.net/v1/credentialrequest/get/{applicationId}
mosip.signup.generate-challenge.endpoint=${mosip.api.internal.url}/v1/otpmanager/otp/generate
mosip.signup.get-identity.endpoint=${mosip.api.internal.url}/idrepository/v1/identity/idvid/%s@phone?type=demo&idType=HANDLE
mosip.signup.identity.endpoint=${mosip.api.internal.url}/idrepository/v1/identity/
mosip.signup.generate-hash.endpoint=${mosip.api.internal.url}/v1/keymanager/generateArgon2Hash
mosip.signup.get-uin.endpoint=${mosip.api.internal.url}/v1/idgenerator/uin
mosip.signup.send-notification.endpoint=${mosip.api.internal.url}/v1/notifier/sms/send
mosip.signup.get-registration-status.endpoint=${mosip.api.internal.url}/v1/credentialrequest/get/{applicationId}
mosip.signup.audit-endpoint=${mosip.api.internal.url}/v1/auditmanager/audits
mosip.signup.add-identity.request.id=mosip.id.create
mosip.signup.update-identity.request.id=mosip.id.update
mosip.signup.identity.request.version=v1
Expand All @@ -95,7 +102,10 @@ mosip.signup.integration.captcha-validator=GoogleRecaptchaValidatorService
mosip.signup.captcha-validator.url=https://www.google.com/recaptcha/api/siteverify
mosip.signup.captcha-validator.site-key=6LcdIvsoAAAAAMq_WeWuxfxgt26Nl3cjvMc-4IUJ
mosip.signup.captcha-validator.secret=6LcdIvsoAAAAALn0Rg5ajDSUAyeBgEOaJmCbL3pX

mosip.signup.cookie.max-age=60
mosip.signup.challenge.resend-attempt=3
mosip.signup.challenge.resend-delay=30
mosip.signup.audit.description.max-length=2048
## ----------------------------- UI-Config -----------------------------------------------------------------------------
# Only after current challenge timeout we should enable resend in the UI.
# In this case timeout and resend-delay should be same always.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import io.mosip.signup.exception.ChallengeFailedException;
import io.mosip.signup.exception.InvalidIdentifierException;
import io.mosip.signup.exception.InvalidTransactionException;
import io.mosip.signup.helper.AuditHelper;
import io.mosip.signup.services.CacheUtilService;
import io.mosip.signup.services.RegistrationService;
import io.mosip.signup.util.*;
import org.junit.Before;
Expand Down Expand Up @@ -50,6 +52,12 @@ public class RegistrationControllerTest {
@MockBean
RegistrationService registrationService;

@MockBean
CacheUtilService cacheUtilService;

@MockBean
AuditHelper auditHelper;

ObjectMapper objectMapper = new ObjectMapper();

private GenerateChallengeRequest generateChallengeRequest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.mosip.esignet.core.dto.RequestWrapper;
import io.mosip.signup.dto.RegistrationStatusResponse;
import io.mosip.signup.dto.ResetPasswordRequest;
import io.mosip.signup.helper.AuditHelper;
import io.mosip.signup.services.RegistrationService;
import io.mosip.signup.util.ActionStatus;
import io.mosip.signup.util.ErrorConstants;
Expand Down Expand Up @@ -46,6 +47,9 @@ public class SignUpControllerTest {
@MockBean
RegistrationService registrationService;

@MockBean
AuditHelper auditHelper;

ObjectMapper objectMapper = new ObjectMapper();

@Test
Expand Down
Loading

0 comments on commit bd32f9e

Please sign in to comment.