Skip to content

Commit

Permalink
fix: mfa multitenancy updates
Browse files Browse the repository at this point in the history
  • Loading branch information
sattvikc committed Oct 17, 2023
1 parent 58a678b commit 388050d
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.supertokens.inmemorydb.queries.utils.JsonUtils;
import io.supertokens.pluginInterface.RowMapper;
import io.supertokens.pluginInterface.exceptions.StorageQueryException;
import io.supertokens.pluginInterface.mfa.MfaFirstFactors;
import io.supertokens.pluginInterface.multitenancy.*;

import java.sql.Connection;
Expand Down Expand Up @@ -54,7 +55,7 @@ public TenantConfig map(ResultSet result) throws StorageQueryException {
new ThirdPartyConfig(result.getBoolean("third_party_enabled"), this.providers),
new PasswordlessConfig(result.getBoolean("passwordless_enabled")),
new TotpConfig(false), // TODO
new MfaConfig(new String[0], new String[0]), // TODO
new MfaConfig(new MfaFirstFactors(null, null), new String[0]), // TODO
JsonUtils.stringToJsonObject(result.getString("core_config"))
);
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import io.supertokens.pluginInterface.RECIPE_ID;
import io.supertokens.pluginInterface.exceptions.InvalidConfigException;
import io.supertokens.pluginInterface.exceptions.StorageQueryException;
import io.supertokens.pluginInterface.mfa.MfaFirstFactors;
import io.supertokens.pluginInterface.multitenancy.*;
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
import io.supertokens.thirdparty.InvalidProviderConfigException;
Expand All @@ -46,7 +47,7 @@ public BaseCreateOrUpdate(Main main) {
protected void handle(HttpServletRequest req, TenantIdentifier sourceTenantIdentifier,
TenantIdentifier targetTenantIdentifier, Boolean emailPasswordEnabled,
Boolean thirdPartyEnabled, Boolean passwordlessEnabled, Boolean totpEnabled,
String[] firstFactors, String[] defaultMFARequirements,
MfaFirstFactors firstFactors, String[] defaultRequiredFactors,
JsonObject coreConfig, HttpServletResponse resp)
throws ServletException, IOException {

Expand Down Expand Up @@ -138,19 +139,19 @@ protected void handle(HttpServletRequest req, TenantIdentifier sourceTenantIdent
tenantConfig.thirdPartyConfig,
tenantConfig.passwordlessConfig,
tenantConfig.totpConfig,
new MfaConfig(firstFactors, tenantConfig.mfaConfig.defaultMFARequirements),
new MfaConfig(firstFactors, tenantConfig.mfaConfig.defaultRequiredFactors),
tenantConfig.coreConfig
);
}

if (defaultMFARequirements != null) {
if (defaultRequiredFactors != null) {
tenantConfig = new TenantConfig(
tenantConfig.tenantIdentifier,
tenantConfig.emailPasswordConfig,
tenantConfig.thirdPartyConfig,
tenantConfig.passwordlessConfig,
tenantConfig.totpConfig,
new MfaConfig(tenantConfig.mfaConfig.firstFactors, defaultMFARequirements),
new MfaConfig(tenantConfig.mfaConfig.firstFactors, defaultRequiredFactors),
tenantConfig.coreConfig
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.google.gson.JsonObject;
import io.supertokens.Main;
import io.supertokens.multitenancy.exception.BadPermissionException;
import io.supertokens.pluginInterface.mfa.MfaFirstFactors;
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
import io.supertokens.utils.SemVer;
Expand Down Expand Up @@ -58,13 +59,20 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO
JsonObject coreConfig = InputParser.parseJsonObjectOrThrowError(input, "coreConfig", true);

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

if (getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_1)) {
totpEnabled = InputParser.parseBooleanOrThrowError(input, "totpEnabled", true);
firstFactors = InputParser.parseStringArrayOrThrowError(input, "firstFactors", true);
defaultMFARequirements = InputParser.parseStringArrayOrThrowError(input, "defaultMFARequirements", true);
defaultRequiredFactors = InputParser.parseStringArrayOrThrowError(input, "defaultRequiredFactors", true);

try {
if (input.has("firstFactors")) {
firstFactors = MfaFirstFactors.fromJson(input.get("firstFactors"));
}
} catch (IllegalArgumentException e) {
throw new ServletException(new BadRequestException(e.getMessage()));
}
}

TenantIdentifier sourceTenantIdentifier;
Expand All @@ -78,7 +86,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO
req, sourceTenantIdentifier,
new TenantIdentifier(sourceTenantIdentifier.getConnectionUriDomain(), appId, null),
emailPasswordEnabled, thirdPartyEnabled, passwordlessEnabled,
totpEnabled, firstFactors, defaultMFARequirements,
totpEnabled, firstFactors, defaultRequiredFactors,
coreConfig, resp);

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

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.exceptions.TenantOrAppNotFoundException;
import io.supertokens.utils.SemVer;
Expand Down Expand Up @@ -56,13 +57,20 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO
JsonObject coreConfig = InputParser.parseJsonObjectOrThrowError(input, "coreConfig", true);

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

if (getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_1)) {
totpEnabled = InputParser.parseBooleanOrThrowError(input, "totpEnabled", true);
firstFactors = InputParser.parseStringArrayOrThrowError(input, "firstFactors", true);
defaultMFARequirements = InputParser.parseStringArrayOrThrowError(input, "defaultMFARequirements", true);
defaultRequiredFactors = InputParser.parseStringArrayOrThrowError(input, "defaultRequiredFactors", true);

try {
if (input.has("firstFactors")) {
firstFactors = MfaFirstFactors.fromJson(input.get("firstFactors"));
}
} catch (IllegalArgumentException e) {
throw new ServletException(new BadRequestException(e.getMessage()));
}
}

TenantIdentifier sourceTenantIdentifier;
Expand All @@ -76,7 +84,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO
req, sourceTenantIdentifier,
new TenantIdentifier(connectionUriDomain, null, null),
emailPasswordEnabled, thirdPartyEnabled, passwordlessEnabled,
totpEnabled, firstFactors, defaultMFARequirements,
totpEnabled, firstFactors, defaultRequiredFactors,
coreConfig, resp);

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import io.supertokens.Main;
import io.supertokens.config.CoreConfig;
import io.supertokens.multitenancy.Multitenancy;
import io.supertokens.pluginInterface.mfa.MfaFirstFactors;
import io.supertokens.pluginInterface.multitenancy.*;
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
import io.supertokens.utils.SemVer;
Expand Down Expand Up @@ -59,13 +60,20 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO
JsonObject coreConfig = InputParser.parseJsonObjectOrThrowError(input, "coreConfig", true);

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

