Skip to content

Commit

Permalink
fix: tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sattvikc committed Oct 18, 2023
1 parent 388050d commit a57eb0b
Show file tree
Hide file tree
Showing 4 changed files with 261 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO
JsonObject coreConfig = InputParser.parseJsonObjectOrThrowError(input, "coreConfig", true);

Boolean totpEnabled = null;
MfaFirstFactors firstFactors = new MfaFirstFactors(null, null);
MfaFirstFactors firstFactors = null;
String[] defaultRequiredFactors = null;

if (getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_1)) {
Expand All @@ -72,7 +72,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO
firstFactors = MfaFirstFactors.fromJson(input.get("firstFactors"));
}
} catch (IllegalArgumentException e) {
throw new ServletException(new BadRequestException(e.getMessage()));
throw new ServletException(new BadRequestException("firstFactors: " + e.getMessage()));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/java/io/supertokens/test/StorageLayerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public void totpCodeLengthTest() throws Exception {
// This error will be different in Postgres and MySQL
// We added (CHECK (LENGTH(code) <= 8)) to the table definition in SQLite
String totpUsedCodeTable = Config.getConfig(start).getTotpUsedCodesTable();
assert e.getMessage().contains("CHECK constraint failed: " + totpUsedCodeTable);
assert e.getMessage().contains("CHECK constraint failed: " + totpUsedCodeTable) || e.getMessage().contains("LENGTH(code) <= 8");
}

// Try code with length < 8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.supertokens.Main;
import io.supertokens.pluginInterface.mfa.MfaFirstFactors;
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
import io.supertokens.pluginInterface.multitenancy.ThirdPartyConfig;
import io.supertokens.test.httpRequest.HttpRequestForTesting;
Expand Down Expand Up @@ -141,6 +142,15 @@ public static JsonObject deleteApp(TenantIdentifier sourceTenant, String appId,
public static JsonObject createTenant(Main main, TenantIdentifier sourceTenant, String tenantId, Boolean emailPasswordEnabled,
Boolean thirdPartyEnabled, Boolean passwordlessEnabled,
JsonObject coreConfig) throws HttpResponseException, IOException {
return createTenant(main, sourceTenant, tenantId, emailPasswordEnabled, thirdPartyEnabled, passwordlessEnabled,
null, null, null, coreConfig, SemVer.v3_0);
}

public static JsonObject createTenant(Main main, TenantIdentifier sourceTenant, String tenantId, Boolean emailPasswordEnabled,
Boolean thirdPartyEnabled, Boolean passwordlessEnabled,
Boolean totpEnabled,
MfaFirstFactors firstFactors, String[] defaultRequiredFactors,
JsonObject coreConfig, SemVer version) throws HttpResponseException, IOException {
JsonObject requestBody = new JsonObject();
requestBody.addProperty("tenantId", tenantId);
if (emailPasswordEnabled != null) {
Expand All @@ -152,12 +162,22 @@ public static JsonObject createTenant(Main main, TenantIdentifier sourceTenant,
if (passwordlessEnabled != null) {
requestBody.addProperty("passwordlessEnabled", passwordlessEnabled);
}
if (totpEnabled != null) {
requestBody.addProperty("totpEnabled", totpEnabled);
}
if (firstFactors != null) {
requestBody.add("firstFactors", firstFactors.toJson());
}
if (defaultRequiredFactors != null) {
requestBody.add("defaultRequiredFactors", new Gson().toJsonTree(defaultRequiredFactors));
}

requestBody.add("coreConfig", coreConfig);

JsonObject response = HttpRequestForTesting.sendJsonPUTRequest(main, "",
HttpRequestForTesting.getMultitenantUrl(sourceTenant, "/recipe/multitenancy/tenant"),
requestBody, 1000, 2500, null,
SemVer.v3_0.get(), "multitenancy");
version.get(), "multitenancy");

assertEquals("OK", response.getAsJsonPrimitive("status").getAsString());
return response;
Expand Down Expand Up @@ -190,11 +210,16 @@ public static JsonObject deleteTenant(TenantIdentifier sourceTenant, String tena

public static JsonObject getTenant(TenantIdentifier tenantIdentifier, Main main)
throws HttpResponseException, IOException {
return getTenant(tenantIdentifier, main, SemVer.v3_0);
}

public static JsonObject getTenant(TenantIdentifier tenantIdentifier, Main main, SemVer version)
throws HttpResponseException, IOException {

JsonObject response = HttpRequestForTesting.sendGETRequest(main, "",
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/multitenancy/tenant"),
null, 1000, 1000, null,
SemVer.v3_0.get(), "multitenancy");
version.get(), "multitenancy");

assertEquals("OK", response.getAsJsonPrimitive("status").getAsString());
return response;
Expand Down
233 changes: 231 additions & 2 deletions src/test/java/io/supertokens/test/multitenant/api/TestTenant.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,18 @@

package io.supertokens.test.multitenant.api;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.*;
import io.supertokens.ProcessState;
import io.supertokens.featureflag.EE_FEATURES;
import io.supertokens.featureflag.FeatureFlagTestContent;
import io.supertokens.featureflag.exceptions.FeatureNotEnabledException;
import io.supertokens.mfa.Mfa;
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.mfa.MfaFirstFactors;
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
import io.supertokens.storageLayer.StorageLayer;
Expand All @@ -35,6 +36,7 @@
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;
Expand Down Expand Up @@ -346,4 +348,231 @@ public void testDefaultRecipesEnabledWhileCreatingTenant() throws Exception {
assertFalse(tenant.get("thirdParty").getAsJsonObject().get("enabled").getAsBoolean());
assertFalse(tenant.get("passwordless").getAsJsonObject().get("enabled").getAsBoolean());
}

@Test
public void testTotpEnabledBoolean() throws Exception {
if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) {
return;
}

JsonObject config = new JsonObject();
StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1);

JsonObject response = TestMultitenancyAPIHelper.createTenant(
process.getProcess(),
new TenantIdentifier(null, null, null),
"t1", null, null, null,
config);

assertTrue(response.get("createdNew").getAsBoolean());

JsonObject tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier(null, null, "t1"),
process.getProcess(), SemVer.v4_1);
assertFalse(tenant.get("totp").getAsJsonObject().get("enabled").getAsBoolean());

response = TestMultitenancyAPIHelper.createTenant(
process.getProcess(),
new TenantIdentifier(null, null, null),
"t1", null, null, null,
true, null, null,
config, SemVer.v4_1);
assertFalse(response.get("createdNew").getAsBoolean());

tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier(null, null, "t1"),
process.getProcess(), SemVer.v4_1);
assertTrue(tenant.get("totp").getAsJsonObject().get("enabled").getAsBoolean());

response = TestMultitenancyAPIHelper.createTenant(
process.getProcess(),
new TenantIdentifier(null, null, null),
"t1", null, null, null,
null, null, null,
config, SemVer.v4_1);
assertFalse(response.get("createdNew").getAsBoolean());

tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier(null, null, "t1"),
process.getProcess(), SemVer.v4_1);
assertTrue(tenant.get("totp").getAsJsonObject().get("enabled").getAsBoolean());

response = TestMultitenancyAPIHelper.createTenant(
process.getProcess(),
new TenantIdentifier(null, null, null),
"t1", null, null, null,
false, null, null,
config, SemVer.v4_1);
assertFalse(response.get("createdNew").getAsBoolean());

tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier(null, null, "t1"),
process.getProcess(), SemVer.v4_1);
assertFalse(tenant.get("totp").getAsJsonObject().get("enabled").getAsBoolean());

