From 4d985b57e56f48552a2841a15a3eb36187cc458f Mon Sep 17 00:00:00 2001 From: Loganathan Sekar <42532387+LoganathanSekar7627@users.noreply.github.com> Date: Mon, 12 Feb 2024 15:17:53 +0530 Subject: [PATCH] Cherry-picking otp validation securiy fix (#1195) * Cherry-picking otp validation securiy fix Signed-off-by: Loganathan Sekar * Updated db scripts Signed-off-by: Loganathan Sekar --------- Signed-off-by: Loganathan Sekar --- .../impl/match/OtpMatchingStrategy.java | 5 +- .../service/impl/match/PinAuthType.java | 2 + .../service/integration/OTPManager.java | 162 ++++- .../service/repository/OtpTxnRepository.java | 8 +- .../service/impl/OTPAuthServiceTest.java | 2 +- .../impl/match/OtpMatchingStrategyTest.java | 2 + .../service/integration/OTPManagerTest.java | 667 +++++++++++++++++- .../integration/ValidateOtpRequestTest.java | 4 +- .../core/constant/IdAuthCommonConstants.java | 4 + .../constant/IdAuthConfigKeyConstants.java | 1 + .../IdAuthenticationErrorConstants.java | 9 +- .../core/spi/indauth/match/MatchType.java | 1 + .../indauth/match/ValidateOtpFunction.java | 2 +- .../mosip_ida/ddl/ida-otp_transaction.sql | 2 +- .../sql/1.2.0.1-B5_to_1.2.0.1_rollback.sql | 5 + .../sql/1.2.0.1-B5_to_1.2.0.1_upgrade.sql | 5 + 16 files changed, 814 insertions(+), 67 deletions(-) diff --git a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/impl/match/OtpMatchingStrategy.java b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/impl/match/OtpMatchingStrategy.java index 68bfb3401ef..ae35ea3615e 100644 --- a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/impl/match/OtpMatchingStrategy.java +++ b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/impl/match/OtpMatchingStrategy.java @@ -21,11 +21,12 @@ public enum OtpMatchingStrategy implements TextMatchingStrategy { EXACT(MatchingStrategyType.EXACT, (Object reqInfo, Object entityInfo, Map props) -> { - if (reqInfo instanceof String && entityInfo instanceof String) { + Object idvidObj = props.get(IdAuthCommonConstants.IDVID); + if (reqInfo instanceof String && entityInfo instanceof String && idvidObj instanceof String) { Object object = props.get(ValidateOtpFunction.class.getSimpleName()); if (object instanceof ValidateOtpFunction) { ValidateOtpFunction func = (ValidateOtpFunction) object; - boolean otpValid = func.validateOtp((String) reqInfo, (String) entityInfo); + boolean otpValid = func.validateOtp((String) reqInfo, (String) entityInfo, (String) idvidObj); if (!otpValid) { return 0; } else { diff --git a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/impl/match/PinAuthType.java b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/impl/match/PinAuthType.java index 118213b3135..719cecbe11a 100644 --- a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/impl/match/PinAuthType.java +++ b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/impl/match/PinAuthType.java @@ -5,6 +5,7 @@ import java.util.Set; import io.mosip.authentication.common.service.impl.AuthTypeImpl; +import io.mosip.authentication.core.constant.IdAuthCommonConstants; import io.mosip.authentication.core.indauth.dto.AuthRequestDTO; import io.mosip.authentication.core.spi.indauth.match.AuthType; import io.mosip.authentication.core.spi.indauth.match.IdInfoFetcher; @@ -29,6 +30,7 @@ public Map getMatchProperties(AuthRequestDTO authRequestDTO, IdI if (isAuthTypeInfoAvailable(authRequestDTO)) { ValidateOtpFunction func = idInfoFetcher.getValidateOTPFunction(); valueMap.put(ValidateOtpFunction.class.getSimpleName(), func); + valueMap.put(IdAuthCommonConstants.IDVID, authRequestDTO.getIndividualId()); } return valueMap; } diff --git a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/integration/OTPManager.java b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/integration/OTPManager.java index 9a403e4bcd8..9ab2ad23395 100644 --- a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/integration/OTPManager.java +++ b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/integration/OTPManager.java @@ -1,10 +1,15 @@ package io.mosip.authentication.common.service.integration; import java.time.LocalDateTime; -import java.util.*; +import java.time.temporal.ChronoUnit; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; @@ -38,10 +43,14 @@ * @author Rakesh Roshan * @author Dinesh Karuppiah.T * @author Manoj SP + * @author Loganathan S */ @Component public class OTPManager { + /** The Constant QUERIED_STATUS_CODES. */ + private static final List QUERIED_STATUS_CODES = List.of(IdAuthCommonConstants.ACTIVE_STATUS, IdAuthCommonConstants.FROZEN); + /** The Constant OTP_EXPIRED. */ private static final String OTP_EXPIRED = "OTP_EXPIRED"; @@ -52,21 +61,29 @@ public class OTPManager { @Autowired private RestHelper restHelper; - @Autowired - private EnvUtil environment; - /** The rest request factory. */ @Autowired private RestRequestFactory restRequestFactory; + /** The security manager. */ @Autowired private IdAuthSecurityManager securityManager; + /** The otp transaction repo. */ @Autowired private OtpTxnRepository otpRepo; + /** The notification service. */ @Autowired private NotificationService notificationService; + + /** The number of validation attempts allowed. */ + @Value("${mosip.ida.otp.validation.attempt.count.threshold:5}") + private int numberOfValidationAttemptsAllowed; + + /** The otp frozen time minutes. */ + @Value("${mosip.ida.otp.frozen.duration.minutes:30}") + private int otpFrozenTimeMinutes; /** The logger. */ private static Logger logger = IdaLogger.getLogger(OTPManager.class); @@ -76,29 +93,40 @@ public class OTPManager { * time-out. * * @param otpRequestDTO the otp request DTO - * @param uin the uin + * @param idvid the idvid + * @param idvidType the idvid type * @param valueMap the value map + * @param templateLanguages the template languages * @return String(otp) * @throws IdAuthenticationBusinessException the id authentication business * exception */ public boolean sendOtp(OtpRequestDTO otpRequestDTO, String idvid, String idvidType, Map valueMap, List templateLanguages) throws IdAuthenticationBusinessException { + + String refIdHash = securityManager.hash(idvid); + Optional otpEntityOpt = otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(refIdHash, QUERIED_STATUS_CODES); + if(otpEntityOpt.isPresent()) { + OtpTransaction otpEntity = otpEntityOpt.get(); + requireOtpNotFrozen(otpEntity, false); + } + String otp = generateOTP(otpRequestDTO.getIndividualId()); LocalDateTime otpGenerationTime = DateUtils.getUTCCurrentDateTime(); String otpHash = IdAuthSecurityManager.digestAsPlainText((otpRequestDTO.getIndividualId() + EnvUtil.getKeySplitter() + otpRequestDTO.getTransactionID() + EnvUtil.getKeySplitter() + otp).getBytes()); - - Optional otpTxnOpt = otpRepo.findByOtpHashAndStatusCode(otpHash, IdAuthCommonConstants.ACTIVE_STATUS); - if (otpTxnOpt.isPresent()) { - OtpTransaction otpTxn = otpTxnOpt.get(); + + OtpTransaction otpTxn; + if (otpEntityOpt.isPresent() + && (otpTxn = otpEntityOpt.get()).getStatusCode().equals(IdAuthCommonConstants.ACTIVE_STATUS)) { otpTxn.setOtpHash(otpHash); otpTxn.setUpdBy(securityManager.getUser()); otpTxn.setUpdDTimes(otpGenerationTime); + otpTxn.setGeneratedDtimes(otpGenerationTime); + otpTxn.setValidationRetryCount(0); otpTxn.setExpiryDtimes(otpGenerationTime.plusSeconds(EnvUtil.getOtpExpiryTime())); - otpTxn.setStatusCode(IdAuthCommonConstants.ACTIVE_STATUS); otpRepo.save(otpTxn); } else { OtpTransaction txn = new OtpTransaction(); @@ -107,11 +135,13 @@ public boolean sendOtp(OtpRequestDTO otpRequestDTO, String idvid, String idvidTy txn.setOtpHash(otpHash); txn.setCrBy(securityManager.getUser()); txn.setCrDtimes(otpGenerationTime); + txn.setGeneratedDtimes(otpGenerationTime); txn.setExpiryDtimes(otpGenerationTime.plusSeconds( EnvUtil.getOtpExpiryTime())); txn.setStatusCode(IdAuthCommonConstants.ACTIVE_STATUS); otpRepo.save(txn); } + String notificationProperty = null; notificationProperty = otpRequestDTO .getOtpChannel().stream().map(channel -> NotificationType.getNotificationTypeForChannel(channel) @@ -123,6 +153,24 @@ public boolean sendOtp(OtpRequestDTO otpRequestDTO, String idvid, String idvidTy return true; } + /** + * Creates the OTP frozen exception. + * + * @return the id authentication business exception + */ + private IdAuthenticationBusinessException createOTPFrozenException() { + return new IdAuthenticationBusinessException(IdAuthenticationErrorConstants.OTP_FROZEN.getErrorCode(), + String.format(IdAuthenticationErrorConstants.OTP_FROZEN.getErrorMessage(), + otpFrozenTimeMinutes + " seconds", numberOfValidationAttemptsAllowed)); + } + + /** + * Generate OTP. + * + * @param uin the uin + * @return the string + * @throws IdAuthUncheckedException the id auth unchecked exception + */ private String generateOTP(String uin) throws IdAuthUncheckedException { try { OtpGenerateRequestDto otpGenerateRequestDto = new OtpGenerateRequestDto(uin); @@ -137,11 +185,10 @@ private String generateOTP(String uin) throws IdAuthUncheckedException { IdAuthenticationErrorConstants.BLOCKED_OTP_VALIDATE.getErrorCode(), USER_BLOCKED); throw new IdAuthUncheckedException(IdAuthenticationErrorConstants.BLOCKED_OTP_VALIDATE); } - if(response !=null && response.getResponse()!=null){ - return response.getResponse().get("otp"); - }else{ + if(response == null || response.getResponse() == null) { throw new IdAuthUncheckedException(IdAuthenticationErrorConstants.OTP_GENERATION_FAILED); } + return response.getResponse().get("otp"); } catch (IDDataValidationException e) { logger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "generateOTP", @@ -160,29 +207,92 @@ private String generateOTP(String uin) throws IdAuthUncheckedException { * * @param pinValue the pin value * @param otpKey the otp key + * @param individualId the individual id * @return true, if successful * @throws IdAuthenticationBusinessException the id authentication business * exception */ - public boolean validateOtp(String pinValue, String otpKey) throws IdAuthenticationBusinessException { - String otpHash; - otpHash = IdAuthSecurityManager.digestAsPlainText( - (otpKey + EnvUtil.getKeySplitter() + pinValue).getBytes()); - Optional otpTxnOpt = otpRepo.findByOtpHashAndStatusCode(otpHash, IdAuthCommonConstants.ACTIVE_STATUS); - if (otpTxnOpt.isPresent()) { - OtpTransaction otpTxn = otpTxnOpt.get(); - //OtpTransaction otpTxn = otpRepo.findByOtpHashAndStatusCode(otpHash, IdAuthCommonConstants.ACTIVE_STATUS); - otpTxn.setStatusCode(IdAuthCommonConstants.USED_STATUS); - otpRepo.save(otpTxn); - if (otpTxn.getExpiryDtimes().isAfter(DateUtils.getUTCCurrentDateTime())) { - return true; - } else { + public boolean validateOtp(String pinValue, String otpKey, String individualId) throws IdAuthenticationBusinessException { + String refIdHash = securityManager.hash(individualId); + Optional otpEntityOpt = otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(refIdHash, QUERIED_STATUS_CODES); + + if (otpEntityOpt.isEmpty()) { + throw new IdAuthenticationBusinessException(IdAuthenticationErrorConstants.OTP_REQUEST_REQUIRED); + } + + OtpTransaction otpEntity = otpEntityOpt.get(); + requireOtpNotFrozen(otpEntity, true); + + if(otpEntity.getStatusCode().equals(IdAuthCommonConstants.UNFROZEN)) { + throw new IdAuthenticationBusinessException(IdAuthenticationErrorConstants.OTP_REQUEST_REQUIRED); + } + + // At this point it should be active status alone. + // Increment the validation attempt count. + int attemptCount = otpEntity.getValidationRetryCount() == null ? 1 : otpEntity.getValidationRetryCount() + 1; + + String otpHash = getOtpHash(pinValue, otpKey); + if (otpEntity.getOtpHash().equals(otpHash)) { + otpEntity.setUpdDTimes(DateUtils.getUTCCurrentDateTime()); + otpEntity.setStatusCode(IdAuthCommonConstants.USED_STATUS); + otpRepo.save(otpEntity); + if (!otpEntity.getExpiryDtimes().isAfter(DateUtils.getUTCCurrentDateTime())) { logger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), IdAuthenticationErrorConstants.EXPIRED_OTP.getErrorCode(), OTP_EXPIRED); throw new IdAuthenticationBusinessException(IdAuthenticationErrorConstants.EXPIRED_OTP); } + return true; } else { + //Set the incremented validation attempt count + otpEntity.setValidationRetryCount(attemptCount); + if (attemptCount >= numberOfValidationAttemptsAllowed) { + otpEntity.setStatusCode(IdAuthCommonConstants.FROZEN); + } + otpEntity.setUpdDTimes(DateUtils.getUTCCurrentDateTime()); + otpRepo.save(otpEntity); return false; } } + + /** + * Require otp not frozen. + * + * @param otpEntity the otp entity + * @throws IdAuthenticationBusinessException the id authentication business exception + */ + private void requireOtpNotFrozen(OtpTransaction otpEntity, boolean saveEntity) throws IdAuthenticationBusinessException { + if(otpEntity.getStatusCode().equals(IdAuthCommonConstants.FROZEN)) { + if(!isAfterFrozenDuration(otpEntity)) { + throw createOTPFrozenException(); + } + logger.info("OTP Frozen wait time is over. Allowing further."); + otpEntity.setStatusCode(IdAuthCommonConstants.UNFROZEN); + if(saveEntity) { + otpRepo.save(otpEntity); + } + } + } + + /** + * Checks if the entity is after frozen duration. + * + * @param otpEntity the otp entity + * @return true, if is after frozen duration + */ + private boolean isAfterFrozenDuration(OtpTransaction otpEntity) { + return DateUtils.getUTCCurrentDateTime().isAfter(otpEntity.getUpdDTimes().plus(otpFrozenTimeMinutes, ChronoUnit.MINUTES)); + } + + /** + * Gets the otp hash. + * + * @param pinValue the pin value + * @param otpKey the otp key + * @return the otp hash + */ + private String getOtpHash(String pinValue, String otpKey) { + return IdAuthSecurityManager.digestAsPlainText( + (otpKey + EnvUtil.getKeySplitter() + pinValue).getBytes()); + } + } diff --git a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/repository/OtpTxnRepository.java b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/repository/OtpTxnRepository.java index 9855fdb04c3..f5ef11c11a6 100644 --- a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/repository/OtpTxnRepository.java +++ b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/repository/OtpTxnRepository.java @@ -1,5 +1,6 @@ package io.mosip.authentication.common.service.repository; +import java.util.List; import java.util.Optional; import io.mosip.authentication.common.service.entity.OtpTransaction; @@ -13,12 +14,11 @@ public interface OtpTxnRepository extends BaseRepository { /** - * Find by otp hash and status code. + * Find first element by ref_id ordered by generated_dtimes in descending order and for the given status codes. * - * @param otpHash the otp hash - * @param statusCode the status code + * @param refIdHash the ref id hash * @return the optional */ - Optional findByOtpHashAndStatusCode(String otpHash, String statusCode); + Optional findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(String refIdHash, List statusCodes); } diff --git a/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/impl/OTPAuthServiceTest.java b/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/impl/OTPAuthServiceTest.java index 853c570c75f..47759155a1a 100644 --- a/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/impl/OTPAuthServiceTest.java +++ b/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/impl/OTPAuthServiceTest.java @@ -139,7 +139,7 @@ public void TestValidValidateOtp() throws IdAuthenticationBusinessException { List valueList = new ArrayList<>(); valueList.add("1234567890"); Mockito.when(repository.findByTxnId(Mockito.anyString(), Mockito.any(), Mockito.any())).thenReturn(autntxnList); - Mockito.when(otpmanager.validateOtp(Mockito.anyString(), Mockito.anyString())).thenReturn(true); + Mockito.when(otpmanager.validateOtp(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(true); AuthStatusInfo authStatusInfo = otpauthserviceimpl.authenticate(authreqdto, "123456", Collections.emptyMap(), "PARTNER1"); assertNotNull(authStatusInfo); diff --git a/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/impl/match/OtpMatchingStrategyTest.java b/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/impl/match/OtpMatchingStrategyTest.java index 67469ed2685..2a08c49f489 100644 --- a/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/impl/match/OtpMatchingStrategyTest.java +++ b/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/impl/match/OtpMatchingStrategyTest.java @@ -25,6 +25,7 @@ import io.mosip.authentication.common.service.integration.OTPManager; import io.mosip.authentication.common.service.repository.OtpTxnRepository; import io.mosip.authentication.common.service.util.EnvUtil; +import io.mosip.authentication.core.constant.IdAuthCommonConstants; import io.mosip.authentication.core.exception.IdAuthenticationBusinessException; import io.mosip.authentication.core.spi.indauth.match.MatchFunction; import io.mosip.authentication.core.spi.indauth.match.ValidateOtpFunction; @@ -98,6 +99,7 @@ public void TestInValidOtpMatchingStrategy() throws IdAuthenticationBusinessExce MatchFunction matchFunction = OtpMatchingStrategy.EXACT.getMatchFunction(); Map matchProperties = new HashMap<>(); matchProperties.put(ValidateOtpFunction.class.getSimpleName(), ""); + matchProperties.put(IdAuthCommonConstants.IDVID, ""); int value = matchFunction.match("123456", "IDA_asdEEFAER", matchProperties); assertEquals(0, value); } diff --git a/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/integration/OTPManagerTest.java b/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/integration/OTPManagerTest.java index 8b8330a1fcd..15cde441316 100644 --- a/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/integration/OTPManagerTest.java +++ b/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/integration/OTPManagerTest.java @@ -3,6 +3,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; @@ -61,6 +65,8 @@ @ContextConfiguration(classes = { TestContext.class, WebApplicationContext.class }) public class OTPManagerTest { + private static final String FROZEN_ERROR_MESSAGE = "OTP request/validation has been frozen for the Individual-ID for 30 seconds due to consecutive failure attempts for 5 times."; + @InjectMocks private OTPManager otpManager; @@ -100,10 +106,12 @@ public class OTPManagerTest { @Before public void before() { ReflectionTestUtils.setField(restRequestFactory, "env", environment); - ReflectionTestUtils.setField(otpManager, "environment", environment); ReflectionTestUtils.setField(env, "otpExpiryTime", 12); + ReflectionTestUtils.setField(otpManager, "numberOfValidationAttemptsAllowed", 5); + ReflectionTestUtils.setField(otpManager, "otpFrozenTimeMinutes", 30); templateLanguages.add("eng"); templateLanguages.add("ara"); + EnvUtil.setKeySplitter("#KEY_SPLITTER#"); } private static final String VALIDATION_UNSUCCESSFUL = "VALIDATION_UNSUCCESSFUL"; @@ -128,8 +136,137 @@ public void sendOtpTest() throws RestServiceException, IdAuthenticationBusinessE Map valueMap = new HashMap<>(); valueMap.put("namePri", "Name in PrimaryLang"); valueMap.put("nameSec", "Name in SecondaryLang"); - boolean sendOtpResponse = otpManager.sendOtp(otpRequestDTO, "426789089018", "UIN", valueMap, templateLanguages); - assertEquals(sendOtpResponse, true); + try { + when(otpRepo.save(Mockito.any())).thenAnswer(invocation -> { + assertEquals(IdAuthCommonConstants.ACTIVE_STATUS, ((OtpTransaction)invocation.getArguments()[0]).getStatusCode()); + return null; + }); + boolean result = otpManager.sendOtp(otpRequestDTO, "426789089018", "UIN", valueMap, templateLanguages); + assertTrue(result); + verify(otpRepo, times(1)).save(Mockito.any()); + } catch(IdAuthUncheckedException ex) { + fail(); + } + } + + @Test + public void sendOtpTest_frozen_within30mins() throws RestServiceException, IdAuthenticationBusinessException { + OtpGeneratorRequestDto otpGeneratorRequestDto = getOtpGeneratorRequestDto(); + ResponseWrapper otpGeneratorResponsetDto = new ResponseWrapper<>(); + Map response = new HashMap<>(); + response.put("status", "success"); + otpGeneratorResponsetDto.setResponse(response); + RestRequestDTO restRequestDTO = getRestRequestDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_GENERATE_SERVICE, otpGeneratorRequestDto, + OtpGeneratorResponseDto.class)).thenReturn(restRequestDTO); + Mockito.when(restHelper.requestSync(Mockito.any())).thenReturn(otpGeneratorResponsetDto); + OtpRequestDTO otpRequestDTO = getOtpRequestDto(); + Map valueMap = new HashMap<>(); + valueMap.put("namePri", "Name in PrimaryLang"); + valueMap.put("nameSec", "Name in SecondaryLang"); + when(securityManager.hash(Mockito.anyString())).thenReturn("refidHash"); + OtpTransaction entity = new OtpTransaction(); + entity.setStatusCode(IdAuthCommonConstants.FROZEN); + entity.setUpdDTimes(DateUtils.getUTCCurrentDateTime().minus(30, ChronoUnit.MINUTES)); + when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(entity)); + try { + otpManager.sendOtp(otpRequestDTO, "426789089018", "UIN", valueMap, templateLanguages); + } catch(IdAuthenticationBusinessException ex) { + assertEquals(IdAuthenticationErrorConstants.OTP_FROZEN.getErrorCode(), ex.getErrorCode()); + assertEquals(FROZEN_ERROR_MESSAGE, ex.getErrorText()); + } + } + + @Test + public void sendOtpTest_frozen_In31mins() throws RestServiceException, IdAuthenticationBusinessException { + OtpGeneratorRequestDto otpGeneratorRequestDto = getOtpGeneratorRequestDto(); + ResponseWrapper otpGeneratorResponsetDto = new ResponseWrapper<>(); + Map response = new HashMap<>(); + response.put("status", "success"); + otpGeneratorResponsetDto.setResponse(response); + RestRequestDTO restRequestDTO = getRestRequestDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_GENERATE_SERVICE, otpGeneratorRequestDto, + OtpGeneratorResponseDto.class)).thenReturn(restRequestDTO); + Mockito.when(restHelper.requestSync(Mockito.any())).thenReturn(otpGeneratorResponsetDto); + OtpRequestDTO otpRequestDTO = getOtpRequestDto(); + Map valueMap = new HashMap<>(); + valueMap.put("namePri", "Name in PrimaryLang"); + valueMap.put("nameSec", "Name in SecondaryLang"); + when(securityManager.hash(Mockito.anyString())).thenReturn("refidHash"); + OtpTransaction entity = new OtpTransaction(); + entity.setStatusCode(IdAuthCommonConstants.FROZEN); + entity.setUpdDTimes(DateUtils.getUTCCurrentDateTime().minus(31, ChronoUnit.MINUTES)); + when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(entity)); + try { + when(otpRepo.save(Mockito.any())).thenAnswer(invocation -> { + assertEquals(IdAuthCommonConstants.ACTIVE_STATUS, ((OtpTransaction)invocation.getArguments()[0]).getStatusCode()); + return null; + }); + boolean result = otpManager.sendOtp(otpRequestDTO, "426789089018", "UIN", valueMap, templateLanguages); + assertTrue(result); + } catch(IdAuthUncheckedException ex) { + fail(); + } + } + + @Test + public void sendOtpTest_USED_entry() throws RestServiceException, IdAuthenticationBusinessException { + OtpGeneratorRequestDto otpGeneratorRequestDto = getOtpGeneratorRequestDto(); + ResponseWrapper otpGeneratorResponsetDto = new ResponseWrapper<>(); + Map response = new HashMap<>(); + response.put("status", "success"); + otpGeneratorResponsetDto.setResponse(response); + RestRequestDTO restRequestDTO = getRestRequestDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_GENERATE_SERVICE, otpGeneratorRequestDto, + OtpGeneratorResponseDto.class)).thenReturn(restRequestDTO); + Mockito.when(restHelper.requestSync(Mockito.any())).thenReturn(otpGeneratorResponsetDto); + OtpRequestDTO otpRequestDTO = getOtpRequestDto(); + Map valueMap = new HashMap<>(); + valueMap.put("namePri", "Name in PrimaryLang"); + valueMap.put("nameSec", "Name in SecondaryLang"); + when(securityManager.hash(Mockito.anyString())).thenReturn("refidHash"); + OtpTransaction entity = new OtpTransaction(); + entity.setStatusCode(IdAuthCommonConstants.USED_STATUS); + entity.setUpdDTimes(DateUtils.getUTCCurrentDateTime().minus(31, ChronoUnit.MINUTES)); + when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(entity)); + try { + when(otpRepo.save(Mockito.any())).thenAnswer(invocation -> { + assertEquals(IdAuthCommonConstants.ACTIVE_STATUS, ((OtpTransaction)invocation.getArguments()[0]).getStatusCode()); + return null; + }); + boolean result = otpManager.sendOtp(otpRequestDTO, "426789089018", "UIN", valueMap, templateLanguages); + assertTrue(result); + } catch(IdAuthUncheckedException ex) { + fail(); + } + } + + @Test + public void sendOtpTest_frozen_within25mins() throws RestServiceException, IdAuthenticationBusinessException { + OtpGeneratorRequestDto otpGeneratorRequestDto = getOtpGeneratorRequestDto(); + ResponseWrapper otpGeneratorResponsetDto = new ResponseWrapper<>(); + Map response = new HashMap<>(); + response.put("status", "success"); + otpGeneratorResponsetDto.setResponse(response); + RestRequestDTO restRequestDTO = getRestRequestDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_GENERATE_SERVICE, otpGeneratorRequestDto, + OtpGeneratorResponseDto.class)).thenReturn(restRequestDTO); + Mockito.when(restHelper.requestSync(Mockito.any())).thenReturn(otpGeneratorResponsetDto); + OtpRequestDTO otpRequestDTO = getOtpRequestDto(); + Map valueMap = new HashMap<>(); + valueMap.put("namePri", "Name in PrimaryLang"); + valueMap.put("nameSec", "Name in SecondaryLang"); + when(securityManager.hash(Mockito.anyString())).thenReturn("refidHash"); + OtpTransaction entity = new OtpTransaction(); + entity.setStatusCode(IdAuthCommonConstants.FROZEN); + entity.setUpdDTimes(DateUtils.getUTCCurrentDateTime().minus(25, ChronoUnit.MINUTES)); + when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(entity)); + try { + otpManager.sendOtp(otpRequestDTO, "426789089018", "UIN", valueMap, templateLanguages); + } catch(IdAuthenticationBusinessException ex) { + assertEquals(IdAuthenticationErrorConstants.OTP_FROZEN.getErrorCode(), ex.getErrorCode()); + assertEquals(FROZEN_ERROR_MESSAGE, ex.getErrorText()); + } } @Test(expected = IdAuthUncheckedException.class) @@ -167,8 +304,6 @@ public void sendOtpTest_existingEntry() throws RestServiceException, IdAuthentic Map valueMap = new HashMap<>(); valueMap.put("namePri", "Name in PrimaryLang"); valueMap.put("nameSec", "Name in SecondaryLang"); - OtpTransaction otpEntry = new OtpTransaction(); - Mockito.when(otpRepo.findByOtpHashAndStatusCode(Mockito.anyString(), Mockito.anyString())).thenReturn(Optional.of(otpEntry )); boolean sendOtpResponse = otpManager.sendOtp(otpRequestDTO, "426789089018", "UIN", valueMap, templateLanguages); assertEquals(sendOtpResponse, true); } @@ -372,7 +507,7 @@ public void TestRestServiceException() throws IdAuthenticationBusinessException, responseMap.put("response", valuemap); Mockito.when(restHelper.requestSync(Mockito.any())) .thenThrow(new RestServiceException(IdRepoErrorConstants.CLIENT_ERROR, output, valuemap)); - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } @Ignore @@ -388,7 +523,7 @@ public void TestOtpAuth() throws RestServiceException, IdAuthenticationBusinessE Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) .thenReturn(restRequestDTO); Mockito.when(restHelper.requestSync(Mockito.any())).thenReturn(response1); - boolean expactedOTP = otpManager.validateOtp("Test123", "123456"); + boolean expactedOTP = otpManager.validateOtp("Test123", "123456", "426789089018"); assertTrue(expactedOTP); } @@ -403,7 +538,14 @@ public void TestOtpAuthFailure() valueMap.put("status", "failure"); valueMap.put("message", "Validation_Unsuccessful"); Mockito.when(restHelper.requestSync(Mockito.any())).thenReturn(valueMap); - boolean expactedOTP = otpManager.validateOtp("Test123", "123456"); + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.ACTIVE_STATUS); + otpEntity.setOtpHash("otphash"); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + boolean expactedOTP = otpManager.validateOtp("Test123", "123456", "426789089018"); assertFalse(expactedOTP); } @@ -424,7 +566,7 @@ public void TestRestServiceExceptionwithInvalid() throws RestServiceException, I .thenReturn(restRequestDTO); Mockito.when(restHelper.requestSync(Mockito.any())) .thenThrow(new RestServiceException(IdRepoErrorConstants.CLIENT_ERROR, output, response)); - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } @Ignore @@ -445,7 +587,7 @@ public void TestRestServiceExceptionwithInvalidUnknownMessage() .thenReturn(restRequestDTO); Mockito.when(restHelper.requestSync(Mockito.any())) .thenThrow(new RestServiceException(IdRepoErrorConstants.CLIENT_ERROR, output, response)); - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } @Ignore @@ -466,7 +608,7 @@ public void TestRestServiceExceptionwithInvalidWithoutStatus() .thenReturn(restRequestDTO); Mockito.when(restHelper.requestSync(Mockito.any())) .thenThrow(new RestServiceException(IdRepoErrorConstants.CLIENT_ERROR, output, responseMap)); - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } @Ignore @@ -486,7 +628,7 @@ public void TestRestServiceExceptionwithInvalidWithoutStatusWithOTPNOTGENERATEDE RestServiceException restServiceException = new RestServiceException(IdRepoErrorConstants.CLIENT_ERROR, output, responseMap); Mockito.when(restHelper.requestSync(Mockito.any())).thenThrow(restServiceException); - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } @Ignore @@ -506,7 +648,7 @@ public void TestRestServiceExceptionwithInvalidWithoutStatusWithSOMEOTHERERRORDE RestServiceException restServiceException = new RestServiceException(IdRepoErrorConstants.CLIENT_ERROR, output, responseMap); Mockito.when(restHelper.requestSync(Mockito.any())).thenThrow(restServiceException); - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } @Ignore @@ -514,7 +656,7 @@ public void TestRestServiceExceptionwithInvalidWithoutStatusWithSOMEOTHERERRORDE public void TestDataValidationException() throws IdAuthenticationBusinessException { Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) .thenThrow(new IDDataValidationException()); - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } @Test(expected = IdAuthUncheckedException.class) @@ -577,7 +719,7 @@ public void testValidateOTP_ThrowRestServiceExceptionWith_StatusFailureAndMessag Mockito.when(restHelper.requestSync(Mockito.any())) .thenThrow(new RestServiceException(IdRepoErrorConstants.CLIENT_ERROR, output, valueMap)); - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } @Ignore @@ -594,7 +736,450 @@ public void TestResponseBodyisEmpty() throws RestServiceException, IdAuthenticat valueMap.put("nameSec", "Name in SecondaryLang"); otpManager.sendOtp(otpRequestDTO, "123456", "UIN", valueMap, templateLanguages); } + + @Test + public void TestInvalidAttemptWith_noEntity() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + + try { + otpManager.validateOtp("Test123", "123456", "426789089018"); + } catch (IdAuthenticationBusinessException ex) { + assertEquals(IdAuthenticationErrorConstants.OTP_REQUEST_REQUIRED.getErrorCode(), ex.getErrorCode()); + } + } + + @Test + public void TestInvalidAttemptWith_UsedEntity() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.USED_STATUS); + otpEntity.setOtpHash("otphash"); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + otpManager.validateOtp("Test123", "123456", "426789089018"); + } catch (IdAuthenticationBusinessException ex) { + assertEquals(IdAuthenticationErrorConstants.OTP_REQUEST_REQUIRED.getErrorCode(), ex.getErrorCode()); + } + } + + @Test + public void TestInvalidAttemptWith_nullUpdateCount() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.ACTIVE_STATUS); + otpEntity.setOtpHash("otphash"); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + boolean result = otpManager.validateOtp("Test123", "123456", "426789089018"); + assertFalse(result); + assertEquals((long)1, (long)otpEntity.getValidationRetryCount()); + assertEquals(IdAuthCommonConstants.ACTIVE_STATUS, otpEntity.getStatusCode()); + verify(otpRepo, times(1)).save(otpEntity); + } catch (IdAuthenticationBusinessException ex) { + fail(); + } + } + + @Test + public void TestInvalidAttemptWith_1UpdateCount() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.ACTIVE_STATUS); + otpEntity.setValidationRetryCount(1); + otpEntity.setOtpHash("otphash"); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + boolean result = otpManager.validateOtp("Test123", "123456", "426789089018"); + assertFalse(result); + assertEquals((long)2, (long)otpEntity.getValidationRetryCount()); + assertEquals(IdAuthCommonConstants.ACTIVE_STATUS, otpEntity.getStatusCode()); + verify(otpRepo, times(1)).save(otpEntity); + } catch (IdAuthenticationBusinessException ex) { + fail(); + } + } + + @Test + public void TestInvalidAttemptWith_4UpdateCount() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.ACTIVE_STATUS); + otpEntity.setValidationRetryCount(4); + otpEntity.setOtpHash("otphash"); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + boolean result = otpManager.validateOtp("Test123", "123456", "426789089018"); + assertFalse(result); + assertEquals((long)5, (long)otpEntity.getValidationRetryCount()); + assertEquals(IdAuthCommonConstants.FROZEN, otpEntity.getStatusCode()); + verify(otpRepo, times(1)).save(otpEntity); + } catch (IdAuthenticationBusinessException ex) { + fail(); + } + } + + @Test + public void TestInvalidAttemptWith_FrozenStatus() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.FROZEN); + otpEntity.setUpdDTimes(DateUtils.getUTCCurrentDateTime().minus(25, ChronoUnit.MINUTES)); + otpEntity.setValidationRetryCount(5); + otpEntity.setOtpHash("otphash"); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + otpManager.validateOtp("Test123", "123456", "426789089018"); + fail(); + } catch (IdAuthenticationBusinessException ex) { + assertEquals((long)5, (long)otpEntity.getValidationRetryCount()); + assertEquals(IdAuthCommonConstants.FROZEN, otpEntity.getStatusCode()); + verify(otpRepo, times(0)).save(otpEntity); + assertEquals(IdAuthenticationErrorConstants.OTP_FROZEN.getErrorCode(), ex.getErrorCode()); + assertEquals(FROZEN_ERROR_MESSAGE, ex.getErrorText()); + } + } + + @Test + public void TestInvalidAttemptWith_FrozenStatusWithin25Mins() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.FROZEN); + otpEntity.setValidationRetryCount(5); + otpEntity.setUpdDTimes(DateUtils.getUTCCurrentDateTime().minus(25, ChronoUnit.MINUTES)); + otpEntity.setOtpHash("otphash"); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + otpManager.validateOtp("Test123", "123456", "426789089018"); + fail(); + } catch (IdAuthenticationBusinessException ex) { + assertEquals((long)5, (long)otpEntity.getValidationRetryCount()); + assertEquals(IdAuthCommonConstants.FROZEN, otpEntity.getStatusCode()); + verify(otpRepo, times(0)).save(otpEntity); + assertEquals(IdAuthenticationErrorConstants.OTP_FROZEN.getErrorCode(), ex.getErrorCode()); + assertEquals(FROZEN_ERROR_MESSAGE, ex.getErrorText()); + } + } + + @Test + public void TestInvalidAttemptWith_FrozenStatusWithin29Mins() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.FROZEN); + otpEntity.setValidationRetryCount(5); + otpEntity.setUpdDTimes(DateUtils.getUTCCurrentDateTime().minus(29, ChronoUnit.MINUTES)); + otpEntity.setOtpHash("otphash"); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + otpManager.validateOtp("Test123", "123456", "426789089018"); + fail(); + } catch (IdAuthenticationBusinessException ex) { + assertEquals((long)5, (long)otpEntity.getValidationRetryCount()); + assertEquals(IdAuthCommonConstants.FROZEN, otpEntity.getStatusCode()); + verify(otpRepo, times(0)).save(otpEntity); + assertEquals(IdAuthenticationErrorConstants.OTP_FROZEN.getErrorCode(), ex.getErrorCode()); + assertEquals(FROZEN_ERROR_MESSAGE, ex.getErrorText()); + } + } + + @Test + public void TestInvalidAttemptWith_FrozenStatusWithin31Mins() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.FROZEN); + otpEntity.setValidationRetryCount(5); + otpEntity.setUpdDTimes(DateUtils.getUTCCurrentDateTime().minus(31, ChronoUnit.MINUTES)); + otpEntity.setOtpHash("otphash"); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + otpManager.validateOtp("Test123", "123456", "426789089018"); + } catch (IdAuthenticationBusinessException ex) { + assertEquals(IdAuthCommonConstants.UNFROZEN, otpEntity.getStatusCode()); + assertEquals((long)5, (long)otpEntity.getValidationRetryCount()); + verify(otpRepo, times(1)).save(otpEntity); + assertEquals(IdAuthenticationErrorConstants.OTP_REQUEST_REQUIRED.getErrorCode(), ex.getErrorCode()); + } + } + + + @Test + public void TestValidAttemptWith_nullUpdateCount() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.ACTIVE_STATUS); + otpEntity.setOtpHash("313233343536234B45595F53504C49545445522354657374313233"); + otpEntity.setExpiryDtimes(DateUtils.getUTCCurrentDateTime().plus(1, ChronoUnit.MINUTES)); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + boolean result = otpManager.validateOtp("Test123", "123456", "426789089018"); + assertTrue(result); + assertEquals(IdAuthCommonConstants.USED_STATUS, otpEntity.getStatusCode()); + verify(otpRepo, times(1)).save(otpEntity); + } catch (IdAuthenticationBusinessException ex) { + fail(); + } + } + + @Test + public void TestValidAttemptWith_1UpdateCount() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.ACTIVE_STATUS); + otpEntity.setValidationRetryCount(1); + otpEntity.setOtpHash("313233343536234B45595F53504C49545445522354657374313233"); + otpEntity.setExpiryDtimes(DateUtils.getUTCCurrentDateTime().plus(1, ChronoUnit.MINUTES)); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + boolean result = otpManager.validateOtp("Test123", "123456", "426789089018"); + assertTrue(result); + assertEquals(IdAuthCommonConstants.USED_STATUS, otpEntity.getStatusCode()); + verify(otpRepo, times(1)).save(otpEntity); + } catch (IdAuthenticationBusinessException ex) { + fail(); + } + } + + @Test + public void TestValidAttemptWith_4UpdateCount() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.ACTIVE_STATUS); + otpEntity.setValidationRetryCount(4); + otpEntity.setOtpHash("313233343536234B45595F53504C49545445522354657374313233"); + otpEntity.setExpiryDtimes(DateUtils.getUTCCurrentDateTime().plus(1, ChronoUnit.MINUTES)); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + boolean result = otpManager.validateOtp("Test123", "123456", "426789089018"); + assertTrue(result); + assertEquals(IdAuthCommonConstants.USED_STATUS, otpEntity.getStatusCode()); + verify(otpRepo, times(1)).save(otpEntity); + } catch (IdAuthenticationBusinessException ex) { + fail(); + } + } + + @Test + public void TestValidAttemptWith_FrozenStatus() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.FROZEN); + otpEntity.setUpdDTimes(DateUtils.getUTCCurrentDateTime().minus(25, ChronoUnit.MINUTES)); + otpEntity.setValidationRetryCount(5); + otpEntity.setOtpHash("313233343536234B45595F53504C49545445522354657374313233"); + otpEntity.setExpiryDtimes(DateUtils.getUTCCurrentDateTime().plus(1, ChronoUnit.MINUTES)); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + otpManager.validateOtp("Test123", "123456", "426789089018"); + fail(); + } catch (IdAuthenticationBusinessException ex) { + assertEquals((long)5, (long)otpEntity.getValidationRetryCount()); + assertEquals(IdAuthCommonConstants.FROZEN, otpEntity.getStatusCode()); + verify(otpRepo, times(0)).save(otpEntity); + assertEquals(IdAuthenticationErrorConstants.OTP_FROZEN.getErrorCode(), ex.getErrorCode()); + assertEquals(FROZEN_ERROR_MESSAGE, ex.getErrorText()); + } + } + + @Test + public void TestValidAttemptWith_FrozenStatusWithin25Mins() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.FROZEN); + otpEntity.setValidationRetryCount(5); + otpEntity.setUpdDTimes(DateUtils.getUTCCurrentDateTime().minus(25, ChronoUnit.MINUTES)); + otpEntity.setOtpHash("313233343536234B45595F53504C49545445522354657374313233"); + otpEntity.setExpiryDtimes(DateUtils.getUTCCurrentDateTime().plus(1, ChronoUnit.MINUTES)); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + otpManager.validateOtp("Test123", "123456", "426789089018"); + fail(); + } catch (IdAuthenticationBusinessException ex) { + assertEquals((long)5, (long)otpEntity.getValidationRetryCount()); + assertEquals(IdAuthCommonConstants.FROZEN, otpEntity.getStatusCode()); + verify(otpRepo, times(0)).save(otpEntity); + assertEquals(IdAuthenticationErrorConstants.OTP_FROZEN.getErrorCode(), ex.getErrorCode()); + assertEquals(FROZEN_ERROR_MESSAGE, ex.getErrorText()); + } + } + + @Test + public void TestValidAttemptWith_FrozenStatusWithin29Mins() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.FROZEN); + otpEntity.setValidationRetryCount(5); + otpEntity.setUpdDTimes(DateUtils.getUTCCurrentDateTime().minus(29, ChronoUnit.MINUTES)); + otpEntity.setOtpHash("313233343536234B45595F53504C49545445522354657374313233"); + otpEntity.setExpiryDtimes(DateUtils.getUTCCurrentDateTime().plus(1, ChronoUnit.MINUTES)); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + otpManager.validateOtp("Test123", "123456", "426789089018"); + fail(); + } catch (IdAuthenticationBusinessException ex) { + assertEquals((long)5, (long)otpEntity.getValidationRetryCount()); + assertEquals(IdAuthCommonConstants.FROZEN, otpEntity.getStatusCode()); + verify(otpRepo, times(0)).save(otpEntity); + assertEquals(IdAuthenticationErrorConstants.OTP_FROZEN.getErrorCode(), ex.getErrorCode()); + assertEquals(FROZEN_ERROR_MESSAGE, ex.getErrorText()); + } + } + + @Test + public void TestValidAttemptWith_FrozenStatusWithin31Mins() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.FROZEN); + otpEntity.setValidationRetryCount(5); + otpEntity.setUpdDTimes(DateUtils.getUTCCurrentDateTime().minus(31, ChronoUnit.MINUTES)); + otpEntity.setOtpHash("313233343536234B45595F53504C49545445522354657374313233"); + otpEntity.setExpiryDtimes(DateUtils.getUTCCurrentDateTime().plus(1, ChronoUnit.MINUTES)); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + otpManager.validateOtp("Test123", "123456", "426789089018"); + } catch (IdAuthenticationBusinessException ex) { + assertEquals(IdAuthCommonConstants.UNFROZEN, otpEntity.getStatusCode()); + assertEquals((long)5, (long)otpEntity.getValidationRetryCount()); + verify(otpRepo, times(1)).save(otpEntity); + assertEquals(IdAuthenticationErrorConstants.OTP_REQUEST_REQUIRED.getErrorCode(), ex.getErrorCode()); + } + } + + @Test + public void TestValidAttemptWith_FrozenStatusWithin31Mins_expiredOtp() + throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { + RestRequestDTO restRequestDTO = getRestRequestvalidDTO(); + Mockito.when(restRequestFactory.buildRequest(RestServicesConstants.OTP_VALIDATE_SERVICE, null, Map.class)) + .thenReturn(restRequestDTO); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.FROZEN); + otpEntity.setValidationRetryCount(5); + otpEntity.setUpdDTimes(DateUtils.getUTCCurrentDateTime().minus(31, ChronoUnit.MINUTES)); + otpEntity.setOtpHash("313233343536234B45595F53504C49545445522354657374313233"); + otpEntity.setExpiryDtimes(DateUtils.getUTCCurrentDateTime().minus(1, ChronoUnit.MINUTES)); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + + try { + otpManager.validateOtp("Test123", "123456", "426789089018"); + } catch (IdAuthenticationBusinessException ex) { + assertEquals((long)5, (long)otpEntity.getValidationRetryCount()); + assertEquals(IdAuthCommonConstants.UNFROZEN, otpEntity.getStatusCode()); + verify(otpRepo, times(1)).save(otpEntity); + assertEquals(IdAuthenticationErrorConstants.OTP_REQUEST_REQUIRED.getErrorCode(), ex.getErrorCode()); + } + } + @Test public void TestThrowOtpException_UINLocked() throws RestServiceException, IdAuthUncheckedException, IdAuthenticationBusinessException { @@ -610,8 +1195,16 @@ public void TestThrowOtpException_UINLocked() Mockito.when(restHelper.requestSync(Mockito.any())).thenThrow(new RestServiceException( IdRepoErrorConstants.CLIENT_ERROR, responseMap.toString(), (Object) responseMap)); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setOtpHash("otphash"); + otpEntity.setStatusCode(IdAuthCommonConstants.ACTIVE_STATUS); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + try { - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } catch (IdAuthenticationBusinessException ex) { assertEquals(IdAuthenticationErrorConstants.BLOCKED_OTP_VALIDATE.getErrorCode(), ex.getErrorCode()); assertEquals(IdAuthenticationErrorConstants.BLOCKED_OTP_VALIDATE.getErrorMessage(), ex.getErrorText()); @@ -630,8 +1223,16 @@ public void TestThrowOtpException_OtpExpired() throws RestServiceException, IdAu responseMap.put("response", valueMap); Mockito.when(restHelper.requestSync(Mockito.any())).thenThrow(new RestServiceException( IdRepoErrorConstants.CLIENT_ERROR, responseMap.toString(), (Object) responseMap)); + + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.ACTIVE_STATUS); + otpEntity.setOtpHash("otphash"); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); + try { - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } catch (IdAuthenticationBusinessException ex) { assertEquals(IdAuthenticationErrorConstants.EXPIRED_OTP.getErrorCode(), ex.getErrorCode()); assertEquals(IdAuthenticationErrorConstants.EXPIRED_OTP.getErrorMessage(), ex.getErrorText()); @@ -651,8 +1252,14 @@ public void TestThrowOtpException_ValidationUnsuccessful() responseMap.put("response", valueMap); Mockito.when(restHelper.requestSync(Mockito.any())).thenThrow(new RestServiceException( IdRepoErrorConstants.CLIENT_ERROR, responseMap.toString(), (Object) responseMap)); + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + OtpTransaction otpEntity = new OtpTransaction(); + otpEntity.setStatusCode(IdAuthCommonConstants.ACTIVE_STATUS); + otpEntity.setOtpHash("otphash"); + + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntity )); try { - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } catch (IdAuthenticationBusinessException ex) { assertEquals(IdAuthenticationErrorConstants.INVALID_OTP.getErrorCode(), ex.getErrorCode()); assertEquals(IdAuthenticationErrorConstants.INVALID_OTP.getErrorMessage(), ex.getErrorText()); @@ -674,9 +1281,12 @@ public void TestThrowOtpException_OtpPresent_Expired() IdRepoErrorConstants.CLIENT_ERROR, responseMap.toString(), (Object) responseMap)); OtpTransaction otpEntry = new OtpTransaction(); otpEntry.setExpiryDtimes(DateUtils.getUTCCurrentDateTime().minus(1, ChronoUnit.HOURS)); - Mockito.when(otpRepo.findByOtpHashAndStatusCode(Mockito.anyString(), Mockito.anyString())).thenReturn(Optional.of(otpEntry)); + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + otpEntry.setStatusCode(IdAuthCommonConstants.ACTIVE_STATUS); + otpEntry.setOtpHash("otphash"); + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntry)); try { - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } catch (IdAuthenticationBusinessException ex) { assertEquals(IdAuthenticationErrorConstants.EXPIRED_OTP.getErrorCode(), ex.getErrorCode()); assertEquals(IdAuthenticationErrorConstants.EXPIRED_OTP.getErrorMessage(), ex.getErrorText()); @@ -698,9 +1308,12 @@ public void TestThrowOtpException_OtpPresent_NotExpired_Valid() IdRepoErrorConstants.CLIENT_ERROR, responseMap.toString(), (Object) responseMap)); OtpTransaction otpEntry = new OtpTransaction(); otpEntry.setExpiryDtimes(DateUtils.getUTCCurrentDateTime().plus(1, ChronoUnit.HOURS)); - Mockito.when(otpRepo.findByOtpHashAndStatusCode(Mockito.anyString(), Mockito.anyString())).thenReturn(Optional.of(otpEntry)); + Mockito.when(securityManager.hash(Mockito.anyString())).thenReturn("hash"); + otpEntry.setStatusCode(IdAuthCommonConstants.ACTIVE_STATUS); + otpEntry.setOtpHash("otphash"); + Mockito.when(otpRepo.findFirstByRefIdAndStatusCodeInAndGeneratedDtimesNotNullOrderByGeneratedDtimesDesc(Mockito.anyString(), Mockito.anyList())).thenReturn(Optional.of(otpEntry)); try { - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } catch (IdAuthenticationBusinessException ex) { assertEquals(IdAuthenticationErrorConstants.INVALID_OTP.getErrorCode(), ex.getErrorCode()); assertEquals(IdAuthenticationErrorConstants.INVALID_OTP.getErrorMessage(), ex.getErrorText()); @@ -721,7 +1334,7 @@ public void TestThrowOtpException_ValidationUnsuccessful_Invalid() responseMap.put("response", valueMap); Mockito.when(restHelper.requestSync(Mockito.any())).thenThrow(new RestServiceException( IdRepoErrorConstants.CLIENT_ERROR, responseMap.toString(), (Object) responseMap)); - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } @Ignore @@ -748,7 +1361,7 @@ public void TestThrowKeynotFound() throws RestServiceException, IdAuthentication responseMap.put("response", valueMap); Mockito.when(restHelper.requestSync(Mockito.any())).thenThrow(new RestServiceException( IdRepoErrorConstants.CLIENT_ERROR, responseMap.toString(), (Object) responseMap)); - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } @Ignore @@ -764,7 +1377,7 @@ public void TestthrowKeyNotFoundException() throws IdAuthenticationBusinessExcep responseMap.put("response", valueMap); Mockito.when(restHelper.requestSync(Mockito.any())).thenThrow(new RestServiceException( IdRepoErrorConstants.CLIENT_ERROR, responseMap.toString(), (Object) responseMap)); - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } @Ignore @@ -779,7 +1392,7 @@ public void TestIDDataValidationException() throws RestServiceException, IdAuthe responseMap.put("response", valueMap); Mockito.when(restHelper.requestSync(Mockito.any())).thenThrow(new RestServiceException( IdRepoErrorConstants.CLIENT_ERROR, responseMap.toString(), (Object) responseMap)); - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } @@ -833,7 +1446,7 @@ public void TestThrowOtpKeyException() throws RestServiceException, IdAuthentica valueMap.put("errors", (Object) errorList); Mockito.when(restHelper.requestSync(Mockito.any())).thenThrow(new RestServiceException( IdRepoErrorConstants.CLIENT_ERROR, new ObjectMapper().writeValueAsString(valueMap), valueMap)); - otpManager.validateOtp("Test123", "123456"); + otpManager.validateOtp("Test123", "123456", "426789089018"); } diff --git a/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/integration/ValidateOtpRequestTest.java b/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/integration/ValidateOtpRequestTest.java index 36c851c9398..d4fb660facf 100644 --- a/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/integration/ValidateOtpRequestTest.java +++ b/authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/integration/ValidateOtpRequestTest.java @@ -101,7 +101,7 @@ public void Test() throws IdAuthenticationBusinessException, RestServiceExceptio // ReflectionTestUtils.setField(otpManager, "otpvalidateresponsedto", otpvalidateresponsedto); // TODO: for validate OTP as true - assertEquals(false, otpManager.validateOtp("12345", "23232")); + assertEquals(false, otpManager.validateOtp("12345", "23232", "426789089018")); } @Test @@ -112,7 +112,7 @@ public void zTest_InvalidvalidateOTP() throws RestServiceException, IdAuthentica Mockito.when(helper.requestSync(Mockito.any(RestRequestDTO.class))).thenReturn(valuemap); ReflectionTestUtils.setField(otpManager, "restHelper", helper); - assertFalse(otpManager.validateOtp("2323", "2323")); + assertFalse(otpManager.validateOtp("2323", "2323", "426789089018")); } } \ No newline at end of file diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthCommonConstants.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthCommonConstants.java index 5075a446a6f..96ec2319a51 100644 --- a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthCommonConstants.java +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthCommonConstants.java @@ -248,6 +248,10 @@ public final class IdAuthCommonConstants { /** The Constant USED_STATUS. */ public static final String USED_STATUS = "used"; + + public static final String FROZEN = "frozen"; + + public static final String UNFROZEN = "unfrozen"; /** The Constant EXPIRY_DT. */ public static final String EXPIRY_DT = "expiryDt"; diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthConfigKeyConstants.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthConfigKeyConstants.java index 192e72c874e..d3aaebbef02 100644 --- a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthConfigKeyConstants.java +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthConfigKeyConstants.java @@ -136,6 +136,7 @@ private IdAuthConfigKeyConstants() { public static final String AUTH_FRAUD_ANALYSIS_TOPIC = "ida-topic-fraud-analysis"; public static final String ON_DEMAND_TEMPLATE_EXTRACTION_TOPIC = "ida-topic-on-demand-template-extraction"; + public static final String IDA_MAX_CREDENTIAL_PULL_WINDOW_DAYS = "ida-max-credential-pull-window-days"; public static final String IDA_MAX_WEBSUB_MSG_PULL_WINDOW_DAYS = "ida-max-websub-messages-pull-window-days"; diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthenticationErrorConstants.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthenticationErrorConstants.java index a0e88ddf7a2..a34ed44f30c 100644 --- a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthenticationErrorConstants.java +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthenticationErrorConstants.java @@ -30,7 +30,9 @@ public enum IdAuthenticationErrorConstants { OTP_CHANNEL_NOT_CONFIGURED("IDA-OTA-009", "%s not configured for the country"), OTP_AUTH_IDTYPE_MISMATCH("IDA-OTA-010", "Input Identity Type does not match Identity Type of OTP Request"), PARTNER_ID_MISMATCH("IDA-OTA-011", "Input Partner-ID does not match Partner-ID of OTP Request"), - + OTP_REQUEST_REQUIRED("IDA-OTA-012", "OTP validation can't be performed against this Individual-ID. Generate OTP first."), + OTP_FROZEN("IDA-OTA-013", + "OTP request/validation has been frozen for the Individual-ID for %s due to consecutive failure attempts for %s times."), INVALID_TIMESTAMP("IDA-MLC-001", "Request to be received at MOSIP within %s seconds", "Please send the request within %s seconds"), @@ -65,7 +67,7 @@ public enum IdAuthenticationErrorConstants { "Please capture biometrics within %s seconds of previous biometric capture"), INVALID_BIO_DIGITALID_TIMESTAMP("IDA-MLC-031", "DigitalId of Biometrics not captured within %s seconds of previous biometrics", "Please capture DigitalId of biometrics within %s seconds of previous biometric capture"), - + DEMOGRAPHIC_DATA_MISMATCH_LANG("IDA-DEA-001", "Demographic data %s in %s did not match", "Please re-enter your %s in %s"), DEMO_DATA_MISMATCH("IDA-DEA-001", "Demographic data %s did not match", "Please re-enter your %s"), @@ -207,8 +209,9 @@ public enum IdAuthenticationErrorConstants { PUBLIC_KEY_BINDING_NOT_ALLOWED("IDA-IKB-003", "Publick Key already Binded to another Id."), IDENTITY_NAME_NOT_FOUND("IDA-IKB-004", "Identity Name not found."), CREATE_CERTIFICATE_OBJECT_ERROR("IDA-IKB-005", "Error creating Certificate object."), + TOKEN_AUTH_IDTYPE_MISMATCH("IDA-TOA-001", "Input Identity Type does not match Identity Type of Token Request"), - + KEY_TYPE_NOT_SUPPORT("IDA-VCI-001", "Not Supported JWK Key Type."), CREATE_VCI_PUBLIC_KEY_OBJECT_ERROR("IDA-VCI-002", "Error creating Public Key object."), KEY_ALREADY_MAPPED_ERROR("IDA-VCI-003", "Error Key already mapped to different id/vid."), diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/match/MatchType.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/match/MatchType.java index 81f8bbe8d52..1965b389880 100644 --- a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/match/MatchType.java +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/match/MatchType.java @@ -17,6 +17,7 @@ import io.mosip.authentication.core.exception.IdAuthenticationBusinessException; import io.mosip.authentication.core.indauth.dto.AuthRequestDTO; import io.mosip.authentication.core.indauth.dto.IdentityInfoDTO; +import io.mosip.authentication.core.indauth.dto.KycAuthRequestDTO; import io.mosip.authentication.core.indauth.dto.RequestDTO; /** diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/match/ValidateOtpFunction.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/match/ValidateOtpFunction.java index 2661afe2469..b5c2b9ee379 100644 --- a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/match/ValidateOtpFunction.java +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/match/ValidateOtpFunction.java @@ -17,6 +17,6 @@ public interface ValidateOtpFunction { * @return true, if successful * @throws IdAuthenticationBusinessException the id authentication business exception */ - public boolean validateOtp(String otpValue, String otpKey) throws IdAuthenticationBusinessException; + public boolean validateOtp(String otpValue, String otpKey, String individualId) throws IdAuthenticationBusinessException; } diff --git a/db_scripts/mosip_ida/ddl/ida-otp_transaction.sql b/db_scripts/mosip_ida/ddl/ida-otp_transaction.sql index 8dc9662eb95..b8bd882b92f 100644 --- a/db_scripts/mosip_ida/ddl/ida-otp_transaction.sql +++ b/db_scripts/mosip_ida/ddl/ida-otp_transaction.sql @@ -32,7 +32,7 @@ CREATE TABLE ida.otp_transaction( ); -- ddl-end -- --index section starts---- -CREATE INDEX ind_otphsh ON ida.otp_transaction (otp_hash,status_code); +CREATE INDEX ind_refid ON ida.otp_transaction (ref_id,status_code); --index section ends------ COMMENT ON TABLE ida.otp_transaction IS 'OTP Transaction: All OTP related data and validation details are maintained here for ID Authentication module.'; -- ddl-end -- diff --git a/db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B5_to_1.2.0.1_rollback.sql b/db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B5_to_1.2.0.1_rollback.sql index 1ea8a6e97f2..37b4fb58b16 100644 --- a/db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B5_to_1.2.0.1_rollback.sql +++ b/db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B5_to_1.2.0.1_rollback.sql @@ -1,3 +1,8 @@ \echo 'Upgrade Queries not required for the transition from 1.2.0.1-B5 to 1.2.0.1' ALTER TABLE ida.credential_event_store ALTER COLUMN credential_transaction_id type character varying(36); + +CREATE INDEX ind_otphsh ON ida.otp_transaction (otp_hash,status_code); + +DROP INDEX IF EXISTS ida.ind_refid; + diff --git a/db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B5_to_1.2.0.1_upgrade.sql b/db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B5_to_1.2.0.1_upgrade.sql index 36efab138ca..39f231307f5 100644 --- a/db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B5_to_1.2.0.1_upgrade.sql +++ b/db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B5_to_1.2.0.1_upgrade.sql @@ -1,3 +1,8 @@ \echo 'Upgrade Queries not required for transition from 1.2.0.1-B5 to 1.2.0.1' ALTER TABLE ida.credential_event_store ALTER COLUMN credential_transaction_id type character varying(64); + +DROP INDEX IF EXISTS ida.ind_otphsh; + +CREATE INDEX ind_refid ON ida.otp_transaction (ref_id,status_code); +