if (getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_1)) {
totpEnabled = InputParser.parseBooleanOrThrowError(input, "totpEnabled", true);
firstFactors = InputParser.parseStringArrayOrThrowError(input, "firstFactors", true);
defaultMFARequirements = InputParser.parseStringArrayOrThrowError(input, "defaultMFARequirements", true);
defaultRequiredFactors = InputParser.parseStringArrayOrThrowError(input, "defaultRequiredFactors", true);

try {
if (input.has("firstFactors")) {
firstFactors = MfaFirstFactors.fromJson(input.get("firstFactors"));
}
} catch (IllegalArgumentException e) {
throw new ServletException(new BadRequestException(e.getMessage()));
}
}

TenantIdentifier sourceTenantIdentifier;
Expand All @@ -79,7 +87,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO
req, sourceTenantIdentifier,
new TenantIdentifier(sourceTenantIdentifier.getConnectionUriDomain(), sourceTenantIdentifier.getAppId(), tenantId),
emailPasswordEnabled, thirdPartyEnabled, passwordlessEnabled,
totpEnabled, firstFactors, defaultMFARequirements,
totpEnabled, firstFactors, defaultRequiredFactors,
coreConfig, resp);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import io.supertokens.pluginInterface.ActiveUsersStorage;
import io.supertokens.pluginInterface.STORAGE_TYPE;
import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo;
import io.supertokens.pluginInterface.mfa.MfaStorage;
import io.supertokens.pluginInterface.multitenancy.*;
import io.supertokens.pluginInterface.nonAuthRecipe.NonAuthRecipeStorage;
import io.supertokens.storageLayer.StorageLayer;
Expand Down Expand Up @@ -77,8 +76,7 @@ public void testDeletingAppDeleteNonAuthRecipeData() throws Exception {

// this list contains the package names for recipes which dont use UserIdMapping
ArrayList<String> classesToSkip = new ArrayList<>(
List.of("io.supertokens.pluginInterface.jwt.JWTRecipeStorage", ActiveUsersStorage.class.getName(),
MfaStorage.class.getName()));
List.of("io.supertokens.pluginInterface.jwt.JWTRecipeStorage", ActiveUsersStorage.class.getName()));

