From 457ead57dc1075cc9b5a10b3d6520b49e6138b08 Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Fri, 18 Oct 2024 14:03:31 +0530 Subject: [PATCH 01/23] Add config retrieval methods. --- .../client/PreferenceRetrievalClient.java | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/PreferenceRetrievalClient.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/PreferenceRetrievalClient.java index 10a4e7129f14..5befc6f8d665 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/PreferenceRetrievalClient.java +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/PreferenceRetrievalClient.java @@ -58,7 +58,7 @@ 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"; @@ -125,11 +125,35 @@ public boolean checkSelfRegistrationSendConfirmationOnCreation(String tenant) th * * @param tenant tenant domain name. * @return returns true if username recovery enabled. - * @throws PreferenceRetrievalClientException + * @throws PreferenceRetrievalClientException If any PreferenceRetrievalClientException occurs. */ public boolean checkUsernameRecovery(String tenant) throws PreferenceRetrievalClientException { - return checkPreference(tenant, RECOVERY_CONNECTOR, USERNAME_RECOVERY_PROPERTY); + return checkPreference(tenant, RECOVERY_CONNECTOR, IdPManagementConstants.USERNAME_RECOVERY_PROPERTY); + } + + /** + * Check email based username recovery is enabled or not. + * + * @param tenant tenant domain name. + * @return returns true if email based username recovery enabled. + * @throws PreferenceRetrievalClientException If any PreferenceRetrievalClientException occurs. + */ + public boolean checkEmailBasedUsernameRecovery(String tenant) throws PreferenceRetrievalClientException { + + return checkPreference(tenant, RECOVERY_CONNECTOR, IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY); + } + + /** + * Check SMS based username recovery is enabled or not. + * + * @param tenant tenant domain name. + * @return returns true if SMS based username recovery enabled. + * @throws PreferenceRetrievalClientException If any PreferenceRetrievalClientException occurs. + */ + public boolean checkSMSBasedUsernameRecovery(String tenant) throws PreferenceRetrievalClientException { + + return checkPreference(tenant, RECOVERY_CONNECTOR, IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY); } /** From 8b61745edc063481553a804071ef25bb54f0163c Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Fri, 18 Oct 2024 14:04:04 +0530 Subject: [PATCH 02/23] Add api call wrappers for username recovery v2. --- .../util/client/api/RecoveryApiV2.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/api/RecoveryApiV2.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/api/RecoveryApiV2.java index 449adde4d7c1..81c6b4edd8c1 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/api/RecoveryApiV2.java +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/api/RecoveryApiV2.java @@ -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; @@ -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 initiateUsernameRecovery(RecoveryInitRequest recoveryInitRequest, + String tenantDomain, Map 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 headers) throws ApiException { + + return recover(recoveryRequest, tenantDomain, headers, PATH_USERNAME_RECOVERY_RECOVER); + } + /** * Initiate recovering the forgotten password. * From d450e0ae7feaf974f8f466a01f6f2ea0798f6541 Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Fri, 18 Oct 2024 14:04:36 +0530 Subject: [PATCH 03/23] Add mobile claim to configs. --- .../mgt/endpoint/util/IdentityManagementEndpointConstants.java | 1 + 1 file changed, 1 insertion(+) diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/IdentityManagementEndpointConstants.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/IdentityManagementEndpointConstants.java index 29ef7a78b7a4..6f529eb89327 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/IdentityManagementEndpointConstants.java +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/IdentityManagementEndpointConstants.java @@ -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"; From 875ad37a16239135b26f52ab93d067c625e4516b Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Fri, 18 Oct 2024 14:04:56 +0530 Subject: [PATCH 04/23] Add username recovery configs. --- .../wso2/carbon/idp/mgt/util/IdPManagementConstants.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java index 0cfbadd94eac..6ae6bcf0ec37 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java @@ -129,6 +129,13 @@ public class IdPManagementConstants { public static final String SMS_OTP_PASSWORD_RECOVERY_PROPERTY = "Recovery.Notification.Password.smsOtp.Enable"; + // Resident IDP Username Recovery Configs + public static final String USERNAME_RECOVERY_PROPERTY = "Recovery.Notification.Username.Enable"; + public 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"; + + + public static class SQLQueries { public static final String GET_IDPS_SQL = "SELECT NAME, IS_PRIMARY, HOME_REALM_ID, DESCRIPTION, " + From 7a1f12046cefb55ec2c75548e7e2b27906898db3 Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Fri, 18 Oct 2024 14:14:28 +0530 Subject: [PATCH 05/23] Remove redundant empty lines. --- .../org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java index 6ae6bcf0ec37..b6069442335e 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java @@ -134,8 +134,6 @@ public class IdPManagementConstants { public 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"; - - public static class SQLQueries { public static final String GET_IDPS_SQL = "SELECT NAME, IS_PRIMARY, HOME_REALM_ID, DESCRIPTION, " + From 218d11bf3024090921c62248724dbbcc48dfd701 Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Fri, 18 Oct 2024 14:15:42 +0530 Subject: [PATCH 06/23] Modify the comments. --- .../org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java index b6069442335e..0d0d43c363f8 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java @@ -129,7 +129,7 @@ public class IdPManagementConstants { public static final String SMS_OTP_PASSWORD_RECOVERY_PROPERTY = "Recovery.Notification.Password.smsOtp.Enable"; - // Resident IDP Username Recovery Configs + // Resident IDP Username Recovery Configs. public static final String USERNAME_RECOVERY_PROPERTY = "Recovery.Notification.Username.Enable"; public 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"; From 554c76ab56b3dd961ff149eb310d4a2d4e5d1750 Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Fri, 18 Oct 2024 14:17:00 +0530 Subject: [PATCH 07/23] Remove redundant lines. --- .../mgt/endpoint/util/client/PreferenceRetrievalClient.java | 1 - 1 file changed, 1 deletion(-) diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/PreferenceRetrievalClient.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/PreferenceRetrievalClient.java index 5befc6f8d665..4253b97cd950 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/PreferenceRetrievalClient.java +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/PreferenceRetrievalClient.java @@ -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 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"; From 49baf92660c9cb7af533f57591f1f8761fe4d612 Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Fri, 18 Oct 2024 16:47:04 +0530 Subject: [PATCH 08/23] Add username recovery api to allowed endpoints. --- ...ication.authentication.framework.server.feature.default.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/resources/org.wso2.carbon.identity.application.authentication.framework.server.feature.default.json b/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/resources/org.wso2.carbon.identity.application.authentication.framework.server.feature.default.json index 5a1788816a67..644e3a2ae773 100644 --- a/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/resources/org.wso2.carbon.identity.application.authentication.framework.server.feature.default.json +++ b/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/resources/org.wso2.carbon.identity.application.authentication.framework.server.feature.default.json @@ -246,7 +246,7 @@ "account_recovery.endpoint.auth.hash":"66cd9688a2ae068244ea01e70f0e230f5623b7fa4cdecb65070a09ec06452262", "authorization_control.skip_authorization.client_authentication.name":"ClientAuthentication", - "authorization_control.skip_authorization.client_authentication.allowedEndpoints": "(.*)/accountrecoveryendpoint(.*),(.*)/api/identity/recovery/(.*),(.*)/data/AuthRequestKey/(.*),(.*)/applications(.*),(.*)/identity-governance(.*),(.*)/user/(.*)/validate-username(.*),(.*)/consent-mgt/v(.*)/consents/(.*),(.*)/user/v(.*)/me(.*),(.*)/identity/auth/v(.*)/data/(.*),(.*)/identity/user/v(.*)/validate-code,(.*)/api/server/v(.*)/identity-providers(.*),(.*)/api/identity/auth/(.*)/context(.*),(.*)/api/identity/user/v(.*)/resend-code(.*),(.*)/api/users/v2/recovery/password/(.*)", + "authorization_control.skip_authorization.client_authentication.allowedEndpoints": "(.*)/accountrecoveryendpoint(.*),(.*)/api/identity/recovery/(.*),(.*)/data/AuthRequestKey/(.*),(.*)/applications(.*),(.*)/identity-governance(.*),(.*)/user/(.*)/validate-username(.*),(.*)/consent-mgt/v(.*)/consents/(.*),(.*)/user/v(.*)/me(.*),(.*)/identity/auth/v(.*)/data/(.*),(.*)/identity/user/v(.*)/validate-code,(.*)/api/server/v(.*)/identity-providers(.*),(.*)/api/identity/auth/(.*)/context(.*),(.*)/api/identity/user/v(.*)/resend-code(.*),(.*)/api/users/v2/recovery/password/(.*),(.*)/api/users/v2/recovery/username/(.*)", "jit_provisioning.indelible_claims.claim_uris": [ "http://wso2.org/claims/userid", From fa56eb895de092b803ac586c0f468c7e38a8c4ad Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Thu, 24 Oct 2024 13:57:33 +0530 Subject: [PATCH 09/23] Add unit tests for the preferenceRetrieval class. --- .../util/PreferenceRetrievalClientTest.java | 235 ++++++++++++++++++ .../src/test/resources/testng.xml | 1 + 2 files changed, 236 insertions(+) create mode 100644 components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java new file mode 100644 index 000000000000..353e09400aa2 --- /dev/null +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.mgt.endpoint.util; + +import org.apache.http.StatusLine; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.testng.MockitoTestNGListener; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Listeners; +import org.testng.annotations.Test; +import org.wso2.carbon.identity.mgt.endpoint.util.client.PreferenceRetrievalClient; +import org.wso2.carbon.identity.mgt.endpoint.util.client.PreferenceRetrievalClientException; +import org.wso2.carbon.utils.HTTPClientUtils; + +import java.io.IOException; +import java.util.Optional; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; + +@Listeners(MockitoTestNGListener.class) +public class PreferenceRetrievalClientTest { + + private PreferenceRetrievalClient preferenceRetrievalClient; + private PreferenceRetrievalClient preferenceRetrievalClientSpy; + private String tenantDomain; + private String callabackURL; + + @BeforeClass + public void setup() throws PreferenceRetrievalClientException { + + this.tenantDomain = "admin"; + this.callabackURL = "test"; + this.preferenceRetrievalClient = new PreferenceRetrievalClient(); + this.preferenceRetrievalClientSpy = Mockito.spy(preferenceRetrievalClient); + + Mockito.doReturn(true).when(preferenceRetrievalClientSpy).checkPreference(anyString(), + anyString(), anyString(), Mockito.anyBoolean()); + Mockito.doReturn(Optional.of("test")).when(preferenceRetrievalClientSpy).getPropertyValue(anyString(), + anyString(), anyString(), anyString()); + Mockito.doReturn(true).when(preferenceRetrievalClientSpy).checkMultiplePreference(anyString(), anyString(), + any()); + + } + + @Test + public void testCheckPreference() throws PreferenceRetrievalClientException { + + try (MockedStatic identityManagementEndpointUtilMockedStatic = + Mockito.mockStatic(IdentityManagementEndpointUtil.class)) { + identityManagementEndpointUtilMockedStatic.when( + () -> IdentityManagementEndpointUtil.getBasePath(anyString(), anyString())) + .thenReturn("https://localhost:9443/api/server/v1/identity-governance/preferences"); + + CloseableHttpResponse closeableHttpResponse = Mockito.mock(CloseableHttpResponse.class); + + CloseableHttpClient closeableHttpClient = Mockito.mock(CloseableHttpClient.class); + Mockito.when(closeableHttpClient.execute(any())).thenReturn(closeableHttpResponse); + + StatusLine statusLine = Mockito.mock(StatusLine.class); + Mockito.when(statusLine.getStatusCode()).thenReturn(201); + Mockito.when(closeableHttpResponse.getStatusLine()).thenReturn(statusLine); + + HttpClientBuilder httpClientBuilder = Mockito.mock(HttpClientBuilder.class); + Mockito.when(httpClientBuilder.build()).thenReturn(closeableHttpClient); + try (MockedStatic httpClientUtilsMockedStatic = Mockito.mockStatic( + HTTPClientUtils.class)) { + httpClientUtilsMockedStatic.when(HTTPClientUtils::createClientWithCustomVerifier) + .thenReturn(httpClientBuilder); + + IdentityManagementServiceUtil identityManagementServiceUtil = + Mockito.mock(IdentityManagementServiceUtil.class); + Mockito.when(identityManagementServiceUtil.getAppName()).thenReturn("testAppName"); + Mockito.when(identityManagementServiceUtil.getAppPassword()).thenReturn("testPassword".toCharArray()); + + try (MockedStatic identityManagementServiceUtilMockedStatic = + Mockito.mockStatic(IdentityManagementServiceUtil.class)) { + + identityManagementServiceUtilMockedStatic.when(IdentityManagementServiceUtil::getInstance) + .thenReturn(identityManagementServiceUtil); + assertTrue(preferenceRetrievalClient.checkSelfRegistration(tenantDomain)); + } + } + + } catch (IOException e) { + throw new RuntimeException(e); + } + + } + + @Test + public void testCheckSelfRegistration() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkSelfRegistration(tenantDomain)); + } + + @Test + public void testCheckSelfRegistrationOnLockCreation() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkSelfRegistrationLockOnCreation(tenantDomain)); + } + + @Test + public void testCheckSelfRegistrationSendConfirmationOnCreation() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkSelfRegistrationSendConfirmationOnCreation(tenantDomain)); + } + + @Test + public void testCheckUsernameRecovery() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkUsernameRecovery(tenantDomain)); + } + + @Test + public void testCheckEmailBasedUsernameRecovery() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkEmailBasedUsernameRecovery(tenantDomain)); + } + + @Test + public void testCheckSMSBasedUsernameRecovery() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkSMSBasedUsernameRecovery(tenantDomain)); + } + + @Test + public void testCheckNotificationBasedPasswordRecovery() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkNotificationBasedPasswordRecovery(tenantDomain)); + } + + @Test + public void testCheckEmailLinkBasedPasswordRecovery() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkEmailLinkBasedPasswordRecovery(tenantDomain)); + } + + @Test + public void testCheckSMSOTPBasedPasswordRecovery() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkSMSOTPBasedPasswordRecovery(tenantDomain)); + } + + @Test + public void testCheckQuestionBasedPasswordRecovery() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkQuestionBasedPasswordRecovery(tenantDomain)); + } + + @Test + public void testCheckMultiAttributeLogin() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkMultiAttributeLogin(tenantDomain)); + } + + @Test + public void testCheckTypingDNA() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkTypingDNA(tenantDomain)); + } + + @Test + public void testCheckAutoLoginAfterSelfRegistrationEnabled() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkAutoLoginAfterSelfRegistrationEnabled(tenantDomain)); + } + + @Test + public void testCheckAutoLoginAfterPasswordRecoveryEnabled() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkAutoLoginAfterPasswordRecoveryEnabled(tenantDomain)); + } + + @Test + public void testCheckMultiAttributeLoginProperty() throws PreferenceRetrievalClientException { + + assertEquals(preferenceRetrievalClientSpy.checkMultiAttributeLoginProperty(tenantDomain), "test"); + } + + @Test + public void testCheckMultiAttributeLoginPropertyNull() throws PreferenceRetrievalClientException { + + Mockito.doReturn(Optional.empty()).when(preferenceRetrievalClientSpy).getPropertyValue(anyString(), anyString(), + anyString(), anyString()); + assertNull(preferenceRetrievalClientSpy.checkMultiAttributeLoginProperty(tenantDomain)); + } + + @Test + public void testCheckIfRecoveryCallbackURLValid() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkIfRecoveryCallbackURLValid(tenantDomain, callabackURL)); + } + + @Test + public void testCheckIfSelfRegCallbackURLValid() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkIfSelfRegCallbackURLValid(tenantDomain, callabackURL)); + } + + @Test + public void testCheckIfLiteRegCallbackURLValid() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkIfLiteRegCallbackURLValid(tenantDomain, callabackURL)); + } + + @Test + public void checkCheckPasswordRecovery() throws PreferenceRetrievalClientException { + + assertTrue(preferenceRetrievalClientSpy.checkPasswordRecovery(tenantDomain)); + } +} diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/resources/testng.xml b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/resources/testng.xml index 065ec256c58a..8a120f99571b 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/resources/testng.xml +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/resources/testng.xml @@ -25,6 +25,7 @@ + From e16faff2e51cfdf79c0fda156d948337c86c2eb3 Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Thu, 24 Oct 2024 14:08:34 +0530 Subject: [PATCH 10/23] Remove the test class. --- .../util/PreferenceRetrievalClientTest.java | 235 ------------------ .../src/test/resources/testng.xml | 1 - 2 files changed, 236 deletions(-) delete mode 100644 components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java deleted file mode 100644 index 353e09400aa2..000000000000 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). - * - * WSO2 LLC. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.wso2.carbon.identity.mgt.endpoint.util; - -import org.apache.http.StatusLine; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.testng.MockitoTestNGListener; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Listeners; -import org.testng.annotations.Test; -import org.wso2.carbon.identity.mgt.endpoint.util.client.PreferenceRetrievalClient; -import org.wso2.carbon.identity.mgt.endpoint.util.client.PreferenceRetrievalClientException; -import org.wso2.carbon.utils.HTTPClientUtils; - -import java.io.IOException; -import java.util.Optional; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; - -@Listeners(MockitoTestNGListener.class) -public class PreferenceRetrievalClientTest { - - private PreferenceRetrievalClient preferenceRetrievalClient; - private PreferenceRetrievalClient preferenceRetrievalClientSpy; - private String tenantDomain; - private String callabackURL; - - @BeforeClass - public void setup() throws PreferenceRetrievalClientException { - - this.tenantDomain = "admin"; - this.callabackURL = "test"; - this.preferenceRetrievalClient = new PreferenceRetrievalClient(); - this.preferenceRetrievalClientSpy = Mockito.spy(preferenceRetrievalClient); - - Mockito.doReturn(true).when(preferenceRetrievalClientSpy).checkPreference(anyString(), - anyString(), anyString(), Mockito.anyBoolean()); - Mockito.doReturn(Optional.of("test")).when(preferenceRetrievalClientSpy).getPropertyValue(anyString(), - anyString(), anyString(), anyString()); - Mockito.doReturn(true).when(preferenceRetrievalClientSpy).checkMultiplePreference(anyString(), anyString(), - any()); - - } - - @Test - public void testCheckPreference() throws PreferenceRetrievalClientException { - - try (MockedStatic identityManagementEndpointUtilMockedStatic = - Mockito.mockStatic(IdentityManagementEndpointUtil.class)) { - identityManagementEndpointUtilMockedStatic.when( - () -> IdentityManagementEndpointUtil.getBasePath(anyString(), anyString())) - .thenReturn("https://localhost:9443/api/server/v1/identity-governance/preferences"); - - CloseableHttpResponse closeableHttpResponse = Mockito.mock(CloseableHttpResponse.class); - - CloseableHttpClient closeableHttpClient = Mockito.mock(CloseableHttpClient.class); - Mockito.when(closeableHttpClient.execute(any())).thenReturn(closeableHttpResponse); - - StatusLine statusLine = Mockito.mock(StatusLine.class); - Mockito.when(statusLine.getStatusCode()).thenReturn(201); - Mockito.when(closeableHttpResponse.getStatusLine()).thenReturn(statusLine); - - HttpClientBuilder httpClientBuilder = Mockito.mock(HttpClientBuilder.class); - Mockito.when(httpClientBuilder.build()).thenReturn(closeableHttpClient); - try (MockedStatic httpClientUtilsMockedStatic = Mockito.mockStatic( - HTTPClientUtils.class)) { - httpClientUtilsMockedStatic.when(HTTPClientUtils::createClientWithCustomVerifier) - .thenReturn(httpClientBuilder); - - IdentityManagementServiceUtil identityManagementServiceUtil = - Mockito.mock(IdentityManagementServiceUtil.class); - Mockito.when(identityManagementServiceUtil.getAppName()).thenReturn("testAppName"); - Mockito.when(identityManagementServiceUtil.getAppPassword()).thenReturn("testPassword".toCharArray()); - - try (MockedStatic identityManagementServiceUtilMockedStatic = - Mockito.mockStatic(IdentityManagementServiceUtil.class)) { - - identityManagementServiceUtilMockedStatic.when(IdentityManagementServiceUtil::getInstance) - .thenReturn(identityManagementServiceUtil); - assertTrue(preferenceRetrievalClient.checkSelfRegistration(tenantDomain)); - } - } - - } catch (IOException e) { - throw new RuntimeException(e); - } - - } - - @Test - public void testCheckSelfRegistration() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkSelfRegistration(tenantDomain)); - } - - @Test - public void testCheckSelfRegistrationOnLockCreation() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkSelfRegistrationLockOnCreation(tenantDomain)); - } - - @Test - public void testCheckSelfRegistrationSendConfirmationOnCreation() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkSelfRegistrationSendConfirmationOnCreation(tenantDomain)); - } - - @Test - public void testCheckUsernameRecovery() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkUsernameRecovery(tenantDomain)); - } - - @Test - public void testCheckEmailBasedUsernameRecovery() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkEmailBasedUsernameRecovery(tenantDomain)); - } - - @Test - public void testCheckSMSBasedUsernameRecovery() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkSMSBasedUsernameRecovery(tenantDomain)); - } - - @Test - public void testCheckNotificationBasedPasswordRecovery() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkNotificationBasedPasswordRecovery(tenantDomain)); - } - - @Test - public void testCheckEmailLinkBasedPasswordRecovery() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkEmailLinkBasedPasswordRecovery(tenantDomain)); - } - - @Test - public void testCheckSMSOTPBasedPasswordRecovery() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkSMSOTPBasedPasswordRecovery(tenantDomain)); - } - - @Test - public void testCheckQuestionBasedPasswordRecovery() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkQuestionBasedPasswordRecovery(tenantDomain)); - } - - @Test - public void testCheckMultiAttributeLogin() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkMultiAttributeLogin(tenantDomain)); - } - - @Test - public void testCheckTypingDNA() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkTypingDNA(tenantDomain)); - } - - @Test - public void testCheckAutoLoginAfterSelfRegistrationEnabled() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkAutoLoginAfterSelfRegistrationEnabled(tenantDomain)); - } - - @Test - public void testCheckAutoLoginAfterPasswordRecoveryEnabled() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkAutoLoginAfterPasswordRecoveryEnabled(tenantDomain)); - } - - @Test - public void testCheckMultiAttributeLoginProperty() throws PreferenceRetrievalClientException { - - assertEquals(preferenceRetrievalClientSpy.checkMultiAttributeLoginProperty(tenantDomain), "test"); - } - - @Test - public void testCheckMultiAttributeLoginPropertyNull() throws PreferenceRetrievalClientException { - - Mockito.doReturn(Optional.empty()).when(preferenceRetrievalClientSpy).getPropertyValue(anyString(), anyString(), - anyString(), anyString()); - assertNull(preferenceRetrievalClientSpy.checkMultiAttributeLoginProperty(tenantDomain)); - } - - @Test - public void testCheckIfRecoveryCallbackURLValid() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkIfRecoveryCallbackURLValid(tenantDomain, callabackURL)); - } - - @Test - public void testCheckIfSelfRegCallbackURLValid() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkIfSelfRegCallbackURLValid(tenantDomain, callabackURL)); - } - - @Test - public void testCheckIfLiteRegCallbackURLValid() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkIfLiteRegCallbackURLValid(tenantDomain, callabackURL)); - } - - @Test - public void checkCheckPasswordRecovery() throws PreferenceRetrievalClientException { - - assertTrue(preferenceRetrievalClientSpy.checkPasswordRecovery(tenantDomain)); - } -} diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/resources/testng.xml b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/resources/testng.xml index 8a120f99571b..065ec256c58a 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/resources/testng.xml +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/resources/testng.xml @@ -25,7 +25,6 @@ - From 61ed13bc28692f6d2db580f3497ab8c28488d1ca Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Thu, 24 Oct 2024 14:17:43 +0530 Subject: [PATCH 11/23] Add unit tests for the recovery configs. --- .../util/PreferenceRetrievalClientTest.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java index 5ff458ad8a4e..8357f047da2b 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java @@ -50,6 +50,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 = @@ -134,6 +136,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 { From 8ff76601da3afff3cfba242f337bb9b492f27c03 Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Mon, 28 Oct 2024 11:46:24 +0530 Subject: [PATCH 12/23] Add unit tests for the recoveryApiV2 --- .../mgt/endpoint/util/RecoveryApiV2Test.java | 245 ++++++++++++++++++ .../src/test/resources/testng.xml | 1 + 2 files changed, 246 insertions(+) create mode 100644 components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java new file mode 100644 index 000000000000..7e5e6d31a699 --- /dev/null +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java @@ -0,0 +1,245 @@ +package org.wso2.carbon.identity.mgt.endpoint.util; + +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.MockitoAnnotations; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.wso2.carbon.identity.mgt.endpoint.util.client.ApiClient; +import org.wso2.carbon.identity.mgt.endpoint.util.client.ApiException; +import org.wso2.carbon.identity.mgt.endpoint.util.client.api.RecoveryApiV2; +import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.AccountRecoveryType; +import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.ConfirmRequest; +import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.ConfirmResponse; +import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.RecoveryInitRequest; +import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.RecoveryRequest; +import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.RecoveryResponse; +import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.ResendRequest; +import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.ResendResponse; +import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.ResetRequest; +import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.ResetResponse; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertEquals; + +public class RecoveryApiV2Test { + + public static final String RECOVERY_API_V2_RELATIVE_PATH = "/api/users/v2/recovery"; + private static final String tenantDomain = "carbon.super"; + private static final String POST = "POST"; + private static final String PATH_PASSWORD_RECOVERY_INIT = "/password/init"; + private static final String PATH_PASSWORD_RECOVERY_RECOVER = "/password/recover"; + 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"; + // Test values. + private static final String TEST_ACCEPT_HEADER = "testAcceptHeader"; + private static final String TEST_CONTENT_HEADER = "testContentHeader"; + private static final String TEST_PATH = "testPath"; + private static final Map headers = new HashMap<>(); + + @Mock + ApiClient apiClient; + + RecoveryApiV2 recoveryApiV2; + + @BeforeMethod + public void setup() { + + MockitoAnnotations.openMocks(this); + + when(apiClient.selectHeaderAccept(any())).thenReturn(TEST_ACCEPT_HEADER); + when(apiClient.selectHeaderContentType(any())).thenReturn(TEST_CONTENT_HEADER); + + try (MockedStatic identityManagementEndpointUtilMockedStatic = + mockStatic(IdentityManagementEndpointUtil.class)) { + identityManagementEndpointUtilMockedStatic.when( + () -> IdentityManagementEndpointUtil.buildEndpointUrl(anyString())) + .thenReturn(TEST_PATH); + + recoveryApiV2 = new RecoveryApiV2(apiClient); + } + + } + + @Test + public void testInitiateUsernameRecovery() throws ApiException { + + List expected = new ArrayList<>(); + expected.add(new AccountRecoveryType()); + + when(apiClient.invokeAPI(eq(PATH_USERNAME_RECOVERY_INIT), eq(POST), any(), any(), any(), any(), + eq(TEST_ACCEPT_HEADER), + eq(TEST_CONTENT_HEADER), + any(), any())).thenReturn(expected); + + try (MockedStatic identityManagementEndpointUtilMockedStatic = + mockStatic(IdentityManagementEndpointUtil.class)) { + identityManagementEndpointUtilMockedStatic.when( + () -> IdentityManagementEndpointUtil.getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)) + .thenReturn(TEST_PATH); + + RecoveryApiV2 recoveryApiV2 = new RecoveryApiV2(apiClient); + List result = + recoveryApiV2.initiateUsernameRecovery(new RecoveryInitRequest(), tenantDomain, headers); + assertEquals(result, expected); + } + } + + @Test + public void testRecoverUsername() throws ApiException { + + RecoveryResponse expected = new RecoveryResponse(); + when(apiClient.invokeAPI(eq(PATH_USERNAME_RECOVERY_RECOVER), eq(POST), any(), any(), any(), any(), + eq(TEST_ACCEPT_HEADER), + eq(TEST_CONTENT_HEADER), + any(), any())).thenReturn(expected); + + try (MockedStatic identityManagementEndpointUtilMockedStatic = + mockStatic(IdentityManagementEndpointUtil.class)) { + identityManagementEndpointUtilMockedStatic.when( + () -> IdentityManagementEndpointUtil.getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)) + .thenReturn(TEST_PATH); + + RecoveryApiV2 recoveryApiV2 = new RecoveryApiV2(apiClient); + RecoveryResponse result = recoveryApiV2.recoverUsername(new RecoveryRequest(), tenantDomain, headers); + assertEquals(result, expected); + } + } + + @Test + public void testInitiatePasswordRecovery() throws ApiException { + + List expected = new ArrayList<>(); + expected.add(new AccountRecoveryType()); + + when(apiClient.invokeAPI(eq(PATH_PASSWORD_RECOVERY_INIT), eq(POST), any(), any(), any(), any(), + eq(TEST_ACCEPT_HEADER), + eq(TEST_CONTENT_HEADER), + any(), any())).thenReturn(expected); + + try (MockedStatic identityManagementEndpointUtilMockedStatic = + mockStatic(IdentityManagementEndpointUtil.class)) { + identityManagementEndpointUtilMockedStatic.when( + () -> IdentityManagementEndpointUtil.getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)) + .thenReturn(TEST_PATH); + + RecoveryApiV2 recoveryApiV2 = new RecoveryApiV2(apiClient); + List result = + recoveryApiV2.initiatePasswordRecovery(new RecoveryInitRequest(), tenantDomain, + headers); + assertEquals(result, expected); + } + } + + @Test + public void testRecoverPassword() throws ApiException { + + RecoveryResponse expected = new RecoveryResponse(); + when(apiClient.invokeAPI(eq(PATH_PASSWORD_RECOVERY_RECOVER), eq(POST), any(), any(), any(), any(), + eq(TEST_ACCEPT_HEADER), + eq(TEST_CONTENT_HEADER), + any(), any())).thenReturn(expected); + + try (MockedStatic identityManagementEndpointUtilMockedStatic = + mockStatic(IdentityManagementEndpointUtil.class)) { + identityManagementEndpointUtilMockedStatic.when( + () -> IdentityManagementEndpointUtil.getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)) + .thenReturn(TEST_PATH); + + RecoveryApiV2 recoveryApiV2 = new RecoveryApiV2(apiClient); + RecoveryResponse result = recoveryApiV2.recoverPassword(new RecoveryRequest(), tenantDomain, headers); + assertEquals(result, expected); + } + } + + @Test + public void testResendPasswordNotification() throws ApiException { + + ResendResponse expected = new ResendResponse(); + when(apiClient.invokeAPI(eq(PATH_PASSWORD_RECOVERY_RESEND), eq(POST), any(), any(), any(), any(), + eq(TEST_ACCEPT_HEADER), + eq(TEST_CONTENT_HEADER), + any(), any())).thenReturn(expected); + + try (MockedStatic identityManagementEndpointUtilMockedStatic = + mockStatic(IdentityManagementEndpointUtil.class)) { + identityManagementEndpointUtilMockedStatic.when( + () -> IdentityManagementEndpointUtil.getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)) + .thenReturn(TEST_PATH); + + RecoveryApiV2 recoveryApiV2 = new RecoveryApiV2(apiClient); + ResendResponse result = + recoveryApiV2.resendPasswordNotification(new ResendRequest(), tenantDomain, headers); + assertEquals(result, expected); + } + } + + @Test + public void testConfirmPasswordRecovery() throws ApiException { + + ConfirmResponse expected = new ConfirmResponse(); + when(apiClient.invokeAPI(eq(PATH_PASSWORD_RECOVERY_CONFIRM), eq(POST), any(), any(), any(), any(), + eq(TEST_ACCEPT_HEADER), + eq(TEST_CONTENT_HEADER), + any(), any())).thenReturn(expected); + + try (MockedStatic identityManagementEndpointUtilMockedStatic = + mockStatic(IdentityManagementEndpointUtil.class)) { + identityManagementEndpointUtilMockedStatic.when( + () -> IdentityManagementEndpointUtil.getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)) + .thenReturn(TEST_PATH); + + RecoveryApiV2 recoveryApiV2 = new RecoveryApiV2(apiClient); + ConfirmResponse result = recoveryApiV2.confirmPasswordRecovery(new ConfirmRequest(), tenantDomain, headers); + assertEquals(result, expected); + } + } + + @Test + public void testResetUserPassword() throws ApiException { + + ResetResponse expected = new ResetResponse(); + when(apiClient.invokeAPI(eq(PATH_PASSWORD_RECOVERY_RESET), eq(POST), any(), any(), any(), any(), + eq(TEST_ACCEPT_HEADER), + eq(TEST_CONTENT_HEADER), + any(), any())).thenReturn(expected); + + try (MockedStatic identityManagementEndpointUtilMockedStatic = + mockStatic(IdentityManagementEndpointUtil.class)) { + identityManagementEndpointUtilMockedStatic.when( + () -> IdentityManagementEndpointUtil.getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)) + .thenReturn(TEST_PATH); + + recoveryApiV2.setApiClient(apiClient); + ResetResponse result = recoveryApiV2.resetUserPassword(new ResetRequest(), tenantDomain, headers); + assertEquals(result, expected); + } + } + + @Test + public void testGetApiClient() { + + assertEquals(recoveryApiV2.getApiClient(), apiClient); + + } + + @Test + public void testSetApiClient() { + + recoveryApiV2.setApiClient(apiClient); + assertEquals(recoveryApiV2.getApiClient(), apiClient); + } + +} diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/resources/testng.xml b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/resources/testng.xml index 8a120f99571b..f3ab9359f19b 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/resources/testng.xml +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/resources/testng.xml @@ -29,6 +29,7 @@ + From 68495d97ca7fb461a59ea591654294698a6a8cab Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Mon, 28 Oct 2024 12:16:13 +0530 Subject: [PATCH 13/23] Reformat the code. --- .../mgt/endpoint/util/RecoveryApiV2Test.java | 60 ++++++++++--------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java index 7e5e6d31a699..e2a4ee11f4a0 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.wso2.carbon.identity.mgt.endpoint.util; import org.mockito.Mock; @@ -86,11 +104,9 @@ public void testInitiateUsernameRecovery() throws ApiException { try (MockedStatic identityManagementEndpointUtilMockedStatic = mockStatic(IdentityManagementEndpointUtil.class)) { - identityManagementEndpointUtilMockedStatic.when( - () -> IdentityManagementEndpointUtil.getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)) - .thenReturn(TEST_PATH); + identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. + getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); - RecoveryApiV2 recoveryApiV2 = new RecoveryApiV2(apiClient); List result = recoveryApiV2.initiateUsernameRecovery(new RecoveryInitRequest(), tenantDomain, headers); assertEquals(result, expected); @@ -108,11 +124,9 @@ public void testRecoverUsername() throws ApiException { try (MockedStatic identityManagementEndpointUtilMockedStatic = mockStatic(IdentityManagementEndpointUtil.class)) { - identityManagementEndpointUtilMockedStatic.when( - () -> IdentityManagementEndpointUtil.getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)) - .thenReturn(TEST_PATH); + identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. + getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); - RecoveryApiV2 recoveryApiV2 = new RecoveryApiV2(apiClient); RecoveryResponse result = recoveryApiV2.recoverUsername(new RecoveryRequest(), tenantDomain, headers); assertEquals(result, expected); } @@ -131,11 +145,9 @@ public void testInitiatePasswordRecovery() throws ApiException { try (MockedStatic identityManagementEndpointUtilMockedStatic = mockStatic(IdentityManagementEndpointUtil.class)) { - identityManagementEndpointUtilMockedStatic.when( - () -> IdentityManagementEndpointUtil.getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)) - .thenReturn(TEST_PATH); + identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. + getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); - RecoveryApiV2 recoveryApiV2 = new RecoveryApiV2(apiClient); List result = recoveryApiV2.initiatePasswordRecovery(new RecoveryInitRequest(), tenantDomain, headers); @@ -154,11 +166,9 @@ public void testRecoverPassword() throws ApiException { try (MockedStatic identityManagementEndpointUtilMockedStatic = mockStatic(IdentityManagementEndpointUtil.class)) { - identityManagementEndpointUtilMockedStatic.when( - () -> IdentityManagementEndpointUtil.getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)) - .thenReturn(TEST_PATH); + identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. + getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); - RecoveryApiV2 recoveryApiV2 = new RecoveryApiV2(apiClient); RecoveryResponse result = recoveryApiV2.recoverPassword(new RecoveryRequest(), tenantDomain, headers); assertEquals(result, expected); } @@ -175,11 +185,9 @@ public void testResendPasswordNotification() throws ApiException { try (MockedStatic identityManagementEndpointUtilMockedStatic = mockStatic(IdentityManagementEndpointUtil.class)) { - identityManagementEndpointUtilMockedStatic.when( - () -> IdentityManagementEndpointUtil.getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)) - .thenReturn(TEST_PATH); + identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. + getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); - RecoveryApiV2 recoveryApiV2 = new RecoveryApiV2(apiClient); ResendResponse result = recoveryApiV2.resendPasswordNotification(new ResendRequest(), tenantDomain, headers); assertEquals(result, expected); @@ -197,11 +205,9 @@ public void testConfirmPasswordRecovery() throws ApiException { try (MockedStatic identityManagementEndpointUtilMockedStatic = mockStatic(IdentityManagementEndpointUtil.class)) { - identityManagementEndpointUtilMockedStatic.when( - () -> IdentityManagementEndpointUtil.getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)) - .thenReturn(TEST_PATH); + identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. + getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); - RecoveryApiV2 recoveryApiV2 = new RecoveryApiV2(apiClient); ConfirmResponse result = recoveryApiV2.confirmPasswordRecovery(new ConfirmRequest(), tenantDomain, headers); assertEquals(result, expected); } @@ -218,11 +224,9 @@ public void testResetUserPassword() throws ApiException { try (MockedStatic identityManagementEndpointUtilMockedStatic = mockStatic(IdentityManagementEndpointUtil.class)) { - identityManagementEndpointUtilMockedStatic.when( - () -> IdentityManagementEndpointUtil.getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)) - .thenReturn(TEST_PATH); + identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. + getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); - recoveryApiV2.setApiClient(apiClient); ResetResponse result = recoveryApiV2.resetUserPassword(new ResetRequest(), tenantDomain, headers); assertEquals(result, expected); } From 3b8c9cdf5d2bb5a587c2db03b762ee62b2316073 Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Mon, 28 Oct 2024 15:43:14 +0530 Subject: [PATCH 14/23] Update the unit test with Error checks. --- .../mgt/endpoint/util/RecoveryApiV2Test.java | 49 +++++++++++++++---- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java index e2a4ee11f4a0..c3a37422a76a 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java @@ -65,7 +65,9 @@ public class RecoveryApiV2Test { private static final String TEST_ACCEPT_HEADER = "testAcceptHeader"; private static final String TEST_CONTENT_HEADER = "testContentHeader"; private static final String TEST_PATH = "testPath"; - private static final Map headers = new HashMap<>(); + private static final Map headers = new HashMap() {{ + put("Test-Header", "TestHeaderValue"); + }}; @Mock ApiClient apiClient; @@ -108,7 +110,7 @@ public void testInitiateUsernameRecovery() throws ApiException { getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); List result = - recoveryApiV2.initiateUsernameRecovery(new RecoveryInitRequest(), tenantDomain, headers); + recoveryApiV2.initiateUsernameRecovery(new RecoveryInitRequest(), "", headers); assertEquals(result, expected); } } @@ -127,7 +129,7 @@ public void testRecoverUsername() throws ApiException { identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); - RecoveryResponse result = recoveryApiV2.recoverUsername(new RecoveryRequest(), tenantDomain, headers); + RecoveryResponse result = recoveryApiV2.recoverUsername(new RecoveryRequest(), "", headers); assertEquals(result, expected); } } @@ -149,8 +151,7 @@ public void testInitiatePasswordRecovery() throws ApiException { getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); List result = - recoveryApiV2.initiatePasswordRecovery(new RecoveryInitRequest(), tenantDomain, - headers); + recoveryApiV2.initiatePasswordRecovery(new RecoveryInitRequest(), "", headers); assertEquals(result, expected); } } @@ -169,7 +170,7 @@ public void testRecoverPassword() throws ApiException { identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); - RecoveryResponse result = recoveryApiV2.recoverPassword(new RecoveryRequest(), tenantDomain, headers); + RecoveryResponse result = recoveryApiV2.recoverPassword(new RecoveryRequest(), "", headers); assertEquals(result, expected); } } @@ -189,7 +190,7 @@ public void testResendPasswordNotification() throws ApiException { getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); ResendResponse result = - recoveryApiV2.resendPasswordNotification(new ResendRequest(), tenantDomain, headers); + recoveryApiV2.resendPasswordNotification(new ResendRequest(), "", headers); assertEquals(result, expected); } } @@ -208,7 +209,8 @@ public void testConfirmPasswordRecovery() throws ApiException { identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); - ConfirmResponse result = recoveryApiV2.confirmPasswordRecovery(new ConfirmRequest(), tenantDomain, headers); + ConfirmResponse result = recoveryApiV2. + confirmPasswordRecovery(new ConfirmRequest(), "", headers); assertEquals(result, expected); } } @@ -227,7 +229,7 @@ public void testResetUserPassword() throws ApiException { identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); - ResetResponse result = recoveryApiV2.resetUserPassword(new ResetRequest(), tenantDomain, headers); + ResetResponse result = recoveryApiV2.resetUserPassword(new ResetRequest(), "", headers); assertEquals(result, expected); } } @@ -246,4 +248,33 @@ public void testSetApiClient() { assertEquals(recoveryApiV2.getApiClient(), apiClient); } + @Test(expectedExceptions = ApiException.class) + public void testInitiateUsernameRecoveryWithNullRequest() throws ApiException { + + recoveryApiV2.initiateUsernameRecovery(null, tenantDomain, headers); + } + + @Test(expectedExceptions = ApiException.class) + public void testRecoverUsernameWithNullRequest() throws ApiException { + + recoveryApiV2.recoverUsername(null, tenantDomain, headers); + } + + @Test(expectedExceptions = ApiException.class) + public void testResendPasswordNotificationWithNullRequest() throws ApiException { + + recoveryApiV2.resendPasswordNotification(null, tenantDomain, headers); + } + + @Test(expectedExceptions = ApiException.class) + public void testConfirmPasswordRecoveryWithNullRequest() throws ApiException { + + recoveryApiV2.confirmPasswordRecovery(null, tenantDomain, headers); + } + + @Test(expectedExceptions = ApiException.class) + public void testResetUserPasswordWithNullRequest() throws ApiException { + + recoveryApiV2.resetUserPassword(null, tenantDomain, headers); + } } From 289a5bf4eacee340264d56bfe8f30cbe713adfbc Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Wed, 30 Oct 2024 09:06:08 +0530 Subject: [PATCH 15/23] Update the variable name in the tests. --- .../mgt/endpoint/util/RecoveryApiV2Test.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java index c3a37422a76a..47b71bddc2f8 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java @@ -52,7 +52,7 @@ public class RecoveryApiV2Test { public static final String RECOVERY_API_V2_RELATIVE_PATH = "/api/users/v2/recovery"; - private static final String tenantDomain = "carbon.super"; + private static final String TENANT_DOMAIN = "carbon.super"; private static final String POST = "POST"; private static final String PATH_PASSWORD_RECOVERY_INIT = "/password/init"; private static final String PATH_PASSWORD_RECOVERY_RECOVER = "/password/recover"; @@ -107,7 +107,7 @@ public void testInitiateUsernameRecovery() throws ApiException { try (MockedStatic identityManagementEndpointUtilMockedStatic = mockStatic(IdentityManagementEndpointUtil.class)) { identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. - getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); + getBasePath(TENANT_DOMAIN, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); List result = recoveryApiV2.initiateUsernameRecovery(new RecoveryInitRequest(), "", headers); @@ -127,7 +127,7 @@ public void testRecoverUsername() throws ApiException { try (MockedStatic identityManagementEndpointUtilMockedStatic = mockStatic(IdentityManagementEndpointUtil.class)) { identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. - getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); + getBasePath(TENANT_DOMAIN, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); RecoveryResponse result = recoveryApiV2.recoverUsername(new RecoveryRequest(), "", headers); assertEquals(result, expected); @@ -148,7 +148,7 @@ public void testInitiatePasswordRecovery() throws ApiException { try (MockedStatic identityManagementEndpointUtilMockedStatic = mockStatic(IdentityManagementEndpointUtil.class)) { identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. - getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); + getBasePath(TENANT_DOMAIN, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); List result = recoveryApiV2.initiatePasswordRecovery(new RecoveryInitRequest(), "", headers); @@ -168,7 +168,7 @@ public void testRecoverPassword() throws ApiException { try (MockedStatic identityManagementEndpointUtilMockedStatic = mockStatic(IdentityManagementEndpointUtil.class)) { identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. - getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); + getBasePath(TENANT_DOMAIN, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); RecoveryResponse result = recoveryApiV2.recoverPassword(new RecoveryRequest(), "", headers); assertEquals(result, expected); @@ -187,7 +187,7 @@ public void testResendPasswordNotification() throws ApiException { try (MockedStatic identityManagementEndpointUtilMockedStatic = mockStatic(IdentityManagementEndpointUtil.class)) { identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. - getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); + getBasePath(TENANT_DOMAIN, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); ResendResponse result = recoveryApiV2.resendPasswordNotification(new ResendRequest(), "", headers); @@ -207,7 +207,7 @@ public void testConfirmPasswordRecovery() throws ApiException { try (MockedStatic identityManagementEndpointUtilMockedStatic = mockStatic(IdentityManagementEndpointUtil.class)) { identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. - getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); + getBasePath(TENANT_DOMAIN, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); ConfirmResponse result = recoveryApiV2. confirmPasswordRecovery(new ConfirmRequest(), "", headers); @@ -227,7 +227,7 @@ public void testResetUserPassword() throws ApiException { try (MockedStatic identityManagementEndpointUtilMockedStatic = mockStatic(IdentityManagementEndpointUtil.class)) { identityManagementEndpointUtilMockedStatic.when(() -> IdentityManagementEndpointUtil. - getBasePath(tenantDomain, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); + getBasePath(TENANT_DOMAIN, RECOVERY_API_V2_RELATIVE_PATH)).thenReturn(TEST_PATH); ResetResponse result = recoveryApiV2.resetUserPassword(new ResetRequest(), "", headers); assertEquals(result, expected); @@ -251,30 +251,30 @@ public void testSetApiClient() { @Test(expectedExceptions = ApiException.class) public void testInitiateUsernameRecoveryWithNullRequest() throws ApiException { - recoveryApiV2.initiateUsernameRecovery(null, tenantDomain, headers); + recoveryApiV2.initiateUsernameRecovery(null, TENANT_DOMAIN, headers); } @Test(expectedExceptions = ApiException.class) public void testRecoverUsernameWithNullRequest() throws ApiException { - recoveryApiV2.recoverUsername(null, tenantDomain, headers); + recoveryApiV2.recoverUsername(null, TENANT_DOMAIN, headers); } @Test(expectedExceptions = ApiException.class) public void testResendPasswordNotificationWithNullRequest() throws ApiException { - recoveryApiV2.resendPasswordNotification(null, tenantDomain, headers); + recoveryApiV2.resendPasswordNotification(null, TENANT_DOMAIN, headers); } @Test(expectedExceptions = ApiException.class) public void testConfirmPasswordRecoveryWithNullRequest() throws ApiException { - recoveryApiV2.confirmPasswordRecovery(null, tenantDomain, headers); + recoveryApiV2.confirmPasswordRecovery(null, TENANT_DOMAIN, headers); } @Test(expectedExceptions = ApiException.class) public void testResetUserPasswordWithNullRequest() throws ApiException { - recoveryApiV2.resetUserPassword(null, tenantDomain, headers); + recoveryApiV2.resetUserPassword(null, TENANT_DOMAIN, headers); } } From 7a96f2823ce06c45efb269d6cc5251db41fb0bea Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Thu, 31 Oct 2024 09:34:15 +0530 Subject: [PATCH 16/23] Rename tenant to tenantDomain. --- .../util/client/PreferenceRetrievalClient.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/PreferenceRetrievalClient.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/PreferenceRetrievalClient.java index 8cd0c30b3474..1e1bb789f661 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/PreferenceRetrievalClient.java +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/client/PreferenceRetrievalClient.java @@ -136,37 +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 If any PreferenceRetrievalClientException occurs. */ - public boolean checkUsernameRecovery(String tenant) throws PreferenceRetrievalClientException { + public boolean checkUsernameRecovery(String tenantDomain) throws PreferenceRetrievalClientException { - return checkPreference(tenant, RECOVERY_CONNECTOR, IdPManagementConstants.USERNAME_RECOVERY_PROPERTY); + return checkPreference(tenantDomain, RECOVERY_CONNECTOR, IdPManagementConstants.USERNAME_RECOVERY_PROPERTY); } /** * Check email based username recovery is enabled or not. * - * @param tenant tenant domain name. + * @param tenantDomain tenant domain name. * @return returns true if email based username recovery enabled. * @throws PreferenceRetrievalClientException If any PreferenceRetrievalClientException occurs. */ - public boolean checkEmailBasedUsernameRecovery(String tenant) throws PreferenceRetrievalClientException { + public boolean checkEmailBasedUsernameRecovery(String tenantDomain) throws PreferenceRetrievalClientException { - return checkPreference(tenant, RECOVERY_CONNECTOR, IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY); + return checkPreference(tenantDomain, RECOVERY_CONNECTOR, IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY); } /** * Check SMS based username recovery is enabled or not. * - * @param tenant tenant domain name. + * @param tenantDomain tenant domain name. * @return returns true if SMS based username recovery enabled. * @throws PreferenceRetrievalClientException If any PreferenceRetrievalClientException occurs. */ - public boolean checkSMSBasedUsernameRecovery(String tenant) throws PreferenceRetrievalClientException { + public boolean checkSMSBasedUsernameRecovery(String tenantDomain) throws PreferenceRetrievalClientException { - return checkPreference(tenant, RECOVERY_CONNECTOR, IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY); + return checkPreference(tenantDomain, RECOVERY_CONNECTOR, IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY); } /** From 47a27ea6f9dea7d33e4630a1b7ce28f0fba5acb9 Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Thu, 31 Oct 2024 09:34:40 +0530 Subject: [PATCH 17/23] change public variable to private. --- .../carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java index 47b71bddc2f8..4f5042dc151d 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java @@ -51,7 +51,7 @@ public class RecoveryApiV2Test { - public static final String RECOVERY_API_V2_RELATIVE_PATH = "/api/users/v2/recovery"; + private static final String RECOVERY_API_V2_RELATIVE_PATH = "/api/users/v2/recovery"; private static final String TENANT_DOMAIN = "carbon.super"; private static final String POST = "POST"; private static final String PATH_PASSWORD_RECOVERY_INIT = "/password/init"; From 85f868d7593f1f3b0609c182b0bfd5091ed698f3 Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Sat, 2 Nov 2024 09:33:49 +0530 Subject: [PATCH 18/23] Update the mobile regex in the constants. --- .../mgt/endpoint/util/IdentityManagementEndpointConstants.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/IdentityManagementEndpointConstants.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/IdentityManagementEndpointConstants.java index 6f529eb89327..0e62c60d895e 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/IdentityManagementEndpointConstants.java +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/IdentityManagementEndpointConstants.java @@ -75,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 { From d0a006af90273a9bfc9952604209268e782d3423 Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Mon, 4 Nov 2024 16:10:32 +0530 Subject: [PATCH 19/23] Add the on-demand migration config logic. --- .../idp/mgt/IdentityProviderManager.java | 1 + .../carbon/idp/mgt/dao/IdPManagementDAO.java | 50 +++++++++++++++++++ .../idp/mgt/util/IdPManagementUtil.java | 46 +++++++++++++++++ .../resources/identity.xml | 1 + .../resources/identity.xml.j2 | 1 + ....identity.core.server.feature.default.json | 1 + 6 files changed, 100 insertions(+) diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/IdentityProviderManager.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/IdentityProviderManager.java index 19734a66cc28..e62ac3186f39 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/IdentityProviderManager.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/IdentityProviderManager.java @@ -319,6 +319,7 @@ public void updateResidentIdP(IdentityProvider identityProvider, String tenantDo List newProperties = new ArrayList<>(); IdPManagementUtil.validatePasswordRecoveryPropertyValues(configurationDetails); + IdPManagementUtil.validateUsernameRecoveryPropertyValues(configurationDetails); for (IdentityProviderProperty identityMgtProperty : identityMgtProperties) { IdentityProviderProperty prop = new IdentityProviderProperty(); diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java index a6ee6a7b45c2..e2db115e08d4 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java @@ -125,6 +125,8 @@ public class IdPManagementDAO { private static final String OPENID_IDP_ENTITY_ID = "IdPEntityId"; private static final String ENABLE_SMS_OTP_IF_RECOVERY_NOTIFICATION_ENABLED = "OnDemandConfig.OnInitialUse.EnableSMSOTPPasswordRecoveryIfConnectorEnabled"; + private static final String ENABLE_SMS_USERNAME_RECOVERY_IF_CONNECTOR_ENABLED + = "OnDemandConfig.OnInitialUse.EnableSMSUsernameRecoveryIfConnectorEnabled"; /** * @param dbConnection @@ -999,6 +1001,10 @@ private List getIdentityPropertiesByIdpId(Connection d boolean isEmailLinkNotificationPasswordRecoveryEnabled = false; boolean isSmsOtpNotificationPasswordRecoveryEnabled = false; + boolean isUsernameRecoveryEnabled = false; + boolean isEmailUsernameRecoveryEnabled = false; + boolean isSmsUsernameRecoveryEnabled = false; + try { String sqlStmt = isH2DB() ? IdPManagementConstants.SQLQueries.GET_IDP_METADATA_BY_IDP_ID_H2 : IdPManagementConstants.SQLQueries.GET_IDP_METADATA_BY_IDP_ID; @@ -1020,6 +1026,15 @@ private List getIdentityPropertiesByIdpId(Connection d isSmsOtpNotificationPasswordRecoveryEnabled = Boolean.parseBoolean(rs.getString("VALUE")); } + if (IdPManagementConstants.USERNAME_RECOVERY_PROPERTY.equals(property.getName())) { + isUsernameRecoveryEnabled = Boolean.parseBoolean(rs.getString("VALUE")); + } + if (IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY.equals(property.getName())) { + isEmailUsernameRecoveryEnabled = Boolean.parseBoolean(rs.getString("VALUE")); + } + if (IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY.equals(property.getName())) { + isSmsUsernameRecoveryEnabled = Boolean.parseBoolean(rs.getString("VALUE")); + } property.setValue(rs.getString("VALUE")); property.setDisplayName(rs.getString("DISPLAY_NAME")); idpProperties.add(property); @@ -1029,6 +1044,10 @@ private List getIdentityPropertiesByIdpId(Connection d && !isSmsOtpNotificationPasswordRecoveryEnabled) { performConfigCorrectionForPasswordRecoveryConfigs(dbConnection, tenantId, idpId, idpProperties); } + // If username recovery configs are inconsistent, correct the configurations. + if (isUsernameRecoveryEnabled && !isEmailUsernameRecoveryEnabled && !isSmsUsernameRecoveryEnabled) { + performConfigCorrectionForUsernameRecoveryConfigs(dbConnection, tenantId, idpId, idpProperties); + } } catch (DataAccessException e) { throw new SQLException("Error while retrieving IDP properties for IDP ID: " + idpId, e); } finally { @@ -6056,4 +6075,35 @@ private void performConfigCorrectionForPasswordRecoveryConfigs(Connection dbConn } updateIdentityProviderProperties(dbConnection, idpId, idpProperties, tenantId); } + + private void performConfigCorrectionForUsernameRecoveryConfigs(Connection dbConnection, int tenantId, int idpId, + List idpProperties) throws SQLException { + // Enable all recovery options when Recovery.Notification.Password.Enable value is set as enabled. + // This keeps functionality consistent with previous API versions for migrating customers. + idpProperties.stream().filter( + idp -> IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY.equals(idp.getName())).findFirst() + .ifPresentOrElse( + emailLinkProperty -> emailLinkProperty.setValue(String.valueOf(true)), + () -> { + IdentityProviderProperty identityProviderProperty = new IdentityProviderProperty(); + identityProviderProperty.setName( + IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY); + identityProviderProperty.setValue("true"); + idpProperties.add(identityProviderProperty); + }); + if (Boolean.parseBoolean(IdentityUtil.getProperty(ENABLE_SMS_USERNAME_RECOVERY_IF_CONNECTOR_ENABLED))) { + idpProperties.stream().filter( + idp -> IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY.equals(idp.getName())).findFirst() + .ifPresentOrElse( + smsOtpProperty -> smsOtpProperty.setValue(String.valueOf(true)), + () -> { + IdentityProviderProperty identityProviderProperty = new IdentityProviderProperty(); + identityProviderProperty.setName( + IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY); + identityProviderProperty.setValue("true"); + idpProperties.add(identityProviderProperty); + }); + } + updateIdentityProviderProperties(dbConnection, idpId, idpProperties, tenantId); + } } diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementUtil.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementUtil.java index 9e2d8d883f21..346cb9d837bc 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementUtil.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementUtil.java @@ -318,4 +318,50 @@ public static void validatePasswordRecoveryPropertyValues(Map co } } } + + /** + * This method is used to validate the username recovery property values. + * + * @param configurationDetails Configuration updates for governance configuration. + */ + public static void validateUsernameRecoveryPropertyValues(Map configurationDetails) + throws IdentityProviderManagementClientException { + + if (configurationDetails.containsKey(IdPManagementConstants.USERNAME_RECOVERY_PROPERTY) || + configurationDetails.containsKey(IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY) || + configurationDetails.containsKey(IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY)) { + // Perform process only if notification based username recovery connector or options are updated. + String usernameRecoveryProp = configurationDetails.get(IdPManagementConstants.USERNAME_RECOVERY_PROPERTY); + String usernameRecoveryEmailProp = + configurationDetails.get(IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY); + String usernameRecoverySmsProp = + configurationDetails.get(IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY); + + boolean usernameRecoveryProperty = Boolean.parseBoolean(usernameRecoveryProp); + boolean usernameRecoveryEmailProperty = Boolean.parseBoolean(usernameRecoveryEmailProp); + boolean usernameRecoverySmsProperty = Boolean.parseBoolean(usernameRecoverySmsProp); + + if (usernameRecoveryProperty && + StringUtils.isNotBlank(usernameRecoveryEmailProp) && !usernameRecoveryEmailProperty && + StringUtils.isNotBlank(usernameRecoverySmsProp) && !usernameRecoverySmsProperty) { + // Disabling all recovery options when recovery connector is enabled is not allowed. + // WARNING : Be mindful about compatibility of earlier recovery api versions when changing + // this behaviour. + throw IdPManagementUtil + .handleClientException( + IdPManagementConstants.ErrorMessage.ERROR_CODE_INVALID_CONNECTOR_CONFIGURATION, + "Disabling all recovery options when recovery connector is enabled, is not allowed."); + + } if (StringUtils.isNotBlank(usernameRecoveryProp) && !usernameRecoveryProperty && + (usernameRecoveryEmailProperty || usernameRecoverySmsProperty)) { + // Enabling any recovery options when connector is disabled is not allowed. + // WARNING : Be mindful about compatibility of earlier recovery api versions when changing + // this behaviour. + throw IdPManagementUtil + .handleClientException( + IdPManagementConstants.ErrorMessage.ERROR_CODE_INVALID_CONNECTOR_CONFIGURATION, + "Enabling recovery options when connector is disabled, is not allowed."); + } + } + } } diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml index 82cb81422020..4174ac536cdb 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml @@ -2676,6 +2676,7 @@ false + false diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 index 9ba5c3d7e4a5..157ea0c8a80f 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 @@ -4336,6 +4336,7 @@ {{on_demand_config.on_initial_use.enable_sms_otp_password_recovery_if_connector_enabled}} + {{on_demand_config.on_initial_use.enable_sms_username_recovery_if_connector_enabled}} diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/org.wso2.carbon.identity.core.server.feature.default.json b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/org.wso2.carbon.identity.core.server.feature.default.json index 30a0411a24bc..2bad9abf6c03 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/org.wso2.carbon.identity.core.server.feature.default.json +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/org.wso2.carbon.identity.core.server.feature.default.json @@ -1637,6 +1637,7 @@ "tenant_mgt.enable_email_domain": false, "on_demand_config.on_initial_use.enable_sms_otp_password_recovery_if_connector_enabled": false, + "on_demand_config.on_initial_use.enable_sms_username_recovery_if_connector_enabled": false, "actions.http_client.connection_timeout": 2000, "actions.http_client.read_timeout": 5000, From 147f38645c7f808d6ae54ccaef8375a578d121ff Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Mon, 4 Nov 2024 16:33:34 +0530 Subject: [PATCH 20/23] Reformat the code. --- .../mgt/endpoint/util/PreferenceRetrievalClientTest.java | 4 ---- .../java/org/wso2/carbon/idp/mgt/util/IdPManagementUtil.java | 3 ++- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java index 8357f047da2b..b0c064917dbf 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/PreferenceRetrievalClientTest.java @@ -18,8 +18,6 @@ package org.wso2.carbon.identity.mgt.endpoint.util; -import org.mockito.InjectMocks; -import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.Spy; import org.testng.annotations.BeforeMethod; @@ -33,11 +31,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import static org.testng.Assert.assertTrue; public class PreferenceRetrievalClientTest { diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementUtil.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementUtil.java index 346cb9d837bc..0da108039c0d 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementUtil.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementUtil.java @@ -352,7 +352,8 @@ public static void validateUsernameRecoveryPropertyValues(Map co IdPManagementConstants.ErrorMessage.ERROR_CODE_INVALID_CONNECTOR_CONFIGURATION, "Disabling all recovery options when recovery connector is enabled, is not allowed."); - } if (StringUtils.isNotBlank(usernameRecoveryProp) && !usernameRecoveryProperty && + } + if (StringUtils.isNotBlank(usernameRecoveryProp) && !usernameRecoveryProperty && (usernameRecoveryEmailProperty || usernameRecoverySmsProperty)) { // Enabling any recovery options when connector is disabled is not allowed. // WARNING : Be mindful about compatibility of earlier recovery api versions when changing From aae76871974a8a29575fe034e17bac4a7d0d5593 Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Tue, 5 Nov 2024 11:36:31 +0530 Subject: [PATCH 21/23] Update the tests for validateUsernameRecoveryPropertyValues. --- .../idp/mgt/util/IdPManagementUtilTest.java | 116 +++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/test/java/org/wso2/carbon/idp/mgt/util/IdPManagementUtilTest.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/test/java/org/wso2/carbon/idp/mgt/util/IdPManagementUtilTest.java index 93828e7f7f53..d7d2d7f4f819 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/test/java/org/wso2/carbon/idp/mgt/util/IdPManagementUtilTest.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/test/java/org/wso2/carbon/idp/mgt/util/IdPManagementUtilTest.java @@ -37,11 +37,15 @@ import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.tenant.TenantManager; +import java.util.HashMap; +import java.util.Map; + import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.when; import static org.testng.Assert.assertEquals; +import static org.testng.AssertJUnit.fail; import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.REMEMBER_ME_TIME_OUT; import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.REMEMBER_ME_TIME_OUT_DEFAULT; import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.SESSION_IDLE_TIME_OUT; @@ -54,6 +58,9 @@ @Listeners(MockitoTestNGListener.class) public class IdPManagementUtilTest { + private static final String TRUE_STRING = "true"; + private static final String FALSE_STRING = "false"; + @Mock private IdentityProviderManager mockedIdentityProviderManager; @Mock @@ -78,7 +85,7 @@ public Object[][] getTenantIdOfDomainData() { public void testGetTenantIdOfDomain(String tenantDomain, int tenantId, String expectedResult) throws Exception { try (MockedStatic idPManagementServiceComponent = - mockStatic(IdPManagementServiceComponent.class)) { + mockStatic(IdPManagementServiceComponent.class)) { idPManagementServiceComponent.when( IdPManagementServiceComponent::getRealmService).thenReturn(mockedRealmService); lenient().when(mockedRealmService.getTenantManager()).thenReturn(mockedTenantManager); @@ -247,4 +254,111 @@ public void testHandleServerException() { assertEquals(exception2.getErrorCode(), "IDP-65002"); assertEquals(exception2.getMessage(), "Error while adding the Identity Provider: test2."); } + + @Test + public void testExceptionValidateUsernameRecoveryPropertyValues() { + + Map configDetails1 = new HashMap<>(); + configDetails1.put(IdPManagementConstants.USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + configDetails1.put(IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY, FALSE_STRING); + configDetails1.put(IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY, FALSE_STRING); + + try { + IdPManagementUtil.validateUsernameRecoveryPropertyValues(configDetails1); + fail("Expected an IdentityProviderManagementServerException to be thrown"); + } catch (IdentityProviderManagementClientException e) { + assertEquals(e.getErrorCode(), + IdPManagementConstants.ErrorMessage.ERROR_CODE_INVALID_CONNECTOR_CONFIGURATION.getCode()); + } + + Map configDetails2 = new HashMap<>(); + configDetails2.put(IdPManagementConstants.USERNAME_RECOVERY_PROPERTY, FALSE_STRING); + configDetails2.put(IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + try { + IdPManagementUtil.validateUsernameRecoveryPropertyValues(configDetails2); + fail("Expected an IdentityProviderManagementServerException to be thrown"); + } catch (IdentityProviderManagementClientException e) { + assertEquals(e.getErrorCode(), ErrorMessage.ERROR_CODE_INVALID_CONNECTOR_CONFIGURATION.getCode()); + } + + Map configDetails3 = new HashMap<>(); + configDetails3.put(IdPManagementConstants.USERNAME_RECOVERY_PROPERTY, FALSE_STRING); + configDetails3.put(IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + try { + IdPManagementUtil.validateUsernameRecoveryPropertyValues(configDetails3); + fail("Expected an IdentityProviderManagementServerException to be thrown"); + } catch (IdentityProviderManagementClientException e) { + assertEquals(e.getErrorCode(), ErrorMessage.ERROR_CODE_INVALID_CONNECTOR_CONFIGURATION.getCode()); + } + + } + + @Test(dataProvider = "setSuccessConfigDetails") + public void testSuccessVerificationsInValidateUsernameRecoveryPropertyValues(Map configDetails) + throws IdentityProviderManagementClientException { + + IdPManagementUtil.validateUsernameRecoveryPropertyValues(configDetails); + } + + @DataProvider(name = "setSuccessConfigDetails") + public Object[][] setSuccessConfigDetails() { + + Map configDetails1 = new HashMap<>(); + configDetails1.put(IdPManagementConstants.USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + configDetails1.put(IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + configDetails1.put(IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + + Map configDetails2 = new HashMap<>(); + configDetails2.put(IdPManagementConstants.USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + configDetails2.put(IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + configDetails2.put(IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY, FALSE_STRING); + + Map configDetails3 = new HashMap<>(); + configDetails3.put(IdPManagementConstants.USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + configDetails3.put(IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY, FALSE_STRING); + configDetails3.put(IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + + Map configDetails4 = new HashMap<>(); + configDetails4.put(IdPManagementConstants.USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + configDetails4.put(IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + + Map configDetails5 = new HashMap<>(); + configDetails5.put(IdPManagementConstants.USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + configDetails5.put(IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY, FALSE_STRING); + + Map configDetails6 = new HashMap<>(); + configDetails6.put(IdPManagementConstants.USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + + Map configDetails7 = new HashMap<>(); + configDetails7.put(IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + + Map configDetails8 = new HashMap<>(); + configDetails8.put(IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY, TRUE_STRING); + + Map configDetails9 = new HashMap<>(); + configDetails9.put(IdPManagementConstants.USERNAME_RECOVERY_PROPERTY, FALSE_STRING); + + Map configDetails10 = new HashMap<>(); + configDetails10.put(IdPManagementConstants.USERNAME_RECOVERY_PROPERTY, FALSE_STRING); + configDetails10.put(IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY, FALSE_STRING); + + Map configDetails11 = new HashMap<>(); + configDetails11.put(IdPManagementConstants.USERNAME_RECOVERY_PROPERTY, FALSE_STRING); + configDetails11.put(IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY, FALSE_STRING); + + return new Object[][]{ + {configDetails1}, + {configDetails2}, + {configDetails3}, + {configDetails4}, + {configDetails5}, + {configDetails6}, + {configDetails7}, + {configDetails8}, + {configDetails9}, + {configDetails10}, + {configDetails11} + }; + } + } From 2b3ead0718fc2df57943a26fa3eb62e40cfe9269 Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Fri, 8 Nov 2024 17:31:53 +0530 Subject: [PATCH 22/23] Remove the extra new line. --- .../carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java | 1 - 1 file changed, 1 deletion(-) diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java index 4f5042dc151d..b9c7dcff58e6 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/RecoveryApiV2Test.java @@ -90,7 +90,6 @@ public void setup() { recoveryApiV2 = new RecoveryApiV2(apiClient); } - } @Test From 4e9afb9e2e1026ff1db6a9b0272f1d6c4e2c9402 Mon Sep 17 00:00:00 2001 From: Malith-19 Date: Tue, 12 Nov 2024 14:24:11 +0530 Subject: [PATCH 23/23] Reformat the code. --- .../carbon/idp/mgt/dao/IdPManagementDAO.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java index 54502adab478..5c170ad8821b 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java @@ -6059,13 +6059,16 @@ private void performConfigCorrectionForPasswordRecoveryConfigs(Connection dbConn } private void performConfigCorrectionForUsernameRecoveryConfigs(Connection dbConnection, int tenantId, int idpId, - List idpProperties) throws SQLException { - // Enable all recovery options when Recovery.Notification.Password.Enable value is set as enabled. + List idpProperties) + throws SQLException { + + // Enable all recovery options when Recovery.Notification.Username.Enable value is set as enabled. // This keeps functionality consistent with previous API versions for migrating customers. idpProperties.stream().filter( - idp -> IdPManagementConstants.EMAIL_USERNAME_RECOVERY_PROPERTY.equals(idp.getName())).findFirst() + idp -> IdPManagementConstants. + EMAIL_USERNAME_RECOVERY_PROPERTY.equals(idp.getName())).findFirst() .ifPresentOrElse( - emailLinkProperty -> emailLinkProperty.setValue(String.valueOf(true)), + emailProperty -> emailProperty.setValue(String.valueOf(true)), () -> { IdentityProviderProperty identityProviderProperty = new IdentityProviderProperty(); identityProviderProperty.setName( @@ -6075,9 +6078,10 @@ private void performConfigCorrectionForUsernameRecoveryConfigs(Connection dbConn }); if (Boolean.parseBoolean(IdentityUtil.getProperty(ENABLE_SMS_USERNAME_RECOVERY_IF_CONNECTOR_ENABLED))) { idpProperties.stream().filter( - idp -> IdPManagementConstants.SMS_USERNAME_RECOVERY_PROPERTY.equals(idp.getName())).findFirst() + idp -> IdPManagementConstants. + SMS_USERNAME_RECOVERY_PROPERTY.equals(idp.getName())).findFirst() .ifPresentOrElse( - smsOtpProperty -> smsOtpProperty.setValue(String.valueOf(true)), + smsProperty -> smsProperty.setValue(String.valueOf(true)), () -> { IdentityProviderProperty identityProviderProperty = new IdentityProviderProperty(); identityProviderProperty.setName(