From 6af95b0c76562cc6f3dd732e65ed2427117e30d2 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 3 May 2024 10:56:09 +0530 Subject: [PATCH] fix: refactor cud tests --- .../api/TestConnectionUriDomain3_0.java | 577 ++++++++++++ ...n.java => TestConnectionUriDomain5_0.java} | 253 ++++-- .../api/TestConnectionUriDomain5_1.java | 850 ++++++++++++++++++ 3 files changed, 1608 insertions(+), 72 deletions(-) create mode 100644 src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain3_0.java rename src/test/java/io/supertokens/test/multitenant/api/{TestConnectionUriDomain.java => TestConnectionUriDomain5_0.java} (72%) create mode 100644 src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain5_1.java diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain3_0.java b/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain3_0.java new file mode 100644 index 000000000..b523bb367 --- /dev/null +++ b/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain3_0.java @@ -0,0 +1,577 @@ +/* + * Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved. + * + * This software is licensed under the Apache License, Version 2.0 (the + * "License") as published by the Apache Software Foundation. + * + * 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 io.supertokens.test.multitenant.api; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import io.supertokens.Main; +import io.supertokens.ProcessState; +import io.supertokens.featureflag.EE_FEATURES; +import io.supertokens.featureflag.FeatureFlagTestContent; +import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; +import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.multitenancy.exception.CannotModifyBaseConfigException; +import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.exceptions.InvalidConfigException; +import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; +import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; +import io.supertokens.storageLayer.StorageLayer; +import io.supertokens.test.TestingProcessManager; +import io.supertokens.test.Utils; +import io.supertokens.test.httpRequest.HttpRequestForTesting; +import io.supertokens.test.httpRequest.HttpResponseException; +import io.supertokens.thirdparty.InvalidProviderConfigException; +import io.supertokens.utils.SemVer; +import io.supertokens.webserver.Webserver; +import io.supertokens.webserver.WebserverAPI; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.util.Set; + +import static org.junit.Assert.*; + +public class TestConnectionUriDomain3_0 { + TestingProcessManager.TestingProcess process; + + @AfterClass + public static void afterTesting() { + Utils.afterTesting(); + } + + @After + public void afterEach() throws InterruptedException { + process.kill(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); + } + + @Before + public void beforeEach() throws InterruptedException, InvalidProviderConfigException, + StorageQueryException, FeatureNotEnabledException, TenantOrAppNotFoundException, IOException, + InvalidConfigException, CannotModifyBaseConfigException, BadPermissionException { + Utils.reset(); + + String[] args = {"../"}; + + this.process = TestingProcessManager.start(args); + FeatureFlagTestContent.getInstance(process.getProcess()) + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MULTI_TENANCY}); + process.startProcess(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + } + + @Test + public void testCreateConnectionUriDomainWorks() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject coreConfig = new JsonObject(); + + StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()) + .modifyConfigToAddANewUserPoolForTesting(coreConfig, 1); + + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1:3567", true, true, true, + coreConfig); + + JsonObject result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + assertTrue(result.has("connectionUriDomains")); + + boolean found = false; + for (JsonElement cud : result.get("connectionUriDomains").getAsJsonArray()) { + JsonObject cudObj = cud.getAsJsonObject(); + if (cudObj.get("connectionUriDomain").getAsString().equals("127.0.0.1")) { + found = true; + + for (JsonElement app : cudObj.get("apps").getAsJsonArray()) { + JsonObject appObj = app.getAsJsonObject(); + + for (JsonElement tenant : appObj.get("tenants").getAsJsonArray()) { + JsonObject tenantObj = tenant.getAsJsonObject(); + assertEquals(5, tenantObj.entrySet().size()); + assertEquals("public", tenantObj.get("tenantId").getAsString()); + assertEquals(1, tenantObj.get("emailPassword").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("emailPassword").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(2, tenantObj.get("thirdParty").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("thirdParty").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(1, tenantObj.get("passwordless").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("passwordless").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(coreConfig, tenantObj.get("coreConfig").getAsJsonObject()); + } + } + } + } + assertTrue(found); + } + + @Test + public void testUpdateConnectionUriDomainWorks() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject coreConfig = new JsonObject(); + + StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()) + .modifyConfigToAddANewUserPoolForTesting(coreConfig, 1); + + // Create + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1:3567", true, true, true, + coreConfig); + + JsonObject newConfig = new JsonObject(); + newConfig.addProperty("email_verification_token_lifetime", 2000); + coreConfig.addProperty("email_verification_token_lifetime", 2000); + + // Update + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1:3567", true, true, true, + newConfig); + + JsonObject result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + assertTrue(result.has("connectionUriDomains")); + + boolean found = false; + for (JsonElement cud : result.get("connectionUriDomains").getAsJsonArray()) { + JsonObject cudObj = cud.getAsJsonObject(); + if (cudObj.get("connectionUriDomain").getAsString().equals("127.0.0.1")) { + found = true; + + for (JsonElement app : cudObj.get("apps").getAsJsonArray()) { + JsonObject appObj = app.getAsJsonObject(); + + for (JsonElement tenant : appObj.get("tenants").getAsJsonArray()) { + JsonObject tenantObj = tenant.getAsJsonObject(); + assertEquals(5, tenantObj.entrySet().size()); + assertEquals("public", tenantObj.get("tenantId").getAsString()); + assertEquals(1, tenantObj.get("emailPassword").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("emailPassword").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(2, tenantObj.get("thirdParty").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("thirdParty").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(1, tenantObj.get("passwordless").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("passwordless").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(coreConfig, tenantObj.get("coreConfig").getAsJsonObject()); + } + } + } + } + assertTrue(found); + } + + @Test + public void testUpdateConnectionUriDomainFromSameConnectionUriDomainWorks() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject coreConfig = new JsonObject(); + + StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()) + .modifyConfigToAddANewUserPoolForTesting(coreConfig, 1); + + // Create + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1:3567", true, true, true, + coreConfig); + + JsonObject newConfig = new JsonObject(); + newConfig.addProperty("email_verification_token_lifetime", 2000); + coreConfig.addProperty("email_verification_token_lifetime", 2000); + + // Update + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier("127.0.0.1", null, null), + "127.0.0.1", true, true, true, + newConfig); + + JsonObject result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + assertTrue(result.has("connectionUriDomains")); + + boolean found = false; + for (JsonElement cud : result.get("connectionUriDomains").getAsJsonArray()) { + JsonObject cudObj = cud.getAsJsonObject(); + if (cudObj.get("connectionUriDomain").getAsString().equals("127.0.0.1")) { + found = true; + + for (JsonElement app : cudObj.get("apps").getAsJsonArray()) { + JsonObject appObj = app.getAsJsonObject(); + + for (JsonElement tenant : appObj.get("tenants").getAsJsonArray()) { + JsonObject tenantObj = tenant.getAsJsonObject(); + assertEquals(5, tenantObj.entrySet().size()); + assertEquals("public", tenantObj.get("tenantId").getAsString()); + assertEquals(1, tenantObj.get("emailPassword").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("emailPassword").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(2, tenantObj.get("thirdParty").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("thirdParty").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(1, tenantObj.get("passwordless").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("passwordless").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(coreConfig, tenantObj.get("coreConfig").getAsJsonObject()); + } + } + } + } + assertTrue(found); + } + + @Test + public void testUpdateWithNullValueDeletesTheSetting() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject coreConfig = new JsonObject(); + + StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()) + .modifyConfigToAddANewUserPoolForTesting(coreConfig, 1); + coreConfig.addProperty("email_verification_token_lifetime", 2000); + + // Create + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1:3567", true, true, true, + coreConfig); + + JsonObject newConfig = new JsonObject(); + newConfig.add("email_verification_token_lifetime", null); + coreConfig.remove("email_verification_token_lifetime"); // for verification + + // Update + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1:3567", true, true, true, + newConfig); + + JsonObject result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + assertTrue(result.has("connectionUriDomains")); + + boolean found = false; + for (JsonElement cud : result.get("connectionUriDomains").getAsJsonArray()) { + JsonObject cudObj = cud.getAsJsonObject(); + if (cudObj.get("connectionUriDomain").getAsString().equals("127.0.0.1")) { + found = true; + + for (JsonElement app : cudObj.get("apps").getAsJsonArray()) { + JsonObject appObj = app.getAsJsonObject(); + + for (JsonElement tenant : appObj.get("tenants").getAsJsonArray()) { + JsonObject tenantObj = tenant.getAsJsonObject(); + assertTrue(tenantObj.get("emailPassword").getAsJsonObject().get("enabled").getAsBoolean()); + assertTrue(tenantObj.get("thirdParty").getAsJsonObject().get("enabled").getAsBoolean()); + assertTrue(tenantObj.get("passwordless").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(coreConfig, tenantObj.get("coreConfig").getAsJsonObject()); + } + } + } + } + assertTrue(found); + } + + @Test + public void testDeleteConnectionUriDomainWorks() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject coreConfig = new JsonObject(); + + StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()) + .modifyConfigToAddANewUserPoolForTesting(coreConfig, 1); + + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1:3567", true, true, true, + coreConfig); + + JsonObject result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + assertTrue(result.has("connectionUriDomains")); + assertEquals(2, result.get("connectionUriDomains").getAsJsonArray().size()); + + JsonObject response = deleteConnectionUriDomain(new TenantIdentifier(null, null, null), + "127.0.0.1:3567", process.getProcess()); + assertTrue(response.get("didExist").getAsBoolean()); + + result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + assertTrue(result.has("connectionUriDomains")); + assertEquals(1, result.get("connectionUriDomains").getAsJsonArray().size()); + + response = deleteConnectionUriDomain(new TenantIdentifier(null, null, null), + "127.0.0.1:3567", process.getProcess()); + assertFalse(response.get("didExist").getAsBoolean()); + } + + @Test + public void testDifferentValuesForCUDThatShouldWork() throws Exception { + String[] valueForCreate = new String[]{"localhost:3567", "LOCALHOST:3567", "loCalHost:3567", "127.0.0.1:3567"}; + String[] valueForQuery = new String[]{"localhost:3567", "LOCALHOST:3567", "LOCALhoST:3567", "127.0.0.1:3567"}; + + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject config = new JsonObject(); + StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); + + process.kill(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); + + for (int i = 0; i < valueForCreate.length; i++) { + String[] args = {"../"}; + this.process = TestingProcessManager.start(args); + FeatureFlagTestContent.getInstance(process.getProcess()) + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MULTI_TENANCY}); + process.startProcess(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + + Webserver.getInstance(process.getProcess()).addAPI(new WebserverAPI(process.getProcess(), "") { + + private static final long serialVersionUID = 1L; + + @Override + public boolean checkAPIKey(HttpServletRequest req) { + return false; + } + + @Override + public String getPath() { + return "/get-cud"; + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, + ServletException { + try { + getTenantStorage(req); + super.sendTextResponse(200, this.getTenantIdentifier(req).getConnectionUriDomain(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } + } + }); + + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + valueForCreate[i], true, true, true, + config); + + String response = HttpRequestForTesting.sendGETRequest(process.getProcess(), "", + "http://" + valueForQuery[i] + "/get-cud", null, 1000, 1000, + null, WebserverAPI.getLatestCDIVersion().get(), null); + + assertEquals(valueForCreate[i].toLowerCase().split(":")[0], response); + + process.kill(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); + } + } + + @Test + public void testCUDsThatAreSame() throws Exception { + String[] valueForCreate = new String[]{"localhost:3567", "LOCALHOST:3567", "loCalHost:3567", "localhost", "localhost:12345"}; + + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject config = new JsonObject(); + StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); + + for (int i = 0; i < valueForCreate.length; i++) { + JsonObject response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + valueForCreate[i], true, true, true, + config); + + if (i == 0) { + assertTrue(response.get("createdNew").getAsBoolean()); + } else { + assertFalse(response.get("createdNew").getAsBoolean()); + } + } + } + + @Test + public void testDifferentValuesForCUDThatShouldNotWork() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + String[] valueForCreate = new String[]{"http://localhost_com", "localhost:", "domain.com:abcd"}; + for (int i = 0; i < valueForCreate.length; i++) { + try { + JsonObject config = new JsonObject(); + StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); + + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + valueForCreate[i], true, true, true, + config); + fail(valueForCreate[i]); + } catch (HttpResponseException e) { + assertTrue(e.getMessage().contains("connectionUriDomain is invalid")); + } + } + } + + @Test + public void testDefaultRecipesEnabledWhileCreatingCUD() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject config = new JsonObject(); + StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); + + JsonObject response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "localhost:3567", null, null, null, + config); + + assertTrue(response.get("createdNew").getAsBoolean()); + + JsonObject tenant = getTenant(new TenantIdentifier("localhost", null, null), + process.getProcess()); + assertTrue(tenant.get("emailPassword").getAsJsonObject().get("enabled").getAsBoolean()); + assertTrue(tenant.get("thirdParty").getAsJsonObject().get("enabled").getAsBoolean()); + assertTrue(tenant.get("passwordless").getAsJsonObject().get("enabled").getAsBoolean()); + } + + private static JsonObject createConnectionUriDomain(Main main, TenantIdentifier sourceTenant, + String connectionUriDomain, Boolean emailPasswordEnabled, + Boolean thirdPartyEnabled, Boolean passwordlessEnabled, + JsonObject coreConfig) throws HttpResponseException, IOException { + JsonObject requestBody = new JsonObject(); + if (connectionUriDomain != null) { + requestBody.addProperty("connectionUriDomain", connectionUriDomain); + } + if (emailPasswordEnabled != null) { + requestBody.addProperty("emailPasswordEnabled", emailPasswordEnabled); + } + if (thirdPartyEnabled != null) { + requestBody.addProperty("thirdPartyEnabled", thirdPartyEnabled); + } + if (passwordlessEnabled != null) { + requestBody.addProperty("passwordlessEnabled", passwordlessEnabled); + } + + requestBody.add("coreConfig", coreConfig); + + JsonObject response = HttpRequestForTesting.sendJsonPUTRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(sourceTenant, "/recipe/multitenancy/connectionuridomain"), + requestBody, 1000, 2500, null, + SemVer.v3_0.get(), "multitenancy"); + + assertEquals("OK", response.getAsJsonPrimitive("status").getAsString()); + + return response; + } + + private static JsonObject listConnectionUriDomains(TenantIdentifier sourceTenant, Main main) + throws HttpResponseException, IOException { + JsonObject response = HttpRequestForTesting.sendGETRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(sourceTenant, "/recipe/multitenancy/connectionuridomain/list"), + null, 1000, 1000, null, + SemVer.v3_0.get(), "multitenancy"); + + assertEquals("OK", response.getAsJsonPrimitive("status").getAsString()); + return response; + } + + private static JsonObject deleteConnectionUriDomain(TenantIdentifier sourceTenant, String connectionUriDomain, + Main main) + throws HttpResponseException, IOException { + JsonObject requestBody = new JsonObject(); + requestBody.addProperty("connectionUriDomain", connectionUriDomain); + + JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(sourceTenant, "/recipe/multitenancy/connectionuridomain/remove"), + requestBody, 1000, 2500, null, + SemVer.v3_0.get(), "multitenancy"); + + assertEquals("OK", response.getAsJsonPrimitive("status").getAsString()); + return response; + } + + private static JsonObject getTenant(TenantIdentifier tenantIdentifier, Main main) + throws HttpResponseException, IOException { + JsonObject response = HttpRequestForTesting.sendGETRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/multitenancy/tenant"), + null, 1000, 1000, null, + SemVer.v3_0.get(), "multitenancy"); + + assertEquals("OK", response.getAsJsonPrimitive("status").getAsString()); + return response; + } +} diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain.java b/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain5_0.java similarity index 72% rename from src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain.java rename to src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain5_0.java index 31102bb5e..eb09f95b1 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain5_0.java @@ -19,6 +19,7 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import io.supertokens.Main; import io.supertokens.ProcessState; import io.supertokens.featureflag.EE_FEATURES; import io.supertokens.featureflag.FeatureFlagTestContent; @@ -52,7 +53,7 @@ import static org.junit.Assert.*; -public class TestConnectionUriDomain { +public class TestConnectionUriDomain5_0 { TestingProcessManager.TestingProcess process; @AfterClass @@ -96,13 +97,13 @@ public void testCreateConnectionUriDomainWorks() throws Exception { StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()) .modifyConfigToAddANewUserPoolForTesting(coreConfig, 1); - TestMultitenancyAPIHelper.createConnectionUriDomain( + createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1:3567", true, true, true, coreConfig); - JsonObject result = TestMultitenancyAPIHelper.listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + JsonObject result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); assertTrue(result.has("connectionUriDomains")); boolean found = false; @@ -116,8 +117,13 @@ public void testCreateConnectionUriDomainWorks() throws Exception { for (JsonElement tenant : appObj.get("tenants").getAsJsonArray()) { JsonObject tenantObj = tenant.getAsJsonObject(); + assertEquals(5, tenantObj.entrySet().size()); + assertEquals("public", tenantObj.get("tenantId").getAsString()); + assertEquals(1, tenantObj.get("emailPassword").getAsJsonObject().entrySet().size()); assertTrue(tenantObj.get("emailPassword").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(2, tenantObj.get("thirdParty").getAsJsonObject().entrySet().size()); assertTrue(tenantObj.get("thirdParty").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(1, tenantObj.get("passwordless").getAsJsonObject().entrySet().size()); assertTrue(tenantObj.get("passwordless").getAsJsonObject().get("enabled").getAsBoolean()); assertEquals(coreConfig, tenantObj.get("coreConfig").getAsJsonObject()); } @@ -143,7 +149,7 @@ public void testUpdateConnectionUriDomainWorks() throws Exception { .modifyConfigToAddANewUserPoolForTesting(coreConfig, 1); // Create - TestMultitenancyAPIHelper.createConnectionUriDomain( + createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1:3567", true, true, true, @@ -154,13 +160,13 @@ public void testUpdateConnectionUriDomainWorks() throws Exception { coreConfig.addProperty("email_verification_token_lifetime", 2000); // Update - TestMultitenancyAPIHelper.createConnectionUriDomain( + createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1:3567", true, true, true, newConfig); - JsonObject result = TestMultitenancyAPIHelper.listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + JsonObject result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); assertTrue(result.has("connectionUriDomains")); boolean found = false; @@ -174,8 +180,13 @@ public void testUpdateConnectionUriDomainWorks() throws Exception { for (JsonElement tenant : appObj.get("tenants").getAsJsonArray()) { JsonObject tenantObj = tenant.getAsJsonObject(); + assertEquals(5, tenantObj.entrySet().size()); + assertEquals("public", tenantObj.get("tenantId").getAsString()); + assertEquals(1, tenantObj.get("emailPassword").getAsJsonObject().entrySet().size()); assertTrue(tenantObj.get("emailPassword").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(2, tenantObj.get("thirdParty").getAsJsonObject().entrySet().size()); assertTrue(tenantObj.get("thirdParty").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(1, tenantObj.get("passwordless").getAsJsonObject().entrySet().size()); assertTrue(tenantObj.get("passwordless").getAsJsonObject().get("enabled").getAsBoolean()); assertEquals(coreConfig, tenantObj.get("coreConfig").getAsJsonObject()); } @@ -201,7 +212,7 @@ public void testUpdateConnectionUriDomainFromSameConnectionUriDomainWorks() thro .modifyConfigToAddANewUserPoolForTesting(coreConfig, 1); // Create - TestMultitenancyAPIHelper.createConnectionUriDomain( + createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1:3567", true, true, true, @@ -212,13 +223,13 @@ public void testUpdateConnectionUriDomainFromSameConnectionUriDomainWorks() thro coreConfig.addProperty("email_verification_token_lifetime", 2000); // Update - TestMultitenancyAPIHelper.createConnectionUriDomain( + createConnectionUriDomain( process.getProcess(), new TenantIdentifier("127.0.0.1", null, null), "127.0.0.1", true, true, true, newConfig); - JsonObject result = TestMultitenancyAPIHelper.listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + JsonObject result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); assertTrue(result.has("connectionUriDomains")); boolean found = false; @@ -232,8 +243,13 @@ public void testUpdateConnectionUriDomainFromSameConnectionUriDomainWorks() thro for (JsonElement tenant : appObj.get("tenants").getAsJsonArray()) { JsonObject tenantObj = tenant.getAsJsonObject(); + assertEquals(5, tenantObj.entrySet().size()); + assertEquals("public", tenantObj.get("tenantId").getAsString()); + assertEquals(1, tenantObj.get("emailPassword").getAsJsonObject().entrySet().size()); assertTrue(tenantObj.get("emailPassword").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(2, tenantObj.get("thirdParty").getAsJsonObject().entrySet().size()); assertTrue(tenantObj.get("thirdParty").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(1, tenantObj.get("passwordless").getAsJsonObject().entrySet().size()); assertTrue(tenantObj.get("passwordless").getAsJsonObject().get("enabled").getAsBoolean()); assertEquals(coreConfig, tenantObj.get("coreConfig").getAsJsonObject()); } @@ -260,7 +276,7 @@ public void testUpdateWithNullValueDeletesTheSetting() throws Exception { coreConfig.addProperty("email_verification_token_lifetime", 2000); // Create - TestMultitenancyAPIHelper.createConnectionUriDomain( + createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1:3567", true, true, true, @@ -271,13 +287,13 @@ public void testUpdateWithNullValueDeletesTheSetting() throws Exception { coreConfig.remove("email_verification_token_lifetime"); // for verification // Update - TestMultitenancyAPIHelper.createConnectionUriDomain( + createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1:3567", true, true, true, newConfig); - JsonObject result = TestMultitenancyAPIHelper.listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + JsonObject result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); assertTrue(result.has("connectionUriDomains")); boolean found = false; @@ -317,25 +333,25 @@ public void testDeleteConnectionUriDomainWorks() throws Exception { StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()) .modifyConfigToAddANewUserPoolForTesting(coreConfig, 1); - TestMultitenancyAPIHelper.createConnectionUriDomain( + createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1:3567", true, true, true, coreConfig); - JsonObject result = TestMultitenancyAPIHelper.listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + JsonObject result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); assertTrue(result.has("connectionUriDomains")); assertEquals(2, result.get("connectionUriDomains").getAsJsonArray().size()); - JsonObject response = TestMultitenancyAPIHelper.deleteConnectionUriDomain(new TenantIdentifier(null, null, null), + JsonObject response = deleteConnectionUriDomain(new TenantIdentifier(null, null, null), "127.0.0.1:3567", process.getProcess()); assertTrue(response.get("didExist").getAsBoolean()); - result = TestMultitenancyAPIHelper.listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); assertTrue(result.has("connectionUriDomains")); assertEquals(1, result.get("connectionUriDomains").getAsJsonArray().size()); - response = TestMultitenancyAPIHelper.deleteConnectionUriDomain(new TenantIdentifier(null, null, null), + response = deleteConnectionUriDomain(new TenantIdentifier(null, null, null), "127.0.0.1:3567", process.getProcess()); assertFalse(response.get("didExist").getAsBoolean()); } @@ -393,7 +409,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } }); - TestMultitenancyAPIHelper.createConnectionUriDomain( + createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), valueForCreate[i], true, true, true, @@ -426,7 +442,7 @@ public void testCUDsThatAreSame() throws Exception { StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); for (int i = 0; i < valueForCreate.length; i++) { - JsonObject response = TestMultitenancyAPIHelper.createConnectionUriDomain( + JsonObject response = createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), valueForCreate[i], true, true, true, @@ -452,7 +468,7 @@ public void testDifferentValuesForCUDThatShouldNotWork() throws Exception { JsonObject config = new JsonObject(); StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); - TestMultitenancyAPIHelper.createConnectionUriDomain( + createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), valueForCreate[i], true, true, true, @@ -477,7 +493,7 @@ public void testDefaultRecipesEnabledWhileCreatingCUD() throws Exception { JsonObject config = new JsonObject(); StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); - JsonObject response = TestMultitenancyAPIHelper.createConnectionUriDomain( + JsonObject response = createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "localhost:3567", null, null, null, @@ -485,7 +501,7 @@ public void testDefaultRecipesEnabledWhileCreatingCUD() throws Exception { assertTrue(response.get("createdNew").getAsBoolean()); - JsonObject tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier("localhost", null, null), + JsonObject tenant = getTenant(new TenantIdentifier("localhost", null, null), process.getProcess()); assertTrue(tenant.get("emailPassword").getAsJsonObject().get("enabled").getAsBoolean()); assertTrue(tenant.get("thirdParty").getAsJsonObject().get("enabled").getAsBoolean()); @@ -505,7 +521,7 @@ public void testFirstFactorsArray() throws Exception { JsonObject config = new JsonObject(); StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); - JsonObject response = TestMultitenancyAPIHelper.createConnectionUriDomain( + JsonObject response = createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1", null, null, null, @@ -513,82 +529,88 @@ public void testFirstFactorsArray() throws Exception { assertTrue(response.get("createdNew").getAsBoolean()); - JsonObject tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier("127.0.0.1", null, null), - process.getProcess(), SemVer.v5_0); + JsonObject tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(6, tenant.entrySet().size()); assertNull(tenant.get("firstFactors")); // builtin firstFactor String[] firstFactors = new String[]{"otp-phone"}; - response = TestMultitenancyAPIHelper.createConnectionUriDomain( + response = createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1", null, null, null, true, new String[]{"otp-phone"}, false, null, - config, SemVer.v5_0); + config); assertFalse(response.get("createdNew").getAsBoolean()); - tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier("127.0.0.1", null, null), - process.getProcess(), SemVer.v5_0); + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(7, tenant.entrySet().size()); assertTrue(tenant.get("firstFactors").isJsonArray()); assertEquals(1, tenant.get("firstFactors").getAsJsonArray().size()); assertEquals(firstFactors, new Gson().fromJson(tenant.get("firstFactors").getAsJsonArray(), String[].class)); - response = TestMultitenancyAPIHelper.createConnectionUriDomain( + response = createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1", null, null, null, false, null, false, null, - config, SemVer.v5_0); + config); assertFalse(response.get("createdNew").getAsBoolean()); - tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier("127.0.0.1", null, null), - process.getProcess(), SemVer.v5_0); + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(7, tenant.entrySet().size()); assertTrue(tenant.get("firstFactors").isJsonArray()); assertEquals(1, tenant.get("firstFactors").getAsJsonArray().size()); assertEquals(firstFactors, new Gson().fromJson(tenant.get("firstFactors").getAsJsonArray(), String[].class)); // custom factors firstFactors = new String[]{"biometric"}; - response = TestMultitenancyAPIHelper.createConnectionUriDomain( + response = createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1", null, null, null, true, firstFactors, false, null, - config, SemVer.v5_0); + config); assertFalse(response.get("createdNew").getAsBoolean()); - tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier("127.0.0.1", null, null), - process.getProcess(), SemVer.v5_0); + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(7, tenant.entrySet().size()); assertTrue(tenant.get("firstFactors").isJsonArray()); assertEquals(1, tenant.get("firstFactors").getAsJsonArray().size()); assertEquals(firstFactors, new Gson().fromJson(tenant.get("firstFactors").getAsJsonArray(), String[].class)); // test both firstFactors = new String[]{"otp-phone", "emailpassword", "biometric", "custom"}; - response = TestMultitenancyAPIHelper.createConnectionUriDomain( + response = createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1", null, null, null, true, firstFactors, false, null, - config, SemVer.v5_0); + config); assertFalse(response.get("createdNew").getAsBoolean()); - tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier("127.0.0.1", null, null), - process.getProcess(), SemVer.v5_0); + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(7, tenant.entrySet().size()); assertTrue(tenant.get("firstFactors").isJsonArray()); assertEquals(4, tenant.get("firstFactors").getAsJsonArray().size()); assertEquals(Set.of(firstFactors), Set.of(new Gson().fromJson(tenant.get("firstFactors").getAsJsonArray(), String[].class))); - response = TestMultitenancyAPIHelper.createConnectionUriDomain( + response = createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1", null, null, null, true, null, false, null, - config, SemVer.v5_0); + config); assertFalse(response.get("createdNew").getAsBoolean()); - tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier("127.0.0.1", null, null), - process.getProcess(), SemVer.v5_0); + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(6, tenant.entrySet().size()); assertNull(tenant.get("firstFactors")); } @@ -605,7 +627,7 @@ public void testRequiredSecondaryFactorsArray() throws Exception { JsonObject config = new JsonObject(); StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); - JsonObject response = TestMultitenancyAPIHelper.createConnectionUriDomain( + JsonObject response = createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1", null, null, null, @@ -613,82 +635,87 @@ public void testRequiredSecondaryFactorsArray() throws Exception { assertTrue(response.get("createdNew").getAsBoolean()); - JsonObject tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier("127.0.0.1", null, null), - process.getProcess(), SemVer.v5_0); + JsonObject tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); assertNull(tenant.get("requiredSecondaryFactors")); // builtin firstFactor String[] requiredSecondaryFactors = new String[]{"otp-phone"}; - response = TestMultitenancyAPIHelper.createConnectionUriDomain( + response = createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1", null, null, null, false, null, true, new String[]{"otp-phone"}, - config, SemVer.v5_0); + config); assertFalse(response.get("createdNew").getAsBoolean()); - tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier("127.0.0.1", null, null), - process.getProcess(), SemVer.v5_0); + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(7, tenant.entrySet().size()); assertTrue(tenant.get("requiredSecondaryFactors").isJsonArray()); assertEquals(1, tenant.get("requiredSecondaryFactors").getAsJsonArray().size()); assertEquals(requiredSecondaryFactors, new Gson().fromJson(tenant.get("requiredSecondaryFactors").getAsJsonArray(), String[].class)); - response = TestMultitenancyAPIHelper.createConnectionUriDomain( + response = createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1", null, null, null, false, null, false, null, - config, SemVer.v5_0); + config); assertFalse(response.get("createdNew").getAsBoolean()); - tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier("127.0.0.1", null, null), - process.getProcess(), SemVer.v5_0); + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(7, tenant.entrySet().size()); assertTrue(tenant.get("requiredSecondaryFactors").isJsonArray()); assertEquals(1, tenant.get("requiredSecondaryFactors").getAsJsonArray().size()); assertEquals(requiredSecondaryFactors, new Gson().fromJson(tenant.get("requiredSecondaryFactors").getAsJsonArray(), String[].class)); // custom factors requiredSecondaryFactors = new String[]{"biometric"}; - response = TestMultitenancyAPIHelper.createConnectionUriDomain( + response = createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1", null, null, null, false, null, true, requiredSecondaryFactors, - config, SemVer.v5_0); + config); assertFalse(response.get("createdNew").getAsBoolean()); - tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier("127.0.0.1", null, null), - process.getProcess(), SemVer.v5_0); + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(7, tenant.entrySet().size()); assertTrue(tenant.get("requiredSecondaryFactors").isJsonArray()); assertEquals(1, tenant.get("requiredSecondaryFactors").getAsJsonArray().size()); assertEquals(requiredSecondaryFactors, new Gson().fromJson(tenant.get("requiredSecondaryFactors").getAsJsonArray(), String[].class)); // test both requiredSecondaryFactors = new String[]{"otp-phone", "emailpassword", "biometric", "custom"}; - response = TestMultitenancyAPIHelper.createConnectionUriDomain( + response = createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1", null, null, null, false, null, true, requiredSecondaryFactors, - config, SemVer.v5_0); + config); assertFalse(response.get("createdNew").getAsBoolean()); - tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier("127.0.0.1", null, null), - process.getProcess(), SemVer.v5_0); + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(7, tenant.entrySet().size()); assertTrue(tenant.get("requiredSecondaryFactors").isJsonArray()); assertEquals(4, tenant.get("requiredSecondaryFactors").getAsJsonArray().size()); assertEquals(Set.of(requiredSecondaryFactors), Set.of(new Gson().fromJson(tenant.get("requiredSecondaryFactors").getAsJsonArray(), String[].class))); - response = TestMultitenancyAPIHelper.createConnectionUriDomain( + response = createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1", null, null, null, false, null, true, null, - config, SemVer.v5_0); + config); assertFalse(response.get("createdNew").getAsBoolean()); - tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier("127.0.0.1", null, null), - process.getProcess(), SemVer.v5_0); + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(6, tenant.entrySet().size()); assertNull(tenant.get("requiredSecondaryFactors")); } @@ -703,12 +730,12 @@ public void testDuplicateValuesInFirstFactorsAndRequiredSecondaryFactors() throw String[] factors = new String[]{"duplicate", "emailpassword", "duplicate", "custom"}; try { - TestMultitenancyAPIHelper.createConnectionUriDomain( + createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1", null, null, null, true, factors, false, null, - config, SemVer.v5_0); + config); fail(); } catch (HttpResponseException e) { assertEquals(400, e.statusCode); @@ -716,17 +743,99 @@ public void testDuplicateValuesInFirstFactorsAndRequiredSecondaryFactors() throw } try { - TestMultitenancyAPIHelper.createConnectionUriDomain( + createConnectionUriDomain( process.getProcess(), new TenantIdentifier(null, null, null), "127.0.0.1", null, null, null, false, null, true, factors, - config, SemVer.v5_0); + config); fail(); } catch (HttpResponseException e) { assertEquals(400, e.statusCode); assertEquals("Http error. Status Code: 400. Message: requiredSecondaryFactors input should not contain duplicate values", e.getMessage()); } + } + + private static JsonObject createConnectionUriDomain(Main main, TenantIdentifier sourceTenant, + String connectionUriDomain, Boolean emailPasswordEnabled, + Boolean thirdPartyEnabled, Boolean passwordlessEnabled, + JsonObject coreConfig) throws HttpResponseException, IOException { + return createConnectionUriDomain(main, sourceTenant, connectionUriDomain, emailPasswordEnabled, thirdPartyEnabled, + passwordlessEnabled, false, null, false, null, coreConfig); + } + + private static JsonObject createConnectionUriDomain(Main main, TenantIdentifier sourceTenant, + String connectionUriDomain, Boolean emailPasswordEnabled, + Boolean thirdPartyEnabled, Boolean passwordlessEnabled, + boolean setFirstFactors, String[] firstFactors, + boolean setRequiredSecondaryFactors, String[] requiredSecondaryFactors, + JsonObject coreConfig) throws HttpResponseException, IOException { + JsonObject requestBody = new JsonObject(); + if (connectionUriDomain != null) { + requestBody.addProperty("connectionUriDomain", connectionUriDomain); + } + if (emailPasswordEnabled != null) { + requestBody.addProperty("emailPasswordEnabled", emailPasswordEnabled); + } + if (thirdPartyEnabled != null) { + requestBody.addProperty("thirdPartyEnabled", thirdPartyEnabled); + } + if (passwordlessEnabled != null) { + requestBody.addProperty("passwordlessEnabled", passwordlessEnabled); + } + if (setFirstFactors || firstFactors != null) { + requestBody.add("firstFactors", new Gson().toJsonTree(firstFactors)); + } + if (setRequiredSecondaryFactors || requiredSecondaryFactors != null) { + requestBody.add("requiredSecondaryFactors", new Gson().toJsonTree(requiredSecondaryFactors)); + } + + requestBody.add("coreConfig", coreConfig); + + JsonObject response = HttpRequestForTesting.sendJsonPUTRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(sourceTenant, "/recipe/multitenancy/connectionuridomain"), + requestBody, 1000, 2500, null, + SemVer.v5_0.get(), "multitenancy"); + + assertEquals("OK", response.getAsJsonPrimitive("status").getAsString()); + + return response; + } + + private static JsonObject listConnectionUriDomains(TenantIdentifier sourceTenant, Main main) + throws HttpResponseException, IOException { + JsonObject response = HttpRequestForTesting.sendGETRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(sourceTenant, "/recipe/multitenancy/connectionuridomain/list"), + null, 1000, 1000, null, + SemVer.v5_0.get(), "multitenancy"); + + assertEquals("OK", response.getAsJsonPrimitive("status").getAsString()); + return response; + } + + private static JsonObject deleteConnectionUriDomain(TenantIdentifier sourceTenant, String connectionUriDomain, + Main main) + throws HttpResponseException, IOException { + JsonObject requestBody = new JsonObject(); + requestBody.addProperty("connectionUriDomain", connectionUriDomain); + + JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(sourceTenant, "/recipe/multitenancy/connectionuridomain/remove"), + requestBody, 1000, 2500, null, + SemVer.v5_0.get(), "multitenancy"); + + assertEquals("OK", response.getAsJsonPrimitive("status").getAsString()); + return response; + } + + private static JsonObject getTenant(TenantIdentifier tenantIdentifier, Main main) + throws HttpResponseException, IOException { + JsonObject response = HttpRequestForTesting.sendGETRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/multitenancy/tenant"), + null, 1000, 1000, null, + SemVer.v5_0.get(), "multitenancy"); + assertEquals("OK", response.getAsJsonPrimitive("status").getAsString()); + return response; } } diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain5_1.java b/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain5_1.java new file mode 100644 index 000000000..8db2d8dde --- /dev/null +++ b/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain5_1.java @@ -0,0 +1,850 @@ +/* + * Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved. + * + * This software is licensed under the Apache License, Version 2.0 (the + * "License") as published by the Apache Software Foundation. + * + * 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 io.supertokens.test.multitenant.api; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import io.supertokens.Main; +import io.supertokens.ProcessState; +import io.supertokens.featureflag.EE_FEATURES; +import io.supertokens.featureflag.FeatureFlagTestContent; +import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; +import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.multitenancy.exception.CannotModifyBaseConfigException; +import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.exceptions.InvalidConfigException; +import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; +import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; +import io.supertokens.storageLayer.StorageLayer; +import io.supertokens.test.TestingProcessManager; +import io.supertokens.test.Utils; +import io.supertokens.test.httpRequest.HttpRequestForTesting; +import io.supertokens.test.httpRequest.HttpResponseException; +import io.supertokens.thirdparty.InvalidProviderConfigException; +import io.supertokens.utils.SemVer; +import io.supertokens.webserver.Webserver; +import io.supertokens.webserver.WebserverAPI; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.util.Set; + +import static org.junit.Assert.*; + +public class TestConnectionUriDomain5_1 { + TestingProcessManager.TestingProcess process; + + @AfterClass + public static void afterTesting() { + Utils.afterTesting(); + } + + @After + public void afterEach() throws InterruptedException { + process.kill(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); + } + + @Before + public void beforeEach() throws InterruptedException, InvalidProviderConfigException, + StorageQueryException, FeatureNotEnabledException, TenantOrAppNotFoundException, IOException, + InvalidConfigException, CannotModifyBaseConfigException, BadPermissionException { + Utils.reset(); + + String[] args = {"../"}; + + this.process = TestingProcessManager.start(args); + FeatureFlagTestContent.getInstance(process.getProcess()) + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MULTI_TENANCY}); + process.startProcess(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + } + + @Test + public void testCreateConnectionUriDomainWorks() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject coreConfig = new JsonObject(); + + StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()) + .modifyConfigToAddANewUserPoolForTesting(coreConfig, 1); + + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1:3567", true, true, true, + coreConfig); + + JsonObject result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + assertTrue(result.has("connectionUriDomains")); + + boolean found = false; + for (JsonElement cud : result.get("connectionUriDomains").getAsJsonArray()) { + JsonObject cudObj = cud.getAsJsonObject(); + if (cudObj.get("connectionUriDomain").getAsString().equals("127.0.0.1")) { + found = true; + + for (JsonElement app : cudObj.get("apps").getAsJsonArray()) { + JsonObject appObj = app.getAsJsonObject(); + + for (JsonElement tenant : appObj.get("tenants").getAsJsonArray()) { + JsonObject tenantObj = tenant.getAsJsonObject(); + assertEquals(6, tenantObj.entrySet().size()); + assertEquals("public", tenantObj.get("tenantId").getAsString()); + assertTrue(tenantObj.get("useFirstFactorsFromStaticConfigIfEmpty").getAsBoolean()); + assertEquals(1, tenantObj.get("emailPassword").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("emailPassword").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(3, tenantObj.get("thirdParty").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("thirdParty").getAsJsonObject().get("enabled").getAsBoolean()); + assertTrue(tenantObj.get("thirdParty").getAsJsonObject().get( + "useThirdPartyProvidersFromStaticConfigIfEmpty").getAsBoolean()); + assertEquals(1, tenantObj.get("passwordless").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("passwordless").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(coreConfig, tenantObj.get("coreConfig").getAsJsonObject()); + } + } + } + } + assertTrue(found); + } + + @Test + public void testUpdateConnectionUriDomainWorks() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject coreConfig = new JsonObject(); + + StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()) + .modifyConfigToAddANewUserPoolForTesting(coreConfig, 1); + + // Create + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1:3567", true, true, true, + coreConfig); + + JsonObject newConfig = new JsonObject(); + newConfig.addProperty("email_verification_token_lifetime", 2000); + coreConfig.addProperty("email_verification_token_lifetime", 2000); + + // Update + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1:3567", true, true, true, + newConfig); + + JsonObject result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + assertTrue(result.has("connectionUriDomains")); + + boolean found = false; + for (JsonElement cud : result.get("connectionUriDomains").getAsJsonArray()) { + JsonObject cudObj = cud.getAsJsonObject(); + if (cudObj.get("connectionUriDomain").getAsString().equals("127.0.0.1")) { + found = true; + + for (JsonElement app : cudObj.get("apps").getAsJsonArray()) { + JsonObject appObj = app.getAsJsonObject(); + + for (JsonElement tenant : appObj.get("tenants").getAsJsonArray()) { + JsonObject tenantObj = tenant.getAsJsonObject(); + assertEquals(6, tenantObj.entrySet().size()); + assertEquals("public", tenantObj.get("tenantId").getAsString()); + assertTrue(tenantObj.get("useFirstFactorsFromStaticConfigIfEmpty").getAsBoolean()); + assertEquals(1, tenantObj.get("emailPassword").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("emailPassword").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(3, tenantObj.get("thirdParty").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("thirdParty").getAsJsonObject().get("enabled").getAsBoolean()); + assertTrue(tenantObj.get("thirdParty").getAsJsonObject().get( + "useThirdPartyProvidersFromStaticConfigIfEmpty").getAsBoolean()); + assertEquals(1, tenantObj.get("passwordless").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("passwordless").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(coreConfig, tenantObj.get("coreConfig").getAsJsonObject()); + } + } + } + } + assertTrue(found); + } + + @Test + public void testUpdateConnectionUriDomainFromSameConnectionUriDomainWorks() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject coreConfig = new JsonObject(); + + StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()) + .modifyConfigToAddANewUserPoolForTesting(coreConfig, 1); + + // Create + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1:3567", true, true, true, + coreConfig); + + JsonObject newConfig = new JsonObject(); + newConfig.addProperty("email_verification_token_lifetime", 2000); + coreConfig.addProperty("email_verification_token_lifetime", 2000); + + // Update + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier("127.0.0.1", null, null), + "127.0.0.1", true, true, true, + newConfig); + + JsonObject result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + assertTrue(result.has("connectionUriDomains")); + + boolean found = false; + for (JsonElement cud : result.get("connectionUriDomains").getAsJsonArray()) { + JsonObject cudObj = cud.getAsJsonObject(); + if (cudObj.get("connectionUriDomain").getAsString().equals("127.0.0.1")) { + found = true; + + for (JsonElement app : cudObj.get("apps").getAsJsonArray()) { + JsonObject appObj = app.getAsJsonObject(); + + for (JsonElement tenant : appObj.get("tenants").getAsJsonArray()) { + JsonObject tenantObj = tenant.getAsJsonObject(); + assertEquals(6, tenantObj.entrySet().size()); + assertEquals("public", tenantObj.get("tenantId").getAsString()); + assertTrue(tenantObj.get("useFirstFactorsFromStaticConfigIfEmpty").getAsBoolean()); + assertEquals(1, tenantObj.get("emailPassword").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("emailPassword").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(3, tenantObj.get("thirdParty").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("thirdParty").getAsJsonObject().get("enabled").getAsBoolean()); + assertTrue(tenantObj.get("thirdParty").getAsJsonObject().get( + "useThirdPartyProvidersFromStaticConfigIfEmpty").getAsBoolean()); + assertEquals(1, tenantObj.get("passwordless").getAsJsonObject().entrySet().size()); + assertTrue(tenantObj.get("passwordless").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(coreConfig, tenantObj.get("coreConfig").getAsJsonObject()); + } + } + } + } + assertTrue(found); + } + + @Test + public void testUpdateWithNullValueDeletesTheSetting() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject coreConfig = new JsonObject(); + + StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()) + .modifyConfigToAddANewUserPoolForTesting(coreConfig, 1); + coreConfig.addProperty("email_verification_token_lifetime", 2000); + + // Create + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1:3567", true, true, true, + coreConfig); + + JsonObject newConfig = new JsonObject(); + newConfig.add("email_verification_token_lifetime", null); + coreConfig.remove("email_verification_token_lifetime"); // for verification + + // Update + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1:3567", true, true, true, + newConfig); + + JsonObject result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + assertTrue(result.has("connectionUriDomains")); + + boolean found = false; + for (JsonElement cud : result.get("connectionUriDomains").getAsJsonArray()) { + JsonObject cudObj = cud.getAsJsonObject(); + if (cudObj.get("connectionUriDomain").getAsString().equals("127.0.0.1")) { + found = true; + + for (JsonElement app : cudObj.get("apps").getAsJsonArray()) { + JsonObject appObj = app.getAsJsonObject(); + + for (JsonElement tenant : appObj.get("tenants").getAsJsonArray()) { + JsonObject tenantObj = tenant.getAsJsonObject(); + assertTrue(tenantObj.get("emailPassword").getAsJsonObject().get("enabled").getAsBoolean()); + assertTrue(tenantObj.get("thirdParty").getAsJsonObject().get("enabled").getAsBoolean()); + assertTrue(tenantObj.get("passwordless").getAsJsonObject().get("enabled").getAsBoolean()); + assertEquals(coreConfig, tenantObj.get("coreConfig").getAsJsonObject()); + } + } + } + } + assertTrue(found); + } + + @Test + public void testDeleteConnectionUriDomainWorks() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject coreConfig = new JsonObject(); + + StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()) + .modifyConfigToAddANewUserPoolForTesting(coreConfig, 1); + + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1:3567", true, true, true, + coreConfig); + + JsonObject result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + assertTrue(result.has("connectionUriDomains")); + assertEquals(2, result.get("connectionUriDomains").getAsJsonArray().size()); + + JsonObject response = deleteConnectionUriDomain(new TenantIdentifier(null, null, null), + "127.0.0.1:3567", process.getProcess()); + assertTrue(response.get("didExist").getAsBoolean()); + + result = listConnectionUriDomains(new TenantIdentifier(null, null, null), process.getProcess()); + assertTrue(result.has("connectionUriDomains")); + assertEquals(1, result.get("connectionUriDomains").getAsJsonArray().size()); + + response = deleteConnectionUriDomain(new TenantIdentifier(null, null, null), + "127.0.0.1:3567", process.getProcess()); + assertFalse(response.get("didExist").getAsBoolean()); + } + + @Test + public void testDifferentValuesForCUDThatShouldWork() throws Exception { + String[] valueForCreate = new String[]{"localhost:3567", "LOCALHOST:3567", "loCalHost:3567", "127.0.0.1:3567"}; + String[] valueForQuery = new String[]{"localhost:3567", "LOCALHOST:3567", "LOCALhoST:3567", "127.0.0.1:3567"}; + + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject config = new JsonObject(); + StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); + + process.kill(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); + + for (int i = 0; i < valueForCreate.length; i++) { + String[] args = {"../"}; + this.process = TestingProcessManager.start(args); + FeatureFlagTestContent.getInstance(process.getProcess()) + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MULTI_TENANCY}); + process.startProcess(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + + Webserver.getInstance(process.getProcess()).addAPI(new WebserverAPI(process.getProcess(), "") { + + private static final long serialVersionUID = 1L; + + @Override + public boolean checkAPIKey(HttpServletRequest req) { + return false; + } + + @Override + public String getPath() { + return "/get-cud"; + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, + ServletException { + try { + getTenantStorage(req); + super.sendTextResponse(200, this.getTenantIdentifier(req).getConnectionUriDomain(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } + } + }); + + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + valueForCreate[i], true, true, true, + config); + + String response = HttpRequestForTesting.sendGETRequest(process.getProcess(), "", + "http://" + valueForQuery[i] + "/get-cud", null, 1000, 1000, + null, WebserverAPI.getLatestCDIVersion().get(), null); + + assertEquals(valueForCreate[i].toLowerCase().split(":")[0], response); + + process.kill(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); + } + } + + @Test + public void testCUDsThatAreSame() throws Exception { + String[] valueForCreate = new String[]{"localhost:3567", "LOCALHOST:3567", "loCalHost:3567", "localhost", "localhost:12345"}; + + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject config = new JsonObject(); + StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); + + for (int i = 0; i < valueForCreate.length; i++) { + JsonObject response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + valueForCreate[i], true, true, true, + config); + + if (i == 0) { + assertTrue(response.get("createdNew").getAsBoolean()); + } else { + assertFalse(response.get("createdNew").getAsBoolean()); + } + } + } + + @Test + public void testDifferentValuesForCUDThatShouldNotWork() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + String[] valueForCreate = new String[]{"http://localhost_com", "localhost:", "domain.com:abcd"}; + for (int i = 0; i < valueForCreate.length; i++) { + try { + JsonObject config = new JsonObject(); + StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); + + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + valueForCreate[i], true, true, true, + config); + fail(valueForCreate[i]); + } catch (HttpResponseException e) { + assertTrue(e.getMessage().contains("connectionUriDomain is invalid")); + } + } + } + + @Test + public void testDefaultRecipesEnabledWhileCreatingCUD() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject config = new JsonObject(); + StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); + + JsonObject response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "localhost:3567", null, null, null, + config); + + assertTrue(response.get("createdNew").getAsBoolean()); + + JsonObject tenant = getTenant(new TenantIdentifier("localhost", null, null), + process.getProcess()); + assertTrue(tenant.get("emailPassword").getAsJsonObject().get("enabled").getAsBoolean()); + assertTrue(tenant.get("thirdParty").getAsJsonObject().get("enabled").getAsBoolean()); + assertTrue(tenant.get("passwordless").getAsJsonObject().get("enabled").getAsBoolean()); + } + + @Test + public void testFirstFactorsArray() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject config = new JsonObject(); + StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); + + JsonObject response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1", null, null, null, + config); + + assertTrue(response.get("createdNew").getAsBoolean()); + + JsonObject tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(7, tenant.entrySet().size()); + assertNull(tenant.get("firstFactors")); + + // builtin firstFactor + String[] firstFactors = new String[]{"otp-phone"}; + response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1", null, null, null, + true, new String[]{"otp-phone"}, false, null, + config); + assertFalse(response.get("createdNew").getAsBoolean()); + + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(8, tenant.entrySet().size()); + assertTrue(tenant.get("firstFactors").isJsonArray()); + assertEquals(1, tenant.get("firstFactors").getAsJsonArray().size()); + assertEquals(firstFactors, new Gson().fromJson(tenant.get("firstFactors").getAsJsonArray(), String[].class)); + + response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1", null, null, null, + false, null, false, null, + config); + assertFalse(response.get("createdNew").getAsBoolean()); + + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(8, tenant.entrySet().size()); + assertTrue(tenant.get("firstFactors").isJsonArray()); + assertEquals(1, tenant.get("firstFactors").getAsJsonArray().size()); + assertEquals(firstFactors, new Gson().fromJson(tenant.get("firstFactors").getAsJsonArray(), String[].class)); + + // custom factors + firstFactors = new String[]{"biometric"}; + response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1", null, null, null, + true, firstFactors, false, null, + config); + assertFalse(response.get("createdNew").getAsBoolean()); + + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(8, tenant.entrySet().size()); + assertTrue(tenant.get("firstFactors").isJsonArray()); + assertEquals(1, tenant.get("firstFactors").getAsJsonArray().size()); + assertEquals(firstFactors, new Gson().fromJson(tenant.get("firstFactors").getAsJsonArray(), String[].class)); + + // test both + firstFactors = new String[]{"otp-phone", "emailpassword", "biometric", "custom"}; + response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1", null, null, null, + true, firstFactors, false, null, + config); + assertFalse(response.get("createdNew").getAsBoolean()); + + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(8, tenant.entrySet().size()); + assertTrue(tenant.get("firstFactors").isJsonArray()); + assertEquals(4, tenant.get("firstFactors").getAsJsonArray().size()); + assertEquals(Set.of(firstFactors), Set.of(new Gson().fromJson(tenant.get("firstFactors").getAsJsonArray(), String[].class))); + + response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1", null, null, null, + true, null, false, null, + config); + assertFalse(response.get("createdNew").getAsBoolean()); + + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(7, tenant.entrySet().size()); + assertNull(tenant.get("firstFactors")); + } + + @Test + public void testRequiredSecondaryFactorsArray() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + + JsonObject config = new JsonObject(); + StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); + + JsonObject response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1", null, null, null, + config); + + assertTrue(response.get("createdNew").getAsBoolean()); + + JsonObject tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertNull(tenant.get("requiredSecondaryFactors")); + + // builtin firstFactor + String[] requiredSecondaryFactors = new String[]{"otp-phone"}; + response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1", null, null, null, + false, null, true, new String[]{"otp-phone"}, + config); + assertFalse(response.get("createdNew").getAsBoolean()); + + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(8, tenant.entrySet().size()); + assertTrue(tenant.get("requiredSecondaryFactors").isJsonArray()); + assertEquals(1, tenant.get("requiredSecondaryFactors").getAsJsonArray().size()); + assertEquals(requiredSecondaryFactors, new Gson().fromJson(tenant.get("requiredSecondaryFactors").getAsJsonArray(), String[].class)); + + response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1", null, null, null, + false, null, false, null, + config); + assertFalse(response.get("createdNew").getAsBoolean()); + + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(8, tenant.entrySet().size()); + assertTrue(tenant.get("requiredSecondaryFactors").isJsonArray()); + assertEquals(1, tenant.get("requiredSecondaryFactors").getAsJsonArray().size()); + assertEquals(requiredSecondaryFactors, new Gson().fromJson(tenant.get("requiredSecondaryFactors").getAsJsonArray(), String[].class)); + + // custom factors + requiredSecondaryFactors = new String[]{"biometric"}; + response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1", null, null, null, + false, null, true, requiredSecondaryFactors, + config); + assertFalse(response.get("createdNew").getAsBoolean()); + + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(8, tenant.entrySet().size()); + assertTrue(tenant.get("requiredSecondaryFactors").isJsonArray()); + assertEquals(1, tenant.get("requiredSecondaryFactors").getAsJsonArray().size()); + assertEquals(requiredSecondaryFactors, new Gson().fromJson(tenant.get("requiredSecondaryFactors").getAsJsonArray(), String[].class)); + + // test both + requiredSecondaryFactors = new String[]{"otp-phone", "emailpassword", "biometric", "custom"}; + response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1", null, null, null, + false, null, true, requiredSecondaryFactors, + config); + assertFalse(response.get("createdNew").getAsBoolean()); + + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(8, tenant.entrySet().size()); + assertTrue(tenant.get("requiredSecondaryFactors").isJsonArray()); + assertEquals(4, tenant.get("requiredSecondaryFactors").getAsJsonArray().size()); + assertEquals(Set.of(requiredSecondaryFactors), Set.of(new Gson().fromJson(tenant.get("requiredSecondaryFactors").getAsJsonArray(), String[].class))); + + response = createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1", null, null, null, + false, null, true, null, + config); + assertFalse(response.get("createdNew").getAsBoolean()); + + tenant = getTenant(new TenantIdentifier("127.0.0.1", null, null), + process.getProcess()); + assertEquals(7, tenant.entrySet().size()); + assertNull(tenant.get("requiredSecondaryFactors")); + } + + @Test + public void testDuplicateValuesInFirstFactorsAndRequiredSecondaryFactors() throws Exception { + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + JsonObject config = new JsonObject(); + StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); + + String[] factors = new String[]{"duplicate", "emailpassword", "duplicate", "custom"}; + try { + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1", null, null, null, + true, factors, false, null, + config); + fail(); + } catch (HttpResponseException e) { + assertEquals(400, e.statusCode); + assertEquals("Http error. Status Code: 400. Message: firstFactors input should not contain duplicate values", e.getMessage()); + } + + try { + createConnectionUriDomain( + process.getProcess(), + new TenantIdentifier(null, null, null), + "127.0.0.1", null, null, null, + false, null, true, factors, + config); + fail(); + } catch (HttpResponseException e) { + assertEquals(400, e.statusCode); + assertEquals("Http error. Status Code: 400. Message: requiredSecondaryFactors input should not contain duplicate values", e.getMessage()); + } + } + + private static JsonObject createConnectionUriDomain(Main main, TenantIdentifier sourceTenant, + String connectionUriDomain, Boolean emailPasswordEnabled, + Boolean thirdPartyEnabled, Boolean passwordlessEnabled, + JsonObject coreConfig) throws HttpResponseException, IOException { + return createConnectionUriDomain(main, sourceTenant, connectionUriDomain, emailPasswordEnabled, thirdPartyEnabled, + passwordlessEnabled, false, null, false, null, coreConfig); + } + + private static JsonObject createConnectionUriDomain(Main main, TenantIdentifier sourceTenant, + String connectionUriDomain, Boolean emailPasswordEnabled, + Boolean thirdPartyEnabled, Boolean passwordlessEnabled, + boolean setFirstFactors, String[] firstFactors, + boolean setRequiredSecondaryFactors, String[] requiredSecondaryFactors, + JsonObject coreConfig) throws HttpResponseException, IOException { + JsonObject requestBody = new JsonObject(); + if (connectionUriDomain != null) { + requestBody.addProperty("connectionUriDomain", connectionUriDomain); + } + if (emailPasswordEnabled != null) { + requestBody.addProperty("emailPasswordEnabled", emailPasswordEnabled); + } + if (thirdPartyEnabled != null) { + requestBody.addProperty("thirdPartyEnabled", thirdPartyEnabled); + } + if (passwordlessEnabled != null) { + requestBody.addProperty("passwordlessEnabled", passwordlessEnabled); + } + if (setFirstFactors || firstFactors != null) { + requestBody.add("firstFactors", new Gson().toJsonTree(firstFactors)); + } + if (setRequiredSecondaryFactors || requiredSecondaryFactors != null) { + requestBody.add("requiredSecondaryFactors", new Gson().toJsonTree(requiredSecondaryFactors)); + } + + requestBody.add("coreConfig", coreConfig); + + JsonObject response = HttpRequestForTesting.sendJsonPUTRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(sourceTenant, "/recipe/multitenancy/connectionuridomain"), + requestBody, 1000, 2500, null, + SemVer.v5_1.get(), "multitenancy"); + + assertEquals("OK", response.getAsJsonPrimitive("status").getAsString()); + + return response; + } + + private static JsonObject listConnectionUriDomains(TenantIdentifier sourceTenant, Main main) + throws HttpResponseException, IOException { + JsonObject response = HttpRequestForTesting.sendGETRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(sourceTenant, "/recipe/multitenancy/connectionuridomain/list"), + null, 1000, 1000, null, + SemVer.v5_1.get(), "multitenancy"); + + assertEquals("OK", response.getAsJsonPrimitive("status").getAsString()); + return response; + } + + private static JsonObject deleteConnectionUriDomain(TenantIdentifier sourceTenant, String connectionUriDomain, + Main main) + throws HttpResponseException, IOException { + JsonObject requestBody = new JsonObject(); + requestBody.addProperty("connectionUriDomain", connectionUriDomain); + + JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(sourceTenant, "/recipe/multitenancy/connectionuridomain/remove"), + requestBody, 1000, 2500, null, + SemVer.v5_1.get(), "multitenancy"); + + assertEquals("OK", response.getAsJsonPrimitive("status").getAsString()); + return response; + } + + private static JsonObject getTenant(TenantIdentifier tenantIdentifier, Main main) + throws HttpResponseException, IOException { + JsonObject response = HttpRequestForTesting.sendGETRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/multitenancy/tenant"), + null, 1000, 1000, null, + SemVer.v5_1.get(), "multitenancy"); + + assertEquals("OK", response.getAsJsonPrimitive("status").getAsString()); + return response; + } +}