Reflections reflections = new Reflections("io.supertokens.pluginInterface");
Set<Class<? extends NonAuthRecipeStorage>> classes = reflections.getSubTypesOf(NonAuthRecipeStorage.class);
Expand Down Expand Up @@ -187,7 +185,7 @@ public void testDisassociationOfUserDeletesNonAuthRecipeData() throws Exception

// this list contains the package names for recipes which dont use UserIdMapping
ArrayList<String> classesToSkip = new ArrayList<>(
List.of("io.supertokens.pluginInterface.jwt.JWTRecipeStorage", ActiveUsersStorage.class.getName(), MfaStorage.class.getName()));
List.of("io.supertokens.pluginInterface.jwt.JWTRecipeStorage", ActiveUsersStorage.class.getName()));

Reflections reflections = new Reflections("io.supertokens.pluginInterface");
Set<Class<? extends NonAuthRecipeStorage>> classes = reflections.getSubTypesOf(NonAuthRecipeStorage.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import io.supertokens.pluginInterface.exceptions.InvalidConfigException;
import io.supertokens.pluginInterface.exceptions.StorageQueryException;
import io.supertokens.pluginInterface.jwt.JWTRecipeStorage;
import io.supertokens.pluginInterface.mfa.MfaStorage;
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage;
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,24 @@

package io.supertokens.test.multitenant.generator;

import io.supertokens.pluginInterface.mfa.MfaFirstFactors;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class GenerateMfaConfig {
private static final String[] FACTORS = new String[]{
"password", "otp-email", "otp-phone", "link-email", "link-phone", "totp", "thirdparty"
"emailpassword",
"thirdparty",
"otp-email",
"otp-phone",
"link-email",
"link-phone"
};

private static final String[] OTHER_FACTORS = new String[]{
"totp", "biometric", "custom"
};

private static String[] selectRandomElements(String[] inputArray) {
Expand Down Expand Up @@ -55,13 +66,14 @@ private static String[] selectRandomElements(String[] inputArray) {

public static ConfigGenerator.GeneratedValueAndExpectation generate_firstFactors() {
String[] factors = selectRandomElements(FACTORS);
String[] customFactors = selectRandomElements(OTHER_FACTORS);

return new ConfigGenerator.GeneratedValueAndExpectation(
factors,
new MfaFirstFactors(factors, customFactors),
new ConfigGenerator.Expectation("ok", factors));
}

public static ConfigGenerator.GeneratedValueAndExpectation generate_defaultMFARequirements() {
public static ConfigGenerator.GeneratedValueAndExpectation generate_defaultRequiredFactors() {
String[] factors = selectRandomElements(FACTORS);

return new ConfigGenerator.GeneratedValueAndExpectation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import io.supertokens.pluginInterface.ActiveUsersStorage;
import io.supertokens.pluginInterface.STORAGE_TYPE;
import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo;
import io.supertokens.pluginInterface.mfa.MfaStorage;
import io.supertokens.pluginInterface.multitenancy.AppIdentifier;
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
import io.supertokens.pluginInterface.nonAuthRecipe.NonAuthRecipeStorage;
Expand Down Expand Up @@ -796,8 +795,7 @@ public void checkThatCreateUserIdMappingHasAllNonAuthRecipeChecks() throws Excep

// this list contains the package names for recipes which dont use UserIdMapping
ArrayList<String> nonAuthRecipesWhichDontNeedUserIdMapping = new ArrayList<>(
List.of("io.supertokens.pluginInterface.jwt.JWTRecipeStorage", ActiveUsersStorage.class.getName(),
MfaStorage.class.getName()));
List.of("io.supertokens.pluginInterface.jwt.JWTRecipeStorage", ActiveUsersStorage.class.getName()));

Reflections reflections = new Reflections("io.supertokens.pluginInterface");
Set<Class<? extends NonAuthRecipeStorage>> classes = reflections.getSubTypesOf(NonAuthRecipeStorage.class);
Expand Down

0 comments on commit 388050d

Please sign in to comment.