From b0be03a27f0433dc1ca24abc3e557a04474ffdfe Mon Sep 17 00:00:00 2001 From: ThaminduR Date: Tue, 7 Jul 2026 15:45:05 +0530 Subject: [PATCH] Retain tenant qualification for configured server URL in account recovery endpoint --- .../util/IdentityManagementEndpointUtil.java | 4 +- .../IdentityManagementEndpointUtilTest.java | 56 +++++++++++++++++++ 2 files changed, 59 insertions(+), 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/IdentityManagementEndpointUtil.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/IdentityManagementEndpointUtil.java index 87656a5e6cf1..415f72d86ff9 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/IdentityManagementEndpointUtil.java +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/main/java/org/wso2/carbon/identity/mgt/endpoint/util/IdentityManagementEndpointUtil.java @@ -898,9 +898,11 @@ public static String getBasePath(String tenantDomain, String context, boolean is } } } else { + // A configured server URL is a bare base URL, so qualify it with the tenant here unless it + // already carries one. if (StringUtils.isNotBlank(tenantDomain) && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME .equalsIgnoreCase(tenantDomain) && isEndpointTenantAware - && !isServerURLAlreadyTenanted(tenantDomain)) { + && !serverUrl.contains(FrameworkConstants.TENANT_CONTEXT_PREFIX)) { basePath = serverUrl + FrameworkConstants.TENANT_CONTEXT_PREFIX + tenantDomain + context; } else { basePath = serverUrl + context; diff --git a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/IdentityManagementEndpointUtilTest.java b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/IdentityManagementEndpointUtilTest.java index 7baff59cd7a9..31b28e1bbbd9 100644 --- a/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/IdentityManagementEndpointUtilTest.java +++ b/components/identity-mgt/org.wso2.carbon.identity.mgt.endpoint.util/src/test/java/org/wso2/carbon/identity/mgt/endpoint/util/IdentityManagementEndpointUtilTest.java @@ -373,6 +373,62 @@ public void testGetBasePath2(boolean isTenantQualifiedUrlsEnabled, String contex } } + @DataProvider(name = "getBasePathConfiguredServerUrlData") + public Object[][] getBasePathConfiguredServerUrlData() { + + return new Object[][] { + // contextUrl (configured server URL) + // tenantDomain + // isEndpointTenantAware + // inboundPath (stubbed serviceURL.getPath() - already tenant-qualified, the case that regressed) + // expected value + + // A configured server URL is tenant-qualified even when the inbound request path already + // carries the tenant (the fix - the tenant must not be dropped here). + { "https://foo.com", + SAMPLE_TENANT_DOMAIN, + true, + "/t/test.com/api/identity/recovery/v0.9", + "https://foo.com/t/test.com/api/identity/recovery/v0.9" + }, + // Configured server URL already carries a tenant: no second /t/ prefix is added. + { "https://foo.com/t/test.com", + SAMPLE_TENANT_DOMAIN, + true, + "/t/test.com/api/identity/recovery/v0.9", + "https://foo.com/t/test.com/api/identity/recovery/v0.9" + }, + // Super tenant: no /t/ prefix. + { "https://foo.com", + MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, + true, + "/t/carbon.super/api/identity/recovery/v0.9", + "https://foo.com/api/identity/recovery/v0.9" + }, + // Not endpoint-tenant-aware: no /t/ prefix. + { "https://foo.com", + SAMPLE_TENANT_DOMAIN, + false, + "/t/test.com/api/identity/recovery/v0.9", + "https://foo.com/api/identity/recovery/v0.9" + } + }; + } + + @Test(dataProvider = "getBasePathConfiguredServerUrlData") + public void testGetBasePathConfiguredServerUrl(String contextUrl, String tenantDomain, + boolean isEndpointTenantAware, String inboundPath, String expected) throws Exception { + + String context = IdentityManagementEndpointConstants.UserInfoRecovery.RECOVERY_API_RELATIVE_PATH; + try (MockedStatic identityTenantUtil = mockStatic(IdentityTenantUtil.class); + MockedStatic serviceURLBuilder = mockStatic(ServiceURLBuilder.class)) { + prepareGetBasePathTest(contextUrl, context, identityTenantUtil, serviceURLBuilder, true, false); + lenient().when(serviceURL.getPath()).thenReturn(inboundPath); + assertEquals(IdentityManagementEndpointUtil.getBasePath(tenantDomain, context, isEndpointTenantAware), + expected); + } + } + @DataProvider(name = "getBasePathUseOrgHandleFalseTestData") public Object[][] getBasePathUseOrgHandleFalseTestData() {