Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Email OTP based verification at registration #720

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2220615
Merge pull request #1 from wso2-extensions/master
Gastro-Diron Jun 12, 2023
f4eda00
Moved the changes to a branch created on master
Gastro-Diron Jun 12, 2023
4ee00db
removed verificationMethod variable and duplicate methods
Gastro-Diron Jun 13, 2023
622a203
Update UserSelfRegistrationHandler.java
Gastro-Diron Jun 13, 2023
f51e3fb
seperated secretKey generation method to two methods
Gastro-Diron Jun 14, 2023
ceb74d3
Update Utils.java
Gastro-Diron Jun 15, 2023
13f5ff7
Assigned constant for OTPCode
Gastro-Diron Jun 19, 2023
4c4231c
Merge pull request #2 from Gastro-Diron/gastrojune14
Gastro-Diron Jun 19, 2023
c4b0c29
add unit test
Gastro-Diron Jun 22, 2023
1230ecc
Merge pull request #3 from Gastro-Diron/gastrojune22
Gastro-Diron Jun 28, 2023
7447dd7
Changes made after code review
Gastro-Diron Jun 29, 2023
ec66550
Reverted the changes in the resendcodeapiserviceimpl.java
Gastro-Diron Jun 29, 2023
ee2dc42
Revert the changes made in the resendcodeapiserviceimpl.java
Gastro-Diron Jun 29, 2023
5329407
change the visibility of triggerNotification to private
Gastro-Diron Jun 29, 2023
b4bca7c
Added the checkstyle to UserSelfRegistrationHandler.java
Gastro-Diron Jun 30, 2023
2d932b9
Added CheckStyle for Utils.java, IdentityRecoveryConstants.java, Self…
Gastro-Diron Jun 30, 2023
fa79de0
Mask the username
Gastro-Diron Jun 30, 2023
553c761
Revert the checkstyle
Gastro-Diron Jun 30, 2023
7d410d6
Change the description of the configuration
Gastro-Diron Jul 6, 2023
d4efc7c
Add checkstyle
Gastro-Diron Jul 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ public class IdentityRecoveryConstants {
public static final String NOTIFICATION_TYPE_RESEND_PASSWORD_RESET = "resendPasswordReset";
public static final String NOTIFICATION_TYPE_ADMIN_FORCED_PASSWORD_RESET = "adminforcedpasswordreset";
public static final String NOTIFICATION_TYPE_RESEND_ADMIN_FORCED_PASSWORD_RESET = "resendAdminForcedPasswordReset";
public static final String NOTIFICATION_TYPE_ADMIN_FORCED_PASSWORD_RESET_WITH_OTP = "adminforcedpasswordresetwithotp";
public static final String NOTIFICATION_TYPE_ADMIN_FORCED_PASSWORD_RESET_WITH_OTP =
"adminforcedpasswordresetwithotp";
public static final String NOTIFICATION_TYPE_RESEND_ADMIN_FORCED_PASSWORD_RESET_WITH_OTP =
"resendAdminForcedPasswordResetWithOTP";
public static final String NOTIFICATION_TYPE_ACCOUNT_CONFIRM = "accountconfirmation";
public static final String NOTIFICATION_TYPE_ACCOUNT_CONFIRM_EMAIL_OTP = "accountConfirmationEmailOTP";
public static final String NOTIFICATION_TYPE_RESEND_ACCOUNT_CONFIRM = "resendaccountconfirmation";
public static final String NOTIFICATION_TYPE_EMAIL_CONFIRM = "emailconfirm";
public static final String NOTIFICATION_TYPE_LITE_USER_EMAIL_CONFIRM = "liteUserEmailConfirmation";
Expand All @@ -71,6 +73,7 @@ public class IdentityRecoveryConstants {
public static final String TEMPLATE_TYPE = "TEMPLATE_TYPE";
public static final String EMAIL_TEMPLATE_NAME = "templateName";
public static final String CONFIRMATION_CODE = "confirmation-code";
public static final String EMAIL_OTP_CODE = "OTPCode";
public static final String VERIFICATION_PENDING_EMAIL = "verification-pending-email";
public static final String NEW_EMAIL_ADDRESS = "new-email-address";
public static final String NOTIFY = "notify";
Expand All @@ -79,8 +82,10 @@ public class IdentityRecoveryConstants {
public static final String ACCOUNT_LOCKED_REASON_CLAIM = "http://wso2.org/claims/identity/lockedReason";
public static final String ACCOUNT_UNLOCK_TIME_CLAIM = "http://wso2.org/claims/identity/unlockTime";
public static final String ACCOUNT_DISABLED_CLAIM = "http://wso2.org/claims/identity/accountDisabled";
public static final String USER_SOURCE_ID_CLAIM_URI = "http://wso2.org/claims/identity/userSourceId";
public static final String LOCAL_CREDENTIAL_EXISTS_CLAIM_URI = "http://wso2.org/claims/identity/localCredentialExists";
public static final String USER_SOURCE_ID_CLAIM_URI =
"http://wso2.org/claims/identity/userSourceId";
public static final String LOCAL_CREDENTIAL_EXISTS_CLAIM_URI =
"http://wso2.org/claims/identity/localCredentialExists";
public static final String LITE_USER_CLAIM = "http://wso2.org/claims/identity/isLiteUser";
public static final String FAILED_LOGIN_LOCKOUT_COUNT_CLAIM =
"http://wso2.org/claims/identity/failedLoginLockoutCount";
Expand Down Expand Up @@ -112,7 +117,8 @@ public class IdentityRecoveryConstants {
public static final String PREFERRED_CHANNEL_CLAIM = "http://wso2.org/claims/identity/preferredChannel";

public static final String ASK_PASSWORD_CLAIM = "http://wso2.org/claims/identity/askPassword";
public static final String ADMIN_FORCED_PASSWORD_RESET_CLAIM = "http://wso2.org/claims/identity/adminForcedPasswordReset";
public static final String ADMIN_FORCED_PASSWORD_RESET_CLAIM =
"http://wso2.org/claims/identity/adminForcedPasswordReset";
public static final String TENANT_ADMIN_ASK_PASSWORD_CLAIM =
"http://wso2.org/claims/identity/tenantAdminAskPassword";
public static final String OTP_PASSWORD_CLAIM = "http://wso2.org/claims/oneTimePassword";
Expand Down Expand Up @@ -163,6 +169,7 @@ public class IdentityRecoveryConstants {
public static final String USER_ACCOUNT_RECOVERY = "UAR";

public static final int SMS_OTP_CODE_LENGTH = 6;
public static final int EMAIL_OTP_CODE_LENGTH = 6;
public static final String ENABLE_DETAILED_ERROR_RESPONSE = "Recovery.ErrorMessage.EnableDetailedErrorMessages";
// Recovery code given at the username and password recovery initiation.
public static final int RECOVERY_CODE_DEFAULT_EXPIRY_TIME = 1;
Expand Down Expand Up @@ -212,12 +219,15 @@ public enum ErrorMessages {
ERROR_CODE_DISABLED_ACCOUNT("17004", "user account is disabled '%s'."),
ERROR_CODE_PENDING_SELF_REGISTERED_ACCOUNT("17005", "User account not yet verified - '%s.'"),
ERROR_CODE_PENDING_PASSWORD_RESET_ACCOUNT("17006", "Password reset is not yet completed '%s.'"),
ERROR_CODE_MOBILE_VERIFICATION_NOT_ENABLE_PRIVILEGED_USERS("17007", "Mobile number verification by privileged users is not enabled."),
ERROR_CODE_MOBILE_VERIFICATION_NOT_ENABLE_PRIVILEGED_USERS("17007", "Mobile number verification" +
"by privileged users is not enabled."),
ERROR_CODE_USER_STORE_READONLY("17008", "User store is readonly - '%s'."),
ERROR_CODE_USER_STORE_INVALID("17009", "User store is invalid - '%s'."),

ERROR_CODE_REGISTRY_EXCEPTION_GET_CHALLENGE_QUESTIONS("20001", "Registry exception while getting challenge question"),
ERROR_CODE_REGISTRY_EXCEPTION_SET_CHALLENGE_QUESTIONS("20002", "Registry exception while setting challenge question"),
ERROR_CODE_REGISTRY_EXCEPTION_GET_CHALLENGE_QUESTIONS("20001", "Registry exception" +
"while getting challenge question"),
ERROR_CODE_REGISTRY_EXCEPTION_SET_CHALLENGE_QUESTIONS("20002", "Registry exception" +
"while setting challenge question"),
ERROR_CODE_GETTING_CHALLENGE_URIS("20003", "Error while getting challenge question URIs '%s'."),
ERROR_CODE_GETTING_CHALLENGE_QUESTIONS("20004", "Error while getting challenge questions '%s'."),
ERROR_CODE_GETTING_CHALLENGE_QUESTION("20005", "Error while getting challenge question '%s'."),
Expand All @@ -232,7 +242,8 @@ public enum ErrorMessages {
ERROR_CODE_NO_FIELD_FOUND_FOR_USER_RECOVERY("20014", "No fileds found for username recovery"),
ERROR_CODE_NO_USER_FOUND_FOR_RECOVERY("20015", "No valid user found"),
ERROR_CODE_ISSUE_IN_LOADING_RECOVERY_CONFIGS("20016", "Error loading recovery configs"),
ERROR_CODE_NOTIFICATION_BASED_PASSWORD_RECOVERY_NOT_ENABLE("20017", "Notification based password recovery is not enabled"),
ERROR_CODE_NOTIFICATION_BASED_PASSWORD_RECOVERY_NOT_ENABLE("20017", "Notification based " +
"password recovery is not enabled"),
ERROR_CODE_QUESTION_BASED_RECOVERY_NOT_ENABLE("20018", "Security questions based recovery is not enabled"),
ERROR_CODE_ADD_SELF_USER("20019", "Error while adding self signup user"),
ERROR_CODE_LOCK_USER_USER("20020", "Error while lock user"),
Expand All @@ -248,7 +259,8 @@ public enum ErrorMessages {
ERROR_CODE_HISTORY_VIOLATE("22001", "This password has been used in recent history. Please choose a different" +
" password"),
ERROR_CODE_MULTIPLE_QUESTION_NOT_ALLOWED("20029", "Multiple challenge question not allowed for this operation"),
ERROR_CODE_USER_ALREADY_EXISTS("20030", "User %s already exists in the system. Please use a different username."),
ERROR_CODE_USER_ALREADY_EXISTS("20030", "User %s already exists in the system. " +
"Please use a different username."),
ERROR_CODE_USERNAME_RECOVERY_NOT_ENABLE("20031", "Username recovery is not enabled"),
ERROR_CODE_MULTIPLE_USERS_MATCHING("20032", "Multiple users found"),
ERROR_CODE_ISSUE_IN_LOADING_SIGNUP_CONFIGS("20033", "Error loading signup configs"),
Expand Down Expand Up @@ -289,7 +301,8 @@ public enum ErrorMessages {
ERROR_CODE_ERROR_DELETING_RECOVERY_DATA("20061", "Error deleting user recovery data of the tenant: %s"),
ERROR_CODE_ERROR_GETTING_CONNECTOR_CONFIG("20062", "Error while getting connector configurations"),

ERROR_CODE_ERROR_RETRIVING_CLAIM("18004", "Error when retrieving the locale claim of user '%s' of '%s' domain."),
ERROR_CODE_ERROR_RETRIVING_CLAIM("18004", "Error when retrieving the locale claim of " +
"user '%s' of '%s' domain."),
ERROR_CODE_RECOVERY_DATA_NOT_FOUND_FOR_USER("18005", "Recovery data not found."),
ERROR_CODE_FAILED_TO_LOCK_FUNCTIONALITY_FOR_USER("55001", "Server error occurred while locking functionality."),
ERROR_CODE_FAILED_TO_UNLOCK_FUNCTIONALITY_FOR_USER("55002", "Server error occurred while unlocking " +
Expand Down Expand Up @@ -365,7 +378,7 @@ public enum ErrorMessages {
"Unsupported notification channel: '%s'"),
ERROR_CODE_ERROR_GENERATING_NEW_RESET_CODE("UAR-15006", "Error while generating new "
+ "password reset code"),
ERROR_CODE_ERROR_RETRIEVING_RECOVERY_DATA("UAR-15007","Error while retrieving the user recovery data: '%s'"),
ERROR_CODE_ERROR_RETRIEVING_RECOVERY_DATA("UAR-15007", "Error while retrieving the user recovery data: '%s'"),
ERROR_CODE_ERROR_UPDATING_RECOVERY_DATA("UAR-15008", "Error while updating recovery data: '%s'"),

// PWR - Password Recovery.
Expand Down Expand Up @@ -508,6 +521,9 @@ public String toString() {
}
}

/**
* This class contains the connector configurations.
*/
public static class ConnectorConfig {

public static final String PASSWORD_RECOVERY_SMS_OTP_EXPIRY_TIME =
Expand Down Expand Up @@ -537,6 +553,7 @@ public static class ConnectorConfig {
".Password.ReCaptcha.MaxFailedAttempts";
public static final String RECOVERY_CALLBACK_REGEX = "Recovery.CallbackRegex";
public static final String ENABLE_SELF_SIGNUP = "SelfRegistration.Enable";
public static final String ENABLE_EMAIL_OTP_VERIFICATION = "SelfRegistration.EmailOTPVerification.Enable";
Gastro-Diron marked this conversation as resolved.
Show resolved Hide resolved
public static final String ACCOUNT_LOCK_ON_CREATION = "SelfRegistration.LockOnCreation";
public static final String SEND_CONFIRMATION_NOTIFICATION = "SelfRegistration.SendConfirmationOnCreation";
public static final String SIGN_UP_NOTIFICATION_INTERNALLY_MANAGE = "SelfRegistration.Notification" +
Expand Down Expand Up @@ -582,18 +599,21 @@ public static class ConnectorConfig {
"EnableVerificationByPrivilegedUser";
public static final String USE_VERIFY_CLAIM_ON_UPDATE = "UserClaimUpdate.UseVerifyClaim";
public static final String ASK_PASSWORD_EXPIRY_TIME = "EmailVerification.AskPassword.ExpiryTime";
public static final String ASK_PASSWORD_TEMP_PASSWORD_GENERATOR = "EmailVerification.AskPassword.PasswordGenerator";
public static final String ASK_PASSWORD_TEMP_PASSWORD_GENERATOR = "EmailVerification.AskPassword" +
".PasswordGenerator";
public static final String ASK_PASSWORD_DISABLE_RANDOM_VALUE_FOR_CREDENTIALS = "EmailVerification.AskPassword" +
".DisableRandomValueForCredentials";
public static final String EMAIL_ACCOUNT_LOCK_ON_CREATION = "EmailVerification.LockOnCreation";
public static final String EMAIL_VERIFICATION_NOTIFICATION_INTERNALLY_MANAGE = "EmailVerification.Notification.InternallyManage";
public static final String EMAIL_VERIFICATION_NOTIFICATION_INTERNALLY_MANAGE = "EmailVerification" +
".Notification.InternallyManage";

public static final String TENANT_ADMIN_ASK_PASSWORD_EXPIRY_TIME = "TenantRegistrationVerification." +
"AskPassword.ExpiryTime";

public static final String ENABLE_ADMIN_PASSWORD_RESET_OFFLINE = "Recovery.AdminPasswordReset.Offline";
public static final String ENABLE_ADMIN_PASSWORD_RESET_WITH_OTP = "Recovery.AdminPasswordReset.OTP";
public static final String ENABLE_ADMIN_PASSWORD_RESET_WITH_RECOVERY_LINK = "Recovery.AdminPasswordReset.RecoveryLink";
public static final String ENABLE_ADMIN_PASSWORD_RESET_WITH_RECOVERY_LINK = "Recovery.AdminPasswordReset" +
".RecoveryLink";
public static final String ADMIN_PASSWORD_RESET_EXPIRY_TIME = "Recovery.AdminPasswordReset.ExpiryTime";

public static final String PASSWORD_RECOVERY_RECAPTCHA_ENABLE = "Recovery.ReCaptcha.Password.Enable";
Expand All @@ -606,14 +626,17 @@ public static class ConnectorConfig {
public static final String SELF_REGISTRATION_AUTO_LOGIN_ALIAS_NAME = "SelfRegistration.AutoLogin.AliasName";
}

/**
* This class contains the database queries.
*/
public static class SQLQueries {

public static final String STORE_RECOVERY_DATA = "INSERT INTO IDN_RECOVERY_DATA "
+ "(USER_NAME, USER_DOMAIN, TENANT_ID, CODE, SCENARIO,STEP, TIME_CREATED, REMAINING_SETS)"
+ "VALUES (?,?,?,?,?,?,?,?)";
public static final String LOAD_RECOVERY_DATA = "SELECT "
+ "* FROM IDN_RECOVERY_DATA WHERE USER_NAME = ? AND USER_DOMAIN = ? AND TENANT_ID = ? AND CODE = ? AND " +
"SCENARIO = ? AND STEP = ?";
+ "* FROM IDN_RECOVERY_DATA WHERE USER_NAME = ? AND USER_DOMAIN = ? AND " +
"TENANT_ID = ? AND CODE = ? AND SCENARIO = ? AND STEP = ?";

public static final String LOAD_RECOVERY_DATA_CASE_INSENSITIVE = "SELECT * FROM IDN_RECOVERY_DATA WHERE" +
" LOWER(USER_NAME)=LOWER(?) AND USER_DOMAIN = ? AND TENANT_ID = ? AND CODE= ? AND SCENARIO = ? AND " +
Expand All @@ -628,28 +651,31 @@ public static class SQLQueries {
"AND SCENARIO <> 'EMAIL_VERIFICATION_ON_UPDATE' AND SCENARIO <> 'MOBILE_VERIFICATION_ON_UPDATE'";

public static final String INVALIDATE_USER_CODES_CASE_INSENSITIVE =
"DELETE FROM IDN_RECOVERY_DATA WHERE LOWER(USER_NAME) = LOWER(?) AND USER_DOMAIN = ? AND TENANT_ID =? " +
"AND SCENARIO <> 'EMAIL_VERIFICATION_ON_UPDATE' AND SCENARIO <> 'MOBILE_VERIFICATION_ON_UPDATE'";
"DELETE FROM IDN_RECOVERY_DATA WHERE LOWER(USER_NAME) = LOWER(?) AND " +
"USER_DOMAIN = ? AND TENANT_ID =? AND SCENARIO <> 'EMAIL_VERIFICATION_ON_UPDATE' AND " +
"SCENARIO <> 'MOBILE_VERIFICATION_ON_UPDATE'";

public static final String INVALIDATE_USER_CODE_BY_SCENARIO = "DELETE FROM IDN_RECOVERY_DATA WHERE " +
"USER_NAME = ? AND SCENARIO = ? AND STEP = ? AND USER_DOMAIN = ? AND TENANT_ID =?";

public static final String UPDATE_CODE = "UPDATE IDN_RECOVERY_DATA SET CODE = ?, STEP = ?, REMAINING_SETS = ? " +
"WHERE CODE = ?";
public static final String UPDATE_CODE = "UPDATE IDN_RECOVERY_DATA SET " +
"CODE = ?, STEP = ?, REMAINING_SETS = ? WHERE CODE = ?";

public static final String INVALIDATE_USER_CODE_BY_SCENARIO_CASE_INSENSITIVE = "DELETE FROM " +
"IDN_RECOVERY_DATA WHERE LOWER(USER_NAME)=LOWER(?) AND SCENARIO = ? AND STEP = ? AND " +
"USER_DOMAIN = ? AND TENANT_ID =?";

public static final String DELETE_USER_RECOVERY_DATA_BY_TENANT_ID = "DELETE FROM IDN_RECOVERY_DATA WHERE TENANT_ID = ?";
public static final String DELETE_USER_RECOVERY_DATA_BY_TENANT_ID = "DELETE FROM IDN_RECOVERY_DATA WHERE " +
"TENANT_ID = ?";

public static final String LOAD_RECOVERY_DATA_OF_USER =
"SELECT * FROM IDN_RECOVERY_DATA WHERE USER_NAME = ? AND USER_DOMAIN = ? AND TENANT_ID = ? " +
"AND SCENARIO <> 'EMAIL_VERIFICATION_ON_UPDATE' AND SCENARIO <> 'MOBILE_VERIFICATION_ON_UPDATE'";

public static final String LOAD_RECOVERY_DATA_OF_USER_CASE_INSENSITIVE =
"SELECT * FROM IDN_RECOVERY_DATA WHERE LOWER(USER_NAME)=LOWER(?) AND USER_DOMAIN = ? AND TENANT_ID = ? " +
"AND SCENARIO <> 'EMAIL_VERIFICATION_ON_UPDATE' AND SCENARIO <> 'MOBILE_VERIFICATION_ON_UPDATE'";
"SELECT * FROM IDN_RECOVERY_DATA WHERE LOWER(USER_NAME)=LOWER(?) AND " +
"USER_DOMAIN = ? AND TENANT_ID = ? AND SCENARIO <> 'EMAIL_VERIFICATION_ON_UPDATE' AND " +
"SCENARIO <> 'MOBILE_VERIFICATION_ON_UPDATE'";

public static final String LOAD_RECOVERY_DATA_OF_USER_BY_SCENARIO = "SELECT "
+ "* FROM IDN_RECOVERY_DATA WHERE USER_NAME = ? AND SCENARIO = ? AND USER_DOMAIN = ? " +
Expand All @@ -668,6 +694,9 @@ public static class SQLQueries {
"AND TENANT_ID = ? AND STEP = ?";
}

/**
* This class contains the Challenge Questions and constants related to the Challenge Questions.
*/
public static class Questions {

public static final String LOCALE_CLAIM = IdentityUtil.getClaimUriLocale();
Expand All @@ -689,6 +718,9 @@ public static class Questions {

}

/**
* This class contains the constants related to the consent management.
*/
public static class Consent {

public static final String COLLECTION_METHOD_SELF_REGISTRATION = "Web Form - Self Registration";
Expand Down
Loading