Skip to content

Commit

Permalink
[ES-904] Added CaptchaHelperService (mosip#787)
Browse files Browse the repository at this point in the history
* [ES-904] Added CaptchHelperService

Signed-off-by: Venkata Saidurga Polamraju <saidurgacsea@gmail.com>

* [ES-904] reviewed comments

Signed-off-by: Venkata Saidurga Polamraju <saidurgacsea@gmail.com>

* [ES-904] updated reviewed comments

Signed-off-by: Venkata Saidurga Polamraju <saidurgacsea@gmail.com>

* [ES-904] Added CaptchHelperService

Signed-off-by: Venkata Saidurga Polamraju <saidurgacsea@gmail.com>

* [ES-904]

Signed-off-by: Venkata Saidurga Polamraju <saidurgacsea@gmail.com>

* [ES-904] Added test cases

Signed-off-by: Venkata Saidurga Polamraju <saidurgacsea@gmail.com>

---------

Signed-off-by: Venkata Saidurga Polamraju <saidurgacsea@gmail.com>
  • Loading branch information
pvsaidurga authored Jul 1, 2024
1 parent 6a35d97 commit 76aecd0
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.mosip.esignet.core.dto;

import lombok.Data;

@Data
public class CaptchaRequest {
private static final long serialVersionUID = 1L;
private String captchaToken;
private String moduleName;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package io.mosip.esignet.core.util;

import io.mosip.esignet.core.constants.ErrorConstants;
import io.mosip.esignet.core.dto.CaptchaRequest;
import io.mosip.esignet.core.dto.RequestWrapper;
import io.mosip.esignet.core.dto.ResponseWrapper;
import io.mosip.esignet.core.exception.EsignetException;
import org.springframework.beans.factory.annotation.Value;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

import static io.mosip.esignet.core.constants.Constants.UTC_DATETIME_PATTERN;

@Service
@Slf4j
public class CaptchaHelper {

@Autowired
private RestTemplate restTemplate;

@Value("${mosip.esignet.captcha.module-name}")
private String moduleName;

@Value("${mosip.esignet.captcha.validator-url}")
private String validatorUrl;

public boolean validateCaptcha(String captchaToken) {

if (captchaToken == null || captchaToken.isBlank()) {
throw new EsignetException(ErrorConstants.INVALID_CAPTCHA);
}

try{
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
CaptchaRequest captchaRequest = new CaptchaRequest();
captchaRequest.setCaptchaToken(captchaToken);
captchaRequest.setModuleName(moduleName);

RequestWrapper<CaptchaRequest> requestWrapper = new RequestWrapper<>();
requestWrapper.setRequestTime(ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern(UTC_DATETIME_PATTERN)));
requestWrapper.setRequest(captchaRequest);
RequestEntity<RequestWrapper<CaptchaRequest>> requestEntity = RequestEntity
.post(URI.create(validatorUrl))
.headers(headers)
.body(requestWrapper);

ResponseEntity<ResponseWrapper> responseEntity = restTemplate.exchange(
requestEntity,
ResponseWrapper.class
);

if (responseEntity.getStatusCode().is2xxSuccessful() && responseEntity.getBody() != null) {
ResponseWrapper<?> responseWrapper = (ResponseWrapper<?>) responseEntity.getBody();
if (responseWrapper != null && responseWrapper.getResponse() != null) {
log.info("Captcha Validation Successful");
return true;
}
log.error("Errors received from CaptchaService: {}", responseWrapper.getErrors()); //NOSONAR responseWrapper is already evaluated to be not null
throw new EsignetException(ErrorConstants.INVALID_CAPTCHA);
}
log.error("Errors received from CaptchaService: {}", responseEntity.getStatusCode());
throw new EsignetException(ErrorConstants.INVALID_CAPTCHA);
} catch (Exception e) {
throw new EsignetException(ErrorConstants.INVALID_CAPTCHA);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package io.mosip.esignet.core;

import io.mosip.esignet.core.dto.ResponseWrapper;
import io.mosip.esignet.core.exception.EsignetException;
import io.mosip.esignet.core.util.CaptchaHelper;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.*;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;

import static org.mockito.ArgumentMatchers.any;

@SpringBootTest
@RunWith(MockitoJUnitRunner.class)
public class CaptchaHelperTest {

@Mock
RestTemplate restTemplate;

@InjectMocks
CaptchaHelper captchaHelper;

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ReflectionTestUtils.setField(captchaHelper, "validatorUrl", "https://api-internal.camdgc-dev1.mosip.net/v1/captcha/validatecaptcha");
ReflectionTestUtils.setField(captchaHelper,"moduleName","esignet");
}

@Test
public void validateCaptcha_WithNullCaptchaToken_ThrowsException() {
CaptchaHelper captchaHelper=new CaptchaHelper();
Assert.assertThrows(EsignetException.class,()->captchaHelper.validateCaptcha(null));
}

@Test
public void validateCaptcha_WithCaptchaToken_ThrowsException() {
CaptchaHelper captchaHelper=new CaptchaHelper();
Assert.assertThrows(EsignetException.class,()->captchaHelper.validateCaptcha(""));
}

@Test
public void validateCaptcha_WithNullResponse_ThrowsException() {
Mockito.when(restTemplate.exchange((RequestEntity<?>) any(), (Class<Object>) any())).thenReturn(null);
Assert.assertThrows(EsignetException.class,()->captchaHelper.validateCaptcha("captchaToken"));
}

@Test
public void validateCaptcha_SuccessfulResponse() {
ResponseWrapper responseWrapper = new ResponseWrapper();
responseWrapper.setResponse("success");
ResponseEntity<ResponseWrapper> responseEntity = ResponseEntity.ok(responseWrapper);
Mockito.when(restTemplate.exchange(Mockito.any(RequestEntity.class), Mockito.eq(ResponseWrapper.class)))
.thenReturn(responseEntity);
boolean result = captchaHelper.validateCaptcha("captchaToken");
Assert.assertTrue(result);
}

@Test
public void validateCaptcha_UnsuccessfulValidation_ThrowsEsignetException() {
ResponseWrapper responseWrapper = new ResponseWrapper();
responseWrapper.setErrors(new ArrayList<>());
ResponseEntity<ResponseWrapper> responseEntity = ResponseEntity.ok(responseWrapper);
Mockito.when(restTemplate.exchange(Mockito.any(RequestEntity.class), Mockito.eq(ResponseWrapper.class)))
.thenReturn(responseEntity);
Assert.assertThrows(EsignetException.class, () -> captchaHelper.validateCaptcha("captchaToken"));
}

@Test
public void validateCaptcha_RequestException_ThrowsEsignetException() {
Mockito.when(restTemplate.exchange(Mockito.any(RequestEntity.class), Mockito.eq(ResponseWrapper.class)))
.thenThrow(new RestClientException("Request failed"));
Assert.assertThrows(EsignetException.class, () -> captchaHelper.validateCaptcha("captchaToken"));
}

}
2 changes: 2 additions & 0 deletions esignet-service/src/main/resources/application-dev.properties
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ mosip.esignet.header-filter.paths-to-validate={'${server.servlet.path}/authoriza
#This property is used for captcha validation and allowed values are send-otp and pwd.
#captcha validation is enabled for send-otp and pwd.
mosip.esignet.captcha.required=send-otp,pwd
mosip.esignet.captcha.validator-url=${mosipbox.public.url}${server.servlet.path}/v1/captcha/validatecaptcha
mosip.esignet.captcha.module-name=esignet

## ------------------------------------------ e-Signet binding ---------------------------------------------------------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ mosip.esignet.header-filter.paths-to-validate={'${server.servlet.path}/authoriza
#This property is used for captcha validation and allowed values are send-otp and pwd.
# captcha validation is enabled for the auth-factors - otp, pwd, bio and pin.
mosip.esignet.captcha.required=send-otp,pwd,bio,pin
mosip.esignet.captcha.validator-url=${mosipbox.public.url}${server.servlet.path}/v1/captcha/validatecaptcha
mosip.esignet.captcha.module-name=esignet

mosip.esignet.host=localhost
mosip.esignet.signup-id-token-expire-seconds=180
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ mosip.esignet.header-filter.paths-to-validate={'${server.servlet.path}/authoriza
#This property is used for captcha validation and allowed values are send-otp and pwd.
#captcha validation is enabled for send-otp and pwd.
mosip.esignet.captcha.required=pwd
mosip.esignet.captcha.validator-url=${mosipbox.public.url}${server.servlet.path}/v1/captcha/validatecaptcha
mosip.esignet.captcha.module-name=esignet

mosip.esignet.host=http://localhost:8088
mosip.esignet.signup-id-token-expire-seconds=180
Expand Down

0 comments on commit 76aecd0

Please sign in to comment.