diff --git a/src/main/java/io/supertokens/config/CoreConfig.java b/src/main/java/io/supertokens/config/CoreConfig.java index f62cbf691..8acf0b698 100644 --- a/src/main/java/io/supertokens/config/CoreConfig.java +++ b/src/main/java/io/supertokens/config/CoreConfig.java @@ -29,6 +29,7 @@ import java.io.File; import java.io.IOException; +import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.regex.PatternSyntaxException; @@ -671,7 +672,19 @@ void assertThatConfigFromSameAppIdAreNotConflicting(CoreConfig other) throws Inv throw new InvalidConfigException( "You cannot set different values for bcrypt_log_rounds for the same appId"); } - } + // Check that the same set of API keys are present + { + String[] thisKeys = this.getAPIKeys() == null ? new String[0] : Arrays.copyOf(this.getAPIKeys(), this.getAPIKeys().length); + String[] otherKeys = other.getAPIKeys() == null ? new String[0] : Arrays.copyOf(other.getAPIKeys(), other.getAPIKeys().length); + Arrays.sort(thisKeys); + Arrays.sort(otherKeys); + + if (!Arrays.equals(thisKeys, otherKeys)) { + throw new InvalidConfigException( + "You cannot set different values for api_keys for the same appId"); + } + } + } } diff --git a/src/test/java/io/supertokens/test/multitenant/ConfigTest.java b/src/test/java/io/supertokens/test/multitenant/ConfigTest.java index 7b33f115c..efd89425d 100644 --- a/src/test/java/io/supertokens/test/multitenant/ConfigTest.java +++ b/src/test/java/io/supertokens/test/multitenant/ConfigTest.java @@ -882,4 +882,104 @@ public void testUpdationOfDefaultTenant() process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); } + + @Test + public void testThatDifferentTenantsInSameAppCannotHaveDifferentAPIKeys() throws Exception { + String[] args = {"../"}; + + TestingProcessManager.TestingProcess process = TestingProcessManager.start(args, false); + FeatureFlagTestContent.getInstance(process.getProcess()) + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MULTI_TENANCY}); + process.startProcess(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + + { // Create an app with API key + JsonObject coreConfig = new JsonObject(); + coreConfig.addProperty("api_keys", "asdfasdfasdfasdfasdf"); + + Multitenancy.addNewOrUpdateAppOrTenant( + process.getProcess(), + new TenantIdentifier(null, null, null), + new TenantConfig( + new TenantIdentifier(null, "a1", null), + new EmailPasswordConfig(true), + new ThirdPartyConfig(true, null), + new PasswordlessConfig(false), + coreConfig + ) + ); + } + + { // Create an tenant with different API key + JsonObject coreConfig = new JsonObject(); + coreConfig.addProperty("api_keys", "qwerqwerqwerqwerqwer"); + + try { + Multitenancy.addNewOrUpdateAppOrTenant( + process.getProcess(), + new TenantIdentifier(null, "a1", null), + new TenantConfig( + new TenantIdentifier(null, "a1", "t1"), + new EmailPasswordConfig(true), + new ThirdPartyConfig(true, null), + new PasswordlessConfig(false), + coreConfig + ) + ); + fail(); + } catch (InvalidConfigException e) { + assertEquals("You cannot set different values for api_keys for the same appId", e.getMessage()); + } + } + + { // Allow same API key or no setting + Multitenancy.addNewOrUpdateAppOrTenant( + process.getProcess(), + new TenantIdentifier(null, "a1", null), + new TenantConfig( + new TenantIdentifier(null, "a1", "t1"), + new EmailPasswordConfig(true), + new ThirdPartyConfig(true, null), + new PasswordlessConfig(false), + new JsonObject() + ) + ); + + JsonObject coreConfig = new JsonObject(); + coreConfig.addProperty("api_keys", "asdfasdfasdfasdfasdf"); + + Multitenancy.addNewOrUpdateAppOrTenant( + process.getProcess(), + new TenantIdentifier(null, "a1", null), + new TenantConfig( + new TenantIdentifier(null, "a1", "t2"), + new EmailPasswordConfig(true), + new ThirdPartyConfig(true, null), + new PasswordlessConfig(false), + coreConfig + ) + ); + } + + { // Create another app with different API key + JsonObject coreConfig = new JsonObject(); + coreConfig.addProperty("api_keys", "qwerqwerqwerqwerqwer"); + + Multitenancy.addNewOrUpdateAppOrTenant( + process.getProcess(), + new TenantIdentifier(null, null, null), + new TenantConfig( + new TenantIdentifier(null, "a2", null), + new EmailPasswordConfig(true), + new ThirdPartyConfig(true, null), + new PasswordlessConfig(false), + coreConfig + ) + ); + } + + process.kill(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); + + } }