response = TestMultitenancyAPIHelper.createTenant(
process.getProcess(),
new TenantIdentifier(null, null, null),
"t1", null, null, null,
null, null, null,
config, SemVer.v4_1);
assertFalse(response.get("createdNew").getAsBoolean());

tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier(null, null, "t1"),
process.getProcess(), SemVer.v4_1);
assertFalse(tenant.get("totp").getAsJsonObject().get("enabled").getAsBoolean());
}

@Test
public void testFirstFactorsArray() throws Exception {
if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) {
return;
}

JsonObject config = new JsonObject();
StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1);

JsonObject response = TestMultitenancyAPIHelper.createTenant(
process.getProcess(),
new TenantIdentifier(null, null, null),
"t1", null, null, null,
config);

assertTrue(response.get("createdNew").getAsBoolean());

JsonObject tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier(null, null, "t1"),
process.getProcess(), SemVer.v4_1);
assertTrue(tenant.get("mfa").getAsJsonObject().get("firstFactors").isJsonArray());
assertEquals(0, tenant.get("mfa").getAsJsonObject().get("firstFactors").getAsJsonArray().size());

// builtin firstFactor
MfaFirstFactors firstFactors = new MfaFirstFactors(new String[]{"otp-phone"}, null);
response = TestMultitenancyAPIHelper.createTenant(
process.getProcess(),
new TenantIdentifier(null, null, null),
"t1", null, null, null,
null, firstFactors, null,
config, SemVer.v4_1);
assertFalse(response.get("createdNew").getAsBoolean());

tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier(null, null, "t1"),
process.getProcess(), SemVer.v4_1);
assertTrue(tenant.get("mfa").getAsJsonObject().get("firstFactors").isJsonArray());
assertEquals(1, tenant.get("mfa").getAsJsonObject().get("firstFactors").getAsJsonArray().size());
assertEquals(firstFactors, MfaFirstFactors.fromJson(tenant.get("mfa").getAsJsonObject().get("firstFactors").getAsJsonArray()));

response = TestMultitenancyAPIHelper.createTenant(
process.getProcess(),
new TenantIdentifier(null, null, null),
"t1", null, null, null,
null, null, null,
config, SemVer.v4_1);
assertFalse(response.get("createdNew").getAsBoolean());

tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier(null, null, "t1"),
process.getProcess(), SemVer.v4_1);
assertTrue(tenant.get("mfa").getAsJsonObject().get("firstFactors").isJsonArray());
assertEquals(1, tenant.get("mfa").getAsJsonObject().get("firstFactors").getAsJsonArray().size());
assertEquals(firstFactors, MfaFirstFactors.fromJson(tenant.get("mfa").getAsJsonObject().get("firstFactors").getAsJsonArray()));

