diff --git a/core/platform-common/src/main/java/org/sunbird/keys/JsonKey.java b/core/platform-common/src/main/java/org/sunbird/keys/JsonKey.java index 26e14eeefc0e7c766f2d82d8ed9a04a76bf560c6..dea1914b83e902c7770a9424dca07b5c03af3ec4 100644 --- a/core/platform-common/src/main/java/org/sunbird/keys/JsonKey.java +++ b/core/platform-common/src/main/java/org/sunbird/keys/JsonKey.java @@ -636,6 +636,7 @@ public final class JsonKey { public static final String ROLE_OPERATION = "roleOperation"; public static final String SCOPE_STR = "scopeString"; public static final String SUNBIRD_SSO_LB_IP = "sunbird_sso_lb_ip"; + public static final String RESET_PASSWORD = "resetPassword"; private JsonKey() {} } diff --git a/service/src/main/java/org/sunbird/actor/otp/OTPActor.java b/service/src/main/java/org/sunbird/actor/otp/OTPActor.java index 8190b366659d122cbe0206fdbbf7c21743bd946c..ad62a357541a18e4801880a7c21dd101ad6136bd 100644 --- a/service/src/main/java/org/sunbird/actor/otp/OTPActor.java +++ b/service/src/main/java/org/sunbird/actor/otp/OTPActor.java @@ -19,7 +19,7 @@ import org.sunbird.service.otp.OTPService; import org.sunbird.service.ratelimit.RateLimitService; import org.sunbird.service.ratelimit.RateLimitServiceImpl; import org.sunbird.telemetry.dto.TelemetryEnvKey; -import org.sunbird.util.OTPUtil; +import org.sunbird.util.otp.OTPUtil; import org.sunbird.util.ProjectUtil; import org.sunbird.util.Util; import org.sunbird.util.ratelimit.OtpRateLimiter; @@ -51,31 +51,18 @@ public class OTPActor extends BaseActor { } } - private String maskOTP(String otp) { - return logMaskService.maskOTP(otp); - } - - private String maskId(String id, String type) { - if (JsonKey.EMAIL.equalsIgnoreCase(type)) { - return logMaskService.maskEmail(id); - } else if (JsonKey.PHONE.equalsIgnoreCase(type)) { - return logMaskService.maskPhone(id); - } - return ""; - } - private void generateOTP(Request request) { - logger.info(request.getRequestContext(), "OTPActor:generateOTP method call start."); + logger.debug(request.getRequestContext(), "OTPActor:generateOTP method call start."); String type = (String) request.getRequest().get(JsonKey.TYPE); - String key = getKey(type, request); + String key = (String) request.getRequest().get(JsonKey.KEY); String userId = (String) request.getRequest().get(JsonKey.USER_ID); if (StringUtils.isNotBlank(userId)) { - key = OTPUtil.getEmailPhoneByUserId(userId, type, request.getRequestContext()); + key = otpService.getEmailPhoneByUserId(userId, type, request.getRequestContext()); type = getType(type); logger.info( request.getRequestContext(), - "OTPActor:OTPUtil.getEmailPhoneByUserId: called for userId = " + "OTPActor:generateOTP:getEmailPhoneByUserId: called for userId = " + userId + " ,key = " + maskId(key, type)); @@ -86,25 +73,25 @@ public class OTPActor extends BaseActor { new RateLimiter[] {OtpRateLimiter.HOUR, OtpRateLimiter.DAY}, request.getRequestContext()); - String otp = null; + String otp; Map<String, Object> details = otpService.getOTPDetails(type, key, request.getRequestContext()); if (MapUtils.isEmpty(details)) { - otp = OTPUtil.generateOtp(request.getRequestContext()); + otp = OTPUtil.generateOTP(request.getRequestContext()); logger.info( request.getRequestContext(), - "OTPActor:generateOTP: inserting otp Key = " + "OTPActor:generateOTP: new otp generated for Key = " + maskId(key, type) - + " OTP = " + + " & OTP = " + maskOTP(otp)); otpService.insertOTPDetails(type, key, otp, request.getRequestContext()); } else { otp = (String) details.get(JsonKey.OTP); logger.info( request.getRequestContext(), - "OTPActor:generateOTP: Re-issuing otp Key = " + "OTPActor:generateOTP: Re-issuing otp for Key = " + maskId(key, type) - + " OTP = " + + " & OTP = " + maskOTP(otp)); } logger.info( @@ -117,34 +104,21 @@ public class OTPActor extends BaseActor { sender().tell(response, self()); } - private String getType(String type) { - switch (type) { - case JsonKey.PREV_USED_EMAIL: - return JsonKey.EMAIL; - case JsonKey.PREV_USED_PHONE: - return JsonKey.PHONE; - case JsonKey.EMAIL: - return JsonKey.EMAIL; - case JsonKey.PHONE: - return JsonKey.PHONE; - case JsonKey.RECOVERY_EMAIL: - return JsonKey.EMAIL; - case JsonKey.RECOVERY_PHONE: - return JsonKey.PHONE; - default: - return null; - } - } - private void verifyOTP(Request request) { String type = (String) request.getRequest().get(JsonKey.TYPE); - String key = getKey(type, request); + String key = (String) request.getRequest().get(JsonKey.KEY); String otpInRequest = (String) request.getRequest().get(JsonKey.OTP); String userId = (String) request.getRequest().get(JsonKey.USER_ID); if (StringUtils.isNotBlank(userId)) { - key = OTPUtil.getEmailPhoneByUserId(userId, type, request.getRequestContext()); + key = otpService.getEmailPhoneByUserId(userId, type, request.getRequestContext()); type = getType(type); + logger.info( + request.getRequestContext(), + "OTPActor:verifyOTP:getEmailPhoneByUserId: called for userId = " + + userId + + " ,key = " + + maskId(key, type)); } Map<String, Object> otpDetails = otpService.getOTPDetails(type, key, request.getRequestContext()); @@ -243,11 +217,31 @@ public class OTPActor extends BaseActor { tellToAnother(sendOtpRequest); } - private String getKey(String type, Request request) { - String key = (String) request.getRequest().get(JsonKey.KEY); - if (JsonKey.EMAIL.equalsIgnoreCase(type) && key != null) { - return key.toLowerCase(); + private String getType(String type) { + switch (type) { + case JsonKey.PREV_USED_EMAIL: + case JsonKey.RECOVERY_EMAIL: + case JsonKey.EMAIL: + return JsonKey.EMAIL; + case JsonKey.PREV_USED_PHONE: + case JsonKey.RECOVERY_PHONE: + case JsonKey.PHONE: + return JsonKey.PHONE; + default: + return null; } - return key; + } + + private String maskOTP(String otp) { + return logMaskService.maskOTP(otp); + } + + private String maskId(String id, String type) { + if (JsonKey.EMAIL.equalsIgnoreCase(type)) { + return logMaskService.maskEmail(id); + } else if (JsonKey.PHONE.equalsIgnoreCase(type)) { + return logMaskService.maskPhone(id); + } + return ""; } } diff --git a/service/src/main/java/org/sunbird/actor/otp/SendOTPActor.java b/service/src/main/java/org/sunbird/actor/otp/SendOTPActor.java index 83d4d3f8e3838c4093167cfb69049bfc0808863a..6890e93e6c206ecd0b51e3d09cad9e0224bbd998 100644 --- a/service/src/main/java/org/sunbird/actor/otp/SendOTPActor.java +++ b/service/src/main/java/org/sunbird/actor/otp/SendOTPActor.java @@ -11,7 +11,7 @@ import org.sunbird.operations.ActorOperations; import org.sunbird.request.Request; import org.sunbird.request.RequestContext; import org.sunbird.response.Response; -import org.sunbird.util.OTPUtil; +import org.sunbird.util.otp.OTPUtil; @ActorConfig( tasks = {}, @@ -19,7 +19,6 @@ import org.sunbird.util.OTPUtil; dispatcher = "notification-dispatcher" ) public class SendOTPActor extends BaseActor { - public static final String RESET_PASSWORD = "resetPassword"; private LogMaskServiceImpl logMaskService = new LogMaskServiceImpl(); @Override @@ -69,16 +68,16 @@ public class SendOTPActor extends BaseActor { emailTemplateMap.put(JsonKey.OTP, otp); emailTemplateMap.put(JsonKey.OTP_EXPIRATION_IN_MINUTES, OTPUtil.getOTPExpirationInMinutes()); emailTemplateMap.put(JsonKey.TEMPLATE_ID, template); - Request emailRequest = null; + Request emailRequest; if (StringUtils.isBlank(otpType)) { - emailRequest = OTPUtil.sendOTPViaEmail(emailTemplateMap, context); + emailRequest = OTPUtil.getRequestToSendOTPViaEmail(emailTemplateMap, context); } else { - emailRequest = OTPUtil.sendOTPViaEmail(emailTemplateMap, RESET_PASSWORD, context); + emailRequest = OTPUtil.getRequestToSendOTPViaEmail(emailTemplateMap, JsonKey.RESET_PASSWORD, context); } emailRequest.setRequestContext(context); logger.info( context, - "SendOTPActor:sendOTP : Calling EmailServiceActor for Key = " + "SendOTPActor:sendOTPViaEmail : Calling EmailServiceActor for Key = " + logMaskService.maskEmail(key)); tellToAnother(emailRequest); } diff --git a/service/src/main/java/org/sunbird/dao/otp/impl/OTPDaoImpl.java b/service/src/main/java/org/sunbird/dao/otp/impl/OTPDaoImpl.java index cbecf0bedf9c78af56c0771314862c2f363582d2..58a52405cada55696a6971c6672128e698004159 100644 --- a/service/src/main/java/org/sunbird/dao/otp/impl/OTPDaoImpl.java +++ b/service/src/main/java/org/sunbird/dao/otp/impl/OTPDaoImpl.java @@ -75,7 +75,7 @@ public class OTPDaoImpl implements OTPDao { compositeKeyMap.put(JsonKey.TYPE, type); compositeKeyMap.put(JsonKey.KEY, key); cassandraOperation.deleteRecord(JsonKey.SUNBIRD, TABLE_NAME, compositeKeyMap, context); - logger.info(context, "OTPDaoImpl:deleteOtp:otp deleted"); + logger.debug(context, "OTPDaoImpl:deleteOtp:otp deleted"); } @Override diff --git a/service/src/main/java/org/sunbird/dao/ratelimit/RateLimitDaoImpl.java b/service/src/main/java/org/sunbird/dao/ratelimit/RateLimitDaoImpl.java index ba3c241624440a377a5e6845fbbc77e8219a3dce..f16327696aa749c52d3ae3883af31531535ca160 100644 --- a/service/src/main/java/org/sunbird/dao/ratelimit/RateLimitDaoImpl.java +++ b/service/src/main/java/org/sunbird/dao/ratelimit/RateLimitDaoImpl.java @@ -36,12 +36,12 @@ public class RateLimitDaoImpl implements RateLimitDao { if (CollectionUtils.isEmpty(rateLimits)) { return; } - List<Integer> ttls = + List<Integer> ttl = rateLimits.stream().map(rateLimit -> rateLimit.getTTL()).collect(Collectors.toList()); List<Map<String, Object>> records = rateLimits.stream().map(rateLimit -> rateLimit.getRecord()).collect(Collectors.toList()); - cassandraOperation.batchInsertWithTTL(Util.KEY_SPACE_NAME, TABLE_NAME, records, ttls, context); + cassandraOperation.batchInsertWithTTL(Util.KEY_SPACE_NAME, TABLE_NAME, records, ttl, context); } @Override diff --git a/service/src/main/java/org/sunbird/service/otp/OTPService.java b/service/src/main/java/org/sunbird/service/otp/OTPService.java index 1d722f98e99c4a5622918128d0a943a8cae28873..ea0a68aaa920536df3e1f4ba929d95b25d37d980 100644 --- a/service/src/main/java/org/sunbird/service/otp/OTPService.java +++ b/service/src/main/java/org/sunbird/service/otp/OTPService.java @@ -2,6 +2,8 @@ package org.sunbird.service.otp; import java.io.StringWriter; import java.util.Map; + +import org.apache.commons.lang3.StringUtils; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.runtime.RuntimeServices; @@ -11,20 +13,22 @@ import org.sunbird.dao.notification.EmailTemplateDao; import org.sunbird.dao.notification.impl.EmailTemplateDaoImpl; import org.sunbird.dao.otp.OTPDao; import org.sunbird.dao.otp.impl.OTPDaoImpl; +import org.sunbird.datasecurity.DecryptionService; +import org.sunbird.exception.ProjectCommonException; +import org.sunbird.exception.ResponseCode; import org.sunbird.keys.JsonKey; import org.sunbird.logging.LoggerUtil; import org.sunbird.request.RequestContext; +import org.sunbird.service.user.UserService; +import org.sunbird.service.user.impl.UserServiceImpl; import org.sunbird.util.ProjectUtil; public class OTPService { private static LoggerUtil logger = new LoggerUtil(OTPService.class); - private static OTPDao otpDao = OTPDaoImpl.getInstance(); - private static EmailTemplateDao emailTemplateDao = EmailTemplateDaoImpl.getInstance(); - - public static String getOTPSMSTemplate(String templateName, RequestContext context) { - return emailTemplateDao.getTemplate(templateName, context); - } + private OTPDao otpDao = OTPDaoImpl.getInstance(); + private EmailTemplateDao emailTemplateDao = EmailTemplateDaoImpl.getInstance(); + private UserService userService = UserServiceImpl.getInstance(); public Map<String, Object> getOTPDetails(String type, String key, RequestContext context) { return otpDao.getOTPDetails(type, key, context); @@ -38,10 +42,21 @@ public class OTPService { otpDao.deleteOtp(type, key, context); } - public static String getSmsBody( + /** + * This method will return either email or phone value of user based on the asked type in request + * + * @param userId + * @param type value can be email, phone, recoveryEmail, recoveryPhone , prevUsedEmail or prevUsedPhone + * @return + */ + public String getEmailPhoneByUserId(String userId, String type, RequestContext context) { + return userService.getDecryptedEmailPhoneByUserId(userId, type, context); + } + + public String getSmsBody( String templateFile, Map<String, String> smsTemplate, RequestContext requestContext) { try { - String sms = getOTPSMSTemplate(templateFile, requestContext); + String sms = emailTemplateDao.getTemplate(templateFile, requestContext); RuntimeServices rs = RuntimeSingleton.getRuntimeServices(); SimpleNode sn = rs.parse(sms, "Sms Information"); Template t = new Template(); diff --git a/service/src/main/java/org/sunbird/service/ratelimit/RateLimitServiceImpl.java b/service/src/main/java/org/sunbird/service/ratelimit/RateLimitServiceImpl.java index 7acfaa0b5f676df9b786c4323f24dcd2a2e2e116..fb681a8f6d8408c2a677d77226a8e6f7672f3054 100644 --- a/service/src/main/java/org/sunbird/service/ratelimit/RateLimitServiceImpl.java +++ b/service/src/main/java/org/sunbird/service/ratelimit/RateLimitServiceImpl.java @@ -43,7 +43,7 @@ public class RateLimitServiceImpl implements RateLimitService { .stream() .forEach( rate -> { - if (!MapUtils.isEmpty(rate)) { + if (MapUtils.isNotEmpty(rate)) { logger.info( context, "RateLimitServiceImpl:throttleByKey: key = " + key + " rate =" + rate); diff --git a/service/src/main/java/org/sunbird/service/user/UserService.java b/service/src/main/java/org/sunbird/service/user/UserService.java index af7ef309a5869511b545984f547016d3d1fdc7de..c3574c0d25f046ca23ec004807787bbd10481071 100644 --- a/service/src/main/java/org/sunbird/service/user/UserService.java +++ b/service/src/main/java/org/sunbird/service/user/UserService.java @@ -47,4 +47,6 @@ public interface UserService { Response saveUserAttributes( Map<String, Object> userMap, ActorRef actorRef, RequestContext context); + + String getDecryptedEmailPhoneByUserId(String userId, String type, RequestContext context); } diff --git a/service/src/main/java/org/sunbird/service/user/impl/UserServiceImpl.java b/service/src/main/java/org/sunbird/service/user/impl/UserServiceImpl.java index 3003269f749c15861c1d0c3d15effb8b77a508dd..358fcb3f1c63456c4caeca81f67b35b125e1aacf 100644 --- a/service/src/main/java/org/sunbird/service/user/impl/UserServiceImpl.java +++ b/service/src/main/java/org/sunbird/service/user/impl/UserServiceImpl.java @@ -24,6 +24,7 @@ import org.sunbird.dao.user.UserDao; import org.sunbird.dao.user.UserLookupDao; import org.sunbird.dao.user.impl.UserDaoImpl; import org.sunbird.dao.user.impl.UserLookupDaoImpl; +import org.sunbird.datasecurity.DecryptionService; import org.sunbird.datasecurity.EncryptionService; import org.sunbird.dto.SearchDTO; import org.sunbird.exception.ProjectCommonException; @@ -431,4 +432,28 @@ public class UserServiceImpl implements UserService { } return null; } + + /** + * This method will return either email or phone value of user based on the asked type in request + * + * @param userId + * @param type value can be email, phone, recoveryEmail, recoveryPhone , prevUsedEmail or prevUsedPhone + * @return + */ + public String getDecryptedEmailPhoneByUserId(String userId, String type, RequestContext context) { + Map<String, Object> user = userDao.getUserDetailsById(userId, context); + if (MapUtils.isEmpty(user)) { + throw new ProjectCommonException( + ResponseCode.userNotFound.getErrorCode(), + ResponseCode.userNotFound.getErrorMessage(), + ResponseCode.RESOURCE_NOT_FOUND.getResponseCode()); + } + DecryptionService decService = + org.sunbird.datasecurity.impl.ServiceFactory.getDecryptionServiceInstance(null); + String emailPhone = decService.decryptData((String) user.get(type), context); + if (StringUtils.isBlank(emailPhone)) { + ProjectCommonException.throwClientErrorException(ResponseCode.invalidRequestData); + } + return emailPhone; + } } diff --git a/service/src/main/java/org/sunbird/util/OTPUtil.java b/service/src/main/java/org/sunbird/util/otp/OTPUtil.java similarity index 70% rename from service/src/main/java/org/sunbird/util/OTPUtil.java rename to service/src/main/java/org/sunbird/util/otp/OTPUtil.java index 1efe2f892ab7f29f1604eb23c1ad05962c96bc69..fd32d008d80c6b41d3bc816316414755ef91b664 100644 --- a/service/src/main/java/org/sunbird/util/OTPUtil.java +++ b/service/src/main/java/org/sunbird/util/otp/OTPUtil.java @@ -1,4 +1,4 @@ -package org.sunbird.util; +package org.sunbird.util.otp; import com.warrenstrange.googleauth.GoogleAuthenticator; import com.warrenstrange.googleauth.GoogleAuthenticatorConfig; @@ -8,30 +8,21 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.apache.commons.collections.CollectionUtils; + import org.apache.commons.lang3.StringUtils; import org.sunbird.actor.BackgroundOperations; -import org.sunbird.cassandra.CassandraOperation; -import org.sunbird.datasecurity.DecryptionService; -import org.sunbird.exception.ProjectCommonException; -import org.sunbird.exception.ResponseCode; -import org.sunbird.helper.ServiceFactory; import org.sunbird.keys.JsonKey; import org.sunbird.logging.LoggerUtil; import org.sunbird.notification.sms.provider.ISmsProvider; import org.sunbird.notification.utils.SMSFactory; import org.sunbird.request.Request; import org.sunbird.request.RequestContext; -import org.sunbird.response.Response; import org.sunbird.service.otp.OTPService; +import org.sunbird.util.ProjectUtil; public final class OTPUtil { private static LoggerUtil logger = new LoggerUtil(OTPUtil.class); - - private static CassandraOperation cassandraOperation = ServiceFactory.getInstance(); - private static DecryptionService decService = - org.sunbird.datasecurity.impl.ServiceFactory.getDecryptionServiceInstance(null); - + private static OTPService otpService = new OTPService(); private static final int MAXIMUM_OTP_LENGTH = 6; private static final int SECONDS_IN_MINUTES = 60; private static final int RETRY_COUNT = 2; @@ -39,38 +30,38 @@ public final class OTPUtil { private OTPUtil() {} - private static String generateOTP() { - String otpSize = ProjectUtil.getConfigValue(JsonKey.SUNBIRD_OTP_LENGTH); - int codeDigits = StringUtils.isBlank(otpSize) ? MAXIMUM_OTP_LENGTH : Integer.valueOf(otpSize); - GoogleAuthenticatorConfig config = - new GoogleAuthenticatorConfig.GoogleAuthenticatorConfigBuilder() - .setCodeDigits(codeDigits) - .setKeyRepresentation(KeyRepresentation.BASE64) - .build(); - GoogleAuthenticator gAuth = new GoogleAuthenticator(config); - GoogleAuthenticatorKey key = gAuth.createCredentials(); - String secret = key.getKey(); - int code = gAuth.getTotpPassword(secret); - return String.valueOf(code); - } - /** * generates otp and ensures otp length is greater than or equal to 4 if otp length is less than 4 * , regenerate otp (max retry 3) * * @return */ - public static String generateOtp(RequestContext context) { + public static String generateOTP(RequestContext context) { String otp = generateOTP(); int noOfAttempts = 0; while (otp.length() < MIN_OTP_LENGTH && noOfAttempts < RETRY_COUNT) { otp = generateOTP(); noOfAttempts++; } - logger.info(context, "OTPUtil: generateOtp: otp generated in " + noOfAttempts + " attempts"); + logger.info(context, "OTPUtil: generateOTP: otp generated in " + noOfAttempts + " attempts"); return ensureOtpLength(otp); } + private static String generateOTP() { + String otpSize = ProjectUtil.getConfigValue(JsonKey.SUNBIRD_OTP_LENGTH); + int codeDigits = StringUtils.isBlank(otpSize) ? MAXIMUM_OTP_LENGTH : Integer.valueOf(otpSize); + GoogleAuthenticatorConfig config = + new GoogleAuthenticatorConfig.GoogleAuthenticatorConfigBuilder() + .setCodeDigits(codeDigits) + .setKeyRepresentation(KeyRepresentation.BASE64) + .build(); + GoogleAuthenticator gAuth = new GoogleAuthenticator(config); + GoogleAuthenticatorKey key = gAuth.createCredentials(); + String secret = key.getKey(); + int code = gAuth.getTotpPassword(secret); + return String.valueOf(code); + } + /** * After 3 attempts, still otp length less that 4 multiply otp with 1000, * @@ -79,17 +70,16 @@ public final class OTPUtil { */ private static String ensureOtpLength(String otp) { if (otp.length() < MIN_OTP_LENGTH) { - int multiplier = (int) Math.pow(10, MAXIMUM_OTP_LENGTH - MIN_OTP_LENGTH + 1); + int multiplier = (int) Math.pow(10, MAXIMUM_OTP_LENGTH - MIN_OTP_LENGTH + 1.0); otp = String.valueOf(Integer.valueOf(otp) * multiplier); } return otp; } - public static void sendOTPViaSMS(Map<String, Object> otpMap, RequestContext context) { + public static boolean sendOTPViaSMS(Map<String, Object> otpMap, RequestContext context) { if (StringUtils.isBlank((String) otpMap.get(JsonKey.PHONE))) { - return; + return false; } - Map<String, String> smsTemplate = new HashMap<>(); String template = (String) otpMap.get(JsonKey.TEMPLATE_ID); smsTemplate.put(JsonKey.OTP, (String) otpMap.get(JsonKey.OTP)); @@ -98,18 +88,18 @@ public final class OTPUtil { smsTemplate.put( JsonKey.INSTALLATION_NAME, ProjectUtil.getConfigValue(JsonKey.SUNBIRD_INSTALLATION_DISPLAY_NAME)); - String sms = null; + String sms; if (StringUtils.isBlank(template)) { - sms = OTPService.getSmsBody(JsonKey.VERIFY_PHONE_OTP_TEMPLATE, smsTemplate, context); + sms = otpService.getSmsBody(JsonKey.VERIFY_PHONE_OTP_TEMPLATE, smsTemplate, context); } else if (StringUtils.isNotBlank(template) && StringUtils.equals(template, JsonKey.WARD_LOGIN_OTP_TEMPLATE_ID)) { - sms = OTPService.getSmsBody(JsonKey.OTP_PHONE_WARD_LOGIN_TEMPLATE, smsTemplate, context); + sms = otpService.getSmsBody(JsonKey.OTP_PHONE_WARD_LOGIN_TEMPLATE, smsTemplate, context); } else { - sms = OTPService.getSmsBody(JsonKey.OTP_PHONE_RESET_PASSWORD_TEMPLATE, smsTemplate, context); + sms = otpService.getSmsBody(JsonKey.OTP_PHONE_RESET_PASSWORD_TEMPLATE, smsTemplate, context); } - logger.info(context, "OTPUtil:sendOTPViaSMS: SMS text = " + sms); + logger.debug(context, "OTPUtil:sendOTPViaSMS: SMS text = " + sms); - String countryCode = ""; + String countryCode; if (StringUtils.isBlank((String) otpMap.get(JsonKey.COUNTRY_CODE))) { countryCode = ProjectUtil.getConfigValue(JsonKey.SUNBIRD_DEFAULT_COUNTRY_CODE); } else { @@ -117,12 +107,12 @@ public final class OTPUtil { } ISmsProvider smsProvider = SMSFactory.getInstance(); - logger.info( + logger.debug( context, "OTPUtil:sendOTPViaSMS: SMS OTP text = " + sms + " with phone = " - + (String) otpMap.get(JsonKey.PHONE)); + + otpMap.get(JsonKey.PHONE)); boolean response = smsProvider.send((String) otpMap.get(JsonKey.PHONE), countryCode, sms); @@ -132,35 +122,10 @@ public final class OTPUtil { + otpMap.get(JsonKey.PHONE) + "is " + response); + return response; } - /** - * This method will return either email or phone value of user based on the asked type in request - * - * @param userId - * @param type value can be email, phone, prevUsedEmail or prevUsedPhone - * @return - */ - public static String getEmailPhoneByUserId(String userId, String type, RequestContext context) { - Util.DbInfo usrDbInfo = Util.dbInfoMap.get(JsonKey.USER_DB); - Response response = - cassandraOperation.getRecordById( - usrDbInfo.getKeySpace(), usrDbInfo.getTableName(), userId, context); - List<Map<String, Object>> userList = (List<Map<String, Object>>) response.get(JsonKey.RESPONSE); - if (CollectionUtils.isNotEmpty(userList)) { - Map<String, Object> user = userList.get(0); - String emailPhone = decService.decryptData((String) user.get(type), context); - if (StringUtils.isBlank(emailPhone)) { - ProjectCommonException.throwClientErrorException(ResponseCode.invalidRequestData); - } - return emailPhone; - } else { - ProjectCommonException.throwClientErrorException(ResponseCode.userNotFound); - } - return null; - } - - public static Request sendOTPViaEmail( + public static Request getRequestToSendOTPViaEmail( Map<String, Object> emailTemplateMap, String otpType, RequestContext context) { Request request = null; if ((StringUtils.isBlank((String) emailTemplateMap.get(JsonKey.EMAIL)))) { @@ -168,7 +133,7 @@ public final class OTPUtil { } String envName = ProjectUtil.getConfigValue(JsonKey.SUNBIRD_INSTALLATION_DISPLAY_NAME); String emailSubject = null; - if ("resetPassword".equalsIgnoreCase(otpType)) { + if (JsonKey.RESET_PASSWORD.equalsIgnoreCase(otpType)) { emailSubject = ProjectUtil.getConfigValue(JsonKey.SUNBIRD_RESET_PASS_MAIL_SUBJECT); } else { // default fallback for all other otpType @@ -197,14 +162,14 @@ public final class OTPUtil { return request; } - public static Request sendOTPViaEmail( + public static Request getRequestToSendOTPViaEmail( Map<String, Object> emailTemplateMap, RequestContext context) { - return sendOTPViaEmail(emailTemplateMap, null, context); + return getRequestToSendOTPViaEmail(emailTemplateMap, null, context); } public static String getOTPExpirationInMinutes() { String expirationInSeconds = ProjectUtil.getConfigValue(JsonKey.SUNBIRD_OTP_EXPIRATION); - int otpExpiration = Integer.valueOf(expirationInSeconds); + int otpExpiration = Integer.parseInt(expirationInSeconds); int otpExpirationInMinutes = Math.floorDiv(otpExpiration, SECONDS_IN_MINUTES); return String.valueOf(otpExpirationInMinutes); } diff --git a/service/src/test/java/org/sunbird/actor/otp/OTPActorTest.java b/service/src/test/java/org/sunbird/actor/otp/OTPActorTest.java index 7d342b65ec567517860bbdb879a5bd98a613a5d8..d413ad64e11c9e776b9276607d043d5c50458b63 100644 --- a/service/src/test/java/org/sunbird/actor/otp/OTPActorTest.java +++ b/service/src/test/java/org/sunbird/actor/otp/OTPActorTest.java @@ -32,11 +32,14 @@ import org.sunbird.helper.ServiceFactory; import org.sunbird.keys.JsonKey; import org.sunbird.operations.ActorOperations; import org.sunbird.request.Request; +import org.sunbird.request.RequestContext; import org.sunbird.response.ClientErrorResponse; import org.sunbird.response.Response; import org.sunbird.service.otp.OTPService; import org.sunbird.service.ratelimit.RateLimitService; import org.sunbird.service.ratelimit.RateLimitServiceImpl; +import org.sunbird.service.user.UserService; +import org.sunbird.service.user.impl.UserServiceImpl; import org.sunbird.util.ratelimit.OtpRateLimiter; @RunWith(PowerMockRunner.class) @@ -48,7 +51,9 @@ import org.sunbird.util.ratelimit.OtpRateLimiter; RateLimitDaoImpl.class, RateLimitDao.class, RateLimitServiceImpl.class, - SunbirdMWService.class + SunbirdMWService.class, + UserService.class, + UserServiceImpl.class }) @PowerMockIgnore({ "javax.management.*", @@ -124,6 +129,82 @@ public class OTPActorTest { verifyOtpSuccessTest(false, mockedCassandraResponse); } + @Test + public void testVerifyOtpSuccessWithEmailOtp2() throws Exception { + Response mockedCassandraResponse = + getMockCassandraRecordByIdSuccessResponse(EMAIL_KEY, EMAIL_TYPE, REQUEST_OTP); + List<Map<String, Object>> responseList = + (List<Map<String, Object>>) mockedCassandraResponse.getResult().get(JsonKey.RESPONSE); + responseList.get(0).put(JsonKey.EMAIL,"xyz@xyz.com"); + Request request = createRequestForVerifyOtp(EMAIL_KEY, EMAIL_TYPE); + request.getRequest().put(JsonKey.USER_ID,"123123-546-4566"); + when(mockCassandraOperation.getRecordById( + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyString(), + Mockito.any())) + .thenReturn(mockedCassandraResponse); + OTPService otpService = PowerMockito.mock(OTPService.class); + PowerMockito.whenNew(OTPService.class).withNoArguments().thenReturn(otpService); + PowerMockito.when(otpService.getEmailPhoneByUserId(Mockito.anyString(),Mockito.anyString(),Mockito.any(RequestContext.class))).thenReturn("xyz@xyz.com"); + when(mockCassandraOperation.getRecordWithTTLById( + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyMap(), + Mockito.anyList(), + Mockito.anyList(), + Mockito.any())) + .thenReturn(mockedCassandraResponse); + subject.tell(request, probe.getRef()); + Response response = probe.expectMsgClass(duration("10 second"), Response.class); + Assert.assertEquals(ResponseCode.OK,response.getResponseCode()); + } + + @Test + public void testVerifyOtpFailureWithEmailOtp3() throws Exception { + Response mockedCassandraResponse = + getMockCassandraRecordByIdSuccessResponse(EMAIL_KEY, EMAIL_TYPE, REQUEST_OTP); + List<Map<String, Object>> responseList = + (List<Map<String, Object>>) mockedCassandraResponse.getResult().get(JsonKey.RESPONSE); + responseList.get(0).put(JsonKey.EMAIL,"xyz@xyz.com"); + Request request = createRequestForVerifyOtp(EMAIL_KEY, EMAIL_TYPE); + request.getRequest().clear(); + request.getRequest().put(JsonKey.OTP,""); + when(mockCassandraOperation.getRecordById( + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyString(), + Mockito.any())) + .thenReturn(mockedCassandraResponse); + OTPService otpService = PowerMockito.mock(OTPService.class); + PowerMockito.whenNew(OTPService.class).withNoArguments().thenReturn(otpService); + PowerMockito.when(otpService.getEmailPhoneByUserId(Mockito.anyString(),Mockito.anyString(),Mockito.any(RequestContext.class))).thenReturn("xyz@xyz.com"); + when(mockCassandraOperation.getRecordWithTTLById( + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyMap(), + Mockito.anyList(), + Mockito.anyList(), + Mockito.any())) + .thenReturn(mockedCassandraResponse); + subject.tell(request, probe.getRef()); + ProjectCommonException exception = + probe.expectMsgClass(duration("100 second"), ProjectCommonException.class); + Assert.assertEquals( + exception + .getCode(), + ResponseCode.errorInvalidOTP.getErrorCode()); + } + + @Test + public void testWithInvalidRequest() { + Request request = new Request(); + request.setOperation("invalidOperation"); + subject.tell(request, probe.getRef()); + ProjectCommonException exception = probe.expectMsgClass(duration("10 second"), ProjectCommonException.class); + Assert.assertNotNull(exception); + } + private Request createRequestForVerifyOtp(String key, String type) { Request request = new Request(); request.setOperation(ActorOperations.VERIFY_OTP.getValue()); @@ -201,7 +282,37 @@ public class OTPActorTest { (errorResponse.getResponseCode().name()).equals(ResponseCode.CLIENT_ERROR.name())); } - // @Test + @Test + public void generateOtpForPhoneSuccess2() { + Request request; + request = createGenerateOtpRequest(PHONE_TYPE, PHONE_KEY); + when(mockCassandraOperation.getRecordsByIdsWithSpecifiedColumnsAndTTL( + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyMap(), + Mockito.anyList(), + Mockito.anyMap(), + Mockito.any())) + .thenReturn(getRateLimitRecords(5)); + + Response mockedCassandraResponse = new Response(); + when(mockCassandraOperation.getRecordWithTTLById( + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyMap(), + Mockito.anyList(), + Mockito.anyList(), + Mockito.any())) + .thenReturn(mockedCassandraResponse); + when(mockCassandraOperation.insertRecord( + Mockito.anyString(), Mockito.anyString(), Mockito.anyMap(), Mockito.any())) + .thenReturn(createCassandraInsertSuccessResponse()); + subject.tell(request, probe.getRef()); + Response response = probe.expectMsgClass(duration("10 second"), Response.class); + Assert.assertEquals(ResponseCode.OK, response.getResponseCode()); + } + + @Test public void generateOtpForPhoneSuccess() { Request request; request = createGenerateOtpRequest(PHONE_TYPE, PHONE_KEY); diff --git a/service/src/test/java/org/sunbird/actor/otp/SendOTPActorTest.java b/service/src/test/java/org/sunbird/actor/otp/SendOTPActorTest.java index 04c6c8c15dd3ac033240492d2aa9356d10b48240..152567f5f9470054495af7d8dca4f7cbcbc024e7 100644 --- a/service/src/test/java/org/sunbird/actor/otp/SendOTPActorTest.java +++ b/service/src/test/java/org/sunbird/actor/otp/SendOTPActorTest.java @@ -5,6 +5,7 @@ import static org.powermock.api.mockito.PowerMockito.mock; import static org.powermock.api.mockito.PowerMockito.when; import akka.actor.ActorRef; +import akka.actor.ActorSelection; import akka.actor.ActorSystem; import akka.actor.Props; import akka.testkit.javadsl.TestKit; @@ -20,6 +21,7 @@ import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; import org.powermock.modules.junit4.PowerMockRunner; +import org.sunbird.actor.service.BaseMWService; import org.sunbird.actor.service.SunbirdMWService; import org.sunbird.cassandra.CassandraOperation; import org.sunbird.cassandraimpl.CassandraOperationImpl; @@ -27,6 +29,7 @@ import org.sunbird.dao.notification.EmailTemplateDao; import org.sunbird.dao.notification.impl.EmailTemplateDaoImpl; import org.sunbird.datasecurity.impl.DefaultDecryptionServiceImpl; import org.sunbird.datasecurity.impl.DefaultEncryptionServivceImpl; +import org.sunbird.exception.ProjectCommonException; import org.sunbird.exception.ResponseCode; import org.sunbird.helper.ServiceFactory; import org.sunbird.keys.JsonKey; @@ -48,7 +51,8 @@ import org.sunbird.response.Response; SMSFactory.class, Msg91SmsProviderFactory.class, EmailTemplateDaoImpl.class, - SunbirdMWService.class + SunbirdMWService.class, + BaseMWService.class }) @PowerMockIgnore({ "javax.management.*", @@ -64,10 +68,6 @@ import org.sunbird.response.Response; public class SendOTPActorTest { private TestKit probe; private ActorRef subject; - - public static DefaultEncryptionServivceImpl encService; - public static DefaultDecryptionServiceImpl decService; - public static org.sunbird.datasecurity.impl.ServiceFactory dataServiceFactory; private static final ActorSystem system = ActorSystem.create("system"); public static final CassandraOperationImpl mockCassandraOperation = mock(CassandraOperationImpl.class); @@ -78,6 +78,11 @@ public class SendOTPActorTest { @Before public void beforeEachTestCase() throws Exception { + PowerMockito.mockStatic(BaseMWService.class); + PowerMockito.mockStatic(SunbirdMWService.class); + SunbirdMWService.tellToBGRouter(Mockito.any(), Mockito.any()); + ActorSelection selection = PowerMockito.mock(ActorSelection.class); + when(BaseMWService.getRemoteRouter(Mockito.anyString())).thenReturn(selection); PowerMockito.mockStatic(ServiceFactory.class); PowerMockito.mockStatic(SMSFactory.class); PowerMockito.mockStatic(EmailTemplateDaoImpl.class); @@ -96,23 +101,90 @@ public class SendOTPActorTest { .thenReturn(decryptionService); probe = new TestKit(system); subject = system.actorOf(props); - /* when(OTPUtil.getOTPExpirationInMinutes()).thenReturn("123456788");*/ + } + @Test + public void testWithInvalidRequest() { + Request request = new Request(); + request.setOperation("invalidOperation"); + subject.tell(request, probe.getRef()); + ProjectCommonException exception = probe.expectMsgClass(duration("10 second"), ProjectCommonException.class); + Assert.assertNotNull(exception); } @Test - public void sendOTPTestForMobile() throws Exception { + public void sendOTPTestForMobile() { request = createOtpRequest("phone", "anyMobileNum", "anyUserId"); when(emailTemplateDao.getTemplate(Mockito.anyString(), Mockito.any())) .thenReturn( "OTP to reset your password on $installationName is $otp. This is valid for $otpExpiryInMinutes minutes only."); subject.tell(request, probe.getRef()); Response response = probe.expectMsgClass(duration("30 second"), Response.class); - Assert.assertTrue(response.getResponseCode().equals(ResponseCode.OK)); + Assert.assertEquals(ResponseCode.OK,response.getResponseCode()); + } + + @Test + public void sendOTPTestWithoutEmailAndPhone() { + request = createOtpRequest("phone", "anyMobileNum", "anyUserId"); + request.getRequest().remove(JsonKey.TYPE); + when(emailTemplateDao.getTemplate(Mockito.anyString(), Mockito.any())) + .thenReturn( + "OTP to reset your password on $installationName is $otp. This is valid for $otpExpiryInMinutes minutes only."); + subject.tell(request, probe.getRef()); + Response response = probe.expectMsgClass(duration("30 second"), Response.class); + Assert.assertEquals(ResponseCode.OK,response.getResponseCode()); + } + + @Test + public void sendOTPTestWithPreUsedPhone() { + request = createOtpRequest("phone", "anyMobileNum", "anyUserId"); + request.getRequest().put(JsonKey.TYPE,JsonKey.PREV_USED_PHONE); + when(emailTemplateDao.getTemplate(Mockito.anyString(), Mockito.any())) + .thenReturn( + "OTP to reset your password on $installationName is $otp. This is valid for $otpExpiryInMinutes minutes only."); + subject.tell(request, probe.getRef()); + Response response = probe.expectMsgClass(duration("30 second"), Response.class); + Assert.assertEquals(ResponseCode.OK, response.getResponseCode()); + } + + @Test + public void sendOTPTestWithRecoveryPhone() { + request = createOtpRequest("phone", "anyMobileNum", "anyUserId"); + request.getRequest().put(JsonKey.TYPE,JsonKey.RECOVERY_PHONE); + when(emailTemplateDao.getTemplate(Mockito.anyString(), Mockito.any())) + .thenReturn( + "OTP to reset your password on $installationName is $otp. This is valid for $otpExpiryInMinutes minutes only."); + subject.tell(request, probe.getRef()); + Response response = probe.expectMsgClass(duration("30 second"), Response.class); + Assert.assertEquals(ResponseCode.OK, response.getResponseCode()); + } + + @Test + public void sendOTPTestWithPreUsedEmail() { + request = createOtpRequest("email", "anyEmailId", "anyUserId"); + request.getRequest().put(JsonKey.TYPE,JsonKey.PREV_USED_EMAIL); + when(emailTemplateDao.getTemplate(Mockito.anyString(), Mockito.any())) + .thenReturn( + "OTP to reset your password on $installationName is $otp. This is valid for $otpExpiryInMinutes minutes only."); + subject.tell(request, probe.getRef()); + Response response = probe.expectMsgClass(duration("30 second"), Response.class); + Assert.assertEquals(ResponseCode.OK, response.getResponseCode()); + } + + @Test + public void sendOTPTestWithRecoveryEmail() { + request = createOtpRequest("email", "anyEmailId", "anyUserId"); + request.getRequest().put(JsonKey.TYPE,JsonKey.RECOVERY_EMAIL); + when(emailTemplateDao.getTemplate(Mockito.anyString(), Mockito.any())) + .thenReturn( + "OTP to reset your password on $installationName is $otp. This is valid for $otpExpiryInMinutes minutes only."); + subject.tell(request, probe.getRef()); + Response response = probe.expectMsgClass(duration("30 second"), Response.class); + Assert.assertEquals(ResponseCode.OK, response.getResponseCode()); } @Test - public void sendOTPTestForEmail() throws Exception { + public void sendOTPTestForEmail() { PowerMockito.mockStatic(SunbirdMWService.class); request = createOtpRequest("email", "anyEmailId", "anyUserId"); when(emailTemplateDao.getTemplate(Mockito.anyString(), Mockito.any())) @@ -120,7 +192,19 @@ public class SendOTPActorTest { "OTP to reset your password on $installationName is $otp. This is valid for $otpExpiryInMinutes minutes only."); subject.tell(request, probe.getRef()); Response response = probe.expectMsgClass(duration("30 second"), Response.class); - Assert.assertTrue(response.getResponseCode().equals(ResponseCode.OK)); + Assert.assertEquals(ResponseCode.OK, response.getResponseCode()); + } + + @Test + public void sendOTPTestForEmail2() { + PowerMockito.mockStatic(SunbirdMWService.class); + request = createOtpRequest("email", "anyEmailId", ""); + when(emailTemplateDao.getTemplate(Mockito.anyString(), Mockito.any())) + .thenReturn( + "OTP to reset your password on $installationName is $otp. This is valid for $otpExpiryInMinutes minutes only."); + subject.tell(request, probe.getRef()); + Response response = probe.expectMsgClass(duration("30 second"), Response.class); + Assert.assertEquals(ResponseCode.OK, response.getResponseCode()); } private Request createOtpRequest(String type, String key, String userId) { diff --git a/service/src/test/java/org/sunbird/service/otp/OTPServiceTest.java b/service/src/test/java/org/sunbird/service/otp/OTPServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7747888bb47c3f3d3c2e519d882a105063915a0e --- /dev/null +++ b/service/src/test/java/org/sunbird/service/otp/OTPServiceTest.java @@ -0,0 +1,91 @@ +package org.sunbird.service.otp; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.sunbird.dao.notification.EmailTemplateDao; +import org.sunbird.dao.notification.impl.EmailTemplateDaoImpl; +import org.sunbird.dao.otp.OTPDao; +import org.sunbird.dao.otp.impl.OTPDaoImpl; +import org.sunbird.keys.JsonKey; +import org.sunbird.request.RequestContext; +import org.sunbird.service.user.UserService; +import org.sunbird.service.user.impl.UserServiceImpl; + +import java.util.HashMap; +import java.util.Map; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ + UserService.class, + UserServiceImpl.class, + EmailTemplateDao.class, + EmailTemplateDaoImpl.class, + OTPDao.class, + OTPDaoImpl.class +}) +@PowerMockIgnore({ + "javax.management.*", + "javax.net.ssl.*", + "javax.security.*", + "jdk.internal.reflect.*", + "javax.crypto.*" +}) +public class OTPServiceTest { + + @Test + public void getEmailPhoneByUserIdTest() { + UserService userService = PowerMockito.mock(UserService.class); + PowerMockito.mockStatic(UserServiceImpl.class); + PowerMockito.when(UserServiceImpl.getInstance()).thenReturn(userService); + PowerMockito.when(userService.getDecryptedEmailPhoneByUserId(Mockito.anyString(), Mockito.anyString(), Mockito.any(RequestContext.class))).thenReturn("xyz@xyz.com"); + OTPService otpService = new OTPService(); + String userEmail = otpService.getEmailPhoneByUserId("12312-465-4546",JsonKey.EMAIL, new RequestContext()); + Assert.assertEquals("xyz@xyz.com",userEmail); + } + + @Test + public void getEmailPhoneByUserIdTest2() { + UserService userService = PowerMockito.mock(UserService.class); + PowerMockito.mockStatic(UserServiceImpl.class); + PowerMockito.when(UserServiceImpl.getInstance()).thenReturn(userService); + PowerMockito.when(userService.getDecryptedEmailPhoneByUserId(Mockito.anyString(), Mockito.anyString(), Mockito.any(RequestContext.class))).thenReturn("9999999999"); + OTPService otpService = new OTPService(); + String userEmail = otpService.getEmailPhoneByUserId("12312-465-4546",JsonKey.PHONE, new RequestContext()); + Assert.assertEquals("9999999999",userEmail); + } + + @Test + public void getSmsBodyTest() { + EmailTemplateDao emailTemplateDao = PowerMockito.mock(EmailTemplateDao.class); + PowerMockito.mockStatic(EmailTemplateDaoImpl.class); + PowerMockito.when(EmailTemplateDaoImpl.getInstance()).thenReturn(emailTemplateDao); + String smsTemplate = "One time password to verify your phone number on $installationName is $otp. This is valid for $otpExpiryInMinutes minutes only.\n"; + PowerMockito.when(emailTemplateDao.getTemplate(Mockito.anyString(), Mockito.any(RequestContext.class))).thenReturn(smsTemplate); + OTPService otpService = new OTPService(); + Map<String, String> smsTemplateMap = new HashMap<>(); + smsTemplateMap.put(JsonKey.OTP,"55555"); + smsTemplateMap.put(JsonKey.OTP_EXPIRATION_IN_MINUTES, "30"); + smsTemplateMap.put(JsonKey.SUNBIRD_INSTALLATION_DISPLAY_NAME,"SunBird"); + String sms = otpService.getSmsBody("otpTemplate" ,smsTemplateMap , new RequestContext()); + Assert.assertNotNull(sms); + } + + @Test + public void getOTPDetailsTest() { + OTPDao otpDao = PowerMockito.mock(OTPDao.class); + PowerMockito.mockStatic(OTPDaoImpl.class); + PowerMockito.when(OTPDaoImpl.getInstance()).thenReturn(otpDao); + Map<String, Object> otp = new HashMap<>(); + otp.put(JsonKey.OTP,"555555"); + PowerMockito.when(otpDao.getOTPDetails(Mockito.anyString(), Mockito.anyString(), Mockito.any(RequestContext.class))).thenReturn(otp); + OTPService otpService = new OTPService(); + Map<String, Object> otpRes = otpService.getOTPDetails(JsonKey.PHONE,"9999999999", new RequestContext()); + Assert.assertNotNull(otpRes); + } +} diff --git a/service/src/test/java/org/sunbird/service/user/UserServiceImplTest.java b/service/src/test/java/org/sunbird/service/user/UserServiceImplTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0bd201b5b7e41417ad6d28996234383e2da10424 --- /dev/null +++ b/service/src/test/java/org/sunbird/service/user/UserServiceImplTest.java @@ -0,0 +1,62 @@ +package org.sunbird.service.user; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.sunbird.dao.user.UserDao; +import org.sunbird.dao.user.impl.UserDaoImpl; +import org.sunbird.exception.ProjectCommonException; +import org.sunbird.keys.JsonKey; +import org.sunbird.request.RequestContext; +import org.sunbird.service.user.impl.UserServiceImpl; + +import java.util.HashMap; +import java.util.Map; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ + UserDao.class, + UserDaoImpl.class +}) +@PowerMockIgnore({ + "javax.management.*", + "javax.net.ssl.*", + "javax.security.*", + "jdk.internal.reflect.*", + "javax.crypto.*" +}) +public class UserServiceImplTest { + + @Test + public void getUserDetailsTest() { + UserDao userDao = PowerMockito.mock(UserDao.class); + PowerMockito.mockStatic(UserDaoImpl.class); + PowerMockito.when(UserDaoImpl.getInstance()).thenReturn(userDao); + Map<String,Object> user = new HashMap<>(); + user.put(JsonKey.USER_ID,"12312-465-4546"); + user.put(JsonKey.PHONE,"9999999999"); + PowerMockito.when(userDao.getUserDetailsById(Mockito.anyString(),Mockito.any(RequestContext.class))).thenReturn(user); + UserService userService = UserServiceImpl.getInstance(); + String phone = userService.getDecryptedEmailPhoneByUserId("2123-456-8997", JsonKey.PHONE, new RequestContext()); + Assert.assertNotNull(phone); + } + + @Test(expected = ProjectCommonException.class) + public void getUserDetailsTest2() { + UserDao userDao = PowerMockito.mock(UserDao.class); + PowerMockito.mockStatic(UserDaoImpl.class); + PowerMockito.when(UserDaoImpl.getInstance()).thenReturn(userDao); + Map<String,Object> user = new HashMap<>(); + user.put(JsonKey.USER_ID,"12312-465-4546"); + user.put(JsonKey.PHONE,"9999999999"); + PowerMockito.when(userDao.getUserDetailsById(Mockito.anyString(),Mockito.any(RequestContext.class))).thenReturn(user); + UserService userService = UserServiceImpl.getInstance(); + userService.getDecryptedEmailPhoneByUserId("2123-456-8997", JsonKey.RECOVERY_PHONE, new RequestContext()); + } + +} diff --git a/service/src/test/java/org/sunbird/service/user/UserServiceTest.java b/service/src/test/java/org/sunbird/service/user/UserServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c157c38ae91dce2412879de4894da6af0f62016e --- /dev/null +++ b/service/src/test/java/org/sunbird/service/user/UserServiceTest.java @@ -0,0 +1,44 @@ +package org.sunbird.service.user; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.sunbird.dao.user.UserDao; +import org.sunbird.dao.user.impl.UserDaoImpl; +import org.sunbird.exception.ProjectCommonException; +import org.sunbird.keys.JsonKey; +import org.sunbird.request.RequestContext; +import org.sunbird.service.user.impl.UserServiceImpl; + +import java.util.HashMap; +import java.util.Map; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ + UserDao.class, + UserDaoImpl.class +}) +@PowerMockIgnore({ + "javax.management.*", + "javax.net.ssl.*", + "javax.security.*", + "jdk.internal.reflect.*", + "javax.crypto.*" +}) +public class UserServiceTest { + + @Test(expected = ProjectCommonException.class) + public void getUserDetailsFailureTest() { + UserDao userDao = PowerMockito.mock(UserDao.class); + PowerMockito.mockStatic(UserDaoImpl.class); + PowerMockito.when(UserDaoImpl.getInstance()).thenReturn(userDao); + Map<String, Object> user = new HashMap<>(); + PowerMockito.when(userDao.getUserDetailsById(Mockito.anyString(), Mockito.any(RequestContext.class))).thenReturn(user); + UserService userService = UserServiceImpl.getInstance(); + userService.getDecryptedEmailPhoneByUserId("2123-456-8997", JsonKey.EMAIL, new RequestContext()); + } +} diff --git a/service/src/test/java/org/sunbird/util/OTPUtilTest.java b/service/src/test/java/org/sunbird/util/OTPUtilTest.java deleted file mode 100644 index c945ea4887185030fd02584a9a63cfa0f4d5300a..0000000000000000000000000000000000000000 --- a/service/src/test/java/org/sunbird/util/OTPUtilTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.sunbird.util; - -import org.junit.Assert; -import org.junit.Test; - -public class OTPUtilTest { - - @Test - public void generateOtpTest() { - for (int i = 0; i < 10000; i++) { - String code = OTPUtil.generateOtp(null); - Assert.assertTrue(code.length() >= 4); - } - } -} diff --git a/service/src/test/java/org/sunbird/util/otp/OTPUtilTest.java b/service/src/test/java/org/sunbird/util/otp/OTPUtilTest.java new file mode 100644 index 0000000000000000000000000000000000000000..58f01878e806012a9f57604395c393f0854ce563 --- /dev/null +++ b/service/src/test/java/org/sunbird/util/otp/OTPUtilTest.java @@ -0,0 +1,184 @@ +package org.sunbird.util.otp; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.sunbird.cassandraimpl.CassandraOperationImpl; +import org.sunbird.exception.ProjectCommonException; +import org.sunbird.keys.JsonKey; +import org.sunbird.notification.sms.provider.ISmsProvider; +import org.sunbird.notification.utils.SMSFactory; +import org.sunbird.request.Request; +import org.sunbird.request.RequestContext; +import org.sunbird.service.otp.OTPService; +import org.sunbird.util.ProjectUtil; + +import java.util.HashMap; +import java.util.Map; + +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ + OTPService.class, + ProjectUtil.class, + SMSFactory.class, + ISmsProvider.class, + CassandraOperationImpl.class, +}) +@PowerMockIgnore({ + "javax.management.*", + "javax.net.ssl.*", + "javax.security.*", + "jdk.internal.reflect.*", + "javax.crypto.*" +}) +public class OTPUtilTest { + + @Test + public void generateOtpTest() { + for (int i = 0; i < 10000; i++) { + String code = OTPUtil.generateOTP(null); + Assert.assertTrue(code.length() >= 4); + } + } + + @Test + public void sendOTPViaSMSTest() throws Exception { + PowerMockito.mockStatic(ProjectUtil.class); + when(ProjectUtil.getConfigValue(Mockito.anyString())).thenReturn("anyString"); + OTPService otpService = PowerMockito.mock(OTPService.class); + PowerMockito.whenNew(OTPService.class).withNoArguments().thenReturn(otpService); + when(otpService.getSmsBody(Mockito.anyString(),Mockito.anyMap(),Mockito.any(RequestContext.class))).thenReturn("some sms text"); + ISmsProvider smsProvider = PowerMockito.mock(ISmsProvider.class); + PowerMockito.mockStatic(SMSFactory.class); + when(SMSFactory.getInstance()).thenReturn(smsProvider); + when(smsProvider.send(Mockito.anyString(),Mockito.anyString(),Mockito.anyString())).thenReturn(true); + Map<String, Object> otpMap = new HashMap<>(); + otpMap.put(JsonKey.PHONE,"9742511111"); + otpMap.put(JsonKey.TEMPLATE_ID,"someTemplateId"); + otpMap.put(JsonKey.OTP_EXPIRATION_IN_MINUTES,"30"); + otpMap.put(JsonKey.SUNBIRD_INSTALLATION_DISPLAY_NAME,"displayName"); + otpMap.put(JsonKey.COUNTRY_CODE,"91"); + boolean bool = OTPUtil.sendOTPViaSMS(otpMap, new RequestContext()); + Assert.assertTrue(bool); + } + + @Test + public void sendOTPViaSMSTest2() throws Exception { + PowerMockito.mockStatic(ProjectUtil.class); + when(ProjectUtil.getConfigValue(Mockito.anyString())).thenReturn("anyString"); + OTPService otpService = PowerMockito.mock(OTPService.class); + PowerMockito.whenNew(OTPService.class).withNoArguments().thenReturn(otpService); + when(otpService.getSmsBody(Mockito.anyString(),Mockito.anyMap(),Mockito.any(RequestContext.class))).thenReturn("some sms text"); + ISmsProvider smsProvider = PowerMockito.mock(ISmsProvider.class); + PowerMockito.mockStatic(SMSFactory.class); + when(SMSFactory.getInstance()).thenReturn(smsProvider); + when(smsProvider.send(Mockito.anyString(),Mockito.anyString(),Mockito.anyString())).thenReturn(true); + Map<String, Object> otpMap = new HashMap<>(); + otpMap.put(JsonKey.PHONE,"9742511111"); + otpMap.put(JsonKey.OTP_EXPIRATION_IN_MINUTES,"30"); + otpMap.put(JsonKey.SUNBIRD_INSTALLATION_DISPLAY_NAME,"displayName"); + otpMap.put(JsonKey.COUNTRY_CODE,"91"); + boolean bool = OTPUtil.sendOTPViaSMS(otpMap, new RequestContext()); + Assert.assertTrue(bool); + } + + @Test + public void sendOTPViaSMSTest3() throws Exception { + PowerMockito.mockStatic(ProjectUtil.class); + when(ProjectUtil.getConfigValue(Mockito.anyString())).thenReturn("anyString"); + OTPService otpService = PowerMockito.mock(OTPService.class); + PowerMockito.whenNew(OTPService.class).withNoArguments().thenReturn(otpService); + when(otpService.getSmsBody(Mockito.anyString(),Mockito.anyMap(),Mockito.any(RequestContext.class))).thenReturn("some sms text"); + ISmsProvider smsProvider = PowerMockito.mock(ISmsProvider.class); + PowerMockito.mockStatic(SMSFactory.class); + when(SMSFactory.getInstance()).thenReturn(smsProvider); + when(smsProvider.send(Mockito.anyString(),Mockito.anyString(),Mockito.anyString())).thenReturn(true); + Map<String, Object> otpMap = new HashMap<>(); + otpMap.put(JsonKey.PHONE,"9742511111"); + otpMap.put(JsonKey.TEMPLATE_ID,JsonKey.WARD_LOGIN_OTP_TEMPLATE_ID); + otpMap.put(JsonKey.OTP_EXPIRATION_IN_MINUTES,"30"); + otpMap.put(JsonKey.SUNBIRD_INSTALLATION_DISPLAY_NAME,"displayName"); + otpMap.put(JsonKey.COUNTRY_CODE,"91"); + boolean bool = OTPUtil.sendOTPViaSMS(otpMap, new RequestContext()); + Assert.assertTrue(bool); + } + + @Test + public void sendOTPViaSMSWithoutPhoneTest() { + Map<String, Object> otpMap = new HashMap<>(); + otpMap.put(JsonKey.TEMPLATE_ID,"someTemplateId"); + otpMap.put(JsonKey.OTP_EXPIRATION_IN_MINUTES,"30"); + otpMap.put(JsonKey.SUNBIRD_INSTALLATION_DISPLAY_NAME,"displayName"); + otpMap.put(JsonKey.COUNTRY_CODE,"91"); + boolean bool = OTPUtil.sendOTPViaSMS(otpMap, new RequestContext()); + Assert.assertFalse(bool); + } + + //@Test + public void getEmailPhoneByUserIdTest() throws Exception { + Map<String, Object> user = new HashMap<>(); + user.put(JsonKey.USER_ID,"1235-4578-156645"); + user.put(JsonKey.EMAIL,"xyz@xyz.com"); + user.put(JsonKey.PHONE,"9999999999"); + OTPService otpService = PowerMockito.mock(OTPService.class); + PowerMockito.whenNew(OTPService.class).withNoArguments().thenReturn(otpService); + String value = otpService.getEmailPhoneByUserId("1235-4578-156645",JsonKey.EMAIL, new RequestContext()); + Assert.assertNotNull(value); + } + + @Test(expected = ProjectCommonException.class) + public void getEmailPhoneByUserId2Test() { + OTPService otpService = new OTPService(); + otpService.getEmailPhoneByUserId("1235-4578-156645",JsonKey.EMAIL, new RequestContext()); + } + + @Test(expected = ProjectCommonException.class) + public void getEmailPhoneByUserId3Test() { + Map<String, Object> user = new HashMap<>(); + user.put(JsonKey.USER_ID,"1235-4578-156645"); + OTPService otpService = new OTPService(); + otpService.getEmailPhoneByUserId("1235-4578-156645",JsonKey.EMAIL, new RequestContext()); + } + + @Test + public void getRequestToSendOTPViaEmailTest() { + PowerMockito.mockStatic(ProjectUtil.class); + when(ProjectUtil.getConfigValue(Mockito.anyString())).thenReturn("anyString"); + + Map<String, Object> emailTemplateMap = new HashMap<>(); + emailTemplateMap.put(JsonKey.EMAIL,"xyz@xyz.com"); + + Request request = OTPUtil.getRequestToSendOTPViaEmail(emailTemplateMap, new RequestContext()); + Assert.assertNotNull(request); + } + + @Test + public void getRequestToSendOTPViaEmailTest2() { + PowerMockito.mockStatic(ProjectUtil.class); + when(ProjectUtil.getConfigValue(Mockito.anyString())).thenReturn("anyString"); + + Map<String, Object> emailTemplateMap = new HashMap<>(); + + Request request = OTPUtil.getRequestToSendOTPViaEmail(emailTemplateMap, new RequestContext()); + Assert.assertNull(request); + } + + @Test + public void getRequestToSendOTPViaEmailTest3() { + PowerMockito.mockStatic(ProjectUtil.class); + when(ProjectUtil.getConfigValue(Mockito.anyString())).thenReturn("anyString"); + + Map<String, Object> emailTemplateMap = new HashMap<>(); + emailTemplateMap.put(JsonKey.EMAIL,"xyz@xyz.com"); + emailTemplateMap.put(JsonKey.TEMPLATE_ID,JsonKey.WARD_LOGIN_OTP_TEMPLATE_ID); + Request request = OTPUtil.getRequestToSendOTPViaEmail(emailTemplateMap, new RequestContext()); + Assert.assertNotNull(request); + } +}