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

Username recovery sms support #6040

Merged
merged 25 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
457ead5
Add config retrieval methods.
Malith-19 Oct 18, 2024
8b61745
Add api call wrappers for username recovery v2.
Malith-19 Oct 18, 2024
d450e0a
Add mobile claim to configs.
Malith-19 Oct 18, 2024
875ad37
Add username recovery configs.
Malith-19 Oct 18, 2024
7a1f120
Remove redundant empty lines.
Malith-19 Oct 18, 2024
218d11b
Modify the comments.
Malith-19 Oct 18, 2024
554c76a
Remove redundant lines.
Malith-19 Oct 18, 2024
49baf92
Add username recovery api to allowed endpoints.
Malith-19 Oct 18, 2024
fa56eb8
Add unit tests for the preferenceRetrieval class.
Malith-19 Oct 24, 2024
e16faff
Remove the test class.
Malith-19 Oct 24, 2024
6233e06
Merge the main branch.
Malith-19 Oct 24, 2024
61ed13b
Add unit tests for the recovery configs.
Malith-19 Oct 24, 2024
8ff7660
Add unit tests for the recoveryApiV2
Malith-19 Oct 28, 2024
68495d9
Reformat the code.
Malith-19 Oct 28, 2024
3b8c9cd
Update the unit test with Error checks.
Malith-19 Oct 28, 2024
289a5bf
Update the variable name in the tests.
Malith-19 Oct 30, 2024
7a96f28
Rename tenant to tenantDomain.
Malith-19 Oct 31, 2024
47a27ea
change public variable to private.
Malith-19 Oct 31, 2024
85f868d
Update the mobile regex in the constants.
Malith-19 Nov 2, 2024
d0a006a
Add the on-demand migration config logic.
Malith-19 Nov 4, 2024
147f386
Reformat the code.
Malith-19 Nov 4, 2024
aae7687
Update the tests for validateUsernameRecoveryPropertyValues.
Malith-19 Nov 5, 2024
1971c57
Merge branch 'master' into username-recovery-sms-support
Malith-19 Nov 8, 2024
2b3ead0
Remove the extra new line.
Malith-19 Nov 8, 2024
4e9afb9
Reformat the code.
Malith-19 Nov 12, 2024
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 @@ -59,6 +59,7 @@ public static final class ClaimURIs {
public static final String FIRST_NAME_CLAIM = "http://wso2.org/claims/givenname";
public static final String LAST_NAME_CLAIM = "http://wso2.org/claims/lastname";
public static final String EMAIL_CLAIM = "http://wso2.org/claims/emailaddress";
public static final String MOBILE_CLAIM = "http://wso2.org/claims/mobile";
public static final String CHALLENGE_QUESTION_URI_CLAIM = "http://wso2.org/claims/challengeQuestionUris";
public static final String CHALLENGE_QUESTION_1_CLAIM = "http://wso2.org/claims/challengeQuestion1";
public static final String CHALLENGE_QUESTION_2_CLAIM = "http://wso2.org/claims/challengeQuestion2";
Expand All @@ -74,6 +75,8 @@ public static final class UserInfoRecovery {
public static final String RECOVERY_API_V2_RELATIVE_PATH = "/api/users/v2/recovery";
public static final String USER_API_RELATIVE_PATH = "/api/identity/user/v1.0";
public static final String RECOVERY_CALLBACK_REGEX = "Recovery.CallbackRegex";
public static final String MOBILE_CLAIM_REGEX = "^\\s*(?:\\+?(\\d{1,3}))?[\\-. (]*(\\d{2,3})[\\-. )]*" +
"(\\d{3})[\\-. ]*(\\d{4,6})(?: *x(\\d+))?\\s*$";
}

public static final class UserInfoRecoveryErrorDesc {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ public class PreferenceRetrievalClient {
private static final String PREFERENCE_API_RELATIVE_PATH = "/api/server/v1/identity-governance/preferences";
private static final String GOVERNANCE_API_RELATIVE_PATH = "/api/server/v1/identity-governance";
private static final String SELF_REGISTRATION_PROPERTY = "SelfRegistration.Enable";
private static final String USERNAME_RECOVERY_PROPERTY = "Recovery.Notification.Username.Enable";
private static final String QUESTION_PASSWORD_RECOVERY_PROPERTY = "Recovery.Question.Password.Enable";
private static final String SELF_SIGN_UP_LOCK_ON_CREATION_PROPERTY = "SelfRegistration.LockOnCreation";
private static final String MULTI_ATTRIBUTE_LOGIN_PROPERTY = "account.multiattributelogin.handler.enable";
Expand Down Expand Up @@ -137,13 +136,37 @@ public boolean checkSelfRegistrationShowUsernameUnavailability(String tenant)
/**
* Check username recovery is enabled or not.
*
* @param tenant tenant domain name.
* @param tenantDomain tenant domain name.
* @return returns true if username recovery enabled.
* @throws PreferenceRetrievalClientException
* @throws PreferenceRetrievalClientException If any PreferenceRetrievalClientException occurs.
*/
public boolean checkUsernameRecovery(String tenantDomain) throws PreferenceRetrievalClientException {

return checkPreference(tenantDomain, RECOVERY_CONNECTOR, IdPManagementConstants.USERNAME_RECOVERY_PROPERTY);
}

/**
* Check email based username recovery is enabled or not.
*
* @param tenantDomain tenant domain name.
* @return returns true if email based username recovery enabled.
* @throws PreferenceRetrievalClientException If any PreferenceRetrievalClientException occurs.
*/
public boolean checkEmailBasedUsernameRecovery(String tenantDomain) throws PreferenceRetrievalClientException {

return checkPreference(tenantDomain, RECOVERY_CONNECTOR, IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY);
}

/**
* Check SMS based username recovery is enabled or not.
*
* @param tenantDomain tenant domain name.
* @return returns true if SMS based username recovery enabled.
* @throws PreferenceRetrievalClientException If any PreferenceRetrievalClientException occurs.
*/
public boolean checkUsernameRecovery(String tenant) throws PreferenceRetrievalClientException {
public boolean checkSMSBasedUsernameRecovery(String tenantDomain) throws PreferenceRetrievalClientException {

return checkPreference(tenant, RECOVERY_CONNECTOR, USERNAME_RECOVERY_PROPERTY);
return checkPreference(tenantDomain, RECOVERY_CONNECTOR, IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ public class RecoveryApiV2 {
private static final String PATH_PASSWORD_RECOVERY_RESEND = "/password/resend";
private static final String PATH_PASSWORD_RECOVERY_CONFIRM = "/password/confirm";
private static final String PATH_PASSWORD_RECOVERY_RESET = "/password/reset";
private static final String PATH_USERNAME_RECOVERY_INIT = "/username/init";
private static final String PATH_USERNAME_RECOVERY_RECOVER = "/username/recover";

String basePath = IdentityManagementEndpointUtil.buildEndpointUrl(IdentityManagementEndpointConstants
.UserInfoRecovery.RECOVERY_API_V2_RELATIVE_PATH);
private ApiClient apiClient;
Expand All @@ -80,6 +83,35 @@ public void setApiClient(ApiClient apiClient) {
this.apiClient = apiClient;
}

/**
* Initiate recovering the forgotten username.
*
* @param recoveryInitRequest Username recovery initiating request. (required)
* @param tenantDomain Tenant Domain which user belongs. Default "carbon.super" (optional)
* @param headers If reCaptcha respond is found, embedded in request header. (optional)
* @return Account recovery options response object.
* @throws ApiException If fails to make API call.
*/
public List<AccountRecoveryType> initiateUsernameRecovery(RecoveryInitRequest recoveryInitRequest,
String tenantDomain, Map<String, String> headers)
throws ApiException {

return initiateRecovery(recoveryInitRequest, tenantDomain, headers, PATH_USERNAME_RECOVERY_INIT);
}

/**
* @param recoveryRequest Recovery request. (required)
* @param tenantDomain Tenant Domain which user belongs. Default "carbon.super" (optional)
* @param headers Any additional headers to be embedded. (optional)
* @return Recovery response.
* @throws ApiException If fails to make API call.
*/
public RecoveryResponse recoverUsername(RecoveryRequest recoveryRequest, String tenantDomain,
Map<String, String> headers) throws ApiException {

return recover(recoveryRequest, tenantDomain, headers, PATH_USERNAME_RECOVERY_RECOVER);
}

/**
* Initiate recovering the forgotten password.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public class PreferenceRetrievalClientTest {
private static final String SELF_REG_CALLBACK_REGEX_PROP = "SelfRegistration.CallbackRegex";
public static final String SHOW_USERNAME_UNAVAILABILITY = "SelfRegistration.ShowUsernameUnavailability";
private static final String USERNAME_RECOVERY_PROPERTY = "Recovery.Notification.Username.Enable";
private static final String EMAIL_USERNAME_RECOVERY_PROPERTY = "Recovery.Notification.Username.Email.Enable";
public static final String SMS_USERNAME_RECOVERY_PROPERTY = "Recovery.Notification.Username.SMS.Enable";
private static final String QUESTION_PASSWORD_RECOVERY_PROPERTY = "Recovery.Question.Password.Enable";
public static final String NOTIFICATION_PASSWORD_ENABLE_PROPERTY = "Recovery.Notification.Password.Enable";
public static final String EMAIL_LINK_PASSWORD_RECOVERY_PROPERTY =
Expand Down Expand Up @@ -130,6 +132,28 @@ public void testCheckUsernameRecovery() throws PreferenceRetrievalClientExceptio
USERNAME_RECOVERY_PROPERTY);
}

@Test
public void testCheckEmailBasedUsernameRecovery() throws PreferenceRetrievalClientException {

doReturn(true).when(preferenceRetrievalClient).
checkPreference(tenantDomain, RECOVERY_CONNECTOR, EMAIL_USERNAME_RECOVERY_PROPERTY);
boolean result = preferenceRetrievalClient.checkEmailBasedUsernameRecovery(tenantDomain);
assertTrue(result);
verify(preferenceRetrievalClient, times(1)).
checkPreference(tenantDomain, RECOVERY_CONNECTOR, EMAIL_USERNAME_RECOVERY_PROPERTY);
}

@Test
public void testCheckSMSBasedUsernameRecovery() throws PreferenceRetrievalClientException {

doReturn(true).when(preferenceRetrievalClient).
checkPreference(tenantDomain, RECOVERY_CONNECTOR, SMS_USERNAME_RECOVERY_PROPERTY);
boolean result = preferenceRetrievalClient.checkSMSBasedUsernameRecovery(tenantDomain);
assertTrue(result);
verify(preferenceRetrievalClient, times(1)).
checkPreference(tenantDomain, RECOVERY_CONNECTOR, SMS_USERNAME_RECOVERY_PROPERTY);
}

@Test
public void testCheckNotificationBasedPasswordRecovery() throws PreferenceRetrievalClientException {

Expand Down
Loading
Loading