// custom factors
firstFactors = new MfaFirstFactors(null, new String[]{"biometric"});
response = TestMultitenancyAPIHelper.createTenant(
process.getProcess(),
new TenantIdentifier(null, null, null),
"t1", null, null, null,
null, firstFactors, null,
config, SemVer.v4_1);
assertFalse(response.get("createdNew").getAsBoolean());

tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier(null, null, "t1"),
process.getProcess(), SemVer.v4_1);
assertTrue(tenant.get("mfa").getAsJsonObject().get("firstFactors").isJsonArray());
assertEquals(1, tenant.get("mfa").getAsJsonObject().get("firstFactors").getAsJsonArray().size());
assertEquals(firstFactors, MfaFirstFactors.fromJson(tenant.get("mfa").getAsJsonObject().get("firstFactors").getAsJsonArray()));

// test both
firstFactors = new MfaFirstFactors(new String[]{"otp-phone", "emailpassword"}, new String[]{"biometric", "custom"});
response = TestMultitenancyAPIHelper.createTenant(
process.getProcess(),
new TenantIdentifier(null, null, null),
"t1", null, null, null,
null, firstFactors, null,
config, SemVer.v4_1);
assertFalse(response.get("createdNew").getAsBoolean());

tenant = TestMultitenancyAPIHelper.getTenant(new TenantIdentifier(null, null, "t1"),
process.getProcess(), SemVer.v4_1);
assertTrue(tenant.get("mfa").getAsJsonObject().get("firstFactors").isJsonArray());
assertEquals(4, tenant.get("mfa").getAsJsonObject().get("firstFactors").getAsJsonArray().size());
assertEquals(firstFactors, MfaFirstFactors.fromJson(tenant.get("mfa").getAsJsonObject().get("firstFactors").getAsJsonArray()));
}

@Test
public void testInvalidValuesForFirstFactor() throws Exception {
try {
JsonObject requestBody = new JsonObject();
requestBody.addProperty("tenantId", "t1");
requestBody.addProperty("firstFactors", "hello"); // invalid type

JsonObject response = HttpRequestForTesting.sendJsonPUTRequest(process.getProcess(), "",
HttpRequestForTesting.getMultitenantUrl(TenantIdentifier.BASE_TENANT, "/recipe/multitenancy/tenant"),
requestBody, 1000, 2500, null,
SemVer.v4_1.get(), "multitenancy");
fail();
} catch (HttpResponseException e) {
assertEquals(400, e.statusCode);
assertTrue(e.getMessage().contains("Input must be a json array"));
}

try {
JsonObject requestBody = new JsonObject();
requestBody.addProperty("tenantId", "t1");
JsonArray array = new JsonArray();
array.add(new JsonPrimitive(100));
requestBody.add("firstFactors", array); // invalid type

JsonObject response = HttpRequestForTesting.sendJsonPUTRequest(process.getProcess(), "",
HttpRequestForTesting.getMultitenantUrl(TenantIdentifier.BASE_TENANT, "/recipe/multitenancy/tenant"),
requestBody, 1000, 2500, null,
SemVer.v4_1.get(), "multitenancy");
fail();
} catch (HttpResponseException e) {
assertEquals(400, e.statusCode);
assertTrue(e.getMessage().contains("100 is not a built-in factor"));
}

try {
JsonObject requestBody = new JsonObject();
requestBody.addProperty("tenantId", "t1");
JsonArray array = new JsonArray();
array.add(new JsonPrimitive("custom"));
requestBody.add("firstFactors", array); // invalid built-in type

JsonObject response = HttpRequestForTesting.sendJsonPUTRequest(process.getProcess(), "",
HttpRequestForTesting.getMultitenantUrl(TenantIdentifier.BASE_TENANT, "/recipe/multitenancy/tenant"),
requestBody, 1000, 2500, null,
SemVer.v4_1.get(), "multitenancy");
fail();
} catch (HttpResponseException e) {
assertEquals(400, e.statusCode);
assertTrue(e.getMessage().contains("custom is not a built-in factor"));
}

try {
JsonObject requestBody = new JsonObject();
requestBody.addProperty("tenantId", "t1");
JsonArray array = new JsonArray();
JsonObject factor = new JsonObject();
factor.addProperty("type", "custom");
factor.addProperty("id", "otp-phone");
array.add(factor);
requestBody.add("firstFactors", array); // built in value in custom

JsonObject response = HttpRequestForTesting.sendJsonPUTRequest(process.getProcess(), "",
HttpRequestForTesting.getMultitenantUrl(TenantIdentifier.BASE_TENANT, "/recipe/multitenancy/tenant"),
requestBody, 1000, 2500, null,
SemVer.v4_1.get(), "multitenancy");
fail();
} catch (HttpResponseException e) {
assertEquals(400, e.statusCode);
assertTrue(e.getMessage().contains("Factor otp-phone cannot be used as a custom factor"));
}
}
}

0 comments on commit a57eb0b

Please sign in to comment.