From eb4496bf28c80109c2ba63fe816c446a77fed6db Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Thu, 29 Feb 2024 19:20:52 +0530 Subject: [PATCH 01/31] fix: non auth recipe stuff --- .../java/io/supertokens/ee/EEFeatureFlag.java | 2 +- .../io/supertokens/authRecipe/AuthRecipe.java | 7 +- .../cronjobs/telemetry/Telemetry.java | 8 +- .../storageLayer/StorageLayer.java | 63 +++--- .../useridmapping/UserIdMapping.java | 45 ++-- .../supertokens/webserver/WebserverAPI.java | 67 +++--- .../CanCreatePrimaryUserAPI.java | 5 +- .../accountlinking/CanLinkAccountsAPI.java | 7 +- .../accountlinking/CreatePrimaryUserAPI.java | 6 +- .../api/accountlinking/LinkAccountsAPI.java | 12 +- .../api/accountlinking/UnlinkAccountAPI.java | 5 +- .../api/core/ActiveUsersCountAPI.java | 2 +- .../webserver/api/core/ConfigAPI.java | 2 +- .../webserver/api/core/DeleteUserAPI.java | 6 +- .../webserver/api/core/EEFeatureFlagAPI.java | 5 +- .../webserver/api/core/GetUserByIdAPI.java | 5 +- .../webserver/api/core/HelloAPI.java | 12 +- .../webserver/api/core/JWKSPublicAPI.java | 2 +- .../webserver/api/core/LicenseKeyAPI.java | 9 +- .../api/core/ListUsersByAccountInfoAPI.java | 9 +- .../api/core/NotFoundOrHelloAPI.java | 18 +- .../webserver/api/core/RequestStatsAPI.java | 6 +- .../webserver/api/core/TelemetryAPI.java | 2 +- .../webserver/api/core/UsersAPI.java | 3 +- .../webserver/api/core/UsersCountAPI.java | 7 +- .../api/dashboard/DashboardSignInAPI.java | 2 +- .../api/dashboard/DashboardUserAPI.java | 8 +- .../GetDashboardSessionsForUserAPI.java | 2 +- .../api/dashboard/GetDashboardUsersAPI.java | 2 +- .../api/dashboard/RevokeSessionAPI.java | 2 +- .../VerifyDashboardUserSessionAPI.java | 2 +- .../ConsumeResetPasswordAPI.java | 2 +- .../GeneratePasswordResetTokenAPI.java | 4 +- .../ImportUserWithPasswordHashAPI.java | 4 +- .../api/emailpassword/ResetPasswordAPI.java | 2 +- .../api/emailpassword/SignInAPI.java | 4 +- .../api/emailpassword/SignUpAPI.java | 4 +- .../webserver/api/emailpassword/UserAPI.java | 19 +- .../GenerateEmailVerificationTokenAPI.java | 2 +- .../RevokeAllTokensForUserAPI.java | 2 +- .../emailverification/UnverifyEmailAPI.java | 17 +- .../api/emailverification/VerifyEmailAPI.java | 19 +- .../webserver/api/jwt/JWKSAPI.java | 7 +- .../webserver/api/jwt/JWTSigningAPI.java | 6 +- .../AssociateUserToTenantAPI.java | 14 +- .../multitenancy/CreateOrUpdateAppAPI.java | 4 +- .../CreateOrUpdateConnectionUriDomainAPI.java | 2 +- .../CreateOrUpdateTenantOrGetTenantAPI.java | 4 +- .../DisassociateUserFromTenant.java | 16 +- .../api/multitenancy/ListAppsAPI.java | 2 +- .../ListConnectionUriDomainsAPI.java | 2 +- .../api/multitenancy/ListTenantsAPI.java | 2 +- .../api/multitenancy/RemoveAppAPI.java | 2 +- .../RemoveConnectionUriDomainAPI.java | 2 +- .../api/multitenancy/RemoveTenantAPI.java | 2 +- .../CreateOrUpdateThirdPartyConfigAPI.java | 2 +- .../thirdparty/RemoveThirdPartyConfigAPI.java | 2 +- .../api/passwordless/ConsumeCodeAPI.java | 6 +- .../api/passwordless/CreateCodeAPI.java | 4 +- .../api/passwordless/DeleteCodeAPI.java | 2 +- .../api/passwordless/DeleteCodesAPI.java | 4 +- .../api/passwordless/GetCodesAPI.java | 10 +- .../webserver/api/passwordless/UserAPI.java | 17 +- .../webserver/api/session/HandshakeAPI.java | 8 +- .../webserver/api/session/JWTDataAPI.java | 5 +- .../api/session/RefreshSessionAPI.java | 18 +- .../webserver/api/session/SessionAPI.java | 13 +- .../webserver/api/session/SessionDataAPI.java | 5 +- .../api/session/SessionRegenerateAPI.java | 14 +- .../api/session/SessionRemoveAPI.java | 10 +- .../webserver/api/session/SessionUserAPI.java | 4 +- .../api/session/VerifySessionAPI.java | 11 +- .../api/thirdparty/GetUsersByEmailAPI.java | 5 +- .../webserver/api/thirdparty/SignInUpAPI.java | 9 +- .../webserver/api/thirdparty/UserAPI.java | 9 +- .../api/totp/CreateOrUpdateTotpDeviceAPI.java | 17 +- .../webserver/api/totp/GetTotpDevicesAPI.java | 7 +- .../api/totp/RemoveTotpDeviceAPI.java | 8 +- .../webserver/api/totp/VerifyTotpAPI.java | 7 +- .../api/totp/VerifyTotpDeviceAPI.java | 5 +- .../useridmapping/RemoveUserIdMappingAPI.java | 5 +- .../UpdateExternalUserIdInfoAPI.java | 5 +- .../api/useridmapping/UserIdMappingAPI.java | 14 +- .../usermetadata/RemoveUserMetadataAPI.java | 18 +- .../api/usermetadata/UserMetadataAPI.java | 35 +++- .../api/userroles/AddUserRoleAPI.java | 2 +- .../api/userroles/CreateRoleAPI.java | 6 +- .../userroles/GetPermissionsForRoleAPI.java | 5 +- .../webserver/api/userroles/GetRolesAPI.java | 5 +- .../userroles/GetRolesForPermissionAPI.java | 5 +- .../api/userroles/GetRolesForUserAPI.java | 2 +- .../api/userroles/GetUsersForRoleAPI.java | 2 +- .../RemovePermissionsForRoleAPI.java | 6 +- .../api/userroles/RemoveRoleAPI.java | 5 +- .../api/userroles/RemoveUserRoleAPI.java | 2 +- .../io/supertokens/test/HelloAPITest.java | 41 +++- .../MultitenantEmailPasswordTest.java | 30 +-- .../test/multitenant/api/TestApp.java | 2 +- .../api/TestConnectionUriDomain.java | 2 +- .../multitenant/api/TestLicenseBehaviour.java | 2 +- .../api/TestMultitenancyAPIHelper.java | 36 ++++ .../test/multitenant/api/TestTenant.java | 2 +- .../api/TestTenantUserAssociation.java | 6 +- .../api/TestWithNonAuthRecipes.java | 194 ++++++++++++++++++ .../test/totp/api/MultitenantAPITest.java | 40 ++-- .../userIdMapping/api/MultitenantAPITest.java | 60 +++--- 106 files changed, 775 insertions(+), 436 deletions(-) create mode 100644 src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java diff --git a/ee/src/main/java/io/supertokens/ee/EEFeatureFlag.java b/ee/src/main/java/io/supertokens/ee/EEFeatureFlag.java index bbb28f280..41c2dda5e 100644 --- a/ee/src/main/java/io/supertokens/ee/EEFeatureFlag.java +++ b/ee/src/main/java/io/supertokens/ee/EEFeatureFlag.java @@ -271,7 +271,7 @@ private JsonObject getMultiTenancyStats() return stats; } - private JsonObject getAccountLinkingStats() throws StorageQueryException { + private JsonObject getAccountLinkingStats() throws StorageQueryException, TenantOrAppNotFoundException { JsonObject result = new JsonObject(); Storage[] storages = StorageLayer.getStoragesForApp(main, this.appIdentifier); boolean usesAccountLinking = false; diff --git a/src/main/java/io/supertokens/authRecipe/AuthRecipe.java b/src/main/java/io/supertokens/authRecipe/AuthRecipe.java index ade17dabb..29945e30d 100644 --- a/src/main/java/io/supertokens/authRecipe/AuthRecipe.java +++ b/src/main/java/io/supertokens/authRecipe/AuthRecipe.java @@ -37,6 +37,7 @@ import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorages; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; @@ -661,20 +662,20 @@ public static long getUsersCountForTenant(TenantIdentifierWithStorage tenantIden tenantIdentifier, includeRecipeIds); } - public static long getUsersCountAcrossAllTenants(AppIdentifierWithStorage appIdentifierWithStorage, + public static long getUsersCountAcrossAllTenants(AppIdentifierWithStorages appIdentifierWithStorages, RECIPE_ID[] includeRecipeIds) throws StorageQueryException, TenantOrAppNotFoundException, BadPermissionException { long count = 0; - for (Storage storage : appIdentifierWithStorage.getStorages()) { + for (Storage storage : appIdentifierWithStorages.getStorages()) { if (storage.getType() != STORAGE_TYPE.SQL) { // we only support SQL for now throw new UnsupportedOperationException(""); } count += ((AuthRecipeStorage) storage).getUsersCount( - appIdentifierWithStorage, includeRecipeIds); + appIdentifierWithStorages, includeRecipeIds); } return count; diff --git a/src/main/java/io/supertokens/cronjobs/telemetry/Telemetry.java b/src/main/java/io/supertokens/cronjobs/telemetry/Telemetry.java index 215024858..8f80ecc86 100644 --- a/src/main/java/io/supertokens/cronjobs/telemetry/Telemetry.java +++ b/src/main/java/io/supertokens/cronjobs/telemetry/Telemetry.java @@ -36,6 +36,7 @@ import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorages; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.storageLayer.StorageLayer; @@ -102,13 +103,12 @@ protected void doTaskPerApp(AppIdentifier app) throws Exception { if (StorageLayer.getBaseStorage(main).getType() == STORAGE_TYPE.SQL) { { // Users count across all tenants Storage[] storages = StorageLayer.getStoragesForApp(main, app); - AppIdentifierWithStorage appIdentifierWithAllTenantStorages = new AppIdentifierWithStorage( - app.getConnectionUriDomain(), app.getAppId(), - StorageLayer.getStorage(app.getAsPublicTenantIdentifier(), main), storages + AppIdentifierWithStorages appIdentifierWithStorages = new AppIdentifierWithStorages( + app.getConnectionUriDomain(), app.getAppId(), storages ); json.addProperty("usersCount", - AuthRecipe.getUsersCountAcrossAllTenants(appIdentifierWithAllTenantStorages, null)); + AuthRecipe.getUsersCountAcrossAllTenants(appIdentifierWithStorages, null)); } { // Dashboard user emails diff --git a/src/main/java/io/supertokens/storageLayer/StorageLayer.java b/src/main/java/io/supertokens/storageLayer/StorageLayer.java index faeaece0d..ec94b05e9 100644 --- a/src/main/java/io/supertokens/storageLayer/StorageLayer.java +++ b/src/main/java/io/supertokens/storageLayer/StorageLayer.java @@ -385,7 +385,8 @@ public static List> getTenantsWithUniqueUserPoolId(Main m return result; } - public static Storage[] getStoragesForApp(Main main, AppIdentifier appIdentifier) { + public static Storage[] getStoragesForApp(Main main, AppIdentifier appIdentifier) + throws TenantOrAppNotFoundException { Map userPoolToStorage = new HashMap<>(); Map resources = @@ -397,7 +398,11 @@ public static Storage[] getStoragesForApp(Main main, AppIdentifier appIdentifier userPoolToStorage.put(storage.getUserPoolId(), storage); } } - return userPoolToStorage.values().toArray(new Storage[0]); + Storage[] storages = userPoolToStorage.values().toArray(new Storage[0]); + if (storages.length == 0) { + throw new TenantOrAppNotFoundException(appIdentifier); + } + return storages; } public static TenantIdentifierWithStorageAndUserIdMapping getTenantIdentifierWithStorageAndUserIdMappingForUser( @@ -432,52 +437,35 @@ public static TenantIdentifierWithStorageAndUserIdMapping getTenantIdentifierWit throw new UnknownUserIdException(); } - public static AppIdentifierWithStorageAndUserIdMapping getAppIdentifierWithStorageAndUserIdMappingForUserWithPriorityForTenantStorage( - Main main, AppIdentifier appIdentifier, Storage priorityStorage, String userId, + public static AppIdentifierWithStorageAndUserIdMapping getAppIdentifierWithStorageAndUserIdMappingForUser( + AppIdentifierWithStorages appIdentifierWithStorages, String userId, UserIdType userIdType) throws StorageQueryException, TenantOrAppNotFoundException, UnknownUserIdException { - Storage[] storages = getStoragesForApp(main, appIdentifier); + Storage[] storages = appIdentifierWithStorages.getStorages(); if (storages.length == 0) { - throw new TenantOrAppNotFoundException(appIdentifier); + throw new TenantOrAppNotFoundException(appIdentifierWithStorages); } - // We look for userId in the priorityStorage first just in case multiple storages have the mapping, we - // return the mapping from the storage of the tenant from which the request came from. - { - UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( - appIdentifier.withStorage(priorityStorage), - userId, userIdType); - - if (mapping != null) { - AppIdentifierWithStorage appIdentifierWithStorage = appIdentifier.withStorage(priorityStorage); - return new AppIdentifierWithStorageAndUserIdMapping(appIdentifierWithStorage, mapping); - } + AppIdentifier appIdentifier = appIdentifierWithStorages; + // First look in auth recipes + for (Storage storage : storages) { if (userIdType != UserIdType.EXTERNAL - && ((AuthRecipeStorage) priorityStorage).doesUserIdExist(appIdentifier, userId)) { - AppIdentifierWithStorage appIdentifierWithStorage = appIdentifier.withStorage(priorityStorage); - return new AppIdentifierWithStorageAndUserIdMapping(appIdentifierWithStorage, null); - } - if (userIdType != UserIdType.SUPERTOKENS) { - AppIdentifierWithStorage appIdentifierWithStorage = appIdentifier.withStorage(priorityStorage); - try { - io.supertokens.useridmapping.UserIdMapping.findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed( - appIdentifierWithStorage, userId, true); - } catch (ServletException e) { - // this means that the userId is being used for a non auth recipe. - return new AppIdentifierWithStorageAndUserIdMapping(appIdentifierWithStorage, null); - } + && ((AuthRecipeStorage) storage).doesUserIdExist(appIdentifier, userId)) { + AppIdentifierWithStorage appIdentifierWithStorage = appIdentifier.withStorage(storage); + + UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( + appIdentifierWithStorages.withStorage(storage), + userId, userIdType); + + return new AppIdentifierWithStorageAndUserIdMapping(appIdentifierWithStorage, mapping); } } for (Storage storage : storages) { - if (storage == priorityStorage) { - continue; // Already checked previously - } - UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( - appIdentifier.withStorage(storage), + appIdentifierWithStorages.withStorage(storage), userId, userIdType); if (mapping != null) { @@ -485,11 +473,6 @@ public static AppIdentifierWithStorageAndUserIdMapping getAppIdentifierWithStora return new AppIdentifierWithStorageAndUserIdMapping(appIdentifierWithStorage, mapping); } - if (userIdType != UserIdType.EXTERNAL - && ((AuthRecipeStorage) storage).doesUserIdExist(appIdentifier, userId)) { - AppIdentifierWithStorage appIdentifierWithStorage = appIdentifier.withStorage(storage); - return new AppIdentifierWithStorageAndUserIdMapping(appIdentifierWithStorage, null); - } if (userIdType != UserIdType.SUPERTOKENS) { AppIdentifierWithStorage appIdentifierWithStorage = appIdentifier.withStorage(storage); try { diff --git a/src/main/java/io/supertokens/useridmapping/UserIdMapping.java b/src/main/java/io/supertokens/useridmapping/UserIdMapping.java index 56a220152..0d82cacc5 100644 --- a/src/main/java/io/supertokens/useridmapping/UserIdMapping.java +++ b/src/main/java/io/supertokens/useridmapping/UserIdMapping.java @@ -28,6 +28,7 @@ import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.jwt.JWTRecipeStorage; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorages; import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.session.SessionStorage; @@ -50,16 +51,26 @@ public class UserIdMapping { @TestOnly - public static void createUserIdMapping(Main main, AppIdentifierWithStorage appIdentifierWithStorage, + public static void createUserIdMapping(AppIdentifierWithStorages appIdentifierWithStorages, String superTokensUserId, String externalUserId, String externalUserIdInfo, boolean force) throws ServletException, UnknownSuperTokensUserIdException, UserIdMappingAlreadyExistsException, StorageQueryException, TenantOrAppNotFoundException { - createUserIdMapping(main, appIdentifierWithStorage, superTokensUserId, externalUserId, externalUserIdInfo, + createUserIdMapping(appIdentifierWithStorages, superTokensUserId, externalUserId, externalUserIdInfo, force, false); } - public static void createUserIdMapping(Main main, AppIdentifierWithStorage appIdentifierWithStorage, + @TestOnly + public static void createUserIdMapping(Main main, AppIdentifierWithStorage appIdentifierWithStorage, String supertokensUserId, String externalUserId, String externalUserIdInfo, boolean force) + throws ServletException, UnknownSuperTokensUserIdException, UserIdMappingAlreadyExistsException, + StorageQueryException, TenantOrAppNotFoundException { + createUserIdMapping( + new AppIdentifierWithStorages(appIdentifierWithStorage.getConnectionUriDomain(), appIdentifierWithStorage.getAppId(), new Storage[]{appIdentifierWithStorage.getStorage()}), + supertokensUserId, externalUserId, externalUserIdInfo, force + ); + } + + public static void createUserIdMapping(AppIdentifierWithStorages appIdentifierWithStorages, String superTokensUserId, String externalUserId, String externalUserIdInfo, boolean force, boolean makeExceptionForEmailVerification) throws UnknownSuperTokensUserIdException, @@ -75,9 +86,8 @@ public static void createUserIdMapping(Main main, AppIdentifierWithStorage appId // race condition is fixed. try { // with external id AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUserWithPriorityForTenantStorage( - main, appIdentifierWithStorage, appIdentifierWithStorage.getStorage(), externalUserId, - UserIdType.EXTERNAL); + StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + appIdentifierWithStorages, externalUserId, UserIdType.EXTERNAL); if (mappingAndStorage.userIdMapping != null) { throw new UserIdMappingAlreadyExistsException( @@ -89,6 +99,16 @@ public static void createUserIdMapping(Main main, AppIdentifierWithStorage appId // ignore this as we do not want external user id to exist } + AppIdentifierWithStorageAndUserIdMapping mappingAndStorage; + try { + mappingAndStorage = StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + appIdentifierWithStorages, superTokensUserId, UserIdType.SUPERTOKENS); + } catch (UnknownUserIdException e) { + throw new UnknownSuperTokensUserIdException(); + } + + AppIdentifierWithStorage appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; + // if a userIdMapping is created with force, then we skip the following checks if (!force) { // We do not allow for a UserIdMapping to be created when the externalUserId is a SuperTokens userId. @@ -99,7 +119,7 @@ public static void createUserIdMapping(Main main, AppIdentifierWithStorage appId { if (((AuthRecipeStorage) appIdentifierWithStorage.getStorage()).doesUserIdExist( - appIdentifierWithStorage, externalUserId)) { + appIdentifierWithStorages, externalUserId)) { throw new ServletException(new WebserverAPI.BadRequestException( "Cannot create a userId mapping where the externalId is also a SuperTokens userID")); } @@ -115,7 +135,7 @@ public static void createUserIdMapping(Main main, AppIdentifierWithStorage appId // an exception, then the creation of userIdMapping for the user will be blocked. And, to overcome that the // email will have to be unverified first, then the userIdMapping should be created and then the email must be // verified again on the externalUserId, which is not a good user experience. - appIdentifierWithStorage.getEmailVerificationStorage().updateIsEmailVerifiedToExternalUserId(appIdentifierWithStorage, superTokensUserId, externalUserId); + appIdentifierWithStorage.getEmailVerificationStorage().updateIsEmailVerifiedToExternalUserId(appIdentifierWithStorages, superTokensUserId, externalUserId); } else if (storageClasses.size() > 0) { String recipeName = storageClasses.get(0); String[] parts = recipeName.split("[.]"); @@ -127,12 +147,10 @@ public static void createUserIdMapping(Main main, AppIdentifierWithStorage appId } else { findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed(appIdentifierWithStorage, superTokensUserId, true); } - - } appIdentifierWithStorage.getUserIdMappingStorage() - .createUserIdMapping(appIdentifierWithStorage, superTokensUserId, + .createUserIdMapping(appIdentifierWithStorages, superTokensUserId, externalUserId, externalUserIdInfo); } @TestOnly @@ -152,9 +170,8 @@ public static void createUserIdMapping(Main main, UserIdMappingAlreadyExistsException, StorageQueryException, ServletException, UnknownUserIdException { try { Storage storage = StorageLayer.getStorage(main); - createUserIdMapping(main, new AppIdentifierWithStorage(null, null, storage), superTokensUserId, - externalUserId, - externalUserIdInfo, force, makeExceptionForEmailVerification); + createUserIdMapping(new AppIdentifierWithStorages(null, null, new Storage[]{storage}), superTokensUserId, + externalUserId, externalUserIdInfo, force, makeExceptionForEmailVerification); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } diff --git a/src/main/java/io/supertokens/webserver/WebserverAPI.java b/src/main/java/io/supertokens/webserver/WebserverAPI.java index 188776eb4..4c4ffa5b3 100644 --- a/src/main/java/io/supertokens/webserver/WebserverAPI.java +++ b/src/main/java/io/supertokens/webserver/WebserverAPI.java @@ -30,10 +30,7 @@ import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.*; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.storageLayer.StorageLayer; import io.supertokens.useridmapping.UserIdType; @@ -88,7 +85,7 @@ public SemVer getLatestCDIVersionForRequest(HttpServletRequest req) throws ServletException, TenantOrAppNotFoundException { SemVer maxCDIVersion = getLatestCDIVersion(); String maxCDIVersionStr = Config.getConfig( - getAppIdentifierWithStorage(req).getAsPublicTenantIdentifier(), main).getMaxCDIVersion(); + getAppIdentifier(req).getAsPublicTenantIdentifier(), main).getMaxCDIVersion(); if (maxCDIVersionStr != null) { maxCDIVersion = new SemVer(maxCDIVersionStr); } @@ -235,10 +232,8 @@ private String getTenantId(HttpServletRequest req) { if (!apiPath.startsWith("/")) { apiPath = "/" + apiPath; } - if (apiPath.equals("/")) { - if (path.equals("") || path.equals("/")) { - return null; - } + if (apiPath.equals("/") && (path.equals("") || path.equals("/"))) { + return null; } else { if (path.matches("^/appid-[a-z0-9-]*/[a-z0-9-]+" + apiPath + "/?$")) { String tenantId = path.split("/")[2].toLowerCase(); @@ -258,7 +253,6 @@ private String getTenantId(HttpServletRequest req) { return null; } } - return null; } private String getAppId(HttpServletRequest req) { @@ -308,7 +302,11 @@ protected TenantIdentifier getTenantIdentifierFromRequest(HttpServletRequest req return new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), this.getTenantId(req)); } - protected TenantIdentifierWithStorage getTenantIdentifierWithStorageFromRequest(HttpServletRequest req) + protected AppIdentifier getAppIdentifier(HttpServletRequest req) throws ServletException { + return new AppIdentifier(this.getConnectionUriDomain(req), this.getAppId(req)); + } + + protected TenantIdentifierWithStorage getTenantStorage(HttpServletRequest req) throws TenantOrAppNotFoundException, ServletException { TenantIdentifier tenantIdentifier = new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), this.getTenantId(req)); @@ -316,36 +314,36 @@ protected TenantIdentifierWithStorage getTenantIdentifierWithStorageFromRequest( return tenantIdentifier.withStorage(storage); } - protected AppIdentifierWithStorage getAppIdentifierWithStorage(HttpServletRequest req) - throws TenantOrAppNotFoundException, ServletException { - TenantIdentifier tenantIdentifier = new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), - this.getTenantId(req)); - - Storage storage = StorageLayer.getStorage(tenantIdentifier, main); - Storage[] storages = StorageLayer.getStoragesForApp(main, tenantIdentifier.toAppIdentifier()); + protected AppIdentifierWithStorages enforcePublicTenantAndGetAllStoragesForApp(HttpServletRequest req) + throws ServletException, BadPermissionException, TenantOrAppNotFoundException { + if (getTenantId(req) != null) { + throw new BadPermissionException("Only public tenantId can this app specific API"); + } - return new AppIdentifierWithStorage(tenantIdentifier.getConnectionUriDomain(), tenantIdentifier.getAppId(), - storage, storages); + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage[] storages = StorageLayer.getStoragesForApp(main, appIdentifier); + return new AppIdentifierWithStorages(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), + storages); } - protected AppIdentifierWithStorage getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant( + protected AppIdentifierWithStorage enforcePublicTenantAndGetPublicTenantStorage( HttpServletRequest req) throws TenantOrAppNotFoundException, BadPermissionException, ServletException { TenantIdentifier tenantIdentifier = new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), this.getTenantId(req)); - if (!tenantIdentifier.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID)) { - throw new BadPermissionException("Only public tenantId can query across tenants"); + if (getTenantId(req) != null) { + throw new BadPermissionException("Only public tenantId can this app specific API"); } Storage storage = StorageLayer.getStorage(tenantIdentifier, main); - Storage[] storages = StorageLayer.getStoragesForApp(main, tenantIdentifier.toAppIdentifier()); return new AppIdentifierWithStorage(tenantIdentifier.getConnectionUriDomain(), tenantIdentifier.getAppId(), - storage, storages); + storage); } protected AppIdentifierWithStorage getPublicTenantStorage(HttpServletRequest req) throws ServletException, TenantOrAppNotFoundException { + // This is only used for update user active time AppIdentifier appIdentifier = new AppIdentifier(this.getConnectionUriDomain(req), this.getAppId(req)); Storage storage = StorageLayer.getStorage(appIdentifier.getAsPublicTenantIdentifier(), main); @@ -353,7 +351,7 @@ protected AppIdentifierWithStorage getPublicTenantStorage(HttpServletRequest req return appIdentifier.withStorage(storage); } - protected TenantIdentifierWithStorageAndUserIdMapping getTenantIdentifierWithStorageAndUserIdMappingFromRequest( + protected TenantIdentifierWithStorageAndUserIdMapping getStorageAndUserIdMappingForTenantSpecificApi( HttpServletRequest req, String userId, UserIdType userIdType) throws StorageQueryException, TenantOrAppNotFoundException, UnknownUserIdException, ServletException { TenantIdentifier tenantIdentifier = new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), @@ -362,19 +360,20 @@ protected TenantIdentifierWithStorageAndUserIdMapping getTenantIdentifierWithSto userIdType); } - protected AppIdentifierWithStorageAndUserIdMapping getAppIdentifierWithStorageAndUserIdMappingFromRequest( + protected AppIdentifierWithStorageAndUserIdMapping getStorageAndUserIdMappingForAppSpecificApi( HttpServletRequest req, String userId, UserIdType userIdType) - throws StorageQueryException, TenantOrAppNotFoundException, UnknownUserIdException, ServletException { - // This function uses storage of the tenent from which the request came from as a priorityStorage + throws StorageQueryException, TenantOrAppNotFoundException, UnknownUserIdException, ServletException, + BadPermissionException { + // This function uses storage of the tenant from which the request came from as a priorityStorage // while searching for the user across all storages for the app - AppIdentifierWithStorage appIdentifierWithStorage = getAppIdentifierWithStorage(req); - return StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUserWithPriorityForTenantStorage(main, - appIdentifierWithStorage, appIdentifierWithStorage.getStorage(), userId, userIdType); + AppIdentifierWithStorages appIdentifierWithStorages = enforcePublicTenantAndGetAllStoragesForApp(req); + return StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + appIdentifierWithStorages, userId, userIdType); } protected boolean checkIPAccess(HttpServletRequest req, HttpServletResponse resp) throws TenantOrAppNotFoundException, ServletException, IOException { - CoreConfig config = Config.getConfig(getTenantIdentifierWithStorageFromRequest(req), main); + CoreConfig config = Config.getConfig(getTenantStorage(req), main); String allow = config.getIpAllowRegex(); String deny = config.getIpDenyRegex(); if (allow == null && deny == null) { @@ -417,7 +416,7 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws TenantIdentifier tenantIdentifier = null; try { try { - tenantIdentifier = getTenantIdentifierWithStorageFromRequest(req); + tenantIdentifier = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { // we do this so that the logs that are printed out have the right "Tenant(.." info in them, // otherwise it will assume the base tenant (with "" CUD), which may not be the one querying diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java index 9457ddd0d..3e4104a8e 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java @@ -22,6 +22,7 @@ import io.supertokens.authRecipe.AuthRecipe; import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException; import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithPrimaryUserIdException; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -57,7 +58,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { String userId = inputRecipeUserId; AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getAppIdentifierWithStorageAndUserIdMappingFromRequest( + getStorageAndUserIdMappingForAppSpecificApi( req, inputRecipeUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { userId = mappingAndStorage.userIdMapping.superTokensUserId; @@ -70,7 +71,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO response.addProperty("status", "OK"); response.addProperty("wasAlreadyAPrimaryUser", result.wasAlreadyAPrimaryUser); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } catch (UnknownUserIdException e) { throw new ServletException(new BadRequestException("Unknown user ID provided")); diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java index 97c10f2c6..a70af4e4e 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java @@ -23,6 +23,7 @@ import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException; import io.supertokens.authRecipe.exception.InputUserIdIsNotAPrimaryUserException; import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; @@ -62,7 +63,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO String recipeUserId = inputRecipeUserId; { AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getAppIdentifierWithStorageAndUserIdMappingFromRequest( + getStorageAndUserIdMappingForAppSpecificApi( req, inputRecipeUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { recipeUserId = mappingAndStorage.userIdMapping.superTokensUserId; @@ -72,7 +73,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO String primaryUserId = inputPrimaryUserId; { AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getAppIdentifierWithStorageAndUserIdMappingFromRequest( + getStorageAndUserIdMappingForAppSpecificApi( req, inputPrimaryUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { primaryUserId = mappingAndStorage.userIdMapping.superTokensUserId; @@ -97,7 +98,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO response.addProperty("status", "OK"); response.addProperty("accountsAlreadyLinked", result.alreadyLinked); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } catch (UnknownUserIdException e) { throw new ServletException(new BadRequestException("Unknown user ID provided")); diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java index 8573650b7..7fc5e14a3 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java @@ -23,6 +23,7 @@ import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException; import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithPrimaryUserIdException; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -59,7 +60,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { String userId = inputRecipeUserId; AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getAppIdentifierWithStorageAndUserIdMappingFromRequest( + getStorageAndUserIdMappingForAppSpecificApi( req, inputRecipeUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { userId = mappingAndStorage.userIdMapping.superTokensUserId; @@ -78,7 +79,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } response.add("user", result.user.toJson()); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException | FeatureNotEnabledException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | FeatureNotEnabledException | + BadPermissionException e) { throw new ServletException(e); } catch (UnknownUserIdException e) { throw new ServletException(new BadRequestException("Unknown user ID provided")); diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java index 76a9d4dfe..94924f7fe 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java @@ -17,7 +17,6 @@ package io.supertokens.webserver.api.accountlinking; import com.google.gson.JsonObject; -import io.supertokens.ActiveUsers; import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; import io.supertokens.authRecipe.AuthRecipe; @@ -25,9 +24,9 @@ import io.supertokens.authRecipe.exception.InputUserIdIsNotAPrimaryUserException; import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; -import io.supertokens.pluginInterface.authRecipe.LoginMethod; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; @@ -41,8 +40,6 @@ import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; public class LinkAccountsAPI extends WebserverAPI { @@ -68,7 +65,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String recipeUserId = inputRecipeUserId; { AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getAppIdentifierWithStorageAndUserIdMappingFromRequest( + getStorageAndUserIdMappingForAppSpecificApi( req, inputRecipeUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { recipeUserId = mappingAndStorage.userIdMapping.superTokensUserId; @@ -78,7 +75,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String primaryUserId = inputPrimaryUserId; { AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getAppIdentifierWithStorageAndUserIdMappingFromRequest( + getStorageAndUserIdMappingForAppSpecificApi( req, inputPrimaryUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { primaryUserId = mappingAndStorage.userIdMapping.superTokensUserId; @@ -107,7 +104,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I response.addProperty("accountsAlreadyLinked", linkAccountsResult.wasAlreadyLinked); response.add("user", linkAccountsResult.user.toJson()); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException | FeatureNotEnabledException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | FeatureNotEnabledException | + BadPermissionException e) { throw new ServletException(e); } catch (UnknownUserIdException e) { throw new ServletException(new BadRequestException("Unknown user ID provided")); diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java index 3abed0328..624c6aeec 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java @@ -21,6 +21,7 @@ import io.supertokens.Main; import io.supertokens.authRecipe.AuthRecipe; import io.supertokens.authRecipe.exception.InputUserIdIsNotAPrimaryUserException; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -56,7 +57,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { String userId = inputRecipeUserId; AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getAppIdentifierWithStorageAndUserIdMappingFromRequest( + getStorageAndUserIdMappingForAppSpecificApi( req, inputRecipeUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { userId = mappingAndStorage.userIdMapping.superTokensUserId; @@ -70,7 +71,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I response.addProperty("wasRecipeUserDeleted", wasDeleted); response.addProperty("wasLinked", true); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } catch (UnknownUserIdException e) { throw new ServletException(new BadRequestException("Unknown user ID provided")); diff --git a/src/main/java/io/supertokens/webserver/api/core/ActiveUsersCountAPI.java b/src/main/java/io/supertokens/webserver/api/core/ActiveUsersCountAPI.java index d69a34015..4e824f5b0 100644 --- a/src/main/java/io/supertokens/webserver/api/core/ActiveUsersCountAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/ActiveUsersCountAPI.java @@ -53,7 +53,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { int count = ActiveUsers.countUsersActiveSince( - this.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req), main, sinceTimestamp); + this.enforcePublicTenantAndGetPublicTenantStorage(req), main, sinceTimestamp); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); result.addProperty("count", count); diff --git a/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java b/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java index 8b997fc56..b9fdcf4b8 100644 --- a/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java @@ -53,7 +53,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO String pid = InputParser.getQueryParamOrThrowError(req, "pid", false); try { - TenantIdentifier tenantIdentifier = getTenantIdentifierWithStorageFromRequest(req); + TenantIdentifier tenantIdentifier = getTenantStorage(req); if (!tenantIdentifier.equals(new TenantIdentifier(null, null, null))) { throw new ServletException(new BadPermissionException("you can call this only from the base connection uri domain, public app and tenant")); } diff --git a/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java b/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java index ce51410f3..a494c3cef 100644 --- a/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java @@ -20,6 +20,7 @@ import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; import io.supertokens.authRecipe.AuthRecipe; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; @@ -59,12 +60,13 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = - this.getAppIdentifierWithStorageAndUserIdMappingFromRequest(req, userId, UserIdType.ANY); + this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); AuthRecipe.deleteUser(appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, userId, removeAllLinkedAccounts, appIdentifierWithStorageAndUserIdMapping.userIdMapping); - } catch (StorageQueryException | TenantOrAppNotFoundException | StorageTransactionLogicException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | StorageTransactionLogicException | + BadPermissionException e) { throw new ServletException(e); } catch (UnknownUserIdException e) { // Do nothing diff --git a/src/main/java/io/supertokens/webserver/api/core/EEFeatureFlagAPI.java b/src/main/java/io/supertokens/webserver/api/core/EEFeatureFlagAPI.java index 1094c372b..c7b384dc9 100644 --- a/src/main/java/io/supertokens/webserver/api/core/EEFeatureFlagAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/EEFeatureFlagAPI.java @@ -24,7 +24,6 @@ import io.supertokens.featureflag.FeatureFlag; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.webserver.WebserverAPI; import jakarta.servlet.ServletException; @@ -49,9 +48,9 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific and can be queried only from public tenant try { - EE_FEATURES[] features = FeatureFlag.getInstance(main, this.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req)) + EE_FEATURES[] features = FeatureFlag.getInstance(main, this.enforcePublicTenantAndGetPublicTenantStorage(req)) .getEnabledFeatures(); - JsonObject stats = FeatureFlag.getInstance(main, this.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req)) + JsonObject stats = FeatureFlag.getInstance(main, this.enforcePublicTenantAndGetPublicTenantStorage(req)) .getPaidFeatureStats(); JsonObject result = new JsonObject(); JsonArray featuresJson = new JsonArray(); diff --git a/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java b/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java index e2562c8fa..eb93d1316 100644 --- a/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java @@ -20,6 +20,7 @@ import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; import io.supertokens.authRecipe.AuthRecipe; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -55,7 +56,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = - this.getAppIdentifierWithStorageAndUserIdMappingFromRequest(req, userId, UserIdType.ANY); + this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the getUserUsingId function if (appIdentifierWithStorageAndUserIdMapping.userIdMapping != null) { userId = appIdentifierWithStorageAndUserIdMapping.userIdMapping.superTokensUserId; @@ -87,7 +88,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO super.sendJsonResponse(200, result, resp); } - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java b/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java index 43887590b..86f889d9d 100644 --- a/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java @@ -17,9 +17,11 @@ package io.supertokens.webserver.api.core; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorages; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.utils.RateLimiter; import io.supertokens.webserver.WebserverAPI; @@ -78,7 +80,7 @@ private void handleRequest(HttpServletRequest req, HttpServletResponse resp) thr // API is app specific try { - RateLimiter rateLimiter = RateLimiter.getInstance(getAppIdentifierWithStorage(req), super.main, 200); + RateLimiter rateLimiter = RateLimiter.getInstance(getAppIdentifier(req), super.main, 200); if (!rateLimiter.checkRequest()) { if (Main.isTesting) { super.sendTextResponse(200, "RateLimitedHello", resp); @@ -88,15 +90,15 @@ private void handleRequest(HttpServletRequest req, HttpServletResponse resp) thr return; } - AppIdentifierWithStorage appIdentifierWithStorage = getAppIdentifierWithStorage(req); + AppIdentifierWithStorages appIdentifierWithStorages = enforcePublicTenantAndGetAllStoragesForApp(req); - for (Storage storage : appIdentifierWithStorage.getStorages()) { + for (Storage storage : appIdentifierWithStorages.getStorages()) { // even if the public tenant does not exist, the following function will return a null // idea here is to test that the storage is working - storage.getKeyValue(appIdentifierWithStorage.getAsPublicTenantIdentifier(), "Test"); + storage.getKeyValue(appIdentifierWithStorages.getAsPublicTenantIdentifier(), "Test"); } super.sendTextResponse(200, "Hello", resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | BadPermissionException | TenantOrAppNotFoundException e) { // we send 500 status code throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/core/JWKSPublicAPI.java b/src/main/java/io/supertokens/webserver/api/core/JWKSPublicAPI.java index 8d1d4ee3c..285f75c69 100644 --- a/src/main/java/io/supertokens/webserver/api/core/JWKSPublicAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/JWKSPublicAPI.java @@ -61,7 +61,7 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { try { - List jwks = SigningKeys.getInstance(this.getAppIdentifierWithStorage(req), main).getJWKS(); + List jwks = SigningKeys.getInstance(this.getAppIdentifier(req), main).getJWKS(); JsonObject reply = new JsonObject(); JsonArray jwksJsonArray = new JsonParser().parse(new Gson().toJson(jwks)).getAsJsonArray(); reply.add("keys", jwksJsonArray); diff --git a/src/main/java/io/supertokens/webserver/api/core/LicenseKeyAPI.java b/src/main/java/io/supertokens/webserver/api/core/LicenseKeyAPI.java index b9960801f..7be99709e 100644 --- a/src/main/java/io/supertokens/webserver/api/core/LicenseKeyAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/LicenseKeyAPI.java @@ -24,7 +24,6 @@ import io.supertokens.httpRequest.HttpResponseException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.WebserverAPI; @@ -53,10 +52,10 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO try { boolean success = false; if (licenseKey != null) { - success = FeatureFlag.getInstance(main, this.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req)) + success = FeatureFlag.getInstance(main, this.enforcePublicTenantAndGetPublicTenantStorage(req)) .setLicenseKeyAndSyncFeatures(licenseKey); } else { - success = FeatureFlag.getInstance(main, this.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req)) + success = FeatureFlag.getInstance(main, this.enforcePublicTenantAndGetPublicTenantStorage(req)) .syncFeatureFlagWithLicenseKey(); } JsonObject result = new JsonObject(); @@ -75,7 +74,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific and can be queried only from public tenant try { - FeatureFlag.getInstance(main, this.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req)) + FeatureFlag.getInstance(main, this.enforcePublicTenantAndGetPublicTenantStorage(req)) .removeLicenseKeyAndSyncFeatures(); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); @@ -89,7 +88,7 @@ protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific and can be queried only from public tenant try { - String licenseKey = FeatureFlag.getInstance(main, this.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req)) + String licenseKey = FeatureFlag.getInstance(main, this.enforcePublicTenantAndGetPublicTenantStorage(req)) .getLicenseKey(); JsonObject result = new JsonObject(); result.addProperty("licenseKey", licenseKey); diff --git a/src/main/java/io/supertokens/webserver/api/core/ListUsersByAccountInfoAPI.java b/src/main/java/io/supertokens/webserver/api/core/ListUsersByAccountInfoAPI.java index 9cb27d0a8..779505f8a 100644 --- a/src/main/java/io/supertokens/webserver/api/core/ListUsersByAccountInfoAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/ListUsersByAccountInfoAPI.java @@ -23,9 +23,9 @@ import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.useridmapping.UserIdMapping; -import io.supertokens.useridmapping.UserIdType; import io.supertokens.utils.Utils; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.WebserverAPI; @@ -73,11 +73,10 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } try { - AppIdentifierWithStorage appIdentifierWithStorage = this.getAppIdentifierWithStorage(req); + TenantIdentifierWithStorage tenantIdentifierWithStorage = this.getTenantStorage(req); AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo( - this.getTenantIdentifierWithStorageFromRequest( - req), doUnionOfAccountInfo, email, phoneNumber, thirdPartyId, thirdPartyUserId); - UserIdMapping.populateExternalUserIdForUsers(appIdentifierWithStorage, users); + this.getTenantStorage(req), doUnionOfAccountInfo, email, phoneNumber, thirdPartyId, thirdPartyUserId); + UserIdMapping.populateExternalUserIdForUsers(tenantIdentifierWithStorage.toAppIdentifierWithStorage(), users); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java b/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java index ed3806e42..03cc3894b 100644 --- a/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java @@ -17,10 +17,12 @@ package io.supertokens.webserver.api.core; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorages; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.utils.RateLimiter; import io.supertokens.webserver.WebserverAPI; @@ -71,11 +73,11 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO protected void handleRequest(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // getServletPath returns the path without the base path. - AppIdentifierWithStorage appIdentifierWithStorage = null; + AppIdentifierWithStorages appIdentifierWithStorages = null; try { - appIdentifierWithStorage = getAppIdentifierWithStorage(req); - } catch (TenantOrAppNotFoundException e) { + appIdentifierWithStorages = enforcePublicTenantAndGetAllStoragesForApp(req); + } catch (TenantOrAppNotFoundException | BadPermissionException e) { // we send 500 status code throw new ServletException(e); } @@ -83,7 +85,7 @@ protected void handleRequest(HttpServletRequest req, HttpServletResponse resp) t if (req.getServletPath().equals("/")) { // API is app specific try { - RateLimiter rateLimiter = RateLimiter.getInstance(getAppIdentifierWithStorage(req), super.main, 200); + RateLimiter rateLimiter = RateLimiter.getInstance(getAppIdentifier(req), super.main, 200); if (!rateLimiter.checkRequest()) { if (Main.isTesting) { super.sendTextResponse(200, "RateLimitedHello", resp); @@ -93,21 +95,21 @@ protected void handleRequest(HttpServletRequest req, HttpServletResponse resp) t return; } - for (Storage storage : appIdentifierWithStorage.getStorages()) { + for (Storage storage : appIdentifierWithStorages.getStorages()) { // even if the public tenant does not exist, the following function will return a null // idea here is to test that the storage is working - storage.getKeyValue(appIdentifierWithStorage.getAsPublicTenantIdentifier(), "Test"); + storage.getKeyValue(appIdentifierWithStorages.getAsPublicTenantIdentifier(), "Test"); } super.sendTextResponse(200, "Hello", resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException e) { // we send 500 status code throw new ServletException(e); } } else { super.sendTextResponse(404, "Not found", resp); - Logging.error(main, appIdentifierWithStorage.getAsPublicTenantIdentifier(), "Unknown API called: " + req.getRequestURL(), false); + Logging.error(main, appIdentifierWithStorages.getAsPublicTenantIdentifier(), "Unknown API called: " + req.getRequestURL(), false); } } diff --git a/src/main/java/io/supertokens/webserver/api/core/RequestStatsAPI.java b/src/main/java/io/supertokens/webserver/api/core/RequestStatsAPI.java index 2cde53961..1905ab258 100644 --- a/src/main/java/io/supertokens/webserver/api/core/RequestStatsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/RequestStatsAPI.java @@ -18,19 +18,15 @@ import com.google.gson.JsonObject; import io.supertokens.Main; -import io.supertokens.cliOptions.CLIOptions; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; -import io.supertokens.webserver.InputParser; import io.supertokens.webserver.RequestStats; import io.supertokens.webserver.WebserverAPI; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import java.io.File; import java.io.IOException; public class RequestStatsAPI extends WebserverAPI { @@ -49,7 +45,7 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific try { - AppIdentifier appIdentifier = getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req); + AppIdentifier appIdentifier = enforcePublicTenantAndGetPublicTenantStorage(req); JsonObject stats = RequestStats.getInstance(main, appIdentifier).getStats(); stats.addProperty("status", "OK"); super.sendJsonResponse(200, stats, resp); diff --git a/src/main/java/io/supertokens/webserver/api/core/TelemetryAPI.java b/src/main/java/io/supertokens/webserver/api/core/TelemetryAPI.java index c42460755..2bc28379a 100644 --- a/src/main/java/io/supertokens/webserver/api/core/TelemetryAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/TelemetryAPI.java @@ -47,7 +47,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO // API is app specific try { KeyValueInfo telemetryId = Telemetry.getTelemetryId(main, - this.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req)); + this.enforcePublicTenantAndGetPublicTenantStorage(req)); JsonObject result = new JsonObject(); if (telemetryId == null) { diff --git a/src/main/java/io/supertokens/webserver/api/core/UsersAPI.java b/src/main/java/io/supertokens/webserver/api/core/UsersAPI.java index 4e7e2120c..fd5bb7dc9 100644 --- a/src/main/java/io/supertokens/webserver/api/core/UsersAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/UsersAPI.java @@ -41,7 +41,6 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; import java.util.stream.Stream; public class UsersAPI extends WebserverAPI { @@ -77,7 +76,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO TenantIdentifierWithStorage tenantIdentifierWithStorage = null; try { - tenantIdentifierWithStorage = this.getTenantIdentifierWithStorageFromRequest(req); + tenantIdentifierWithStorage = this.getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/core/UsersCountAPI.java b/src/main/java/io/supertokens/webserver/api/core/UsersCountAPI.java index 686676776..65d234260 100644 --- a/src/main/java/io/supertokens/webserver/api/core/UsersCountAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/UsersCountAPI.java @@ -23,6 +23,7 @@ import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorages; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.WebserverAPI; @@ -76,13 +77,13 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO long count; if (includeAllTenants) { - AppIdentifierWithStorage appIdentifierWithStorage = getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req); + AppIdentifierWithStorages appIdentifierWithStorages = enforcePublicTenantAndGetAllStoragesForApp(req); - count = AuthRecipe.getUsersCountAcrossAllTenants(appIdentifierWithStorage, + count = AuthRecipe.getUsersCountAcrossAllTenants(appIdentifierWithStorages, recipeIdsEnumBuilder.build().toArray(RECIPE_ID[]::new)); } else { - count = AuthRecipe.getUsersCountForTenant(this.getTenantIdentifierWithStorageFromRequest(req), + count = AuthRecipe.getUsersCountForTenant(this.getTenantStorage(req), recipeIdsEnumBuilder.build().toArray(RECIPE_ID[]::new)); } JsonObject result = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/dashboard/DashboardSignInAPI.java b/src/main/java/io/supertokens/webserver/api/dashboard/DashboardSignInAPI.java index f7296a2a5..7cf68d727 100644 --- a/src/main/java/io/supertokens/webserver/api/dashboard/DashboardSignInAPI.java +++ b/src/main/java/io/supertokens/webserver/api/dashboard/DashboardSignInAPI.java @@ -61,7 +61,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { String sessionId = Dashboard.signInDashboardUser( - super.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req), main, email, password); + super.enforcePublicTenantAndGetPublicTenantStorage(req), main, email, password); if (sessionId == null) { JsonObject response = new JsonObject(); response.addProperty("status", "INVALID_CREDENTIALS_ERROR"); diff --git a/src/main/java/io/supertokens/webserver/api/dashboard/DashboardUserAPI.java b/src/main/java/io/supertokens/webserver/api/dashboard/DashboardUserAPI.java index 51eb3618e..38764de5b 100644 --- a/src/main/java/io/supertokens/webserver/api/dashboard/DashboardUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/dashboard/DashboardUserAPI.java @@ -91,7 +91,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } DashboardUser user = Dashboard.signUpDashboardUser( - this.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req), + this.enforcePublicTenantAndGetPublicTenantStorage(req), main, email, password); JsonObject userAsJsonObject = new JsonParser().parse(new Gson().toJson(user)).getAsJsonObject(); @@ -147,7 +147,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO try { AppIdentifierWithStorage appIdentifierWithStorage = - this.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant( + this.enforcePublicTenantAndGetPublicTenantStorage( req); String userId = InputParser.parseStringOrThrowError(input, "userId", true); if (userId != null) { @@ -216,7 +216,7 @@ protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws // normalize userId userId = Utils.normalizeAndValidateStringParam(userId, "userId"); boolean didUserExist = Dashboard.deleteUserWithUserId( - super.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req), userId); + super.enforcePublicTenantAndGetPublicTenantStorage(req), userId); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); response.addProperty("didUserExist", didUserExist); @@ -232,7 +232,7 @@ protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws email = io.supertokens.utils.Utils.normaliseEmail(email); boolean didUserExist = Dashboard.deleteUserWithEmail( - super.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req), email); + super.enforcePublicTenantAndGetPublicTenantStorage(req), email); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); response.addProperty("didUserExist", didUserExist); diff --git a/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardSessionsForUserAPI.java b/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardSessionsForUserAPI.java index 395e28337..0c4958b1f 100644 --- a/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardSessionsForUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardSessionsForUserAPI.java @@ -56,7 +56,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO JsonArray arr = new com.google.gson.JsonParser().parse(new Gson().toJson( Dashboard.getAllDashboardSessionsForUser( - super.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req), + super.enforcePublicTenantAndGetPublicTenantStorage(req), userId))).getAsJsonArray(); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardUsersAPI.java b/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardUsersAPI.java index 6bbd5b817..fe3be4539 100644 --- a/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardUsersAPI.java +++ b/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardUsersAPI.java @@ -51,7 +51,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO JsonArray arr = new com.google.gson.JsonParser().parse(new Gson().toJson( Dashboard.getAllDashboardUsers( - super.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req), main))) + super.enforcePublicTenantAndGetPublicTenantStorage(req), main))) .getAsJsonArray(); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/dashboard/RevokeSessionAPI.java b/src/main/java/io/supertokens/webserver/api/dashboard/RevokeSessionAPI.java index 20ad008ce..5af0cf5a2 100644 --- a/src/main/java/io/supertokens/webserver/api/dashboard/RevokeSessionAPI.java +++ b/src/main/java/io/supertokens/webserver/api/dashboard/RevokeSessionAPI.java @@ -53,7 +53,7 @@ protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws try { Dashboard.revokeSessionWithSessionId( - super.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req), sessionId); + super.enforcePublicTenantAndGetPublicTenantStorage(req), sessionId); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); super.sendJsonResponse(200, response, resp); diff --git a/src/main/java/io/supertokens/webserver/api/dashboard/VerifyDashboardUserSessionAPI.java b/src/main/java/io/supertokens/webserver/api/dashboard/VerifyDashboardUserSessionAPI.java index 917ea7877..c01cfac15 100644 --- a/src/main/java/io/supertokens/webserver/api/dashboard/VerifyDashboardUserSessionAPI.java +++ b/src/main/java/io/supertokens/webserver/api/dashboard/VerifyDashboardUserSessionAPI.java @@ -61,7 +61,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { JsonObject invalidSessionResp = new JsonObject(); invalidSessionResp.addProperty("status", "INVALID_SESSION_ERROR"); - AppIdentifierWithStorage identifierWithStorage = super.getAppIdentifierWithStorageFromRequestAndEnforcePublicTenant(req); + AppIdentifierWithStorage identifierWithStorage = super.enforcePublicTenantAndGetPublicTenantStorage(req); if (Dashboard.isValidUserSession(identifierWithStorage, main, sessionId)) { String email = Dashboard.getEmailFromSessionId(identifierWithStorage, main, sessionId); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/ConsumeResetPasswordAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/ConsumeResetPasswordAPI.java index 362ce9020..bed18f114 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/ConsumeResetPasswordAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/ConsumeResetPasswordAPI.java @@ -59,7 +59,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I TenantIdentifierWithStorage tenantIdentifierWithStorage = null; try { - tenantIdentifierWithStorage = getTenantIdentifierWithStorageFromRequest(req); + tenantIdentifierWithStorage = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/GeneratePasswordResetTokenAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/GeneratePasswordResetTokenAPI.java index 24f55a679..27ecd6fb4 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/GeneratePasswordResetTokenAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/GeneratePasswordResetTokenAPI.java @@ -62,14 +62,14 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I // logic according to https://github.com/supertokens/supertokens-core/issues/106 TenantIdentifier tenantIdentifier = null; try { - tenantIdentifier = getTenantIdentifierWithStorageFromRequest(req); + tenantIdentifier = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } try { TenantIdentifierWithStorageAndUserIdMapping tenantIdentifierStorageAndMapping = - getTenantIdentifierWithStorageAndUserIdMappingFromRequest(req, userId, UserIdType.ANY); + getStorageAndUserIdMappingForTenantSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the generatePasswordResetToken if (tenantIdentifierStorageAndMapping.userIdMapping != null) { userId = tenantIdentifierStorageAndMapping.userIdMapping.superTokensUserId; diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/ImportUserWithPasswordHashAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/ImportUserWithPasswordHashAPI.java index f1d9a7a9a..b162eb678 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/ImportUserWithPasswordHashAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/ImportUserWithPasswordHashAPI.java @@ -94,11 +94,11 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - TenantIdentifierWithStorage tenant = this.getTenantIdentifierWithStorageFromRequest(req); + TenantIdentifierWithStorage tenant = this.getTenantStorage(req); EmailPassword.ImportUserResponse importUserResponse = EmailPassword.importUserWithPasswordHash( tenant, main, email, passwordHash, passwordHashingAlgorithm); - UserIdMapping.populateExternalUserIdForUsers(getTenantIdentifierWithStorageFromRequest(req), new AuthRecipeUserInfo[]{importUserResponse.user}); + UserIdMapping.populateExternalUserIdForUsers(getTenantStorage(req), new AuthRecipeUserInfo[]{importUserResponse.user}); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); JsonObject userJson = diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/ResetPasswordAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/ResetPasswordAPI.java index 05d354676..66f92e0b0 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/ResetPasswordAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/ResetPasswordAPI.java @@ -75,7 +75,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I TenantIdentifierWithStorage tenantIdentifierWithStorage = null; try { - tenantIdentifierWithStorage = getTenantIdentifierWithStorageFromRequest(req); + tenantIdentifierWithStorage = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java index 720869e95..cabca592c 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java @@ -29,8 +29,6 @@ import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; -import io.supertokens.pluginInterface.useridmapping.UserIdMapping; -import io.supertokens.useridmapping.UserIdType; import io.supertokens.utils.SemVer; import io.supertokens.utils.Utils; import io.supertokens.webserver.InputParser; @@ -69,7 +67,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I TenantIdentifierWithStorage tenantIdentifierWithStorage = null; try { - tenantIdentifierWithStorage = getTenantIdentifierWithStorageFromRequest(req); + tenantIdentifierWithStorage = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java index 11d510dad..165e618e5 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java @@ -71,13 +71,13 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I TenantIdentifier tenantIdentifier = null; try { - tenantIdentifier = getTenantIdentifierWithStorageFromRequest(req); + tenantIdentifier = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } try { - TenantIdentifierWithStorage tenant = this.getTenantIdentifierWithStorageFromRequest(req); + TenantIdentifierWithStorage tenant = this.getTenantStorage(req); AuthRecipeUserInfo user = EmailPassword.signUp(tenant, super.main, normalisedEmail, password); ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, user.getSupertokensUserId()); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java index 7f992f6a5..079183928 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java @@ -21,6 +21,7 @@ import io.supertokens.Main; import io.supertokens.emailpassword.EmailPassword; import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; @@ -81,7 +82,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO if (userId != null) { // Query by userId AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = - this.getAppIdentifierWithStorageAndUserIdMappingFromRequest(req, userId, UserIdType.ANY); + this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the getUserUsingId function if (appIdentifierWithStorageAndUserIdMapping.userIdMapping != null) { userId = appIdentifierWithStorageAndUserIdMapping.userIdMapping.superTokensUserId; @@ -98,7 +99,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO // Query by email String normalisedEmail = Utils.normaliseEmail(email); TenantIdentifierWithStorage tenantIdentifierWithStorage = - this.getTenantIdentifierWithStorageFromRequest( + this.getTenantStorage( req); user = EmailPassword.getUserUsingEmail(tenantIdentifierWithStorage, normalisedEmail); @@ -131,7 +132,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO super.sendJsonResponse(200, result, resp); } - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } @@ -158,16 +159,11 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO } email = Utils.normaliseEmail(email); - AppIdentifier appIdentifier = null; - try { - appIdentifier = this.getAppIdentifierWithStorage(req); - } catch (TenantOrAppNotFoundException e) { - throw new ServletException(e); - } + AppIdentifier appIdentifier = this.getAppIdentifier(req); try { AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = - this.getAppIdentifierWithStorageAndUserIdMappingFromRequest(req, userId, UserIdType.ANY); + this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the updateUsersEmailOrPassword if (appIdentifierWithStorageAndUserIdMapping.userIdMapping != null) { userId = appIdentifierWithStorageAndUserIdMapping.userIdMapping.superTokensUserId; @@ -181,7 +177,8 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO result.addProperty("status", "OK"); super.sendJsonResponse(200, result, resp); - } catch (StorageQueryException | StorageTransactionLogicException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | StorageTransactionLogicException | TenantOrAppNotFoundException | + BadPermissionException e) { throw new ServletException(e); } catch (UnknownUserIdException e) { diff --git a/src/main/java/io/supertokens/webserver/api/emailverification/GenerateEmailVerificationTokenAPI.java b/src/main/java/io/supertokens/webserver/api/emailverification/GenerateEmailVerificationTokenAPI.java index 4d4ccdefb..eaee7d8c9 100644 --- a/src/main/java/io/supertokens/webserver/api/emailverification/GenerateEmailVerificationTokenAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailverification/GenerateEmailVerificationTokenAPI.java @@ -61,7 +61,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I TenantIdentifierWithStorage tenantIdentifierWithStorage = null; try { - tenantIdentifierWithStorage = getTenantIdentifierWithStorageFromRequest(req); + tenantIdentifierWithStorage = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/emailverification/RevokeAllTokensForUserAPI.java b/src/main/java/io/supertokens/webserver/api/emailverification/RevokeAllTokensForUserAPI.java index b91fa45b9..b5de5e342 100644 --- a/src/main/java/io/supertokens/webserver/api/emailverification/RevokeAllTokensForUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailverification/RevokeAllTokensForUserAPI.java @@ -52,7 +52,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I email = Utils.normaliseEmail(email); try { - EmailVerification.revokeAllTokens(this.getTenantIdentifierWithStorageFromRequest(req), userId, email); + EmailVerification.revokeAllTokens(this.getTenantStorage(req), userId, email); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java b/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java index cc3f0931b..7eb92e42f 100644 --- a/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java @@ -17,11 +17,16 @@ package io.supertokens.webserver.api.emailverification; import com.google.gson.JsonObject; +import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; import io.supertokens.emailverification.EmailVerification; +import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.useridmapping.UserIdType; import io.supertokens.utils.Utils; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.WebserverAPI; @@ -52,13 +57,21 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I email = Utils.normaliseEmail(email); try { - EmailVerification.unverifyEmail(this.getAppIdentifierWithStorage(req), userId, email); + AppIdentifierWithStorage appIdentifierWithStorage; + try { + AppIdentifierWithStorageAndUserIdMapping storageAndUidMapping = getStorageAndUserIdMappingForAppSpecificApi( + req, userId, UserIdType.ANY); + appIdentifierWithStorage = storageAndUidMapping.appIdentifierWithStorage; + } catch (UnknownUserIdException e) { + appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); + } + EmailVerification.unverifyEmail(appIdentifierWithStorage, userId, email); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java b/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java index f0fd338ec..1eefac604 100644 --- a/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java @@ -17,16 +17,21 @@ package io.supertokens.webserver.api.emailverification; import com.google.gson.JsonObject; +import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; import io.supertokens.emailverification.EmailVerification; import io.supertokens.emailverification.User; import io.supertokens.emailverification.exception.EmailVerificationInvalidTokenException; +import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; +import io.supertokens.useridmapping.UserIdType; import io.supertokens.utils.Utils; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.WebserverAPI; @@ -67,7 +72,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I TenantIdentifierWithStorage tenantIdentifierWithStorage = null; try { - tenantIdentifierWithStorage = this.getTenantIdentifierWithStorageFromRequest(req); + tenantIdentifierWithStorage = this.getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } @@ -101,7 +106,15 @@ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws Servl assert email != null; try { - boolean isVerified = EmailVerification.isEmailVerified(this.getAppIdentifierWithStorage(req), userId, + AppIdentifierWithStorage appIdentifierWithStorage; + try { + AppIdentifierWithStorageAndUserIdMapping storageAndUidMapping = getStorageAndUserIdMappingForAppSpecificApi( + req, userId, UserIdType.ANY); + appIdentifierWithStorage = storageAndUidMapping.appIdentifierWithStorage; + } catch (UnknownUserIdException e) { + appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); + } + boolean isVerified = EmailVerification.isEmailVerified(appIdentifierWithStorage, userId, email); JsonObject result = new JsonObject(); @@ -109,7 +122,7 @@ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws Servl result.addProperty("isVerified", isVerified); super.sendJsonResponse(200, result, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/jwt/JWKSAPI.java b/src/main/java/io/supertokens/webserver/api/jwt/JWKSAPI.java index c79d0f1d2..49b197e45 100644 --- a/src/main/java/io/supertokens/webserver/api/jwt/JWKSAPI.java +++ b/src/main/java/io/supertokens/webserver/api/jwt/JWKSAPI.java @@ -22,6 +22,7 @@ import com.google.gson.JsonParser; import io.supertokens.Main; import io.supertokens.jwt.exceptions.UnsupportedJWTSigningAlgorithmException; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; @@ -54,13 +55,15 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific try { - List jwks = SigningKeys.getInstance(this.getAppIdentifierWithStorage(req), main).getJWKS(); + List jwks = SigningKeys.getInstance(this.enforcePublicTenantAndGetPublicTenantStorage(req), main).getJWKS(); JsonObject reply = new JsonObject(); JsonArray jwksJsonArray = new JsonParser().parse(new Gson().toJson(jwks)).getAsJsonArray(); reply.add("keys", jwksJsonArray); reply.addProperty("status", "OK"); super.sendJsonResponse(200, reply, resp); - } catch (StorageQueryException | UnsupportedJWTSigningAlgorithmException | StorageTransactionLogicException | NoSuchAlgorithmException | InvalidKeySpecException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | UnsupportedJWTSigningAlgorithmException | StorageTransactionLogicException | + NoSuchAlgorithmException | InvalidKeySpecException | TenantOrAppNotFoundException | + BadPermissionException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/jwt/JWTSigningAPI.java b/src/main/java/io/supertokens/webserver/api/jwt/JWTSigningAPI.java index 6c65f3bfd..464b01926 100644 --- a/src/main/java/io/supertokens/webserver/api/jwt/JWTSigningAPI.java +++ b/src/main/java/io/supertokens/webserver/api/jwt/JWTSigningAPI.java @@ -20,6 +20,7 @@ import io.supertokens.Main; import io.supertokens.jwt.JWTSigningFunctions; import io.supertokens.jwt.exceptions.UnsupportedJWTSigningAlgorithmException; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; @@ -78,7 +79,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - String jwt = JWTSigningFunctions.createJWTToken(this.getAppIdentifierWithStorage(req), main, + String jwt = JWTSigningFunctions.createJWTToken(this.enforcePublicTenantAndGetPublicTenantStorage(req), main, algorithm.toUpperCase(), payload, jwksDomain, validity, useDynamicKey); JsonObject reply = new JsonObject(); @@ -89,7 +90,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject reply = new JsonObject(); reply.addProperty("status", UNSUPPORTED_ALGORITHM_ERROR_STATUS); super.sendJsonResponse(200, reply, resp); - } catch (StorageQueryException | StorageTransactionLogicException | NoSuchAlgorithmException | InvalidKeySpecException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | StorageTransactionLogicException | NoSuchAlgorithmException | + InvalidKeySpecException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/AssociateUserToTenantAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/AssociateUserToTenantAPI.java index 739d182bd..5cd0efa99 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/AssociateUserToTenantAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/AssociateUserToTenantAPI.java @@ -24,13 +24,16 @@ import io.supertokens.multitenancy.exception.AnotherPrimaryUserWithEmailAlreadyExistsException; import io.supertokens.multitenancy.exception.AnotherPrimaryUserWithPhoneNumberAlreadyExistsException; import io.supertokens.multitenancy.exception.AnotherPrimaryUserWithThirdPartyInfoAlreadyExistsException; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.passwordless.exception.DuplicatePhoneNumberException; import io.supertokens.pluginInterface.thirdparty.exception.DuplicateThirdPartyUserException; +import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; import io.supertokens.utils.SemVer; import io.supertokens.webserver.InputParser; @@ -73,14 +76,15 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getAppIdentifierWithStorageAndUserIdMappingFromRequest(req, userId, UserIdType.ANY); - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; + AppIdentifierWithStorage appIdentifierWithStorage = getTenantStorage(req).toAppIdentifierWithStorage(); + io.supertokens.pluginInterface.useridmapping.UserIdMapping mapping = UserIdMapping.getUserIdMapping( + appIdentifierWithStorage, userId, UserIdType.ANY); + if (mapping != null) { + userId = mapping.superTokensUserId; } boolean addedToTenant = Multitenancy.addUserIdToTenant(main, - getTenantIdentifierWithStorageFromRequest(req), userId); + getTenantStorage(req), userId); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java index d84cfcf7b..fdfe474de 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java @@ -18,12 +18,10 @@ import com.google.gson.JsonObject; import io.supertokens.Main; -import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.Utils; -import io.supertokens.webserver.api.multitenancy.BaseCreateOrUpdate; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -58,7 +56,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO TenantIdentifier sourceTenantIdentifier; try { - sourceTenantIdentifier = this.getTenantIdentifierWithStorageFromRequest(req); + sourceTenantIdentifier = this.getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java index 8d88cb8d6..1e28287ab 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java @@ -56,7 +56,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO TenantIdentifier sourceTenantIdentifier; try { - sourceTenantIdentifier = this.getTenantIdentifierWithStorageFromRequest(req); + sourceTenantIdentifier = this.getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java index 27d08cc40..3e193398a 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java @@ -59,7 +59,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO TenantIdentifier sourceTenantIdentifier; try { - sourceTenantIdentifier = this.getTenantIdentifierWithStorageFromRequest(req); + sourceTenantIdentifier = this.getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } @@ -74,7 +74,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { try { - TenantIdentifierWithStorage tenantIdentifier = this.getTenantIdentifierWithStorageFromRequest(req); + TenantIdentifierWithStorage tenantIdentifier = this.getTenantStorage(req); TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifier); if (config == null) { throw new TenantOrAppNotFoundException(tenantIdentifier); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/DisassociateUserFromTenant.java b/src/main/java/io/supertokens/webserver/api/multitenancy/DisassociateUserFromTenant.java index a37c3a595..17a55c88a 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/DisassociateUserFromTenant.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/DisassociateUserFromTenant.java @@ -24,7 +24,9 @@ import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; +import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; import io.supertokens.utils.SemVer; import io.supertokens.webserver.InputParser; @@ -67,15 +69,16 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { String externalUserId = null; - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getAppIdentifierWithStorageAndUserIdMappingFromRequest(req, userId, UserIdType.ANY); - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; - externalUserId = mappingAndStorage.userIdMapping.externalUserId; + AppIdentifierWithStorage appIdentifierWithStorage = getTenantStorage(req).toAppIdentifierWithStorage(); + io.supertokens.pluginInterface.useridmapping.UserIdMapping mapping = UserIdMapping.getUserIdMapping( + appIdentifierWithStorage, userId, UserIdType.ANY); + if (mapping != null) { + userId = mapping.superTokensUserId; + externalUserId = mapping.externalUserId; } boolean wasAssociated = Multitenancy.removeUserIdFromTenant(main, - getTenantIdentifierWithStorageFromRequest(req), userId, externalUserId); + getTenantStorage(req), userId, externalUserId); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); @@ -90,6 +93,5 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } catch (StorageQueryException | TenantOrAppNotFoundException | FeatureNotEnabledException e) { throw new ServletException(e); } - } } diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/ListAppsAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/ListAppsAPI.java index 03b44525f..b8966b1b9 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/ListAppsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/ListAppsAPI.java @@ -54,7 +54,7 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { TenantIdentifierWithStorage tenantIdentifierWithStorage; try { - tenantIdentifierWithStorage = this.getTenantIdentifierWithStorageFromRequest(req); + tenantIdentifierWithStorage = this.getTenantStorage(req); if (!tenantIdentifierWithStorage.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID) || !tenantIdentifierWithStorage.getAppId().equals(TenantIdentifier.DEFAULT_APP_ID)) { diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/ListConnectionUriDomainsAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/ListConnectionUriDomainsAPI.java index 2aae0c19b..29551e3c5 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/ListConnectionUriDomainsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/ListConnectionUriDomainsAPI.java @@ -54,7 +54,7 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { TenantIdentifierWithStorage tenantIdentifierWithStorage; try { - tenantIdentifierWithStorage = this.getTenantIdentifierWithStorageFromRequest(req); + tenantIdentifierWithStorage = this.getTenantStorage(req); if (!tenantIdentifierWithStorage.equals(new TenantIdentifier(null, null, null))) { throw new BadPermissionException( diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/ListTenantsAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/ListTenantsAPI.java index 0000eb2b8..f72c9421d 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/ListTenantsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/ListTenantsAPI.java @@ -50,7 +50,7 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { TenantIdentifierWithStorage tenantIdentifierWithStorage; try { - tenantIdentifierWithStorage = this.getTenantIdentifierWithStorageFromRequest(req); + tenantIdentifierWithStorage = this.getTenantStorage(req); if (!tenantIdentifierWithStorage.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID)) { throw new BadPermissionException("Only the public tenantId is allowed to list all tenants " + diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java index 1b6768d98..321d97779 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java @@ -59,7 +59,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - TenantIdentifier sourceTenantIdentifier = this.getTenantIdentifierWithStorageFromRequest(req); + TenantIdentifier sourceTenantIdentifier = this.getTenantStorage(req); if (!sourceTenantIdentifier.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID) || !sourceTenantIdentifier.getAppId().equals(TenantIdentifier.DEFAULT_APP_ID)) { throw new BadPermissionException("Only the public tenantId and public appId is allowed to delete an app"); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java index 5097937ea..275e82dd7 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java @@ -58,7 +58,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - TenantIdentifier sourceTenantIdentifier = this.getTenantIdentifierWithStorageFromRequest(req); + TenantIdentifier sourceTenantIdentifier = this.getTenantStorage(req); if (!sourceTenantIdentifier.equals(new TenantIdentifier(null, null, null))) { throw new BadPermissionException( "Only the public tenantId, public appId and default connectionUriDomain is allowed to delete a connectionUriDomain"); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveTenantAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveTenantAPI.java index 480b1cdd7..06446f647 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveTenantAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveTenantAPI.java @@ -58,7 +58,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - TenantIdentifier sourceTenantIdentifier = this.getTenantIdentifierWithStorageFromRequest(req); + TenantIdentifier sourceTenantIdentifier = this.getTenantStorage(req); if (!sourceTenantIdentifier.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID)) { throw new BadPermissionException("Only the public tenantId is allowed to delete a tenant"); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/CreateOrUpdateThirdPartyConfigAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/CreateOrUpdateThirdPartyConfigAPI.java index eff3a93d9..2b4e9a146 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/CreateOrUpdateThirdPartyConfigAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/CreateOrUpdateThirdPartyConfigAPI.java @@ -70,7 +70,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO } try { - TenantIdentifierWithStorage tenantIdentifier = this.getTenantIdentifierWithStorageFromRequest(req); + TenantIdentifierWithStorage tenantIdentifier = this.getTenantStorage(req); if (!tenantIdentifier.equals(TenantIdentifier.BASE_TENANT)) { if (Arrays.stream(FeatureFlag.getInstance(main, new AppIdentifier(null, null)).getEnabledFeatures()) diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/RemoveThirdPartyConfigAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/RemoveThirdPartyConfigAPI.java index 8f5b5570c..f5a371c6c 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/RemoveThirdPartyConfigAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/RemoveThirdPartyConfigAPI.java @@ -59,7 +59,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I thirdPartyId = thirdPartyId.trim(); try { - TenantIdentifierWithStorage tenantIdentifier = this.getTenantIdentifierWithStorageFromRequest(req); + TenantIdentifierWithStorage tenantIdentifier = this.getTenantStorage(req); TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifier); if (config == null) { throw new TenantOrAppNotFoundException(tenantIdentifier); diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java index 4b622328b..299f66b7f 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java @@ -29,8 +29,6 @@ import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; -import io.supertokens.pluginInterface.useridmapping.UserIdMapping; -import io.supertokens.useridmapping.UserIdType; import io.supertokens.utils.SemVer; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.WebserverAPI; @@ -84,12 +82,12 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { ConsumeCodeResponse consumeCodeResponse = Passwordless.consumeCode( - this.getTenantIdentifierWithStorageFromRequest(req), main, + this.getTenantStorage(req), main, deviceId, deviceIdHash, userInputCode, linkCode, // From CDI version 4.0 onwards, the email verification will be set getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0)); - io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(this.getTenantIdentifierWithStorageFromRequest(req), new AuthRecipeUserInfo[]{consumeCodeResponse.user}); + io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(this.getTenantStorage(req), new AuthRecipeUserInfo[]{consumeCodeResponse.user}); ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, consumeCodeResponse.user.getSupertokensUserId()); diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/CreateCodeAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/CreateCodeAPI.java index 96ee64990..16e182073 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/CreateCodeAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/CreateCodeAPI.java @@ -79,10 +79,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { CreateCodeResponse createCodeResponse = Passwordless.createCode( - this.getTenantIdentifierWithStorageFromRequest(req), main, email, + this.getTenantStorage(req), main, email, phoneNumber, deviceId, userInputCode); - long passwordlessCodeLifetime = Config.getConfig(this.getTenantIdentifierWithStorageFromRequest(req), main) + long passwordlessCodeLifetime = Config.getConfig(this.getTenantStorage(req), main) .getPasswordlessCodeLifetime(); JsonObject result = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodeAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodeAPI.java index 78b23ca3c..6a557759c 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodeAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodeAPI.java @@ -53,7 +53,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String codeId = InputParser.parseStringOrThrowError(input, "codeId", false); try { - Passwordless.removeCode(this.getTenantIdentifierWithStorageFromRequest(req), codeId); + Passwordless.removeCode(this.getTenantStorage(req), codeId); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodesAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodesAPI.java index 476e4b562..21b579abc 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodesAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodesAPI.java @@ -64,9 +64,9 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { if (email != null) { email = Utils.normaliseEmail(email); - Passwordless.removeCodesByEmail(this.getTenantIdentifierWithStorageFromRequest(req), email); + Passwordless.removeCodesByEmail(this.getTenantStorage(req), email); } else { - Passwordless.removeCodesByPhoneNumber(this.getTenantIdentifierWithStorageFromRequest(req), phoneNumber); + Passwordless.removeCodesByPhoneNumber(this.getTenantStorage(req), phoneNumber); } } catch (StorageTransactionLogicException | StorageQueryException | TenantOrAppNotFoundException e) { throw new ServletException(e); diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/GetCodesAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/GetCodesAPI.java index 4a318195c..84c0f3a4f 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/GetCodesAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/GetCodesAPI.java @@ -70,24 +70,24 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } try { - long passwordlessCodeLifetime = Config.getConfig(this.getTenantIdentifierWithStorageFromRequest(req), main) + long passwordlessCodeLifetime = Config.getConfig(this.getTenantStorage(req), main) .getPasswordlessCodeLifetime(); List devicesInfos; if (deviceId != null) { - DeviceWithCodes deviceWithCodes = Passwordless.getDeviceWithCodesById(this.getTenantIdentifierWithStorageFromRequest(req), + DeviceWithCodes deviceWithCodes = Passwordless.getDeviceWithCodesById(this.getTenantStorage(req), deviceId); devicesInfos = deviceWithCodes == null ? Collections.emptyList() : Collections.singletonList(deviceWithCodes); } else if (deviceIdHash != null) { DeviceWithCodes deviceWithCodes = Passwordless.getDeviceWithCodesByIdHash( - this.getTenantIdentifierWithStorageFromRequest(req), deviceIdHash); + this.getTenantStorage(req), deviceIdHash); devicesInfos = deviceWithCodes == null ? Collections.emptyList() : Collections.singletonList(deviceWithCodes); } else if (email != null) { email = Utils.normaliseEmail(email); - devicesInfos = Passwordless.getDevicesWithCodesByEmail(this.getTenantIdentifierWithStorageFromRequest(req), email); + devicesInfos = Passwordless.getDevicesWithCodesByEmail(this.getTenantStorage(req), email); } else { - devicesInfos = Passwordless.getDevicesWithCodesByPhoneNumber(this.getTenantIdentifierWithStorageFromRequest(req), + devicesInfos = Passwordless.getDevicesWithCodesByPhoneNumber(this.getTenantStorage(req), phoneNumber); } diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java index c4f3854f3..b4d17a9c3 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java @@ -20,6 +20,7 @@ import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.passwordless.Passwordless; import io.supertokens.passwordless.Passwordless.FieldUpdate; import io.supertokens.passwordless.exceptions.PhoneNumberChangeNotAllowedException; @@ -77,7 +78,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO if (userId != null) { try { AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = - this.getAppIdentifierWithStorageAndUserIdMappingFromRequest(req, userId, UserIdType.ANY); + this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); if (appIdentifierWithStorageAndUserIdMapping.userIdMapping != null) { userId = appIdentifierWithStorageAndUserIdMapping.userIdMapping.superTokensUserId; } @@ -93,15 +94,15 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } } else if (email != null) { email = Utils.normaliseEmail(email); - user = Passwordless.getUserByEmail(this.getTenantIdentifierWithStorageFromRequest(req), email); + user = Passwordless.getUserByEmail(this.getTenantStorage(req), email); if (user != null) { - io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(this.getTenantIdentifierWithStorageFromRequest(req), new AuthRecipeUserInfo[]{user}); + io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(this.getTenantStorage(req), new AuthRecipeUserInfo[]{user}); } } else { - user = Passwordless.getUserByPhoneNumber(this.getTenantIdentifierWithStorageFromRequest(req), + user = Passwordless.getUserByPhoneNumber(this.getTenantStorage(req), phoneNumber); if (user != null) { - io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(this.getTenantIdentifierWithStorageFromRequest(req), new AuthRecipeUserInfo[]{user}); + io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(this.getTenantStorage(req), new AuthRecipeUserInfo[]{user}); } } @@ -125,7 +126,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO result.add("user", userJson); super.sendJsonResponse(200, result, resp); } - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } @@ -153,7 +154,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO try { AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = - this.getAppIdentifierWithStorageAndUserIdMappingFromRequest(req, userId, UserIdType.ANY); + this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the updateUser if (appIdentifierWithStorageAndUserIdMapping.userIdMapping != null) { userId = appIdentifierWithStorageAndUserIdMapping.userIdMapping.superTokensUserId; @@ -165,7 +166,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject result = new JsonObject(); result.addProperty("status", "OK"); super.sendJsonResponse(200, result, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } catch (UnknownUserIdException e) { JsonObject result = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/session/HandshakeAPI.java b/src/main/java/io/supertokens/webserver/api/session/HandshakeAPI.java index 283b18e5a..7646ef968 100644 --- a/src/main/java/io/supertokens/webserver/api/session/HandshakeAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/HandshakeAPI.java @@ -57,17 +57,17 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject result = new JsonObject(); result.addProperty("status", "OK"); - Utils.addLegacySigningKeyInfos(this.getAppIdentifierWithStorage(req), main, result, + Utils.addLegacySigningKeyInfos(this.getAppIdentifier(req), main, result, super.getVersionFromRequest(req).betweenInclusive(SemVer.v2_9, SemVer.v2_21)); result.addProperty("accessTokenBlacklistingEnabled", - Config.getConfig(this.getTenantIdentifierWithStorageFromRequest(req), main) + Config.getConfig(this.getTenantStorage(req), main) .getAccessTokenBlacklisting()); result.addProperty("accessTokenValidity", - Config.getConfig(this.getTenantIdentifierWithStorageFromRequest(req), main) + Config.getConfig(this.getTenantStorage(req), main) .getAccessTokenValidity()); result.addProperty("refreshTokenValidity", - Config.getConfig(this.getTenantIdentifierWithStorageFromRequest(req), main) + Config.getConfig(this.getTenantStorage(req), main) .getRefreshTokenValidity()); super.sendJsonResponse(200, result, resp); } catch (StorageQueryException | StorageTransactionLogicException | TenantOrAppNotFoundException | UnsupportedJWTSigningAlgorithmException e) { diff --git a/src/main/java/io/supertokens/webserver/api/session/JWTDataAPI.java b/src/main/java/io/supertokens/webserver/api/session/JWTDataAPI.java index 22995811c..a4b121496 100644 --- a/src/main/java/io/supertokens/webserver/api/session/JWTDataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/JWTDataAPI.java @@ -24,6 +24,7 @@ import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; @@ -66,7 +67,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO TenantIdentifierWithStorage tenantIdentifierWithStorage = null; try { - AppIdentifierWithStorage appIdentifier = getAppIdentifierWithStorage(req); + AppIdentifier appIdentifier = getAppIdentifier(req); TenantIdentifier tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), Session.getTenantIdFromSessionHandle(sessionHandle)); tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); } catch (TenantOrAppNotFoundException e) { @@ -110,7 +111,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO TenantIdentifierWithStorage tenantIdentifierWithStorage = null; try { - AppIdentifierWithStorage appIdentifier = getAppIdentifierWithStorage(req); + AppIdentifier appIdentifier = getAppIdentifier(req); TenantIdentifier tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), Session.getTenantIdFromSessionHandle(sessionHandle)); tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); } catch (TenantOrAppNotFoundException e) { diff --git a/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java b/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java index 1749e154b..26d2f7328 100644 --- a/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java @@ -28,6 +28,7 @@ import io.supertokens.pluginInterface.STORAGE_TYPE; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.useridmapping.UserIdMapping; @@ -68,26 +69,21 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I assert enableAntiCsrf != null; assert refreshToken != null; - AppIdentifierWithStorage appIdentifierWithStorage = null; - try { - appIdentifierWithStorage = this.getAppIdentifierWithStorage(req); - } catch (TenantOrAppNotFoundException e) { - throw new ServletException(e); - } + AppIdentifier appIdentifier = this.getAppIdentifier(req); SemVer version = super.getVersionFromRequest(req); try { AccessToken.VERSION accessTokenVersion = AccessToken.getAccessTokenVersionForCDI(version); - SessionInformationHolder sessionInfo = Session.refreshSession(appIdentifierWithStorage, main, + SessionInformationHolder sessionInfo = Session.refreshSession(appIdentifier, main, refreshToken, antiCsrfToken, enableAntiCsrf, accessTokenVersion); - if (StorageLayer.getStorage(this.getTenantIdentifierWithStorageFromRequest(req), main).getType() == + if (StorageLayer.getStorage(this.getTenantStorage(req), main).getType() == STORAGE_TYPE.SQL) { try { UserIdMapping userIdMapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( - this.getAppIdentifierWithStorage(req), + this.getTenantStorage(req).toAppIdentifierWithStorage(), sessionInfo.session.userId, UserIdType.ANY); if (userIdMapping != null) { ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, @@ -118,14 +114,14 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I UnsupportedJWTSigningAlgorithmException e) { throw new ServletException(e); } catch (AccessTokenPayloadError | UnauthorisedException e) { - Logging.debug(main, appIdentifierWithStorage.getAsPublicTenantIdentifier(), + Logging.debug(main, appIdentifier.getAsPublicTenantIdentifier(), Utils.exceptionStacktraceToString(e)); JsonObject reply = new JsonObject(); reply.addProperty("status", "UNAUTHORISED"); reply.addProperty("message", e.getMessage()); super.sendJsonResponse(200, reply, resp); } catch (TokenTheftDetectedException e) { - Logging.debug(main, appIdentifierWithStorage.getAsPublicTenantIdentifier(), + Logging.debug(main, appIdentifier.getAsPublicTenantIdentifier(), Utils.exceptionStacktraceToString(e)); JsonObject reply = new JsonObject(); reply.addProperty("status", "TOKEN_THEFT_DETECTED"); diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionAPI.java index 7691ee81e..5b6ce77b6 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionAPI.java @@ -29,6 +29,7 @@ import io.supertokens.pluginInterface.STORAGE_TYPE; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; @@ -85,7 +86,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I assert userDataInDatabase != null; try { - boolean useStaticSigningKey = !Config.getConfig(this.getTenantIdentifierWithStorageFromRequest(req), main) + boolean useStaticSigningKey = !Config.getConfig(this.getTenantStorage(req), main) .getAccessTokenSigningKeyDynamic(); if (version.greaterThanOrEqualTo(SemVer.v2_21)) { Boolean useDynamicSigningKey = InputParser.parseBooleanOrThrowError(input, "useDynamicSigningKey", @@ -98,16 +99,16 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I AccessToken.VERSION accessTokenVersion = AccessToken.getAccessTokenVersionForCDI(version); SessionInformationHolder sessionInfo = Session.createNewSession( - this.getTenantIdentifierWithStorageFromRequest(req), main, userId, userDataInJWT, + this.getTenantStorage(req), main, userId, userDataInJWT, userDataInDatabase, enableAntiCsrf, accessTokenVersion, useStaticSigningKey); - if (StorageLayer.getStorage(this.getTenantIdentifierWithStorageFromRequest(req), main).getType() == + if (StorageLayer.getStorage(this.getTenantStorage(req), main).getType() == STORAGE_TYPE.SQL) { try { io.supertokens.pluginInterface.useridmapping.UserIdMapping userIdMapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( - this.getAppIdentifierWithStorage(req), + this.getTenantStorage(req).toAppIdentifierWithStorage(), sessionInfo.session.userId, UserIdType.ANY); if (userIdMapping != null) { ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, @@ -134,7 +135,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I if (super.getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v2_21)) { result.remove("idRefreshToken"); } else { - Utils.addLegacySigningKeyInfos(this.getAppIdentifierWithStorage(req), main, result, + Utils.addLegacySigningKeyInfos(this.getTenantStorage(req).toAppIdentifier(), main, result, super.getVersionFromRequest(req).betweenInclusive(SemVer.v2_9, SemVer.v2_21)); } @@ -157,7 +158,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO TenantIdentifierWithStorage tenantIdentifierWithStorage = null; try { - AppIdentifierWithStorage appIdentifier = getAppIdentifierWithStorage(req); + AppIdentifier appIdentifier = getAppIdentifier(req); TenantIdentifier tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), Session.getTenantIdFromSessionHandle(sessionHandle)); tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionDataAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionDataAPI.java index 3243f5781..29971d899 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionDataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionDataAPI.java @@ -23,6 +23,7 @@ import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; @@ -61,7 +62,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO TenantIdentifierWithStorage tenantIdentifierWithStorage = null; try { - AppIdentifierWithStorage appIdentifier = getAppIdentifierWithStorage(req); + AppIdentifier appIdentifier = getAppIdentifier(req); TenantIdentifier tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), Session.getTenantIdFromSessionHandle(sessionHandle)); tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); } catch (TenantOrAppNotFoundException e) { @@ -98,7 +99,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO TenantIdentifierWithStorage tenantIdentifierWithStorage = null; try { - AppIdentifierWithStorage appIdentifier = getAppIdentifierWithStorage(req); + AppIdentifier appIdentifier = getAppIdentifier(req); TenantIdentifier tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), Session.getTenantIdFromSessionHandle(sessionHandle)); tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); } catch (TenantOrAppNotFoundException e) { diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionRegenerateAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionRegenerateAPI.java index 0f2843e65..c480b194c 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionRegenerateAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionRegenerateAPI.java @@ -26,6 +26,7 @@ import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.session.Session; @@ -68,17 +69,12 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject userDataInJWT = InputParser.parseJsonObjectOrThrowError(input, "userDataInJWT", true); - AppIdentifierWithStorage appIdentifierWithStorage = null; - try { - appIdentifierWithStorage = this.getAppIdentifierWithStorage(req); - } catch (TenantOrAppNotFoundException e) { - throw new ServletException(e); - } + AppIdentifier appIdentifier = this.getAppIdentifier(req); try { SessionInformationHolder sessionInfo = getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v2_21) ? - Session.regenerateToken(this.getAppIdentifierWithStorage(req), main, accessToken, userDataInJWT) : - Session.regenerateTokenBeforeCDI2_21(appIdentifierWithStorage, main, accessToken, + Session.regenerateToken(appIdentifier, main, accessToken, userDataInJWT) : + Session.regenerateTokenBeforeCDI2_21(appIdentifier, main, accessToken, userDataInJWT); JsonObject result = sessionInfo.toJsonObject(); @@ -98,7 +94,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I UnsupportedJWTSigningAlgorithmException | TenantOrAppNotFoundException e) { throw new ServletException(e); } catch (UnauthorisedException | TryRefreshTokenException e) { - Logging.debug(main, appIdentifierWithStorage.getAsPublicTenantIdentifier(), + Logging.debug(main, appIdentifier.getAsPublicTenantIdentifier(), Utils.exceptionStacktraceToString(e)); JsonObject reply = new JsonObject(); reply.addProperty("status", "UNAUTHORISED"); diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java index 22fba74cf..1beeec007 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java @@ -102,18 +102,18 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String[] sessionHandlesRevoked; if (revokeAcrossAllTenants) { sessionHandlesRevoked = Session.revokeAllSessionsForUser( - main, this.getAppIdentifierWithStorage(req), userId, revokeSessionsForLinkedAccounts); + main, this.getTenantStorage(req).toAppIdentifierWithStorage(), userId, revokeSessionsForLinkedAccounts); } else { sessionHandlesRevoked = Session.revokeAllSessionsForUser( - main, this.getTenantIdentifierWithStorageFromRequest(req), userId, + main, this.getTenantStorage(req), userId, revokeSessionsForLinkedAccounts); } - if (StorageLayer.getStorage(this.getTenantIdentifierWithStorageFromRequest(req), main).getType() == + if (StorageLayer.getStorage(this.getTenantStorage(req), main).getType() == STORAGE_TYPE.SQL) { try { UserIdMapping userIdMapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( - this.getAppIdentifierWithStorage(req), + this.getTenantStorage(req).toAppIdentifierWithStorage(), userId, UserIdType.ANY); if (userIdMapping != null) { ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, @@ -138,7 +138,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } else { try { String[] sessionHandlesRevoked = Session.revokeSessionUsingSessionHandles(main, - this.getAppIdentifierWithStorage(req), sessionHandles); + this.getTenantStorage(req).toAppIdentifierWithStorage(), sessionHandles); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); JsonArray sessionHandlesRevokedJSON = new JsonArray(); diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java index e31c32ee1..bb5ccd837 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java @@ -69,10 +69,10 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO String[] sessionHandles; if (fetchAcrossAllTenants) { sessionHandles = Session.getAllNonExpiredSessionHandlesForUser( - main, this.getAppIdentifierWithStorage(req), userId, fetchSessionsForAllLinkedAccounts); + main, this.getTenantStorage(req).toAppIdentifierWithStorage(), userId, fetchSessionsForAllLinkedAccounts); } else { sessionHandles = Session.getAllNonExpiredSessionHandlesForUser( - this.getTenantIdentifierWithStorageFromRequest(req), userId, fetchSessionsForAllLinkedAccounts); + this.getTenantStorage(req), userId, fetchSessionsForAllLinkedAccounts); } JsonObject result = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/session/VerifySessionAPI.java b/src/main/java/io/supertokens/webserver/api/session/VerifySessionAPI.java index 8b3fd7d84..4286afb9c 100644 --- a/src/main/java/io/supertokens/webserver/api/session/VerifySessionAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/VerifySessionAPI.java @@ -67,14 +67,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I Boolean enableAntiCsrf = InputParser.parseBooleanOrThrowError(input, "enableAntiCsrf", false); assert enableAntiCsrf != null; - AppIdentifier appIdentifier; - try { - // We actually don't use the storage because tenantId is obtained from the accessToken, - // and appropriate storage is obtained later - appIdentifier = this.getAppIdentifierWithStorage(req); - } catch (TenantOrAppNotFoundException e) { - throw new ServletException(e); - } + AppIdentifier appIdentifier = this.getAppIdentifier(req); try { @@ -135,7 +128,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I reply.addProperty("jwtSigningPublicKeyExpiryTime", SigningKeys.getInstance(appIdentifier, main).getDynamicSigningKeyExpiryTime()); - Utils.addLegacySigningKeyInfos(this.getAppIdentifierWithStorage(req), main, reply, + Utils.addLegacySigningKeyInfos(this.getAppIdentifier(req), main, reply, super.getVersionFromRequest(req).betweenInclusive(SemVer.v2_9, SemVer.v2_21)); } diff --git a/src/main/java/io/supertokens/webserver/api/thirdparty/GetUsersByEmailAPI.java b/src/main/java/io/supertokens/webserver/api/thirdparty/GetUsersByEmailAPI.java index 391db2c70..d880a9686 100644 --- a/src/main/java/io/supertokens/webserver/api/thirdparty/GetUsersByEmailAPI.java +++ b/src/main/java/io/supertokens/webserver/api/thirdparty/GetUsersByEmailAPI.java @@ -28,7 +28,6 @@ import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.thirdparty.ThirdParty; import io.supertokens.useridmapping.UserIdMapping; -import io.supertokens.useridmapping.UserIdType; import io.supertokens.utils.SemVer; import io.supertokens.utils.Utils; import io.supertokens.webserver.InputParser; @@ -56,9 +55,9 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // this API is tenant specific try { - TenantIdentifierWithStorage tenantIdentifierWithStorage = this.getTenantIdentifierWithStorageFromRequest( + TenantIdentifierWithStorage tenantIdentifierWithStorage = this.getTenantStorage( req); - AppIdentifierWithStorage appIdentifierWithStorage = this.getAppIdentifierWithStorage(req); + AppIdentifierWithStorage appIdentifierWithStorage = tenantIdentifierWithStorage.toAppIdentifierWithStorage(); String email = InputParser.getQueryParamOrThrowError(req, "email", false); email = Utils.normaliseEmail(email); diff --git a/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java b/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java index 34a70df28..4e47b6303 100644 --- a/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java +++ b/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java @@ -28,7 +28,6 @@ import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.thirdparty.ThirdParty; import io.supertokens.useridmapping.UserIdMapping; -import io.supertokens.useridmapping.UserIdType; import io.supertokens.utils.SemVer; import io.supertokens.utils.Utils; import io.supertokens.webserver.InputParser; @@ -76,10 +75,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { ThirdParty.SignInUpResponse response = ThirdParty.signInUp2_7( - this.getTenantIdentifierWithStorageFromRequest(req), super.main, + this.getTenantStorage(req), super.main, thirdPartyId, thirdPartyUserId, email, isEmailVerified); - UserIdMapping.populateExternalUserIdForUsers(this.getTenantIdentifierWithStorageFromRequest(req), new AuthRecipeUserInfo[]{response.user}); + UserIdMapping.populateExternalUserIdForUsers(this.getTenantStorage(req), new AuthRecipeUserInfo[]{response.user}); ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, response.user.getSupertokensUserId()); @@ -135,9 +134,9 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { ThirdParty.SignInUpResponse response = ThirdParty.signInUp( - this.getTenantIdentifierWithStorageFromRequest(req), super.main, thirdPartyId, thirdPartyUserId, + this.getTenantStorage(req), super.main, thirdPartyId, thirdPartyUserId, email, isEmailVerified); - UserIdMapping.populateExternalUserIdForUsers(this.getTenantIdentifierWithStorageFromRequest(req), new AuthRecipeUserInfo[]{response.user}); + UserIdMapping.populateExternalUserIdForUsers(this.getTenantStorage(req), new AuthRecipeUserInfo[]{response.user}); ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, response.user.getSupertokensUserId()); diff --git a/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java b/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java index 2ce566281..a819aeb6f 100644 --- a/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java @@ -19,6 +19,7 @@ import com.google.gson.JsonObject; import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; @@ -76,7 +77,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO // Query by userId try { AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = - this.getAppIdentifierWithStorageAndUserIdMappingFromRequest(req, userId, UserIdType.ANY); + this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the getUserUsingId function if (appIdentifierWithStorageAndUserIdMapping.userIdMapping != null) { userId = appIdentifierWithStorageAndUserIdMapping.userIdMapping.superTokensUserId; @@ -91,10 +92,10 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO // let the user be null } } else { - user = ThirdParty.getUser(this.getTenantIdentifierWithStorageFromRequest(req), thirdPartyId, + user = ThirdParty.getUser(this.getTenantStorage(req), thirdPartyId, thirdPartyUserId); if (user != null) { - UserIdMapping.populateExternalUserIdForUsers(getTenantIdentifierWithStorageFromRequest(req), new AuthRecipeUserInfo[]{user}); + UserIdMapping.populateExternalUserIdForUsers(getTenantStorage(req), new AuthRecipeUserInfo[]{user}); } } @@ -118,7 +119,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO super.sendJsonResponse(200, result, resp); } - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java index 3d1ad47aa..08dfdca21 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java @@ -4,6 +4,7 @@ import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -72,7 +73,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I // Try to find the appIdentifier with right storage based on the userId AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getAppIdentifierWithStorageAndUserIdMappingFromRequest( + getStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { @@ -80,8 +81,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; } catch (UnknownUserIdException e) { - // if the user is not found, just use the storage of the tenant of interest - appIdentifierWithStorage = getAppIdentifierWithStorage(req); + // if the user is not found, just use the public tenant storage + appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); } TOTPDevice device = Totp.registerDevice(appIdentifierWithStorage, main, userId, deviceName, skew, period); @@ -93,7 +94,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I result.addProperty("status", "DEVICE_ALREADY_EXISTS_ERROR"); super.sendJsonResponse(200, result, resp); } catch (StorageQueryException | NoSuchAlgorithmException | FeatureNotEnabledException | - TenantOrAppNotFoundException e) { + TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } @@ -127,7 +128,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO // Try to find the appIdentifier with right storage based on the userId AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getAppIdentifierWithStorageAndUserIdMappingFromRequest( + getStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { @@ -135,8 +136,8 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO } appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; } catch (UnknownUserIdException e) { - // if the user is not found, just use the storage of the tenant of interest - appIdentifierWithStorage = getAppIdentifierWithStorage(req); + // if the user is not found, just use the public storage + appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); } Totp.updateDeviceName(appIdentifierWithStorage, userId, existingDeviceName, newDeviceName); @@ -152,7 +153,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO } catch (DeviceAlreadyExistsException e) { result.addProperty("status", "DEVICE_ALREADY_EXISTS_ERROR"); super.sendJsonResponse(200, result, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java b/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java index 079daae94..7cc254c7a 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java @@ -4,6 +4,7 @@ import com.google.gson.JsonObject; import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -51,7 +52,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO // While sending the usage stats we do a join, so totp tables also must use internal user id. // Try to find the appIdentifier with right storage based on the userId - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = getAppIdentifierWithStorageAndUserIdMappingFromRequest( + AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = getStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { @@ -60,7 +61,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest - appIdentifierWithStorage = getAppIdentifierWithStorage(req); + appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); } TOTPDevice[] devices = Totp.getDevices(appIdentifierWithStorage, @@ -83,7 +84,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } catch (TotpNotEnabledException e) { result.addProperty("status", "TOTP_NOT_ENABLED_ERROR"); super.sendJsonResponse(200, result, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java index df3ea4801..b4eac5b5a 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java @@ -3,6 +3,7 @@ import com.google.gson.JsonObject; import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -58,7 +59,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I // Try to find the appIdentifier with right storage based on the userId AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getAppIdentifierWithStorageAndUserIdMappingFromRequest( + getStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { @@ -67,7 +68,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest - appIdentifierWithStorage = getAppIdentifierWithStorage(req); + appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); } Totp.removeDevice(appIdentifierWithStorage, userId, deviceName); @@ -82,7 +83,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I result.addProperty("status", "OK"); result.addProperty("didDeviceExist", false); super.sendJsonResponse(200, result, resp); - } catch (StorageQueryException | StorageTransactionLogicException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | StorageTransactionLogicException | TenantOrAppNotFoundException | + BadPermissionException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java index 7d3980d99..6e3916672 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java @@ -4,7 +4,6 @@ import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; import io.supertokens.TenantIdentifierWithStorageAndUserIdMapping; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; @@ -12,11 +11,9 @@ import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException; -import io.supertokens.pluginInterface.useridmapping.UserIdMapping; import io.supertokens.totp.Totp; import io.supertokens.totp.exceptions.InvalidTotpException; import io.supertokens.totp.exceptions.LimitReachedException; @@ -64,7 +61,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I // This step is required only because user_last_active table stores supertokens internal user id. // While sending the usage stats we do a join, so totp tables also must use internal user id. - TenantIdentifierWithStorageAndUserIdMapping mappingAndStorage = getTenantIdentifierWithStorageAndUserIdMappingFromRequest( + TenantIdentifierWithStorageAndUserIdMapping mappingAndStorage = getStorageAndUserIdMappingForTenantSpecificApi( req, userId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { @@ -73,7 +70,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I tenantIdentifierWithStorage = mappingAndStorage.tenantIdentifierWithStorage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest - tenantIdentifierWithStorage = getTenantIdentifierWithStorageFromRequest(req); + tenantIdentifierWithStorage = getTenantStorage(req); } Totp.verifyCode(tenantIdentifierWithStorage, main, userId, totp, allowUnverifiedDevices); diff --git a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java index a068e07e4..b15e86d32 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java @@ -14,7 +14,6 @@ import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException; import io.supertokens.pluginInterface.totp.exception.UnknownDeviceException; -import io.supertokens.pluginInterface.useridmapping.UserIdMapping; import io.supertokens.totp.Totp; import io.supertokens.totp.exceptions.InvalidTotpException; import io.supertokens.totp.exceptions.LimitReachedException; @@ -64,7 +63,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I // This step is required only because user_last_active table stores supertokens internal user id. // While sending the usage stats we do a join, so totp tables also must use internal user id. - TenantIdentifierWithStorageAndUserIdMapping mappingAndStorage = getTenantIdentifierWithStorageAndUserIdMappingFromRequest( + TenantIdentifierWithStorageAndUserIdMapping mappingAndStorage = getStorageAndUserIdMappingForTenantSpecificApi( req, userId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { @@ -73,7 +72,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I tenantIdentifierWithStorage = mappingAndStorage.tenantIdentifierWithStorage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest - tenantIdentifierWithStorage = getTenantIdentifierWithStorageFromRequest(req); + tenantIdentifierWithStorage = getTenantStorage(req); } boolean isNewlyVerified = Totp.verifyDevice(tenantIdentifierWithStorage, main, userId, deviceName, totp); diff --git a/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java b/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java index 26d71902f..1200a4ddd 100644 --- a/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java +++ b/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java @@ -18,6 +18,7 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; @@ -85,7 +86,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = - this.getAppIdentifierWithStorageAndUserIdMappingFromRequest(req, userId, userIdType); + this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType); boolean didMappingExist = UserIdMapping.deleteUserIdMapping( appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, userId, userIdType, force); @@ -94,7 +95,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I response.addProperty("didMappingExist", didMappingExist); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } catch (UnknownUserIdException e) { diff --git a/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java b/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java index e1cae3fae..d8896a7ee 100644 --- a/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java +++ b/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java @@ -18,6 +18,7 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; @@ -94,7 +95,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO try { AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = - this.getAppIdentifierWithStorageAndUserIdMappingFromRequest(req, userId, userIdType); + this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType); if (UserIdMapping.updateOrDeleteExternalUserIdInfo( appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, userId, userIdType, externalUserIdInfo)) { @@ -108,7 +109,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO response.addProperty("status", "UNKNOWN_MAPPING_ERROR"); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } catch (UnknownUserIdException e) { diff --git a/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java b/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java index 2afc24650..1756ba315 100644 --- a/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java +++ b/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java @@ -18,6 +18,7 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; @@ -94,10 +95,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = - this.getAppIdentifierWithStorageAndUserIdMappingFromRequest(req, superTokensUserId, UserIdType.SUPERTOKENS); - - UserIdMapping.createUserIdMapping(main, appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, + UserIdMapping.createUserIdMapping(enforcePublicTenantAndGetAllStoragesForApp(req), superTokensUserId, externalUserId, externalUserIdInfo, force, getVersionFromRequest(req).greaterThanOrEqualTo( SemVer.v4_0)); @@ -105,7 +103,7 @@ superTokensUserId, externalUserId, externalUserIdInfo, force, getVersionFromRequ response.addProperty("status", "OK"); super.sendJsonResponse(200, response, resp); - } catch (UnknownSuperTokensUserIdException | UnknownUserIdException e) { + } catch (UnknownSuperTokensUserIdException e) { JsonObject response = new JsonObject(); response.addProperty("status", "UNKNOWN_SUPERTOKENS_USER_ID_ERROR"); super.sendJsonResponse(200, response, resp); @@ -117,7 +115,7 @@ superTokensUserId, externalUserId, externalUserIdInfo, force, getVersionFromRequ response.addProperty("doesExternalUserIdExist", e.doesExternalUserIdExist); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } @@ -164,7 +162,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO // Request from (app1, tenant3) may result in either user1 or user2 AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = - this.getAppIdentifierWithStorageAndUserIdMappingFromRequest(req, userId, userIdType); + this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType); if (appIdentifierWithStorageAndUserIdMapping.userIdMapping == null) { JsonObject response = new JsonObject(); @@ -185,7 +183,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } catch (UnknownUserIdException e) { diff --git a/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java b/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java index 174d0da91..4ef1bc926 100644 --- a/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java @@ -17,10 +17,15 @@ package io.supertokens.webserver.api.usermetadata; import com.google.gson.JsonObject; +import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.useridmapping.UserIdType; import io.supertokens.usermetadata.UserMetadata; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.WebserverAPI; @@ -48,11 +53,20 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String userId = InputParser.parseStringOrThrowError(input, "userId", false); try { - UserMetadata.deleteUserMetadata(this.getAppIdentifierWithStorage(req), userId); + try { + AppIdentifierWithStorageAndUserIdMapping appIdStorageAndMapping = + this.getStorageAndUserIdMappingForAppSpecificApi( + req, userId, UserIdType.ANY); + UserMetadata.deleteUserMetadata(appIdStorageAndMapping.appIdentifierWithStorage, userId); + } catch (UnknownUserIdException e) { + AppIdentifierWithStorage appIdentifierWithStorage = this.enforcePublicTenantAndGetPublicTenantStorage(req); + UserMetadata.deleteUserMetadata(appIdentifierWithStorage, userId); + } + JsonObject response = new JsonObject(); response.addProperty("status", "OK"); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java b/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java index 9586c3a37..022e41f07 100644 --- a/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java @@ -17,11 +17,16 @@ package io.supertokens.webserver.api.usermetadata; import com.google.gson.JsonObject; +import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; +import io.supertokens.useridmapping.UserIdType; import io.supertokens.usermetadata.UserMetadata; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.WebserverAPI; @@ -48,12 +53,22 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO // API is app specific String userId = InputParser.getQueryParamOrThrowError(req, "userId", false); try { - JsonObject metadata = UserMetadata.getUserMetadata(this.getAppIdentifierWithStorage(req), userId); + JsonObject metadata; + try { + AppIdentifierWithStorageAndUserIdMapping appIdStorageAndMapping = + this.getStorageAndUserIdMappingForAppSpecificApi( + req, userId, UserIdType.ANY); + metadata = UserMetadata.getUserMetadata(appIdStorageAndMapping.appIdentifierWithStorage, userId); + } catch (UnknownUserIdException e) { + AppIdentifierWithStorage appIdentifierWithStorage = this.enforcePublicTenantAndGetPublicTenantStorage(req); + metadata = UserMetadata.getUserMetadata(appIdentifierWithStorage, userId); + } + JsonObject response = new JsonObject(); response.add("metadata", metadata); response.addProperty("status", "OK"); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } @@ -65,12 +80,24 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO String userId = InputParser.parseStringOrThrowError(input, "userId", false); JsonObject update = InputParser.parseJsonObjectOrThrowError(input, "metadataUpdate", false); try { - JsonObject metadata = UserMetadata.updateUserMetadata(this.getAppIdentifierWithStorage(req), userId, update); + JsonObject metadata; + + try { + AppIdentifierWithStorageAndUserIdMapping appIdStorageAndMapping = + this.getStorageAndUserIdMappingForAppSpecificApi( + req, userId, UserIdType.ANY); + metadata = UserMetadata.updateUserMetadata(appIdStorageAndMapping.appIdentifierWithStorage, userId, + update); + } catch (UnknownUserIdException e) { + AppIdentifierWithStorage appIdentifierWithStorage = this.enforcePublicTenantAndGetPublicTenantStorage(req); + metadata = UserMetadata.updateUserMetadata(appIdentifierWithStorage, userId, update); + } + JsonObject response = new JsonObject(); response.add("metadata", metadata); response.addProperty("status", "OK"); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | StorageTransactionLogicException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | StorageTransactionLogicException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java index 92e88357c..973848e1f 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java @@ -61,7 +61,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO try { boolean didUserAlreadyHaveRole = !UserRoles.addRoleToUser( - this.getTenantIdentifierWithStorageFromRequest(req), userId, role); + this.getTenantStorage(req), userId, role); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); response.addProperty("didUserAlreadyHaveRole", didUserAlreadyHaveRole); diff --git a/src/main/java/io/supertokens/webserver/api/userroles/CreateRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/CreateRoleAPI.java index c24d88e14..082969848 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/CreateRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/CreateRoleAPI.java @@ -19,6 +19,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -81,14 +82,15 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO try { boolean createdNewRole = UserRoles.createNewRoleOrModifyItsPermissions( - this.getAppIdentifierWithStorage(req), role, permissions); + this.enforcePublicTenantAndGetPublicTenantStorage(req), role, permissions); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); response.addProperty("createdNewRole", createdNewRole); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | StorageTransactionLogicException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | StorageTransactionLogicException | TenantOrAppNotFoundException | + BadPermissionException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/userroles/GetPermissionsForRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/GetPermissionsForRoleAPI.java index 38973448e..e20641b51 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/GetPermissionsForRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/GetPermissionsForRoleAPI.java @@ -20,6 +20,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -59,7 +60,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } try { - String[] permissions = UserRoles.getPermissionsForRole(this.getAppIdentifierWithStorage(req), role); + String[] permissions = UserRoles.getPermissionsForRole(this.enforcePublicTenantAndGetPublicTenantStorage(req), role); JsonArray arr = new JsonArray(); for (String permission : permissions) { arr.add(new JsonPrimitive(permission)); @@ -72,7 +73,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject response = new JsonObject(); response.addProperty("status", "UNKNOWN_ROLE_ERROR"); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/userroles/GetRolesAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/GetRolesAPI.java index 1519a746e..20ba99bc9 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/GetRolesAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/GetRolesAPI.java @@ -20,6 +20,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -50,7 +51,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO // API is app specific try { - String[] roles = UserRoles.getRoles(this.getAppIdentifierWithStorage(req)); + String[] roles = UserRoles.getRoles(this.enforcePublicTenantAndGetPublicTenantStorage(req)); JsonArray arr = new JsonArray(); for (String s : roles) { @@ -62,7 +63,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO response.addProperty("status", "OK"); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForPermissionAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForPermissionAPI.java index e2e295f3b..df64526d6 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForPermissionAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForPermissionAPI.java @@ -20,6 +20,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -60,7 +61,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { - String[] roles = UserRoles.getRolesThatHavePermission(this.getAppIdentifierWithStorage(req), permission); + String[] roles = UserRoles.getRolesThatHavePermission(this.enforcePublicTenantAndGetPublicTenantStorage(req), permission); JsonArray arr = new JsonArray(); for (String s : roles) { @@ -72,7 +73,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO response.addProperty("status", "OK"); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForUserAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForUserAPI.java index d4efe7c93..2f0e52c42 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForUserAPI.java @@ -52,7 +52,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO String userId = InputParser.getQueryParamOrThrowError(req, "userId", false); try { - String[] userRoles = UserRoles.getRolesForUser(this.getTenantIdentifierWithStorageFromRequest(req), + String[] userRoles = UserRoles.getRolesForUser(this.getTenantStorage(req), userId); JsonArray arr = new JsonArray(); for (String s : userRoles) { diff --git a/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java index 47e0901bc..655ac5d7b 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java @@ -61,7 +61,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { - String[] roleUsers = UserRoles.getUsersForRole(this.getTenantIdentifierWithStorageFromRequest(req), role); + String[] roleUsers = UserRoles.getUsersForRole(this.getTenantStorage(req), role); JsonArray arr = new JsonArray(); for (String s : roleUsers) { diff --git a/src/main/java/io/supertokens/webserver/api/userroles/RemovePermissionsForRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/RemovePermissionsForRoleAPI.java index ca0b19f3f..0c68d365d 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/RemovePermissionsForRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/RemovePermissionsForRoleAPI.java @@ -19,6 +19,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -80,11 +81,12 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - UserRoles.deletePermissionsFromRole(this.getAppIdentifierWithStorage(req), role, permissions); + UserRoles.deletePermissionsFromRole(this.enforcePublicTenantAndGetPublicTenantStorage(req), role, permissions); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | StorageTransactionLogicException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | StorageTransactionLogicException | TenantOrAppNotFoundException | + BadPermissionException e) { throw new ServletException(e); } catch (UnknownRoleException e) { JsonObject response = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java index fe5914bda..b49446b04 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java @@ -18,6 +18,7 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -57,13 +58,13 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - boolean didRoleExist = UserRoles.deleteRole(this.getAppIdentifierWithStorage(req), role); + boolean didRoleExist = UserRoles.deleteRole(this.enforcePublicTenantAndGetPublicTenantStorage(req), role); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); response.addProperty("didRoleExist", didRoleExist); super.sendJsonResponse(200, response, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java index 38a13d0ad..6c40b6f6f 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java @@ -60,7 +60,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - boolean didUserHaveRole = UserRoles.removeUserRole(this.getTenantIdentifierWithStorageFromRequest(req), + boolean didUserHaveRole = UserRoles.removeUserRole(this.getTenantStorage(req), userId, role); JsonObject response = new JsonObject(); diff --git a/src/test/java/io/supertokens/test/HelloAPITest.java b/src/test/java/io/supertokens/test/HelloAPITest.java index 61049ff3e..c337208e6 100644 --- a/src/test/java/io/supertokens/test/HelloAPITest.java +++ b/src/test/java/io/supertokens/test/HelloAPITest.java @@ -144,7 +144,6 @@ public void testHelloAPIWithBasePath3() throws Exception { "http://localhost:3567/hello/hello/", // baseUrl + (hello tenant) + / : works because the hello api doesn't check if that tenant exists "http://localhost:3567/hello/appid-hello/hello", // baseUrl + app + /hello "http://localhost:3567/hello/appid-hello/hello/", // baseUrl + app + /hello - "http://localhost:3567/hello/appid-hello/test/hello", // baseUrl + app + tenant + /hello }; for (String helloUrl: HELLO_ROUTES) { @@ -160,11 +159,11 @@ public void testHelloAPIWithBasePath3() throws Exception { "http://localhost:3567/hello/appid-hello", // baseUrl + app + / "http://localhost:3567/hello/appid-hello/", // baseUrl + app + / "http://localhost:3567/hello/appid-hello/test", // baseUrl + app + tenant + / - "http://localhost:3567/hello/appid-hello/test/", // baseUrl + app + tenant + / }; // Not found for (String notFoundUrl : NOT_FOUND_ROUTES) { + System.out.println(notFoundUrl); try { String res = HttpRequestForTesting.sendGETRequest(process.getProcess(), "", notFoundUrl, null, 1000, 1000, @@ -175,6 +174,23 @@ public void testHelloAPIWithBasePath3() throws Exception { } } + String[] BAD_PERMISSION_ROUTES = new String[]{ + "http://localhost:3567/hello/appid-hello/test/hello", // baseUrl + app + tenant + /hello + "http://localhost:3567/hello/appid-hello/test/", // baseUrl + app + tenant + / + }; + + // Bad permission + for (String badPermUrl : BAD_PERMISSION_ROUTES) { + try { + String res = HttpRequestForTesting.sendGETRequest(process.getProcess(), "", + badPermUrl, null, 1000, 1000, + null, Utils.getCdiVersionStringLatestForTests(), ""); + fail(); + } catch (HttpResponseException e) { + assertEquals(403, e.statusCode); + } + } + process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); } @@ -227,7 +243,6 @@ public void testWithBasePathThatHelloAPIDoesNotRequireAPIKeys() throws Exception "http://localhost:3567/hello/hello/", // baseUrl + (hello tenant) + / : works because the hello api doesn't check if that tenant exists "http://localhost:3567/hello/appid-hello/hello", // baseUrl + app + /hello "http://localhost:3567/hello/appid-hello/hello/", // baseUrl + app + /hello - "http://localhost:3567/hello/appid-hello/test/hello", // baseUrl + app + tenant + /hello }; for (String helloUrl: HELLO_ROUTES) { @@ -245,7 +260,6 @@ public void testWithBasePathThatHelloAPIDoesNotRequireAPIKeys() throws Exception "http://localhost:3567/hello/appid-hello", // baseUrl + app + / "http://localhost:3567/hello/appid-hello/", // baseUrl + app + / "http://localhost:3567/hello/appid-hello/test", // baseUrl + app + tenant + / - "http://localhost:3567/hello/appid-hello/test/", // baseUrl + app + tenant + / }; // Not found @@ -260,6 +274,23 @@ public void testWithBasePathThatHelloAPIDoesNotRequireAPIKeys() throws Exception } } + String[] BAD_PERMISSION_ROUTES = new String[]{ + "http://localhost:3567/hello/appid-hello/test/hello", // baseUrl + app + tenant + /hello + "http://localhost:3567/hello/appid-hello/test/", // baseUrl + app + tenant + / + }; + + // Bad permission + for (String badPermUrl : BAD_PERMISSION_ROUTES) { + try { + String res = HttpRequestForTesting.sendGETRequest(process.getProcess(), "", + badPermUrl, null, 1000, 1000, + null, Utils.getCdiVersionStringLatestForTests(), ""); + fail(); + } catch (HttpResponseException e) { + assertEquals(403, e.statusCode); + } + } + process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); } @@ -311,7 +342,6 @@ public void testThatHelloAPIDoesNotRequireAPIKeys() throws Exception { "http://localhost:3567/hello/", // (hello tenant) + / : works because the hello api doesn't check if that tenant exists "http://localhost:3567/appid-hello/hello", // app + /hello "http://localhost:3567/appid-hello/hello/", // app + /hello - "http://localhost:3567/appid-hello/test/hello", // app + tenant + /hello }; for (String helloUrl: HELLO_ROUTES) { @@ -328,7 +358,6 @@ public void testThatHelloAPIDoesNotRequireAPIKeys() throws Exception { "http://localhost:3567/appid-hello", // app + / "http://localhost:3567/appid-hello/", // app + / "http://localhost:3567/appid-hello/test", // app + tenant + / - "http://localhost:3567/appid-hello/test/", // app + tenant + / }; // Not found diff --git a/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java b/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java index 80a6fbfe1..7d75a27b2 100644 --- a/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java +++ b/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java @@ -271,24 +271,27 @@ public void testGetUserUsingIdReturnsCorrectUser() { AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingId( - StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUserWithPriorityForTenantStorage( - process.getProcess(), new AppIdentifier(null, "a1"), storage, user1.getSupertokensUserId(), + StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + new AppIdentifierWithStorages(null, "a1", new Storage[]{storage}), + user1.getSupertokensUserId(), UserIdType.SUPERTOKENS).appIdentifierWithStorage, user1.getSupertokensUserId()); assertEquals(user1, userInfo); } { AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingId( - StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUserWithPriorityForTenantStorage( - process.getProcess(), new AppIdentifier(null, "a1"), storage, user2.getSupertokensUserId(), + StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + new AppIdentifierWithStorages(null, "a1", new Storage[]{storage}), + user2.getSupertokensUserId(), UserIdType.SUPERTOKENS).appIdentifierWithStorage, user2.getSupertokensUserId()); assertEquals(user2, userInfo); } { AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingId( - StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUserWithPriorityForTenantStorage( - process.getProcess(), new AppIdentifier(null, "a1"), storage, user3.getSupertokensUserId(), + StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + new AppIdentifierWithStorages(null, "a1", new Storage[]{storage}), + user3.getSupertokensUserId(), UserIdType.SUPERTOKENS).appIdentifierWithStorage, user3.getSupertokensUserId()); assertEquals(user3, userInfo); } @@ -381,18 +384,21 @@ public void testUpdatePasswordWorksCorrectlyAcrossAllTenants() Storage storage = StorageLayer.getStorage(process.getProcess()); EmailPassword.updateUsersEmailOrPassword( - StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUserWithPriorityForTenantStorage( - process.getProcess(), new AppIdentifier(null, "a1"), storage, user1.getSupertokensUserId(), + StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + new AppIdentifierWithStorages(null, "a1", new Storage[]{storage}), + user1.getSupertokensUserId(), UserIdType.SUPERTOKENS).appIdentifierWithStorage, process.getProcess(), user1.getSupertokensUserId(), null, "newpassword1"); EmailPassword.updateUsersEmailOrPassword( - StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUserWithPriorityForTenantStorage( - process.getProcess(), new AppIdentifier(null, "a1"), storage, user2.getSupertokensUserId(), + StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + new AppIdentifierWithStorages(null, "a1", new Storage[]{storage}), + user2.getSupertokensUserId(), UserIdType.SUPERTOKENS).appIdentifierWithStorage, process.getProcess(), user2.getSupertokensUserId(), null, "newpassword2"); EmailPassword.updateUsersEmailOrPassword( - StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUserWithPriorityForTenantStorage( - process.getProcess(), new AppIdentifier(null, "a1"), storage, user3.getSupertokensUserId(), + StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + new AppIdentifierWithStorages(null, "a1", new Storage[]{storage}), + user3.getSupertokensUserId(), UserIdType.SUPERTOKENS).appIdentifierWithStorage, process.getProcess(), user3.getSupertokensUserId(), null, "newpassword3"); diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestApp.java b/src/test/java/io/supertokens/test/multitenant/api/TestApp.java index b548ebb4c..8a2b117bc 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestApp.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestApp.java @@ -322,7 +322,7 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { try { - super.sendTextResponse(200, this.getAppIdentifierWithStorage(req).getAppId(), resp); + super.sendTextResponse(200, this.getTenantStorage(req).getAppId(), resp); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain.java b/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain.java index 8ca0855f1..a41b0487c 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain.java @@ -382,7 +382,7 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { try { - super.sendTextResponse(200, this.getAppIdentifierWithStorage(req).getConnectionUriDomain(), resp); + super.sendTextResponse(200, this.getTenantStorage(req).getConnectionUriDomain(), resp); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestLicenseBehaviour.java b/src/test/java/io/supertokens/test/multitenant/api/TestLicenseBehaviour.java index 09cc22754..ffcfd7964 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestLicenseBehaviour.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestLicenseBehaviour.java @@ -99,7 +99,7 @@ public void testAllowLicenseRemovalForCoreWithMultitenancy() throws Exception { // Sign up and get user info JsonObject userInfo = TestMultitenancyAPIHelper.epSignUp(new TenantIdentifier(null, "a1", "t1"), "user@example.com", "password", process.getProcess()); - JsonObject userInfo2 = TestMultitenancyAPIHelper.getEpUserById(new TenantIdentifier(null, "a1", "t1"), + JsonObject userInfo2 = TestMultitenancyAPIHelper.getEpUserById(new TenantIdentifier(null, "a1", null), userInfo.get("id").getAsString(), process.getProcess()); assertEquals(userInfo, userInfo2); } diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java b/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java index 119672092..17297da0d 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java @@ -434,4 +434,40 @@ public static void createUserIdMapping(TenantIdentifier tenantIdentifier, String SemVer.v3_0.get(), "useridmapping"); assertEquals("OK", response.get("status").getAsString()); } + + public static JsonObject getUserById(TenantIdentifier tenantIdentifier, String userId, Main main) + throws HttpResponseException, IOException { + Map params = new HashMap<>(); + params.put("userId", userId); + JsonObject response = HttpRequestForTesting.sendGETRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/user/id"), + params, 1000, 1000, null, + WebserverAPI.getLatestCDIVersion().get(), ""); + return response; + } + + public static JsonObject updateUserMetadata(TenantIdentifier tenantIdentifier, String userId, JsonObject metadata, + Main main) + throws HttpResponseException, IOException { + JsonObject requestBody = new JsonObject(); + requestBody.addProperty("userId", userId); + requestBody.add("metadataUpdate", metadata); + JsonObject resp = HttpRequestForTesting.sendJsonPUTRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/user/metadata"), + requestBody, 1000, 1000, null, + WebserverAPI.getLatestCDIVersion().get(), "usermetadata"); + return resp; + } + + public static JsonObject removeMetadata(TenantIdentifier tenantIdentifier, String userId, Main main) + throws HttpResponseException, IOException { + JsonObject requestBody = new JsonObject(); + requestBody.addProperty("userId", userId); + JsonObject resp = HttpRequestForTesting.sendJsonPOSTRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/user/metadata/remove"), + requestBody, 1000, 1000, null, + WebserverAPI.getLatestCDIVersion().get(), "usermetadata"); + + return resp; + } } diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestTenant.java b/src/test/java/io/supertokens/test/multitenant/api/TestTenant.java index b03ebd71c..e9959d242 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestTenant.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestTenant.java @@ -272,7 +272,7 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { try { - super.sendTextResponse(200, this.getTenantIdentifierWithStorageFromRequest(req).getTenantId(), resp); + super.sendTextResponse(200, this.getTenantStorage(req).getTenantId(), resp); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java b/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java index 9c86c127e..60ffd7a3e 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java @@ -429,7 +429,7 @@ public void testThatDisassociateUserWithUseridMappingFromWrongTenantDoesNotWork( "password", process.getProcess()); String userId = user.get("id").getAsString(); - TestMultitenancyAPIHelper.createUserIdMapping(new TenantIdentifier(null, "a1", "t1"), userId, "externalid", + TestMultitenancyAPIHelper.createUserIdMapping(new TenantIdentifier(null, "a1", null), userId, "externalid", process.getProcess()); JsonObject response = TestMultitenancyAPIHelper.disassociateUserFromTenant( @@ -449,7 +449,7 @@ public void testAssociateAndDisassociateWithUseridMapping() throws Exception { "password", process.getProcess()); String userId = user.get("id").getAsString(); - TestMultitenancyAPIHelper.createUserIdMapping(new TenantIdentifier(null, "a1", "t1"), userId, "externalid", + TestMultitenancyAPIHelper.createUserIdMapping(new TenantIdentifier(null, "a1", null), userId, "externalid", process.getProcess()); JsonObject response = TestMultitenancyAPIHelper.associateUserToTenant(new TenantIdentifier(null, "a1", "t2"), @@ -475,7 +475,7 @@ public void testDisassociateUserWithUserIdMappingAndSession() throws Exception { "password", process.getProcess()); String userId = user.get("id").getAsString(); - TestMultitenancyAPIHelper.createUserIdMapping(new TenantIdentifier(null, "a1", "t1"), userId, "externalid", + TestMultitenancyAPIHelper.createUserIdMapping(new TenantIdentifier(null, "a1", null), userId, "externalid", process.getProcess()); JsonObject response = TestMultitenancyAPIHelper.associateUserToTenant(new TenantIdentifier(null, "a1", "t2"), diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java b/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java new file mode 100644 index 000000000..dd0bad0c3 --- /dev/null +++ b/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2024, 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.JsonObject; +import io.supertokens.ProcessState; +import io.supertokens.emailpassword.EmailPassword; +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.authRecipe.AuthRecipeUserInfo; +import io.supertokens.pluginInterface.exceptions.InvalidConfigException; +import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; +import io.supertokens.pluginInterface.usermetadata.sqlStorage.UserMetadataSQLStorage; +import io.supertokens.storageLayer.StorageLayer; +import io.supertokens.test.TestingProcessManager; +import io.supertokens.test.Utils; +import io.supertokens.test.httpRequest.HttpResponseException; +import io.supertokens.thirdparty.InvalidProviderConfigException; +import io.supertokens.useridmapping.UserIdMapping; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.*; + +public class TestWithNonAuthRecipes { + 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, HttpResponseException { + 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)); + + JsonObject config = new JsonObject(); + StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 1); + TestMultitenancyAPIHelper.createTenant(process.getProcess(), TenantIdentifier.BASE_TENANT, "t1", true, true, + true, config); + StorageLayer.getBaseStorage(process.getProcess()).modifyConfigToAddANewUserPoolForTesting(config, 2); + TestMultitenancyAPIHelper.createTenant(process.getProcess(), TenantIdentifier.BASE_TENANT, "t2", true, true, + true, config); + } + + @Test + public void testThatUserMetadataIsSavedInTheStorageWhereUserExists() throws Exception { + TenantIdentifier t0 = new TenantIdentifier(null, null, null); + TenantIdentifierWithStorage t0WithStorage = t0.withStorage(StorageLayer.getStorage(t0, process.getProcess())); + + TenantIdentifier t1 = new TenantIdentifier(null, null, "t1"); + TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); + + // Create users + AuthRecipeUserInfo user1 = EmailPassword.signUp(t0WithStorage, process.getProcess(), "test@example.com", "password123"); + AuthRecipeUserInfo user2 = EmailPassword.signUp(t1WithStorage, process.getProcess(), "test@example.com", "password123"); + + UserIdMapping.populateExternalUserIdForUsers(t0WithStorage, new AuthRecipeUserInfo[]{user1}); + UserIdMapping.populateExternalUserIdForUsers(t1WithStorage, new AuthRecipeUserInfo[]{user2}); + + // Check that get user by ID works fine + JsonObject jsonUser1 = TestMultitenancyAPIHelper.getUserById(t0, user1.getSupertokensUserId(), process.getProcess()); + assertEquals(user1.toJson(), jsonUser1.get("user").getAsJsonObject()); + + JsonObject jsonUser2 = TestMultitenancyAPIHelper.getUserById(t0, user2.getSupertokensUserId(), process.getProcess()); + assertEquals(user2.toJson(), jsonUser2.get("user").getAsJsonObject()); + + JsonObject metadata = new JsonObject(); + metadata.addProperty("key", "value"); + + { + // Add metadata for user2 using t0 and ensure get user works fine + TestMultitenancyAPIHelper.updateUserMetadata(t0, user2.getSupertokensUserId(), metadata, process.getProcess()); + + jsonUser2 = TestMultitenancyAPIHelper.getUserById(t0, user2.getSupertokensUserId(), process.getProcess()); + assertEquals(user2.toJson(), jsonUser2.get("user").getAsJsonObject()); + + try { + TestMultitenancyAPIHelper.getUserById(t1, user2.getSupertokensUserId(), + process.getProcess()); + fail(); + } catch (HttpResponseException e) { + assertEquals(403, e.statusCode); + } + } + + { // Add metadata using t1 results in 403 + try { + TestMultitenancyAPIHelper.updateUserMetadata(t1, user1.getSupertokensUserId(), metadata, process.getProcess()); + fail(); + } catch (HttpResponseException e) { + assertEquals(403, e.statusCode); + } + } + + { + // Add metadata for user1 using t0 and ensure get user works fine + TestMultitenancyAPIHelper.updateUserMetadata(t0, user1.getSupertokensUserId(), metadata, process.getProcess()); + + jsonUser1 = TestMultitenancyAPIHelper.getUserById(t0, user1.getSupertokensUserId(), process.getProcess()); + assertEquals(user1.toJson(), jsonUser1.get("user").getAsJsonObject()); + + try { + TestMultitenancyAPIHelper.getUserById(t1, user1.getSupertokensUserId(), process.getProcess()); + fail(); + } catch (HttpResponseException e) { + assertEquals(403, e.statusCode); + } + } + + UserMetadataSQLStorage t0UserMetadataStorage = t0WithStorage.toAppIdentifierWithStorage() + .getUserMetadataStorage(); + UserMetadataSQLStorage t1UserMetadataStorage = t1WithStorage.toAppIdentifierWithStorage() + .getUserMetadataStorage(); + + // Ensure that the metadata is saved in the correct storage + assertNotNull(t0UserMetadataStorage.getUserMetadata(t0.toAppIdentifier(), user1.getSupertokensUserId())); // ensure t0 storage does not have user2's metadata + assertNotNull(t1UserMetadataStorage.getUserMetadata(t0.toAppIdentifier(), user2.getSupertokensUserId())); // ensure t1 storage does not have user1's metadata + + // Ensure that the metadata is not stored in the wrong storage + assertNull(t0UserMetadataStorage.getUserMetadata(t0.toAppIdentifier(), user2.getSupertokensUserId())); // ensure t0 storage does not have user2's metadata + assertNull(t1UserMetadataStorage.getUserMetadata(t0.toAppIdentifier(), user1.getSupertokensUserId())); // ensure t1 storage does not have user1's metadata + + // Try deleting metadata + try { + TestMultitenancyAPIHelper.removeMetadata(t1, user1.getSupertokensUserId(), process.getProcess()); + fail(); + } catch (HttpResponseException e) { + assertEquals(403, e.statusCode); + } + TestMultitenancyAPIHelper.removeMetadata(t0, user1.getSupertokensUserId(), process.getProcess()); + TestMultitenancyAPIHelper.removeMetadata(t0, user2.getSupertokensUserId(), process.getProcess()); + assertNull(t0UserMetadataStorage.getUserMetadata(t0.toAppIdentifier(), user1.getSupertokensUserId())); // ensure t0 storage does not have user2's metadata + assertNull(t1UserMetadataStorage.getUserMetadata(t0.toAppIdentifier(), user2.getSupertokensUserId())); // ensure t1 storage does not have user1's metadata + } + + @Test + public void testThatUserRolesWorkWithDifferentTenantsOnDifferentStorages() throws Exception { + TenantIdentifier t0 = new TenantIdentifier(null, null, null); + TenantIdentifierWithStorage t0WithStorage = t0.withStorage(StorageLayer.getStorage(t0, process.getProcess())); + + TenantIdentifier t1 = new TenantIdentifier(null, null, "t1"); + TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); + + // Create users + AuthRecipeUserInfo user1 = EmailPassword.signUp(t0WithStorage, process.getProcess(), "test@example.com", "password123"); + AuthRecipeUserInfo user2 = EmailPassword.signUp(t1WithStorage, process.getProcess(), "test@example.com", "password123"); + + UserIdMapping.populateExternalUserIdForUsers(t0WithStorage, new AuthRecipeUserInfo[]{user1}); + UserIdMapping.populateExternalUserIdForUsers(t1WithStorage, new AuthRecipeUserInfo[]{user2}); + + + } +} diff --git a/src/test/java/io/supertokens/test/totp/api/MultitenantAPITest.java b/src/test/java/io/supertokens/test/totp/api/MultitenantAPITest.java index 3479cd320..e17b84ba9 100644 --- a/src/test/java/io/supertokens/test/totp/api/MultitenantAPITest.java +++ b/src/test/java/io/supertokens/test/totp/api/MultitenantAPITest.java @@ -18,6 +18,7 @@ import com.google.gson.JsonObject; import io.supertokens.ProcessState; +import io.supertokens.emailpassword.EmailPassword; import io.supertokens.featureflag.EE_FEATURES; import io.supertokens.featureflag.FeatureFlagTestContent; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; @@ -25,6 +26,7 @@ import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.multitenancy.exception.CannotModifyBaseConfigException; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.exceptions.InvalidConfigException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.*; @@ -45,8 +47,7 @@ import java.io.IOException; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.*; public class MultitenantAPITest { TestingProcessManager.TestingProcess process; @@ -104,7 +105,7 @@ private void createTenants() new TenantIdentifier(null, null, null), new TenantConfig( tenantIdentifier, - new EmailPasswordConfig(false), + new EmailPasswordConfig(true), new ThirdPartyConfig(false, null), new PasswordlessConfig(true), config @@ -124,7 +125,7 @@ private void createTenants() new TenantIdentifier(null, "a1", null), new TenantConfig( tenantIdentifier, - new EmailPasswordConfig(false), + new EmailPasswordConfig(true), new ThirdPartyConfig(false, null), new PasswordlessConfig(true), config @@ -144,7 +145,7 @@ private void createTenants() new TenantIdentifier(null, "a1", null), new TenantConfig( tenantIdentifier, - new EmailPasswordConfig(false), + new EmailPasswordConfig(true), new ThirdPartyConfig(false, null), new PasswordlessConfig(true), config @@ -240,18 +241,22 @@ private void validateTotp(TenantIdentifier tenantIdentifier, String userId, Stri } @Test - public void testDevicesWorkAppWide() throws Exception { + public void testCreateDeviceWorksFromPublicTenantOnly() throws Exception { if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { return; } - TenantIdentifier[] tenants = new TenantIdentifier[]{t1, t2, t3}; int userCount = 1; - for (TenantIdentifier tenant1 : tenants) { - createDevice(tenant1, "user" + userCount); + createDevice(t1, "user"); + createDeviceAlreadyExists(t1, "user"); - for (TenantIdentifier tenant2 : tenants) { - createDeviceAlreadyExists(tenant2, "user1"); + TenantIdentifier[] tenants = new TenantIdentifier[]{t2, t3}; + for (TenantIdentifier tenant1 : tenants) { + try { + createDevice(tenant1, "user" + userCount); + fail(); + } catch (HttpResponseException e) { + assertEquals(403, e.statusCode); } userCount++; @@ -267,16 +272,21 @@ public void testSameCodeUsedOnDifferentTenantsIsAllowed() throws Exception { TenantIdentifier[] tenants = new TenantIdentifier[]{t2, t3}; int userCount = 1; for (TenantIdentifier tenant1 : tenants) { - JsonObject deviceResponse = createDevice(tenant1, "user" + userCount); + AuthRecipeUserInfo user = EmailPassword.signUp( + tenant1.withStorage(StorageLayer.getStorage(tenant1, process.getProcess())), process.getProcess(), + "test@example.com", "password1"); + String userId = user.getSupertokensUserId(); + + JsonObject deviceResponse = createDevice(t1, userId); String secretKey = deviceResponse.get("secret").getAsString(); - TOTPDevice device = new TOTPDevice("user" + userCount, "d1", secretKey, 2, 1, true); + TOTPDevice device = new TOTPDevice(userId, "d1", secretKey, 2, 1, true); String validTotp = TOTPRecipeTest.generateTotpCode(process.getProcess(), device); - verifyDevice(tenant1, "user" + userCount, validTotp); + verifyDevice(tenant1, userId, validTotp); Thread.sleep(2500); // Wait for a new TOTP String validTotp2 = TOTPRecipeTest.generateTotpCode(process.getProcess(), device); for (TenantIdentifier tenant2 : tenants) { - validateTotp(tenant2, "user" + userCount, validTotp2); + validateTotp(tenant2, userId, validTotp2); } userCount++; diff --git a/src/test/java/io/supertokens/test/userIdMapping/api/MultitenantAPITest.java b/src/test/java/io/supertokens/test/userIdMapping/api/MultitenantAPITest.java index 942653763..1336e1d92 100644 --- a/src/test/java/io/supertokens/test/userIdMapping/api/MultitenantAPITest.java +++ b/src/test/java/io/supertokens/test/userIdMapping/api/MultitenantAPITest.java @@ -271,12 +271,12 @@ public void testUserIdMappingWorksCorrectlyAcrossTenants() throws Exception { user3.addProperty("externalUserId", "euserid3"); - for (TenantIdentifier createTenant: new TenantIdentifier[]{t1, t2, t3}) { + for (TenantIdentifier createTenant: new TenantIdentifier[]{t1}) { successfulCreateUserIdMapping(createTenant, user1.get("id").getAsString(), "euserid1"); successfulCreateUserIdMapping(createTenant, user2.get("id").getAsString(), "euserid2"); successfulCreateUserIdMapping(createTenant, user3.get("id").getAsString(), "euserid3"); - for (TenantIdentifier queryTenant : new TenantIdentifier[]{t1, t2, t3}) { + for (TenantIdentifier queryTenant : new TenantIdentifier[]{t1}) { for (JsonObject user : new JsonObject[]{user1, user2, user3}) { { JsonObject mapping = getUserIdMapping(queryTenant, user.get("id").getAsString(), "SUPERTOKENS"); @@ -328,8 +328,8 @@ public void testSameExternalIdIsDisallowedIrrespectiveOfUserPool() throws Except String externalUserId = "euserid" + (testcase++); - successfulCreateUserIdMapping(tx, user1.get("id").getAsString(), externalUserId); - mappingAlreadyExistsWithCreateUserIdMapping(ty, user2.get("id").getAsString(), externalUserId); + successfulCreateUserIdMapping(t1, user1.get("id").getAsString(), externalUserId); + mappingAlreadyExistsWithCreateUserIdMapping(t1, user2.get("id").getAsString(), externalUserId); } } } @@ -348,39 +348,35 @@ public void testRemoveMappingWorksAppWide() throws Exception { String externalUserId = "euserid" + userCount; user.addProperty("externalUserId", externalUserId); - for (TenantIdentifier tx : tenants) { - for (TenantIdentifier ty : tenants) { - { - successfulCreateUserIdMapping(tx, user.get("id").getAsString(), externalUserId); - getUserIdMapping(ty, user.get("id").getAsString(), "SUPERTOKENS"); - successfulRemoveUserIdMapping(ty, user.get("id").getAsString(), "SUPERTOKENS"); - getUnknownUserIdMapping(ty, user.get("id").getAsString(), "SUPERTOKENS"); - } - { - successfulCreateUserIdMapping(tx, user.get("id").getAsString(), externalUserId); - getUserIdMapping(ty, user.get("id").getAsString(), "ANY"); - successfulRemoveUserIdMapping(ty, user.get("id").getAsString(), "ANY"); - getUnknownUserIdMapping(ty, user.get("id").getAsString(), "ANY"); - } - { - successfulCreateUserIdMapping(tx, user.get("id").getAsString(), externalUserId); - getUserIdMapping(ty, user.get("externalUserId").getAsString(), "EXTERNAL"); - successfulRemoveUserIdMapping(ty, user.get("externalUserId").getAsString(), "EXTERNAL"); - getUnknownUserIdMapping(ty, user.get("externalUserId").getAsString(), "EXTERNAL"); - } - { - successfulCreateUserIdMapping(tx, user.get("id").getAsString(), externalUserId); - getUserIdMapping(ty, user.get("externalUserId").getAsString(), "ANY"); - successfulRemoveUserIdMapping(ty, user.get("externalUserId").getAsString(), "ANY"); - getUnknownUserIdMapping(ty, user.get("externalUserId").getAsString(), "ANY"); - } - } + { + successfulCreateUserIdMapping(t1, user.get("id").getAsString(), externalUserId); + getUserIdMapping(t1, user.get("id").getAsString(), "SUPERTOKENS"); + successfulRemoveUserIdMapping(t1, user.get("id").getAsString(), "SUPERTOKENS"); + getUnknownUserIdMapping(t1, user.get("id").getAsString(), "SUPERTOKENS"); + } + { + successfulCreateUserIdMapping(t1, user.get("id").getAsString(), externalUserId); + getUserIdMapping(t1, user.get("id").getAsString(), "ANY"); + successfulRemoveUserIdMapping(t1, user.get("id").getAsString(), "ANY"); + getUnknownUserIdMapping(t1, user.get("id").getAsString(), "ANY"); + } + { + successfulCreateUserIdMapping(t1, user.get("id").getAsString(), externalUserId); + getUserIdMapping(t1, user.get("externalUserId").getAsString(), "EXTERNAL"); + successfulRemoveUserIdMapping(t1, user.get("externalUserId").getAsString(), "EXTERNAL"); + getUnknownUserIdMapping(t1, user.get("externalUserId").getAsString(), "EXTERNAL"); + } + { + successfulCreateUserIdMapping(t1, user.get("id").getAsString(), externalUserId); + getUserIdMapping(t1, user.get("externalUserId").getAsString(), "ANY"); + successfulRemoveUserIdMapping(t1, user.get("externalUserId").getAsString(), "ANY"); + getUnknownUserIdMapping(t1, user.get("externalUserId").getAsString(), "ANY"); } } } @Test - public void testSameExternalIdAcrossUserPoolPrioritizesTenantOfInterest() throws Exception { + public void testSameExternalIdAcrossUserPoolJustReturnsOneOfThem() throws Exception { if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { return; } From d26731256927b05c904795d98e412cc4502b7748 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Thu, 29 Feb 2024 19:35:04 +0530 Subject: [PATCH 02/31] fix: user roles --- .../webserver/api/userroles/AddUserRoleAPI.java | 5 +++-- .../webserver/api/userroles/GetRolesForUserAPI.java | 6 +++--- .../webserver/api/userroles/GetUsersForRoleAPI.java | 7 ++++--- .../webserver/api/userroles/RemoveUserRoleAPI.java | 5 +++-- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java index 973848e1f..397091c47 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java @@ -48,7 +48,7 @@ public String getPath() { @Override protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - // API is tenant specific + // API is tenant specific, but uses public tenant storage JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String userId = InputParser.parseStringOrThrowError(input, "userId", false); String role = InputParser.parseStringOrThrowError(input, "role", false); @@ -61,7 +61,8 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO try { boolean didUserAlreadyHaveRole = !UserRoles.addRoleToUser( - this.getTenantStorage(req), userId, role); + this.getTenantStorage(req).withStorage(this.getPublicTenantStorage(req).getStorage()), + userId, role); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); response.addProperty("didUserAlreadyHaveRole", didUserAlreadyHaveRole); diff --git a/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForUserAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForUserAPI.java index 2f0e52c42..4ce961a6a 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForUserAPI.java @@ -48,11 +48,11 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - // API is tenant specific + // API is tenant specific, but using the public tenant storage String userId = InputParser.getQueryParamOrThrowError(req, "userId", false); try { - - String[] userRoles = UserRoles.getRolesForUser(this.getTenantStorage(req), + String[] userRoles = UserRoles.getRolesForUser( + this.getTenantStorage(req).withStorage(this.getPublicTenantStorage(req).getStorage()), userId); JsonArray arr = new JsonArray(); for (String s : userRoles) { diff --git a/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java index 655ac5d7b..6743f89c0 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java @@ -49,7 +49,7 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - // API is tenant specific + // API is tenant specific, but uses public tenant storage String role = InputParser.getQueryParamOrThrowError(req, "role", false); // normalize roles @@ -60,8 +60,9 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } try { - - String[] roleUsers = UserRoles.getUsersForRole(this.getTenantStorage(req), role); + String[] roleUsers = UserRoles.getUsersForRole( + this.getTenantStorage(req).withStorage(this.getPublicTenantStorage(req).getStorage()), + role); JsonArray arr = new JsonArray(); for (String s : roleUsers) { diff --git a/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java index 6c40b6f6f..4eb665fd9 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java @@ -48,7 +48,7 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - // API is tenant specific + // API is tenant specific, but uses public tenant storage JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String userId = InputParser.parseStringOrThrowError(input, "userId", false); String role = InputParser.parseStringOrThrowError(input, "role", false); @@ -60,7 +60,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - boolean didUserHaveRole = UserRoles.removeUserRole(this.getTenantStorage(req), + boolean didUserHaveRole = UserRoles.removeUserRole( + this.getTenantStorage(req).withStorage(this.getPublicTenantStorage(req).getStorage()), userId, role); JsonObject response = new JsonObject(); From 6b2a45ca5f7072267d6935b5046fc2d8ae3c3c40 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 1 Mar 2024 14:11:05 +0530 Subject: [PATCH 03/31] fix: half done --- src/main/java/io/supertokens/ActiveUsers.java | 28 +- ...ping.java => StorageAndUserIdMapping.java} | 12 +- ...IdentifierWithStorageAndUserIdMapping.java | 41 --- .../io/supertokens/authRecipe/AuthRecipe.java | 331 +++++++++--------- .../cronjobs/telemetry/Telemetry.java | 9 +- .../io/supertokens/dashboard/Dashboard.java | 142 ++++---- .../emailpassword/EmailPassword.java | 173 +++++---- .../java/io/supertokens/session/Session.java | 68 ++-- .../storageLayer/StorageLayer.java | 123 ++++--- .../useridmapping/UserIdMapping.java | 180 ++++------ .../usermetadata/UserMetadata.java | 31 +- .../io/supertokens/userroles/UserRoles.java | 123 +++---- .../supertokens/webserver/WebserverAPI.java | 52 +-- .../CanCreatePrimaryUserAPI.java | 23 +- .../accountlinking/CanLinkAccountsAPI.java | 33 +- .../accountlinking/CreatePrimaryUserAPI.java | 19 +- .../api/accountlinking/LinkAccountsAPI.java | 34 +- .../api/accountlinking/UnlinkAccountAPI.java | 15 +- .../api/core/ActiveUsersCountAPI.java | 3 +- .../webserver/api/core/ConfigAPI.java | 3 +- .../webserver/api/core/DeleteUserAPI.java | 8 +- .../webserver/api/core/EEFeatureFlagAPI.java | 7 +- .../webserver/api/core/GetUserByIdAPI.java | 15 +- .../webserver/api/core/HelloAPI.java | 10 +- .../webserver/api/core/LicenseKeyAPI.java | 13 +- .../api/core/ListUsersByAccountInfoAPI.java | 12 +- .../api/core/NotFoundOrHelloAPI.java | 15 +- .../webserver/api/core/RequestStatsAPI.java | 3 +- .../webserver/api/core/TelemetryAPI.java | 4 +- .../webserver/api/core/UsersAPI.java | 14 +- .../webserver/api/core/UsersCountAPI.java | 15 +- .../api/dashboard/DashboardSignInAPI.java | 3 +- .../api/dashboard/DashboardUserAPI.java | 25 +- .../GetDashboardSessionsForUserAPI.java | 3 +- .../api/dashboard/GetDashboardUsersAPI.java | 3 +- .../api/dashboard/RevokeSessionAPI.java | 3 +- .../VerifyDashboardUserSessionAPI.java | 10 +- .../ConsumeResetPasswordAPI.java | 18 +- .../GeneratePasswordResetTokenAPI.java | 18 +- .../ImportUserWithPasswordHashAPI.java | 8 +- .../api/emailpassword/ResetPasswordAPI.java | 14 +- .../api/emailpassword/SignInAPI.java | 17 +- .../api/emailpassword/SignUpAPI.java | 14 +- .../webserver/api/emailpassword/UserAPI.java | 36 +- .../useridmapping/RemoveUserIdMappingAPI.java | 7 +- .../UpdateExternalUserIdInfoAPI.java | 7 +- .../api/useridmapping/UserIdMappingAPI.java | 7 +- .../io/supertokens/test/PathRouterTest.java | 106 +++--- .../RequestConnectionUriDomainTest.java | 12 +- 49 files changed, 925 insertions(+), 945 deletions(-) rename src/main/java/io/supertokens/{AppIdentifierWithStorageAndUserIdMapping.java => StorageAndUserIdMapping.java} (69%) delete mode 100644 src/main/java/io/supertokens/TenantIdentifierWithStorageAndUserIdMapping.java diff --git a/src/main/java/io/supertokens/ActiveUsers.java b/src/main/java/io/supertokens/ActiveUsers.java index 7c4601958..1083d7077 100644 --- a/src/main/java/io/supertokens/ActiveUsers.java +++ b/src/main/java/io/supertokens/ActiveUsers.java @@ -1,19 +1,21 @@ package io.supertokens; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.authRecipe.sqlStorage.AuthRecipeSQLStorage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.storageLayer.StorageLayer; import org.jetbrains.annotations.TestOnly; public class ActiveUsers { - public static void updateLastActive(AppIdentifierWithStorage appIdentifierWithStorage, Main main, String userId) + public static void updateLastActive(AppIdentifier appIdentifier, Storage storage, String userId) throws TenantOrAppNotFoundException { try { - appIdentifierWithStorage.getActiveUsersStorage().updateLastActive(appIdentifierWithStorage, userId); + StorageUtils.getActiveUsersStorage(storage).updateLastActive(appIdentifier, userId); } catch (StorageQueryException ignored) { } } @@ -21,31 +23,31 @@ public static void updateLastActive(AppIdentifierWithStorage appIdentifierWithSt @TestOnly public static void updateLastActive(Main main, String userId) { try { - ActiveUsers.updateLastActive(new AppIdentifierWithStorage(null, null, StorageLayer.getStorage(main)), main, - userId); + ActiveUsers.updateLastActive(new AppIdentifier(null, null), + StorageLayer.getStorage(main), userId); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static int countUsersActiveSince(AppIdentifierWithStorage appIdentifierWithStorage, Main main, long time) + public static int countUsersActiveSince(AppIdentifier appIdentifier, Storage storage, long time) throws StorageQueryException, TenantOrAppNotFoundException { - return appIdentifierWithStorage.getActiveUsersStorage().countUsersActiveSince(appIdentifierWithStorage, time); + return StorageUtils.getActiveUsersStorage(storage).countUsersActiveSince(appIdentifier, time); } @TestOnly public static int countUsersActiveSince(Main main, long time) throws StorageQueryException, TenantOrAppNotFoundException { - return countUsersActiveSince(new AppIdentifierWithStorage(null, null, StorageLayer.getStorage(main)), main, - time); + return countUsersActiveSince(new AppIdentifier(null, null), + StorageLayer.getStorage(main), time); } - public static void removeActiveUser(AppIdentifierWithStorage appIdentifierWithStorage, String userId) + public static void removeActiveUser(AppIdentifier appIdentifier, Storage storage, String userId) throws StorageQueryException { try { - ((AuthRecipeSQLStorage) appIdentifierWithStorage.getActiveUsersStorage()).startTransaction(con -> { - appIdentifierWithStorage.getActiveUsersStorage().deleteUserActive_Transaction(con, appIdentifierWithStorage, userId); - ((AuthRecipeSQLStorage) appIdentifierWithStorage.getActiveUsersStorage()).commitTransaction(con); + ((AuthRecipeSQLStorage) StorageUtils.getActiveUsersStorage(storage)).startTransaction(con -> { + StorageUtils.getActiveUsersStorage(storage).deleteUserActive_Transaction(con, appIdentifier, userId); + ((AuthRecipeSQLStorage) StorageUtils.getActiveUsersStorage(storage)).commitTransaction(con); return null; }); diff --git a/src/main/java/io/supertokens/AppIdentifierWithStorageAndUserIdMapping.java b/src/main/java/io/supertokens/StorageAndUserIdMapping.java similarity index 69% rename from src/main/java/io/supertokens/AppIdentifierWithStorageAndUserIdMapping.java rename to src/main/java/io/supertokens/StorageAndUserIdMapping.java index 42760c500..f4cf990de 100644 --- a/src/main/java/io/supertokens/AppIdentifierWithStorageAndUserIdMapping.java +++ b/src/main/java/io/supertokens/StorageAndUserIdMapping.java @@ -16,23 +16,21 @@ package io.supertokens; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.useridmapping.UserIdMapping; import javax.annotation.Nonnull; import javax.annotation.Nullable; -public class AppIdentifierWithStorageAndUserIdMapping { +public class StorageAndUserIdMapping { @Nullable public final io.supertokens.pluginInterface.useridmapping.UserIdMapping userIdMapping; @Nonnull - public final AppIdentifierWithStorage appIdentifierWithStorage; + public final Storage storage; - public AppIdentifierWithStorageAndUserIdMapping(AppIdentifierWithStorage appIdentifierWithStorage, UserIdMapping userIdMapping) { - this.appIdentifierWithStorage = appIdentifierWithStorage; + public StorageAndUserIdMapping(Storage storage, UserIdMapping userIdMapping) { + this.storage = storage; this.userIdMapping = userIdMapping; - - assert(this.appIdentifierWithStorage != null); } } diff --git a/src/main/java/io/supertokens/TenantIdentifierWithStorageAndUserIdMapping.java b/src/main/java/io/supertokens/TenantIdentifierWithStorageAndUserIdMapping.java deleted file mode 100644 index 156ec77f3..000000000 --- a/src/main/java/io/supertokens/TenantIdentifierWithStorageAndUserIdMapping.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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; - -import io.supertokens.pluginInterface.Storage; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; -import io.supertokens.pluginInterface.useridmapping.UserIdMapping; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public class TenantIdentifierWithStorageAndUserIdMapping { - @Nullable - public final io.supertokens.pluginInterface.useridmapping.UserIdMapping userIdMapping; - - @Nonnull - public final TenantIdentifierWithStorage tenantIdentifierWithStorage; - - public TenantIdentifierWithStorageAndUserIdMapping(TenantIdentifierWithStorage tenantIdentifierWithStorage, - UserIdMapping userIdMapping) { - this.tenantIdentifierWithStorage = tenantIdentifierWithStorage; - this.userIdMapping = userIdMapping; - - assert(this.tenantIdentifierWithStorage != null); - } -} diff --git a/src/main/java/io/supertokens/authRecipe/AuthRecipe.java b/src/main/java/io/supertokens/authRecipe/AuthRecipe.java index 29945e30d..6d355209f 100644 --- a/src/main/java/io/supertokens/authRecipe/AuthRecipe.java +++ b/src/main/java/io/supertokens/authRecipe/AuthRecipe.java @@ -28,6 +28,7 @@ import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.STORAGE_TYPE; import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.authRecipe.AuthRecipeStorage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.authRecipe.LoginMethod; @@ -36,10 +37,8 @@ import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorages; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.session.sqlStorage.SessionSQLStorage; import io.supertokens.pluginInterface.sqlStorage.TransactionConnection; @@ -61,21 +60,19 @@ public class AuthRecipe { @TestOnly public static boolean unlinkAccounts(Main main, String recipeUserId) throws StorageQueryException, UnknownUserIdException, InputUserIdIsNotAPrimaryUserException { - AppIdentifierWithStorage appId = new AppIdentifierWithStorage(null, null, - StorageLayer.getStorage(main)); - return unlinkAccounts(main, appId, recipeUserId); + return unlinkAccounts(main, new AppIdentifier(null, null), StorageLayer.getStorage(main), recipeUserId); } // returns true if the input user ID was deleted - which can happens if it was a primary user id and // there were other accounts linked to it as well. - public static boolean unlinkAccounts(Main main, AppIdentifierWithStorage appIdentifierWithStorage, - String recipeUserId) + public static boolean unlinkAccounts(Main main, AppIdentifier appIdentifier, + Storage storage, String recipeUserId) throws StorageQueryException, UnknownUserIdException, InputUserIdIsNotAPrimaryUserException { - AuthRecipeSQLStorage storage = (AuthRecipeSQLStorage) appIdentifierWithStorage.getAuthRecipeStorage(); + AuthRecipeSQLStorage authRecipeStorage = StorageUtils.getAuthRecipeStorage(storage); try { - UnlinkResult res = storage.startTransaction(con -> { - AuthRecipeUserInfo primaryUser = storage.getPrimaryUserById_Transaction(appIdentifierWithStorage, con, + UnlinkResult res = authRecipeStorage.startTransaction(con -> { + AuthRecipeUserInfo primaryUser = authRecipeStorage.getPrimaryUserById_Transaction(appIdentifier, con, recipeUserId); if (primaryUser == null) { throw new StorageTransactionLogicException(new UnknownUserIdException()); @@ -87,13 +84,13 @@ public static boolean unlinkAccounts(Main main, AppIdentifierWithStorage appIden io.supertokens.pluginInterface.useridmapping.UserIdMapping mappingResult = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( - appIdentifierWithStorage, + appIdentifier, authRecipeStorage, recipeUserId, UserIdType.SUPERTOKENS); if (primaryUser.getSupertokensUserId().equals(recipeUserId)) { // we are trying to unlink the user ID which is the same as the primary one. if (primaryUser.loginMethods.length == 1) { - storage.unlinkAccounts_Transaction(appIdentifierWithStorage, con, primaryUser.getSupertokensUserId(), recipeUserId); + authRecipeStorage.unlinkAccounts_Transaction(appIdentifier, con, primaryUser.getSupertokensUserId(), recipeUserId); return new UnlinkResult(mappingResult == null ? recipeUserId : mappingResult.externalUserId, false); } else { // Here we delete the recipe user id cause if we just unlink, then there will be two @@ -101,15 +98,15 @@ public static boolean unlinkAccounts(Main main, AppIdentifierWithStorage appIden // The delete will also cause the automatic unlinking. // We need to make sure that it only deletes sessions for recipeUserId and not other linked // users who have their sessions for primaryUserId (that is equal to the recipeUserId) - deleteUserHelper(con, appIdentifierWithStorage, recipeUserId, false, mappingResult); + deleteUserHelper(con, appIdentifier, storage, recipeUserId, false, mappingResult); return new UnlinkResult(mappingResult == null ? recipeUserId : mappingResult.externalUserId, true); } } else { - storage.unlinkAccounts_Transaction(appIdentifierWithStorage, con, primaryUser.getSupertokensUserId(), recipeUserId); + authRecipeStorage.unlinkAccounts_Transaction(appIdentifier, con, primaryUser.getSupertokensUserId(), recipeUserId); return new UnlinkResult(mappingResult == null ? recipeUserId : mappingResult.externalUserId, false); } }); - Session.revokeAllSessionsForUser(main, appIdentifierWithStorage, res.userId, false); + Session.revokeAllSessionsForUser(main, appIdentifier, storage, res.userId, false); return res.wasLinked; } catch (StorageTransactionLogicException e) { if (e.actualException instanceof UnknownUserIdException) { @@ -124,14 +121,12 @@ public static boolean unlinkAccounts(Main main, AppIdentifierWithStorage appIden @TestOnly public static AuthRecipeUserInfo getUserById(Main main, String userId) throws StorageQueryException { - AppIdentifierWithStorage appId = new AppIdentifierWithStorage(null, null, - StorageLayer.getStorage(main)); - return getUserById(appId, userId); + return getUserById(new AppIdentifier(null, null), StorageLayer.getStorage(main), userId); } - public static AuthRecipeUserInfo getUserById(AppIdentifierWithStorage appIdentifierWithStorage, String userId) + public static AuthRecipeUserInfo getUserById(AppIdentifier appIdentifier, Storage storage, String userId) throws StorageQueryException { - return appIdentifierWithStorage.getAuthRecipeStorage().getPrimaryUserById(appIdentifierWithStorage, userId); + return StorageUtils.getAuthRecipeStorage(storage).getPrimaryUserById(appIdentifier, userId); } public static class CreatePrimaryUserResult { @@ -162,24 +157,22 @@ public static CanLinkAccountsResult canLinkAccounts(Main main, String recipeUser throws StorageQueryException, UnknownUserIdException, InputUserIdIsNotAPrimaryUserException, RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException, AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException { - AppIdentifierWithStorage appId = new AppIdentifierWithStorage(null, null, - StorageLayer.getStorage(main)); - return canLinkAccounts(appId, recipeUserId, primaryUserId); + return canLinkAccounts(new AppIdentifier(null, null), StorageLayer.getStorage(main), recipeUserId, primaryUserId); } - public static CanLinkAccountsResult canLinkAccounts(AppIdentifierWithStorage appIdentifierWithStorage, + public static CanLinkAccountsResult canLinkAccounts(AppIdentifier appIdentifier, Storage storage, String recipeUserId, String primaryUserId) throws StorageQueryException, UnknownUserIdException, InputUserIdIsNotAPrimaryUserException, RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException, AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException { - AuthRecipeSQLStorage storage = (AuthRecipeSQLStorage) appIdentifierWithStorage.getAuthRecipeStorage(); + AuthRecipeSQLStorage authRecipeStorage = StorageUtils.getAuthRecipeStorage(storage); try { - return storage.startTransaction(con -> { + return authRecipeStorage.startTransaction(con -> { try { - CanLinkAccountsResult result = canLinkAccountsHelper(con, appIdentifierWithStorage, + CanLinkAccountsResult result = canLinkAccountsHelper(con, appIdentifier, authRecipeStorage, recipeUserId, primaryUserId); - storage.commitTransaction(con); + authRecipeStorage.commitTransaction(con); return result; } catch (UnknownUserIdException | InputUserIdIsNotAPrimaryUserException | @@ -203,13 +196,14 @@ public static CanLinkAccountsResult canLinkAccounts(AppIdentifierWithStorage app } private static CanLinkAccountsResult canLinkAccountsHelper(TransactionConnection con, - AppIdentifierWithStorage appIdentifierWithStorage, + AppIdentifier appIdentifier, + Storage storage, String _recipeUserId, String _primaryUserId) throws StorageQueryException, UnknownUserIdException, InputUserIdIsNotAPrimaryUserException, RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException, AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException { - AuthRecipeSQLStorage storage = (AuthRecipeSQLStorage) appIdentifierWithStorage.getAuthRecipeStorage(); - AuthRecipeUserInfo primaryUser = storage.getPrimaryUserById_Transaction(appIdentifierWithStorage, con, + AuthRecipeSQLStorage authRecipeStorage = StorageUtils.getAuthRecipeStorage(storage); + AuthRecipeUserInfo primaryUser = authRecipeStorage.getPrimaryUserById_Transaction(appIdentifier, con, _primaryUserId); if (primaryUser == null) { @@ -220,7 +214,7 @@ private static CanLinkAccountsResult canLinkAccountsHelper(TransactionConnection throw new InputUserIdIsNotAPrimaryUserException(primaryUser.getSupertokensUserId()); } - AuthRecipeUserInfo recipeUser = storage.getPrimaryUserById_Transaction(appIdentifierWithStorage, con, + AuthRecipeUserInfo recipeUser = authRecipeStorage.getPrimaryUserById_Transaction(appIdentifier, con, _recipeUserId); if (recipeUser == null) { throw new UnknownUserIdException(); @@ -256,15 +250,15 @@ private static CanLinkAccountsResult canLinkAccountsHelper(TransactionConnection // do the checks in both. for (String tenantId : tenantIds) { TenantIdentifier tenantIdentifier = new TenantIdentifier( - appIdentifierWithStorage.getConnectionUriDomain(), appIdentifierWithStorage.getAppId(), + appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), tenantId); // we do not bother with getting the tenantIdentifierWithStorage here because // we get the tenants from the user itself, and the user can only be shared across // tenants of the same storage - therefore, the storage will be the same. if (recipeUserIdLM.email != null) { - AuthRecipeUserInfo[] usersWithSameEmail = storage - .listPrimaryUsersByEmail_Transaction(appIdentifierWithStorage, con, + AuthRecipeUserInfo[] usersWithSameEmail = authRecipeStorage + .listPrimaryUsersByEmail_Transaction(appIdentifier, con, recipeUserIdLM.email); for (AuthRecipeUserInfo user : usersWithSameEmail) { if (!user.tenantIds.contains(tenantId)) { @@ -278,8 +272,8 @@ private static CanLinkAccountsResult canLinkAccountsHelper(TransactionConnection } if (recipeUserIdLM.phoneNumber != null) { - AuthRecipeUserInfo[] usersWithSamePhoneNumber = storage - .listPrimaryUsersByPhoneNumber_Transaction(appIdentifierWithStorage, con, + AuthRecipeUserInfo[] usersWithSamePhoneNumber = authRecipeStorage + .listPrimaryUsersByPhoneNumber_Transaction(appIdentifier, con, recipeUserIdLM.phoneNumber); for (AuthRecipeUserInfo user : usersWithSamePhoneNumber) { if (!user.tenantIds.contains(tenantId)) { @@ -294,8 +288,8 @@ private static CanLinkAccountsResult canLinkAccountsHelper(TransactionConnection } if (recipeUserIdLM.thirdParty != null) { - AuthRecipeUserInfo[] usersWithSameThirdParty = storage - .listPrimaryUsersByThirdPartyInfo_Transaction(appIdentifierWithStorage, con, + AuthRecipeUserInfo[] usersWithSameThirdParty = authRecipeStorage + .listPrimaryUsersByThirdPartyInfo_Transaction(appIdentifier, con, recipeUserIdLM.thirdParty.id, recipeUserIdLM.thirdParty.userId); for (AuthRecipeUserInfo userWithSameThirdParty : usersWithSameThirdParty) { if (!userWithSameThirdParty.tenantIds.contains(tenantId)) { @@ -322,46 +316,45 @@ public static LinkAccountsResult linkAccounts(Main main, String recipeUserId, St UnknownUserIdException, FeatureNotEnabledException, InputUserIdIsNotAPrimaryUserException, RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException { - AppIdentifierWithStorage appId = new AppIdentifierWithStorage(null, null, - StorageLayer.getStorage(main)); try { - return linkAccounts(main, appId, recipeUserId, primaryUserId); + return linkAccounts(main, new AppIdentifier(null, null), + StorageLayer.getStorage(main), recipeUserId, primaryUserId); } catch (TenantOrAppNotFoundException e) { throw new RuntimeException(e); } } - public static LinkAccountsResult linkAccounts(Main main, AppIdentifierWithStorage appIdentifierWithStorage, - String _recipeUserId, String _primaryUserId) + public static LinkAccountsResult linkAccounts(Main main, AppIdentifier appIdentifier, + Storage storage, String _recipeUserId, String _primaryUserId) throws StorageQueryException, AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException, RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException, InputUserIdIsNotAPrimaryUserException, UnknownUserIdException, TenantOrAppNotFoundException, FeatureNotEnabledException { - if (Arrays.stream(FeatureFlag.getInstance(main, appIdentifierWithStorage).getEnabledFeatures()) + if (Arrays.stream(FeatureFlag.getInstance(main, appIdentifier).getEnabledFeatures()) .noneMatch(t -> t == EE_FEATURES.ACCOUNT_LINKING)) { throw new FeatureNotEnabledException( "Account linking feature is not enabled for this app. Please contact support to enable it."); } - AuthRecipeSQLStorage storage = (AuthRecipeSQLStorage) appIdentifierWithStorage.getAuthRecipeStorage(); + AuthRecipeSQLStorage authRecipeStorage = StorageUtils.getAuthRecipeStorage(storage); try { - LinkAccountsResult result = storage.startTransaction(con -> { + LinkAccountsResult result = authRecipeStorage.startTransaction(con -> { try { - CanLinkAccountsResult canLinkAccounts = canLinkAccountsHelper(con, appIdentifierWithStorage, - _recipeUserId, _primaryUserId); + CanLinkAccountsResult canLinkAccounts = canLinkAccountsHelper(con, appIdentifier, + authRecipeStorage, _recipeUserId, _primaryUserId); if (canLinkAccounts.alreadyLinked) { - return new LinkAccountsResult(getUserById(appIdentifierWithStorage, canLinkAccounts.primaryUserId), true); + return new LinkAccountsResult(getUserById(appIdentifier, authRecipeStorage, canLinkAccounts.primaryUserId), true); } // now we can link accounts in the db. - storage.linkAccounts_Transaction(appIdentifierWithStorage, con, canLinkAccounts.recipeUserId, + authRecipeStorage.linkAccounts_Transaction(appIdentifier, con, canLinkAccounts.recipeUserId, canLinkAccounts.primaryUserId); - storage.commitTransaction(con); + authRecipeStorage.commitTransaction(con); - return new LinkAccountsResult(getUserById(appIdentifierWithStorage, canLinkAccounts.primaryUserId), false); + return new LinkAccountsResult(getUserById(appIdentifier, authRecipeStorage, canLinkAccounts.primaryUserId), false); } catch (UnknownUserIdException | InputUserIdIsNotAPrimaryUserException | RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException | AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException e) { @@ -372,10 +365,10 @@ public static LinkAccountsResult linkAccounts(Main main, AppIdentifierWithStorag if (!result.wasAlreadyLinked) { io.supertokens.pluginInterface.useridmapping.UserIdMapping mappingResult = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( - appIdentifierWithStorage, + appIdentifier, authRecipeStorage, _recipeUserId, UserIdType.SUPERTOKENS); // finally, we revoke all sessions of the recipeUser Id cause their user ID has changed. - Session.revokeAllSessionsForUser(main, appIdentifierWithStorage, + Session.revokeAllSessionsForUser(main, appIdentifier, authRecipeStorage, mappingResult == null ? _recipeUserId : mappingResult.externalUserId, false); } @@ -409,21 +402,20 @@ public static CreatePrimaryUserResult canCreatePrimaryUser(Main main, String recipeUserId) throws StorageQueryException, AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException, RecipeUserIdAlreadyLinkedWithPrimaryUserIdException, UnknownUserIdException { - AppIdentifierWithStorage appId = new AppIdentifierWithStorage(null, null, - StorageLayer.getStorage(main)); - return canCreatePrimaryUser(appId, recipeUserId); + return canCreatePrimaryUser(new AppIdentifier(null, null), StorageLayer.getStorage(main), recipeUserId); } - public static CreatePrimaryUserResult canCreatePrimaryUser(AppIdentifierWithStorage appIdentifierWithStorage, + public static CreatePrimaryUserResult canCreatePrimaryUser(AppIdentifier appIdentifier, + Storage storage, String recipeUserId) throws StorageQueryException, AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException, RecipeUserIdAlreadyLinkedWithPrimaryUserIdException, UnknownUserIdException { - AuthRecipeSQLStorage storage = (AuthRecipeSQLStorage) appIdentifierWithStorage.getAuthRecipeStorage(); + AuthRecipeSQLStorage authRecipeStorage = StorageUtils.getAuthRecipeStorage(storage); try { - return storage.startTransaction(con -> { + return authRecipeStorage.startTransaction(con -> { try { - return canCreatePrimaryUserHelper(con, appIdentifierWithStorage, + return canCreatePrimaryUserHelper(con, appIdentifier, storage, recipeUserId); } catch (UnknownUserIdException | RecipeUserIdAlreadyLinkedWithPrimaryUserIdException | @@ -444,13 +436,14 @@ public static CreatePrimaryUserResult canCreatePrimaryUser(AppIdentifierWithStor } private static CreatePrimaryUserResult canCreatePrimaryUserHelper(TransactionConnection con, - AppIdentifierWithStorage appIdentifierWithStorage, + AppIdentifier appIdentifier, + Storage storage, String recipeUserId) throws StorageQueryException, UnknownUserIdException, RecipeUserIdAlreadyLinkedWithPrimaryUserIdException, AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException { - AuthRecipeSQLStorage storage = (AuthRecipeSQLStorage) appIdentifierWithStorage.getAuthRecipeStorage(); + AuthRecipeSQLStorage authRecipeStorage = StorageUtils.getAuthRecipeStorage(storage); - AuthRecipeUserInfo targetUser = storage.getPrimaryUserById_Transaction(appIdentifierWithStorage, con, + AuthRecipeUserInfo targetUser = authRecipeStorage.getPrimaryUserById_Transaction(appIdentifier, con, recipeUserId); if (targetUser == null) { throw new UnknownUserIdException(); @@ -471,8 +464,8 @@ private static CreatePrimaryUserResult canCreatePrimaryUserHelper(TransactionCon for (String tenantId : targetUser.tenantIds) { if (loginMethod.email != null) { - AuthRecipeUserInfo[] usersWithSameEmail = storage - .listPrimaryUsersByEmail_Transaction(appIdentifierWithStorage, con, + AuthRecipeUserInfo[] usersWithSameEmail = authRecipeStorage + .listPrimaryUsersByEmail_Transaction(appIdentifier, con, loginMethod.email); for (AuthRecipeUserInfo user : usersWithSameEmail) { if (!user.tenantIds.contains(tenantId)) { @@ -486,8 +479,8 @@ private static CreatePrimaryUserResult canCreatePrimaryUserHelper(TransactionCon } if (loginMethod.phoneNumber != null) { - AuthRecipeUserInfo[] usersWithSamePhoneNumber = storage - .listPrimaryUsersByPhoneNumber_Transaction(appIdentifierWithStorage, con, + AuthRecipeUserInfo[] usersWithSamePhoneNumber = authRecipeStorage + .listPrimaryUsersByPhoneNumber_Transaction(appIdentifier, con, loginMethod.phoneNumber); for (AuthRecipeUserInfo user : usersWithSamePhoneNumber) { if (!user.tenantIds.contains(tenantId)) { @@ -502,8 +495,8 @@ private static CreatePrimaryUserResult canCreatePrimaryUserHelper(TransactionCon } if (loginMethod.thirdParty != null) { - AuthRecipeUserInfo[] usersWithSameThirdParty = storage - .listPrimaryUsersByThirdPartyInfo_Transaction(appIdentifierWithStorage, con, + AuthRecipeUserInfo[] usersWithSameThirdParty = authRecipeStorage + .listPrimaryUsersByThirdPartyInfo_Transaction(appIdentifier, con, loginMethod.thirdParty.id, loginMethod.thirdParty.userId); for (AuthRecipeUserInfo userWithSameThirdParty : usersWithSameThirdParty) { if (!userWithSameThirdParty.tenantIds.contains(tenantId)) { @@ -528,41 +521,40 @@ public static CreatePrimaryUserResult createPrimaryUser(Main main, throws StorageQueryException, AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException, RecipeUserIdAlreadyLinkedWithPrimaryUserIdException, UnknownUserIdException, FeatureNotEnabledException { - AppIdentifierWithStorage appId = new AppIdentifierWithStorage(null, null, - StorageLayer.getStorage(main)); try { - return createPrimaryUser(main, appId, recipeUserId); + return createPrimaryUser(main, new AppIdentifier(null, null), StorageLayer.getStorage(main), recipeUserId); } catch (TenantOrAppNotFoundException e) { throw new RuntimeException(e); } } public static CreatePrimaryUserResult createPrimaryUser(Main main, - AppIdentifierWithStorage appIdentifierWithStorage, + AppIdentifier appIdentifier, + Storage storage, String recipeUserId) throws StorageQueryException, AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException, RecipeUserIdAlreadyLinkedWithPrimaryUserIdException, UnknownUserIdException, TenantOrAppNotFoundException, FeatureNotEnabledException { - if (Arrays.stream(FeatureFlag.getInstance(main, appIdentifierWithStorage).getEnabledFeatures()) + if (Arrays.stream(FeatureFlag.getInstance(main, appIdentifier).getEnabledFeatures()) .noneMatch(t -> t == EE_FEATURES.ACCOUNT_LINKING)) { throw new FeatureNotEnabledException( "Account linking feature is not enabled for this app. Please contact support to enable it."); } - AuthRecipeSQLStorage storage = (AuthRecipeSQLStorage) appIdentifierWithStorage.getAuthRecipeStorage(); + AuthRecipeSQLStorage authRecipeStorage = StorageUtils.getAuthRecipeStorage(storage); try { - return storage.startTransaction(con -> { + return authRecipeStorage.startTransaction(con -> { try { - CreatePrimaryUserResult result = canCreatePrimaryUserHelper(con, appIdentifierWithStorage, + CreatePrimaryUserResult result = canCreatePrimaryUserHelper(con, appIdentifier, authRecipeStorage, recipeUserId); if (result.wasAlreadyAPrimaryUser) { return result; } - storage.makePrimaryUser_Transaction(appIdentifierWithStorage, con, result.user.getSupertokensUserId()); + authRecipeStorage.makePrimaryUser_Transaction(appIdentifier, con, result.user.getSupertokensUserId()); - storage.commitTransaction(con); + authRecipeStorage.commitTransaction(con); result.user.isPrimaryUser = true; @@ -584,7 +576,8 @@ public static CreatePrimaryUserResult createPrimaryUser(Main main, } } - public static AuthRecipeUserInfo[] getUsersByAccountInfo(TenantIdentifierWithStorage tenantIdentifier, + public static AuthRecipeUserInfo[] getUsersByAccountInfo(TenantIdentifier tenantIdentifier, + Storage storage, boolean doUnionOfAccountInfo, String email, String phoneNumber, String thirdPartyId, String thirdPartyUserId) @@ -592,17 +585,17 @@ public static AuthRecipeUserInfo[] getUsersByAccountInfo(TenantIdentifierWithSto Set result = new HashSet<>(); if (email != null) { - AuthRecipeUserInfo[] users = tenantIdentifier.getAuthRecipeStorage() + AuthRecipeUserInfo[] users = StorageUtils.getAuthRecipeStorage(storage) .listPrimaryUsersByEmail(tenantIdentifier, email); result.addAll(List.of(users)); } if (phoneNumber != null) { - AuthRecipeUserInfo[] users = tenantIdentifier.getAuthRecipeStorage() + AuthRecipeUserInfo[] users = StorageUtils.getAuthRecipeStorage(storage) .listPrimaryUsersByPhoneNumber(tenantIdentifier, phoneNumber); result.addAll(List.of(users)); } if (thirdPartyId != null && thirdPartyUserId != null) { - AuthRecipeUserInfo user = tenantIdentifier.getAuthRecipeStorage() + AuthRecipeUserInfo user = StorageUtils.getAuthRecipeStorage(storage) .getPrimaryUserByThirdPartyInfo(tenantIdentifier, thirdPartyId, thirdPartyUserId); if (user != null) { result.add(user); @@ -654,28 +647,25 @@ public static AuthRecipeUserInfo[] getUsersByAccountInfo(TenantIdentifierWithSto } - public static long getUsersCountForTenant(TenantIdentifierWithStorage tenantIdentifier, + public static long getUsersCountForTenant(TenantIdentifier tenantIdentifier, + Storage storage, RECIPE_ID[] includeRecipeIds) throws StorageQueryException, TenantOrAppNotFoundException, BadPermissionException { - return tenantIdentifier.getAuthRecipeStorage().getUsersCount( + return StorageUtils.getAuthRecipeStorage(storage).getUsersCount( tenantIdentifier, includeRecipeIds); } - public static long getUsersCountAcrossAllTenants(AppIdentifierWithStorages appIdentifierWithStorages, + public static long getUsersCountAcrossAllTenants(AppIdentifier appIdentappIdentifierfierWithStorages, + Storage[] storages, RECIPE_ID[] includeRecipeIds) throws StorageQueryException, TenantOrAppNotFoundException, BadPermissionException { long count = 0; - for (Storage storage : appIdentifierWithStorages.getStorages()) { - if (storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - - count += ((AuthRecipeStorage) storage).getUsersCount( - appIdentifierWithStorages, includeRecipeIds); + for (Storage storage : storages) { + count += StorageUtils.getAuthRecipeStorage(storage).getUsersCount( + appIdentappIdentifierfierWithStorages, includeRecipeIds); } return count; @@ -686,15 +676,14 @@ public static long getUsersCount(Main main, RECIPE_ID[] includeRecipeIds) throws StorageQueryException { try { Storage storage = StorageLayer.getStorage(main); - return getUsersCountForTenant(new TenantIdentifierWithStorage( - null, null, null, storage), - includeRecipeIds); + return getUsersCountForTenant(TenantIdentifier.BASE_TENANT, storage, includeRecipeIds); } catch (TenantOrAppNotFoundException | BadPermissionException e) { throw new IllegalStateException(e); } } - public static UserPaginationContainer getUsers(TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static UserPaginationContainer getUsers(TenantIdentifier tenantIdentifier, + Storage storage, Integer limit, String timeJoinedOrder, @Nullable String paginationToken, @Nullable RECIPE_ID[] includeRecipeIds, @@ -702,13 +691,13 @@ public static UserPaginationContainer getUsers(TenantIdentifierWithStorage tenan throws StorageQueryException, UserPaginationToken.InvalidTokenException, TenantOrAppNotFoundException { AuthRecipeUserInfo[] users; if (paginationToken == null) { - users = tenantIdentifierWithStorage.getAuthRecipeStorage() - .getUsers(tenantIdentifierWithStorage, limit + 1, timeJoinedOrder, includeRecipeIds, null, + users = StorageUtils.getAuthRecipeStorage(storage) + .getUsers(tenantIdentifier, limit + 1, timeJoinedOrder, includeRecipeIds, null, null, dashboardSearchTags); } else { UserPaginationToken tokenInfo = UserPaginationToken.extractTokenInfo(paginationToken); - users = tenantIdentifierWithStorage.getAuthRecipeStorage() - .getUsers(tenantIdentifierWithStorage, limit + 1, timeJoinedOrder, includeRecipeIds, + users = StorageUtils.getAuthRecipeStorage(storage) + .getUsers(tenantIdentifier, limit + 1, timeJoinedOrder, includeRecipeIds, tokenInfo.userId, tokenInfo.timeJoined, dashboardSearchTags); } @@ -737,8 +726,7 @@ public static UserPaginationContainer getUsers(Main main, throws StorageQueryException, UserPaginationToken.InvalidTokenException { try { Storage storage = StorageLayer.getStorage(main); - return getUsers(new TenantIdentifierWithStorage( - null, null, null, storage), + return getUsers(TenantIdentifier.BASE_TENANT, storage, limit, timeJoinedOrder, paginationToken, includeRecipeIds, dashboardSearchTags); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); @@ -746,31 +734,32 @@ public static UserPaginationContainer getUsers(Main main, } @TestOnly - public static void deleteUser(AppIdentifierWithStorage appIdentifierWithStorage, String userId, + public static void deleteUser(AppIdentifier appIdentifier, Storage storage, String userId, UserIdMapping userIdMapping) throws StorageQueryException, StorageTransactionLogicException { - deleteUser(appIdentifierWithStorage, userId, true, userIdMapping); + deleteUser(appIdentifier, storage, userId, true, userIdMapping); } - public static void deleteUser(AppIdentifierWithStorage appIdentifierWithStorage, String userId, + public static void deleteUser(AppIdentifier appIdentifier, Storage storage, String userId, boolean removeAllLinkedAccounts, UserIdMapping userIdMapping) throws StorageQueryException, StorageTransactionLogicException { - AuthRecipeSQLStorage storage = (AuthRecipeSQLStorage) appIdentifierWithStorage.getAuthRecipeStorage(); + AuthRecipeSQLStorage authRecipeStorage = StorageUtils.getAuthRecipeStorage(storage); - storage.startTransaction(con -> { - deleteUserHelper(con, appIdentifierWithStorage, userId, removeAllLinkedAccounts, userIdMapping); - storage.commitTransaction(con); + authRecipeStorage.startTransaction(con -> { + deleteUserHelper(con, appIdentifier, storage, userId, removeAllLinkedAccounts, userIdMapping); + authRecipeStorage.commitTransaction(con); return null; }); } - private static void deleteUserHelper(TransactionConnection con, AppIdentifierWithStorage appIdentifierWithStorage, + private static void deleteUserHelper(TransactionConnection con, AppIdentifier appIdentifier, + Storage storage, String userId, boolean removeAllLinkedAccounts, UserIdMapping userIdMapping) throws StorageQueryException { - AuthRecipeSQLStorage storage = (AuthRecipeSQLStorage) appIdentifierWithStorage.getAuthRecipeStorage(); + AuthRecipeSQLStorage authRecipeStorage = StorageUtils.getAuthRecipeStorage(storage); String userIdToDeleteForNonAuthRecipeForRecipeUserId; String userIdToDeleteForAuthRecipe; @@ -800,8 +789,8 @@ private static void deleteUserHelper(TransactionConnection con, AppIdentifierWit // in reference to // https://docs.google.com/spreadsheets/d/17hYV32B0aDCeLnSxbZhfRN2Y9b0LC2xUF44vV88RNAA/edit?usp=sharing // we want to check which state the db is in - if (((AuthRecipeSQLStorage) appIdentifierWithStorage.getAuthRecipeStorage()) - .doesUserIdExist_Transaction(con, appIdentifierWithStorage, userIdMapping.externalUserId)) { + if (authRecipeStorage + .doesUserIdExist_Transaction(con, appIdentifier, userIdMapping.externalUserId)) { // db is in state A4 // delete only from auth tables userIdToDeleteForAuthRecipe = userId; @@ -822,7 +811,7 @@ private static void deleteUserHelper(TransactionConnection con, AppIdentifierWit // this user ID represents the non auth recipe stuff to delete for the primary user id String primaryUserIdToDeleteNonAuthRecipe = null; - AuthRecipeUserInfo userToDelete = storage.getPrimaryUserById_Transaction(appIdentifierWithStorage, con, + AuthRecipeUserInfo userToDelete = authRecipeStorage.getPrimaryUserById_Transaction(appIdentifier, con, userIdToDeleteForAuthRecipe); if (userToDelete == null) { @@ -833,7 +822,7 @@ private static void deleteUserHelper(TransactionConnection con, AppIdentifierWit if (userToDelete.getSupertokensUserId().equals(userIdToDeleteForAuthRecipe)) { primaryUserIdToDeleteNonAuthRecipe = userIdToDeleteForNonAuthRecipeForRecipeUserId; if (primaryUserIdToDeleteNonAuthRecipe == null) { - deleteAuthRecipeUser(con, appIdentifierWithStorage, userToDelete.getSupertokensUserId(), + deleteAuthRecipeUser(con, appIdentifier, storage, userToDelete.getSupertokensUserId(), true); return; } @@ -842,7 +831,8 @@ private static void deleteUserHelper(TransactionConnection con, AppIdentifierWit io.supertokens.pluginInterface.useridmapping.UserIdMapping mappingResult = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( con, - appIdentifierWithStorage, + appIdentifier, + storage, userToDelete.getSupertokensUserId(), UserIdType.SUPERTOKENS); if (mappingResult != null) { primaryUserIdToDeleteNonAuthRecipe = mappingResult.externalUserId; @@ -860,19 +850,19 @@ private static void deleteUserHelper(TransactionConnection con, AppIdentifierWit } if (!removeAllLinkedAccounts) { - deleteAuthRecipeUser(con, appIdentifierWithStorage, userIdToDeleteForAuthRecipe, + deleteAuthRecipeUser(con, appIdentifier, storage, userIdToDeleteForAuthRecipe, !userIdToDeleteForAuthRecipe.equals(userToDelete.getSupertokensUserId())); if (userIdToDeleteForNonAuthRecipeForRecipeUserId != null) { - deleteNonAuthRecipeUser(con, appIdentifierWithStorage, userIdToDeleteForNonAuthRecipeForRecipeUserId); + deleteNonAuthRecipeUser(con, appIdentifier, storage, userIdToDeleteForNonAuthRecipeForRecipeUserId); } if (primaryUserIdToDeleteNonAuthRecipe != null) { - deleteNonAuthRecipeUser(con, appIdentifierWithStorage, primaryUserIdToDeleteNonAuthRecipe); + deleteNonAuthRecipeUser(con, appIdentifier, storage, primaryUserIdToDeleteNonAuthRecipe); // this is only done to also delete the user ID mapping in case it exists, since we do not delete in the // previous call to deleteAuthRecipeUser above. - deleteAuthRecipeUser(con, appIdentifierWithStorage, userToDelete.getSupertokensUserId(), + deleteAuthRecipeUser(con, appIdentifier, storage, userToDelete.getSupertokensUserId(), true); } } else { @@ -881,9 +871,10 @@ private static void deleteUserHelper(TransactionConnection con, AppIdentifierWit userIdToDeleteForAuthRecipe) ? userIdMapping : io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( con, - appIdentifierWithStorage, + appIdentifier, + storage, lM.getSupertokensUserId(), UserIdType.SUPERTOKENS); - deleteUserHelper(con, appIdentifierWithStorage, lM.getSupertokensUserId(), false, mappingResult); + deleteUserHelper(con, appIdentifier, storage, lM.getSupertokensUserId(), false, mappingResult); } } } @@ -892,67 +883,65 @@ private static void deleteUserHelper(TransactionConnection con, AppIdentifierWit public static void deleteUser(Main main, String userId, boolean removeAllLinkedAccounts) throws StorageQueryException, StorageTransactionLogicException { Storage storage = StorageLayer.getStorage(main); - AppIdentifierWithStorage appIdentifier = new AppIdentifierWithStorage( - null, null, storage); + AppIdentifier appIdentifier = new AppIdentifier(null, null); UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping(appIdentifier, - userId, UserIdType.ANY); + storage, userId, UserIdType.ANY); - deleteUser(appIdentifier, userId, removeAllLinkedAccounts, mapping); + deleteUser(appIdentifier, storage, userId, removeAllLinkedAccounts, mapping); } @TestOnly public static void deleteUser(Main main, String userId) throws StorageQueryException, StorageTransactionLogicException { Storage storage = StorageLayer.getStorage(main); - AppIdentifierWithStorage appIdentifier = new AppIdentifierWithStorage( - null, null, storage); + AppIdentifier appIdentifier = new AppIdentifier(null, null); UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping(appIdentifier, - userId, UserIdType.ANY); + storage, userId, UserIdType.ANY); - deleteUser(appIdentifier, userId, mapping); + deleteUser(appIdentifier, storage, userId, mapping); } @TestOnly - public static void deleteUser(AppIdentifierWithStorage appIdentifierWithStorage, String userId) + public static void deleteUser(AppIdentifier appIdentifier, Storage storage, String userId) throws StorageQueryException, StorageTransactionLogicException { - Storage storage = appIdentifierWithStorage.getStorage(); - UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping(appIdentifierWithStorage, - userId, UserIdType.ANY); + UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping(appIdentifier, + storage, userId, UserIdType.ANY); - deleteUser(appIdentifierWithStorage, userId, mapping); + deleteUser(appIdentifier, storage, userId, mapping); } - private static void deleteNonAuthRecipeUser(TransactionConnection con, AppIdentifierWithStorage - appIdentifierWithStorage, String userId) + private static void deleteNonAuthRecipeUser(TransactionConnection con, AppIdentifier appIdentifier, + Storage storage, String userId) throws StorageQueryException { - appIdentifierWithStorage.getUserMetadataStorage() - .deleteUserMetadata_Transaction(con, appIdentifierWithStorage, userId); - ((SessionSQLStorage) appIdentifierWithStorage.getSessionStorage()) - .deleteSessionsOfUser_Transaction(con, appIdentifierWithStorage, userId); - appIdentifierWithStorage.getEmailVerificationStorage() - .deleteEmailVerificationUserInfo_Transaction(con, appIdentifierWithStorage, userId); - appIdentifierWithStorage.getUserRolesStorage() - .deleteAllRolesForUser_Transaction(con, appIdentifierWithStorage, userId); - appIdentifierWithStorage.getActiveUsersStorage() - .deleteUserActive_Transaction(con, appIdentifierWithStorage, userId); - appIdentifierWithStorage.getTOTPStorage().removeUser_Transaction(con, appIdentifierWithStorage, userId); + StorageUtils.getUserMetadataStorage(storage) + .deleteUserMetadata_Transaction(con, appIdentifier, userId); + ((SessionSQLStorage) StorageUtils.getSessionStorage(storage)) + .deleteSessionsOfUser_Transaction(con, appIdentifier, userId); + StorageUtils.getEmailVerificationStorage(storage) + .deleteEmailVerificationUserInfo_Transaction(con, appIdentifier, userId); + StorageUtils.getUserRolesStorage(storage) + .deleteAllRolesForUser_Transaction(con, appIdentifier, userId); + StorageUtils.getActiveUsersStorage(storage) + .deleteUserActive_Transaction(con, appIdentifier, userId); + StorageUtils.getTOTPStorage(storage) + .removeUser_Transaction(con, appIdentifier, userId); } private static void deleteAuthRecipeUser(TransactionConnection con, - AppIdentifierWithStorage appIdentifierWithStorage, String - userId, boolean deleteFromUserIdToAppIdTableToo) + AppIdentifier appIdentifier, + Storage storage, + String userId, boolean deleteFromUserIdToAppIdTableToo) throws StorageQueryException { // auth recipe deletions here only - appIdentifierWithStorage.getEmailPasswordStorage() - .deleteEmailPasswordUser_Transaction(con, appIdentifierWithStorage, userId, deleteFromUserIdToAppIdTableToo); - appIdentifierWithStorage.getThirdPartyStorage() - .deleteThirdPartyUser_Transaction(con, appIdentifierWithStorage, userId, deleteFromUserIdToAppIdTableToo); - appIdentifierWithStorage.getPasswordlessStorage() - .deletePasswordlessUser_Transaction(con, appIdentifierWithStorage, userId, deleteFromUserIdToAppIdTableToo); + StorageUtils.getEmailPasswordStorage(storage) + .deleteEmailPasswordUser_Transaction(con, appIdentifier, userId, deleteFromUserIdToAppIdTableToo); + StorageUtils.getThirdPartyStorage(storage) + .deleteThirdPartyUser_Transaction(con, appIdentifier, userId, deleteFromUserIdToAppIdTableToo); + StorageUtils.getPasswordlessStorage(storage) + .deletePasswordlessUser_Transaction(con, appIdentifier, userId, deleteFromUserIdToAppIdTableToo); } - public static boolean deleteNonAuthRecipeUser(TenantIdentifierWithStorage - tenantIdentifierWithStorage, String userId) + public static boolean deleteNonAuthRecipeUser(TenantIdentifier tenantIdentifier, Storage storage, String userId) throws StorageQueryException { // UserMetadata is per app, so nothing to delete @@ -960,20 +949,20 @@ public static boolean deleteNonAuthRecipeUser(TenantIdentifierWithStorage boolean finalDidExist = false; boolean didExist = false; - didExist = tenantIdentifierWithStorage.getSessionStorage() - .deleteSessionsOfUser(tenantIdentifierWithStorage, userId); + didExist = StorageUtils.getSessionStorage(storage) + .deleteSessionsOfUser(tenantIdentifier, userId); finalDidExist = finalDidExist || didExist; - didExist = tenantIdentifierWithStorage.getEmailVerificationStorage() - .deleteEmailVerificationUserInfo(tenantIdentifierWithStorage, userId); + didExist = StorageUtils.getEmailVerificationStorage(storage) + .deleteEmailVerificationUserInfo(tenantIdentifier, userId); finalDidExist = finalDidExist || didExist; - didExist = (tenantIdentifierWithStorage.getUserRolesStorage() - .deleteAllRolesForUser(tenantIdentifierWithStorage, userId) > 0); + didExist = StorageUtils.getUserRolesStorage(storage) + .deleteAllRolesForUser(tenantIdentifier, userId) > 0; finalDidExist = finalDidExist || didExist; - didExist = tenantIdentifierWithStorage.getTOTPStorage() - .removeUser(tenantIdentifierWithStorage, userId); + didExist = StorageUtils.getTOTPStorage(storage) + .removeUser(tenantIdentifier, userId); finalDidExist = finalDidExist || didExist; return finalDidExist; diff --git a/src/main/java/io/supertokens/cronjobs/telemetry/Telemetry.java b/src/main/java/io/supertokens/cronjobs/telemetry/Telemetry.java index 8f80ecc86..cbb17c0c9 100644 --- a/src/main/java/io/supertokens/cronjobs/telemetry/Telemetry.java +++ b/src/main/java/io/supertokens/cronjobs/telemetry/Telemetry.java @@ -35,8 +35,6 @@ import io.supertokens.pluginInterface.dashboard.DashboardUser; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorages; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.storageLayer.StorageLayer; @@ -103,18 +101,15 @@ protected void doTaskPerApp(AppIdentifier app) throws Exception { if (StorageLayer.getBaseStorage(main).getType() == STORAGE_TYPE.SQL) { { // Users count across all tenants Storage[] storages = StorageLayer.getStoragesForApp(main, app); - AppIdentifierWithStorages appIdentifierWithStorages = new AppIdentifierWithStorages( - app.getConnectionUriDomain(), app.getAppId(), storages - ); json.addProperty("usersCount", - AuthRecipe.getUsersCountAcrossAllTenants(appIdentifierWithStorages, null)); + AuthRecipe.getUsersCountAcrossAllTenants(app, storages, null)); } { // Dashboard user emails // Dashboard APIs are app specific and are always stored on the public tenant DashboardUser[] dashboardUsers = Dashboard.getAllDashboardUsers( - app.withStorage(StorageLayer.getStorage(app.getAsPublicTenantIdentifier(), main)), main); + app, StorageLayer.getStorage(app.getAsPublicTenantIdentifier(), main), main); JsonArray dashboardUserEmails = new JsonArray(); for (DashboardUser user : dashboardUsers) { dashboardUserEmails.add(new JsonPrimitive(user.email)); diff --git a/src/main/java/io/supertokens/dashboard/Dashboard.java b/src/main/java/io/supertokens/dashboard/Dashboard.java index 746273aa5..ce9486891 100644 --- a/src/main/java/io/supertokens/dashboard/Dashboard.java +++ b/src/main/java/io/supertokens/dashboard/Dashboard.java @@ -23,6 +23,7 @@ import io.supertokens.featureflag.FeatureFlag; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.dashboard.DashboardSessionInfo; import io.supertokens.pluginInterface.dashboard.DashboardUser; import io.supertokens.pluginInterface.dashboard.exceptions.DuplicateEmailException; @@ -32,7 +33,6 @@ import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.storageLayer.StorageLayer; import io.supertokens.utils.Utils; @@ -55,26 +55,26 @@ public static DashboardUser signUpDashboardUser(Main main, String email, throws StorageQueryException, DuplicateEmailException, FeatureNotEnabledException { try { Storage storage = StorageLayer.getStorage(main); - return signUpDashboardUser(new AppIdentifierWithStorage(null, null, storage), + return signUpDashboardUser(new AppIdentifier(null, null), storage, main, email, password); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static DashboardUser signUpDashboardUser(AppIdentifierWithStorage appIdentifierWithStorage, Main main, String email, + public static DashboardUser signUpDashboardUser(AppIdentifier appIdentifier, Storage storage, Main main, String email, String password) throws StorageQueryException, DuplicateEmailException, FeatureNotEnabledException, TenantOrAppNotFoundException { - if (appIdentifierWithStorage.getDashboardStorage().getDashboardUserByEmail(appIdentifierWithStorage, email) != + if (StorageUtils.getDashboardStorage(storage).getDashboardUserByEmail(appIdentifier, email) != null) { throw new DuplicateEmailException(); } - if (!isDashboardFeatureFlagEnabled(main, appIdentifierWithStorage)) { - DashboardUser[] users = appIdentifierWithStorage.getDashboardStorage() - .getAllDashboardUsers(appIdentifierWithStorage); + if (!isDashboardFeatureFlagEnabled(main, appIdentifier)) { + DashboardUser[] users = StorageUtils.getDashboardStorage(storage) + .getAllDashboardUsers(appIdentifier); if (users.length >= MAX_NUMBER_OF_FREE_DASHBOARD_USERS) { throw new FeatureNotEnabledException( "Free user limit reached. Please subscribe to a SuperTokens core license key to allow more " + @@ -82,7 +82,7 @@ public static DashboardUser signUpDashboardUser(AppIdentifierWithStorage appIden } } - String hashedPassword = PasswordHashing.getInstance(main).createHashWithSalt(appIdentifierWithStorage, password); + String hashedPassword = PasswordHashing.getInstance(main).createHashWithSalt(appIdentifier, password); while (true) { String userId = Utils.getUUID(); @@ -90,7 +90,7 @@ public static DashboardUser signUpDashboardUser(AppIdentifierWithStorage appIden try { DashboardUser user = new DashboardUser(userId, email, hashedPassword, timeJoined); - appIdentifierWithStorage.getDashboardStorage().createNewDashboardUser(appIdentifierWithStorage, user); + StorageUtils.getDashboardStorage(storage).createNewDashboardUser(appIdentifier, user); return user; } catch (DuplicateUserIdException ignored) { // we retry with a new userId (while loop) @@ -102,15 +102,15 @@ public static DashboardUser signUpDashboardUser(AppIdentifierWithStorage appIden public static DashboardUser[] getAllDashboardUsers(Main main) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - return getAllDashboardUsers(new AppIdentifierWithStorage(null, null, storage), main); + return getAllDashboardUsers(new AppIdentifier(null, null), storage, main); } - public static DashboardUser[] getAllDashboardUsers(AppIdentifierWithStorage appIdentifierWithStorage, Main main) + public static DashboardUser[] getAllDashboardUsers(AppIdentifier appIdentifier, Storage storage, Main main) throws StorageQueryException { - DashboardUser[] dashboardUsers = appIdentifierWithStorage.getDashboardStorage() - .getAllDashboardUsers(appIdentifierWithStorage); - if (isDashboardFeatureFlagEnabled(main, appIdentifierWithStorage)) { + DashboardUser[] dashboardUsers = StorageUtils.getDashboardStorage(storage) + .getAllDashboardUsers(appIdentifier); + if (isDashboardFeatureFlagEnabled(main, appIdentifier)) { return dashboardUsers; } else { List validDashboardUsers = new ArrayList<>(); @@ -126,26 +126,26 @@ public static String signInDashboardUser(Main main, String email, String passwor throws StorageQueryException, UserSuspendedException { try { Storage storage = StorageLayer.getStorage(main); - return signInDashboardUser(new AppIdentifierWithStorage(null, null, storage), + return signInDashboardUser(new AppIdentifier(null, null), storage, main, email, password); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static String signInDashboardUser(AppIdentifierWithStorage appIdentifierWithStorage, Main main, + public static String signInDashboardUser(AppIdentifier appIdentifier, Storage storage, Main main, String email, String password) throws StorageQueryException, UserSuspendedException, TenantOrAppNotFoundException { - DashboardUser user = appIdentifierWithStorage.getDashboardStorage() - .getDashboardUserByEmail(appIdentifierWithStorage, email); + DashboardUser user = StorageUtils.getDashboardStorage(storage) + .getDashboardUserByEmail(appIdentifier, email); if (user != null) { - if (isUserSuspended(appIdentifierWithStorage, main, email, null)) { + if (isUserSuspended(appIdentifier, storage, main, email, null)) { throw new UserSuspendedException(); } - if (PasswordHashing.getInstance(main).verifyPasswordWithHash(appIdentifierWithStorage, password, user.passwordHash)) { + if (PasswordHashing.getInstance(main).verifyPasswordWithHash(appIdentifier, password, user.passwordHash)) { // create a new session for the user try { - return createSessionForDashboardUser(appIdentifierWithStorage, user); + return createSessionForDashboardUser(appIdentifier, storage, user); } catch (UserIdNotFoundException e) { throw new IllegalStateException(e); } @@ -158,21 +158,21 @@ public static String signInDashboardUser(AppIdentifierWithStorage appIdentifierW public static boolean deleteUserWithUserId(Main main, String userId) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - return deleteUserWithUserId(new AppIdentifierWithStorage(null, null, storage), userId); + return deleteUserWithUserId(new AppIdentifier(null, null), storage, userId); } - public static boolean deleteUserWithUserId(AppIdentifierWithStorage appIdentifierWithStorage, String userId) + public static boolean deleteUserWithUserId(AppIdentifier appIdentifier, Storage storage, String userId) throws StorageQueryException { - return appIdentifierWithStorage.getDashboardStorage() - .deleteDashboardUserWithUserId(appIdentifierWithStorage, userId); + return StorageUtils.getDashboardStorage(storage) + .deleteDashboardUserWithUserId(appIdentifier, userId); } - private static boolean isUserSuspended(AppIdentifierWithStorage appIdentifierWithStorage, Main main, @Nullable String email, + private static boolean isUserSuspended(AppIdentifier appIdentifier, Storage storage, Main main, @Nullable String email, @Nullable String userId) throws StorageQueryException { - if (!isDashboardFeatureFlagEnabled(main, appIdentifierWithStorage)) { - DashboardUser[] users = appIdentifierWithStorage.getDashboardStorage() - .getAllDashboardUsers(appIdentifierWithStorage); + if (!isDashboardFeatureFlagEnabled(main, appIdentifier)) { + DashboardUser[] users = StorageUtils.getDashboardStorage(storage) + .getAllDashboardUsers(appIdentifier); if (email != null) { for (int i = 0; i < MAX_NUMBER_OF_FREE_DASHBOARD_USERS; i++) { @@ -199,15 +199,15 @@ private static boolean isUserSuspended(AppIdentifierWithStorage appIdentifierWit public static boolean deleteUserWithEmail(Main main, String email) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - return deleteUserWithEmail(new AppIdentifierWithStorage(null, null, storage), email); + return deleteUserWithEmail(new AppIdentifier(null, null), storage, email); } - public static boolean deleteUserWithEmail(AppIdentifierWithStorage appIdentifierWithStorage, String email) + public static boolean deleteUserWithEmail(AppIdentifier appIdentifier, Storage storage, String email) throws StorageQueryException { - DashboardUser user = appIdentifierWithStorage.getDashboardStorage() - .getDashboardUserByEmail(appIdentifierWithStorage, email); + DashboardUser user = StorageUtils.getDashboardStorage(storage) + .getDashboardUserByEmail(appIdentifier, email); if (user != null) { - return deleteUserWithUserId(appIdentifierWithStorage, user.userId); + return deleteUserWithUserId(appIdentifier, storage, user.userId); } return false; } @@ -221,25 +221,25 @@ public static DashboardUser updateUsersCredentialsWithUserId(Main main, String u try { Storage storage = StorageLayer.getStorage(main); return updateUsersCredentialsWithUserId( - new AppIdentifierWithStorage(null, null, storage), main, userId, + new AppIdentifier(null, null), storage, main, userId, newEmail, newPassword); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static DashboardUser updateUsersCredentialsWithUserId(AppIdentifierWithStorage appIdentifierWithStorage, + public static DashboardUser updateUsersCredentialsWithUserId(AppIdentifier appIdentifier, Storage storage, Main main, String userId, String newEmail, String newPassword) throws StorageQueryException, DuplicateEmailException, UserIdNotFoundException, StorageTransactionLogicException, TenantOrAppNotFoundException { - DashboardSQLStorage storage = appIdentifierWithStorage.getDashboardStorage(); + DashboardSQLStorage dashboardStorage = StorageUtils.getDashboardStorage(storage); try { - storage.startTransaction(transaction -> { + dashboardStorage.startTransaction(transaction -> { if (newEmail != null) { try { - storage.updateDashboardUsersEmailWithUserId_Transaction(appIdentifierWithStorage, transaction, userId, + dashboardStorage.updateDashboardUsersEmailWithUserId_Transaction(appIdentifier, transaction, userId, newEmail); } catch (DuplicateEmailException | UserIdNotFoundException e) { throw new StorageTransactionLogicException(e); @@ -249,14 +249,14 @@ public static DashboardUser updateUsersCredentialsWithUserId(AppIdentifierWithSt if (newPassword != null) { try { String hashedPassword = PasswordHashing.getInstance(main) - .createHashWithSalt(appIdentifierWithStorage, newPassword); - storage.updateDashboardUsersPasswordWithUserId_Transaction(appIdentifierWithStorage, transaction, userId, + .createHashWithSalt(appIdentifier, newPassword); + dashboardStorage.updateDashboardUsersPasswordWithUserId_Transaction(appIdentifier, transaction, userId, hashedPassword); } catch (UserIdNotFoundException | TenantOrAppNotFoundException e) { throw new StorageTransactionLogicException(e); } } - storage.commitTransaction(transaction); + dashboardStorage.commitTransaction(transaction); return null; }); } catch (StorageTransactionLogicException e) { @@ -273,41 +273,41 @@ public static DashboardUser updateUsersCredentialsWithUserId(AppIdentifierWithSt } // revoke sessions for the user - DashboardSessionInfo[] sessionInfo = Dashboard.getAllDashboardSessionsForUser(appIdentifierWithStorage, userId); + DashboardSessionInfo[] sessionInfo = Dashboard.getAllDashboardSessionsForUser(appIdentifier, storage, userId); for (int i = 0; i < sessionInfo.length; i++) { - appIdentifierWithStorage.getDashboardStorage() - .revokeSessionWithSessionId(appIdentifierWithStorage, sessionInfo[i].sessionId); + StorageUtils.getDashboardStorage(storage) + .revokeSessionWithSessionId(appIdentifier, sessionInfo[i].sessionId); } - return appIdentifierWithStorage.getDashboardStorage() - .getDashboardUserByUserId(appIdentifierWithStorage, userId); + return StorageUtils.getDashboardStorage(storage) + .getDashboardUserByUserId(appIdentifier, userId); } @TestOnly public static DashboardUser getDashboardUserByEmail(Main main, String email) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - return getDashboardUserByEmail(new AppIdentifierWithStorage(null, null, storage), email); + return getDashboardUserByEmail(new AppIdentifier(null, null), storage, email); } - public static DashboardUser getDashboardUserByEmail(AppIdentifierWithStorage appIdentifierWithStorage, String email) + public static DashboardUser getDashboardUserByEmail(AppIdentifier appIdentifier, Storage storage, String email) throws StorageQueryException { - return appIdentifierWithStorage.getDashboardStorage() - .getDashboardUserByEmail(appIdentifierWithStorage, email); + return StorageUtils.getDashboardStorage(storage) + .getDashboardUserByEmail(appIdentifier, email); } @TestOnly public static boolean revokeSessionWithSessionId(Main main, String sessionId) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - return revokeSessionWithSessionId(new AppIdentifierWithStorage(null, null, storage), sessionId); + return revokeSessionWithSessionId(new AppIdentifier(null, null), storage, sessionId); } - public static boolean revokeSessionWithSessionId(AppIdentifierWithStorage appIdentifierWithStorage, String sessionId) + public static boolean revokeSessionWithSessionId(AppIdentifier appIdentifier, Storage storage, String sessionId) throws StorageQueryException { - return appIdentifierWithStorage.getDashboardStorage() - .revokeSessionWithSessionId(appIdentifierWithStorage, sessionId); + return StorageUtils.getDashboardStorage(storage) + .revokeSessionWithSessionId(appIdentifier, sessionId); } @TestOnly @@ -316,14 +316,14 @@ public static DashboardSessionInfo[] getAllDashboardSessionsForUser(Main main, throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); return getAllDashboardSessionsForUser( - new AppIdentifierWithStorage(null, null, storage), userId); + new AppIdentifier(null, null), storage, userId); } - public static DashboardSessionInfo[] getAllDashboardSessionsForUser(AppIdentifierWithStorage appIdentifierWithStorage, + public static DashboardSessionInfo[] getAllDashboardSessionsForUser(AppIdentifier appIdentifier, Storage storage, String userId) throws StorageQueryException { - return appIdentifierWithStorage.getDashboardStorage() - .getAllSessionsForUserId(appIdentifierWithStorage, userId); + return StorageUtils.getDashboardStorage(storage) + .getAllSessionsForUserId(appIdentifier, userId); } private static boolean isDashboardFeatureFlagEnabled(Main main, AppIdentifier appIdentifier) { @@ -335,14 +335,14 @@ private static boolean isDashboardFeatureFlagEnabled(Main main, AppIdentifier ap } } - private static String createSessionForDashboardUser(AppIdentifierWithStorage appIdentifierWithStorage, + private static String createSessionForDashboardUser(AppIdentifier appIdentifier, Storage storage, DashboardUser user) throws StorageQueryException, UserIdNotFoundException { String sessionId = UUID.randomUUID().toString(); long timeCreated = System.currentTimeMillis(); long expiry = timeCreated + DASHBOARD_SESSION_DURATION; - appIdentifierWithStorage.getDashboardStorage() - .createNewDashboardUserSession(appIdentifierWithStorage, user.userId, sessionId, timeCreated, + StorageUtils.getDashboardStorage(storage) + .createNewDashboardUserSession(appIdentifier, user.userId, sessionId, timeCreated, expiry); return sessionId; } @@ -386,16 +386,16 @@ public static String validatePassword(String password) { public static boolean isValidUserSession(Main main, String sessionId) throws StorageQueryException, UserSuspendedException { Storage storage = StorageLayer.getStorage(main); - return isValidUserSession(new AppIdentifierWithStorage(null, null, storage), main, sessionId); + return isValidUserSession(new AppIdentifier(null, null), storage, main, sessionId); } - public static boolean isValidUserSession(AppIdentifierWithStorage appIdentifierWithStorage, Main main, String sessionId) + public static boolean isValidUserSession(AppIdentifier appIdentifier, Storage storage, Main main, String sessionId) throws StorageQueryException, UserSuspendedException { - DashboardSessionInfo sessionInfo = appIdentifierWithStorage.getDashboardStorage() - .getSessionInfoWithSessionId(appIdentifierWithStorage, sessionId); + DashboardSessionInfo sessionInfo = StorageUtils.getDashboardStorage(storage) + .getSessionInfoWithSessionId(appIdentifier, sessionId); if (sessionInfo != null) { // check if user is suspended - if (isUserSuspended(appIdentifierWithStorage, main, null, sessionInfo.userId)) { + if (isUserSuspended(appIdentifier, storage, main, null, sessionInfo.userId)) { throw new UserSuspendedException(); } return true; @@ -403,14 +403,14 @@ public static boolean isValidUserSession(AppIdentifierWithStorage appIdentifierW return false; } - public static String getEmailFromSessionId(AppIdentifierWithStorage appIdentifierWithStorage, Main main, String sessionId) throws StorageQueryException { - DashboardSessionInfo sessionInfo = appIdentifierWithStorage.getDashboardStorage() - .getSessionInfoWithSessionId(appIdentifierWithStorage, sessionId); + public static String getEmailFromSessionId(AppIdentifier appIdentifier, Storage storage, String sessionId) throws StorageQueryException { + DashboardSessionInfo sessionInfo = StorageUtils.getDashboardStorage(storage) + .getSessionInfoWithSessionId(appIdentifier, sessionId); if (sessionInfo != null) { String userId = sessionInfo.userId; - DashboardUser user = appIdentifierWithStorage.getDashboardStorage().getDashboardUserByUserId(appIdentifierWithStorage, userId); + DashboardUser user = StorageUtils.getDashboardStorage(storage).getDashboardUserByUserId(appIdentifier, userId); if (user != null) { return user.email; diff --git a/src/main/java/io/supertokens/emailpassword/EmailPassword.java b/src/main/java/io/supertokens/emailpassword/EmailPassword.java index 0c7fb08a0..517cb3e3a 100644 --- a/src/main/java/io/supertokens/emailpassword/EmailPassword.java +++ b/src/main/java/io/supertokens/emailpassword/EmailPassword.java @@ -28,6 +28,7 @@ import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.authRecipe.LoginMethod; import io.supertokens.pluginInterface.authRecipe.sqlStorage.AuthRecipeSQLStorage; @@ -39,10 +40,9 @@ import io.supertokens.pluginInterface.emailpassword.sqlStorage.EmailPasswordSQLStorage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.TenantConfig; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.storageLayer.StorageLayer; import io.supertokens.utils.Utils; @@ -86,28 +86,28 @@ public static AuthRecipeUserInfo signUp(Main main, @Nonnull String email, @Nonnu throws DuplicateEmailException, StorageQueryException { try { Storage storage = StorageLayer.getStorage(main); - return signUp(new TenantIdentifierWithStorage(null, null, null, storage), + return signUp(new TenantIdentifier(null, null, null), storage, main, email, password); } catch (TenantOrAppNotFoundException | BadPermissionException e) { throw new IllegalStateException(e); } } - public static AuthRecipeUserInfo signUp(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, + public static AuthRecipeUserInfo signUp(TenantIdentifier tenantIdentifier, Storage storage, Main main, @Nonnull String email, @Nonnull String password) throws DuplicateEmailException, StorageQueryException, TenantOrAppNotFoundException, BadPermissionException { - TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifierWithStorage); + TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifier); if (config == null) { - throw new TenantOrAppNotFoundException(tenantIdentifierWithStorage); + throw new TenantOrAppNotFoundException(tenantIdentifier); } if (!config.emailPasswordConfig.enabled) { throw new BadPermissionException("Email password login not enabled for tenant"); } String hashedPassword = PasswordHashing.getInstance(main) - .createHashWithSalt(tenantIdentifierWithStorage.toAppIdentifier(), password); + .createHashWithSalt(tenantIdentifier.toAppIdentifier(), password); while (true) { @@ -115,8 +115,8 @@ public static AuthRecipeUserInfo signUp(TenantIdentifierWithStorage tenantIdenti long timeJoined = System.currentTimeMillis(); try { - return tenantIdentifierWithStorage.getEmailPasswordStorage() - .signUp(tenantIdentifierWithStorage, userId, email, hashedPassword, timeJoined); + return StorageUtils.getEmailPasswordStorage(storage) + .signUp(tenantIdentifier, userId, email, hashedPassword, timeJoined); } catch (DuplicateUserIdException ignored) { // we retry with a new userId (while loop) @@ -133,51 +133,51 @@ public static ImportUserResponse importUserWithPasswordHash(Main main, @Nonnull Storage storage = StorageLayer.getStorage(main); return importUserWithPasswordHash( - new TenantIdentifierWithStorage(null, null, null, storage), main, email, + new TenantIdentifier(null, null, null), storage, main, email, passwordHash, hashingAlgorithm); } catch (TenantOrAppNotFoundException | BadPermissionException e) { throw new IllegalStateException(e); } } - public static ImportUserResponse importUserWithPasswordHash(TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static ImportUserResponse importUserWithPasswordHash(TenantIdentifier tenantIdentifier, Storage storage, Main main, @Nonnull String email, @Nonnull String passwordHash, @Nullable CoreConfig.PASSWORD_HASHING_ALG hashingAlgorithm) throws StorageQueryException, StorageTransactionLogicException, UnsupportedPasswordHashingFormatException, TenantOrAppNotFoundException, BadPermissionException { - TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifierWithStorage); + TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifier); if (config == null) { - throw new TenantOrAppNotFoundException(tenantIdentifierWithStorage); + throw new TenantOrAppNotFoundException(tenantIdentifier); } if (!config.emailPasswordConfig.enabled) { throw new BadPermissionException("Email password login not enabled for tenant"); } PasswordHashingUtils.assertSuperTokensSupportInputPasswordHashFormat( - tenantIdentifierWithStorage.toAppIdentifier(), main, + tenantIdentifier.toAppIdentifier(), main, passwordHash, hashingAlgorithm); while (true) { String userId = Utils.getUUID(); long timeJoined = System.currentTimeMillis(); - EmailPasswordSQLStorage storage = tenantIdentifierWithStorage.getEmailPasswordStorage(); + EmailPasswordSQLStorage epStorage = StorageUtils.getEmailPasswordStorage(storage); try { - AuthRecipeUserInfo userInfo = storage.signUp(tenantIdentifierWithStorage, userId, email, passwordHash, + AuthRecipeUserInfo userInfo = epStorage.signUp(tenantIdentifier, userId, email, passwordHash, timeJoined); return new ImportUserResponse(false, userInfo); } catch (DuplicateUserIdException e) { // we retry with a new userId } catch (DuplicateEmailException e) { - AuthRecipeUserInfo[] allUsers = storage.listPrimaryUsersByEmail(tenantIdentifierWithStorage, email); + AuthRecipeUserInfo[] allUsers = epStorage.listPrimaryUsersByEmail(tenantIdentifier, email); AuthRecipeUserInfo userInfoToBeUpdated = null; LoginMethod loginMethod = null; for (AuthRecipeUserInfo currUser : allUsers) { for (LoginMethod currLM : currUser.loginMethods) { - if (currLM.email.equals(email) && currLM.recipeId == RECIPE_ID.EMAIL_PASSWORD && currLM.tenantIds.contains(tenantIdentifierWithStorage.getTenantId())) { + if (currLM.email.equals(email) && currLM.recipeId == RECIPE_ID.EMAIL_PASSWORD && currLM.tenantIds.contains(tenantIdentifier.getTenantId())) { userInfoToBeUpdated = currUser; loginMethod = currLM; break; @@ -187,8 +187,8 @@ public static ImportUserResponse importUserWithPasswordHash(TenantIdentifierWith if (userInfoToBeUpdated != null) { LoginMethod finalLoginMethod = loginMethod; - storage.startTransaction(con -> { - storage.updateUsersPassword_Transaction(tenantIdentifierWithStorage.toAppIdentifier(), con, + epStorage.startTransaction(con -> { + epStorage.updateUsersPassword_Transaction(tenantIdentifier.toAppIdentifier(), con, finalLoginMethod.getSupertokensUserId(), passwordHash); return null; }); @@ -205,7 +205,7 @@ public static ImportUserResponse importUserWithPasswordHash(Main main, @Nonnull try { Storage storage = StorageLayer.getStorage(main); return importUserWithPasswordHash( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, main, email, passwordHash, null); } catch (TenantOrAppNotFoundException | BadPermissionException e) { throw new IllegalStateException(e); @@ -218,35 +218,35 @@ public static AuthRecipeUserInfo signIn(Main main, @Nonnull String email, throws StorageQueryException, WrongCredentialsException { try { Storage storage = StorageLayer.getStorage(main); - return signIn(new TenantIdentifierWithStorage(null, null, null, storage), + return signIn(new TenantIdentifier(null, null, null), storage, main, email, password); } catch (TenantOrAppNotFoundException | BadPermissionException e) { throw new IllegalStateException(e); } } - public static AuthRecipeUserInfo signIn(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, + public static AuthRecipeUserInfo signIn(TenantIdentifier tenantIdentifier, Storage storage, Main main, @Nonnull String email, @Nonnull String password) throws StorageQueryException, WrongCredentialsException, TenantOrAppNotFoundException, BadPermissionException { - TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifierWithStorage); + TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifier); if (config == null) { - throw new TenantOrAppNotFoundException(tenantIdentifierWithStorage); + throw new TenantOrAppNotFoundException(tenantIdentifier); } if (!config.emailPasswordConfig.enabled) { throw new BadPermissionException("Email password login not enabled for tenant"); } - AuthRecipeUserInfo[] users = tenantIdentifierWithStorage.getAuthRecipeStorage() - .listPrimaryUsersByEmail(tenantIdentifierWithStorage, email); + AuthRecipeUserInfo[] users = StorageUtils.getEmailPasswordStorage(storage) + .listPrimaryUsersByEmail(tenantIdentifier, email); AuthRecipeUserInfo user = null; LoginMethod lM = null; for (AuthRecipeUserInfo currUser : users) { for (LoginMethod currLM : currUser.loginMethods) { - if (currLM.recipeId == RECIPE_ID.EMAIL_PASSWORD && currLM.email.equals(email) && currLM.tenantIds.contains(tenantIdentifierWithStorage.getTenantId())) { + if (currLM.recipeId == RECIPE_ID.EMAIL_PASSWORD && currLM.email.equals(email) && currLM.tenantIds.contains(tenantIdentifier.getTenantId())) { user = currUser; lM = currLM; } @@ -259,7 +259,7 @@ public static AuthRecipeUserInfo signIn(TenantIdentifierWithStorage tenantIdenti try { if (!PasswordHashing.getInstance(main) - .verifyPasswordWithHash(tenantIdentifierWithStorage.toAppIdentifier(), password, + .verifyPasswordWithHash(tenantIdentifier.toAppIdentifier(), password, lM.passwordHash)) { throw new WrongCredentialsException(); } @@ -284,7 +284,7 @@ public static String generatePasswordResetTokenBeforeCdi4_0(Main main, String us try { Storage storage = StorageLayer.getStorage(main); return generatePasswordResetTokenBeforeCdi4_0( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, main, userId); } catch (TenantOrAppNotFoundException | BadPermissionException | WebserverAPI.BadRequestException e) { throw new IllegalStateException(e); @@ -297,7 +297,7 @@ public static String generatePasswordResetTokenBeforeCdi4_0WithoutAddingEmail(Ma try { Storage storage = StorageLayer.getStorage(main); return generatePasswordResetToken( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, main, userId, null); } catch (TenantOrAppNotFoundException | BadPermissionException e) { throw new IllegalStateException(e); @@ -310,21 +310,19 @@ public static String generatePasswordResetToken(Main main, String userId, String try { Storage storage = StorageLayer.getStorage(main); return generatePasswordResetToken( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, main, userId, email); } catch (TenantOrAppNotFoundException | BadPermissionException e) { throw new IllegalStateException(e); } } - public static String generatePasswordResetTokenBeforeCdi4_0(TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static String generatePasswordResetTokenBeforeCdi4_0(TenantIdentifier tenantIdentifier, Storage storage, Main main, String userId) throws InvalidKeySpecException, NoSuchAlgorithmException, StorageQueryException, UnknownUserIdException, TenantOrAppNotFoundException, BadPermissionException, WebserverAPI.BadRequestException { - AppIdentifierWithStorage appIdentifierWithStorage = - tenantIdentifierWithStorage.toAppIdentifierWithStorage(); - AuthRecipeUserInfo user = AuthRecipe.getUserById(appIdentifierWithStorage, userId); + AuthRecipeUserInfo user = AuthRecipe.getUserById(tenantIdentifier.toAppIdentifier(), storage, userId); if (user == null) { throw new UnknownUserIdException(); } @@ -336,17 +334,17 @@ public static String generatePasswordResetTokenBeforeCdi4_0(TenantIdentifierWith // this used to be the behaviour of the older CDI version and it was enforced via a fkey constraint throw new UnknownUserIdException(); } - return generatePasswordResetToken(tenantIdentifierWithStorage, main, userId, user.loginMethods[0].email); + return generatePasswordResetToken(tenantIdentifier, storage, main, userId, user.loginMethods[0].email); } - public static String generatePasswordResetToken(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, + public static String generatePasswordResetToken(TenantIdentifier tenantIdentifier, Storage storage, Main main, String userId, String email) throws InvalidKeySpecException, NoSuchAlgorithmException, StorageQueryException, UnknownUserIdException, TenantOrAppNotFoundException, BadPermissionException { - TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifierWithStorage); + TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifier); if (config == null) { - throw new TenantOrAppNotFoundException(tenantIdentifierWithStorage); + throw new TenantOrAppNotFoundException(tenantIdentifier); } if (!config.emailPasswordConfig.enabled) { throw new BadPermissionException("Email password login not enabled for tenant"); @@ -374,10 +372,10 @@ public static String generatePasswordResetToken(TenantIdentifierWithStorage tena String hashedToken = Utils.hashSHA256(token); try { - tenantIdentifierWithStorage.getEmailPasswordStorage().addPasswordResetToken( - tenantIdentifierWithStorage.toAppIdentifier(), new PasswordResetTokenInfo(userId, + StorageUtils.getEmailPasswordStorage(storage).addPasswordResetToken( + tenantIdentifier.toAppIdentifier(), new PasswordResetTokenInfo(userId, hashedToken, System.currentTimeMillis() + - getPasswordResetTokenLifetime(tenantIdentifierWithStorage, main), email)); + getPasswordResetTokenLifetime(tenantIdentifier, main), email)); return token; } catch (DuplicatePasswordResetTokenException ignored) { } @@ -392,7 +390,7 @@ public static String resetPassword(Main main, String token, StorageTransactionLogicException { try { Storage storage = StorageLayer.getStorage(main); - return resetPassword(new TenantIdentifierWithStorage(null, null, null, storage), + return resetPassword(new TenantIdentifier(null, null, null), storage, main, token, password); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); @@ -400,17 +398,17 @@ public static String resetPassword(Main main, String token, } @Deprecated - public static String resetPassword(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, String token, + public static String resetPassword(TenantIdentifier tenantIdentifier, Storage storage, Main main, String token, String password) throws ResetPasswordInvalidTokenException, NoSuchAlgorithmException, StorageQueryException, StorageTransactionLogicException, TenantOrAppNotFoundException { String hashedToken = Utils.hashSHA256(token); String hashedPassword = PasswordHashing.getInstance(main) - .createHashWithSalt(tenantIdentifierWithStorage.toAppIdentifier(), password); - EmailPasswordSQLStorage storage = tenantIdentifierWithStorage.getEmailPasswordStorage(); + .createHashWithSalt(tenantIdentifier.toAppIdentifier(), password); + EmailPasswordSQLStorage epStorage = StorageUtils.getEmailPasswordStorage(storage); - PasswordResetTokenInfo resetInfo = storage.getPasswordResetTokenInfo( - tenantIdentifierWithStorage.toAppIdentifier(), hashedToken); + PasswordResetTokenInfo resetInfo = epStorage.getPasswordResetTokenInfo( + tenantIdentifier.toAppIdentifier(), hashedToken); if (resetInfo == null) { throw new ResetPasswordInvalidTokenException(); @@ -419,10 +417,10 @@ public static String resetPassword(TenantIdentifierWithStorage tenantIdentifierW final String userId = resetInfo.userId; try { - return storage.startTransaction(con -> { + return epStorage.startTransaction(con -> { - PasswordResetTokenInfo[] allTokens = storage.getAllPasswordResetTokenInfoForUser_Transaction( - tenantIdentifierWithStorage.toAppIdentifier(), con, + PasswordResetTokenInfo[] allTokens = epStorage.getAllPasswordResetTokenInfoForUser_Transaction( + tenantIdentifier.toAppIdentifier(), con, userId); PasswordResetTokenInfo matchedToken = null; @@ -437,19 +435,19 @@ public static String resetPassword(TenantIdentifierWithStorage tenantIdentifierW throw new StorageTransactionLogicException(new ResetPasswordInvalidTokenException()); } - storage.deleteAllPasswordResetTokensForUser_Transaction(tenantIdentifierWithStorage.toAppIdentifier(), + epStorage.deleteAllPasswordResetTokensForUser_Transaction(tenantIdentifier.toAppIdentifier(), con, userId); if (matchedToken.tokenExpiry < System.currentTimeMillis()) { - storage.commitTransaction(con); + epStorage.commitTransaction(con); throw new StorageTransactionLogicException(new ResetPasswordInvalidTokenException()); } - storage.updateUsersPassword_Transaction(tenantIdentifierWithStorage.toAppIdentifier(), con, userId, + epStorage.updateUsersPassword_Transaction(tenantIdentifier.toAppIdentifier(), con, userId, hashedPassword); - storage.commitTransaction(con); + epStorage.commitTransaction(con); return userId; }); } catch (StorageTransactionLogicException e) { @@ -466,7 +464,7 @@ public static ConsumeResetPasswordTokenResult consumeResetPasswordToken(Main mai StorageTransactionLogicException { try { Storage storage = StorageLayer.getStorage(main); - return consumeResetPasswordToken(new TenantIdentifierWithStorage(null, null, null, storage), + return consumeResetPasswordToken(new TenantIdentifier(null, null, null), storage, token); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); @@ -484,15 +482,15 @@ public ConsumeResetPasswordTokenResult(String userId, String email) { } public static ConsumeResetPasswordTokenResult consumeResetPasswordToken( - TenantIdentifierWithStorage tenantIdentifierWithStorage, String token) + TenantIdentifier tenantIdentifier, Storage storage, String token) throws ResetPasswordInvalidTokenException, NoSuchAlgorithmException, StorageQueryException, StorageTransactionLogicException, TenantOrAppNotFoundException { String hashedToken = Utils.hashSHA256(token); - EmailPasswordSQLStorage storage = tenantIdentifierWithStorage.getEmailPasswordStorage(); + EmailPasswordSQLStorage epStorage = StorageUtils.getEmailPasswordStorage(storage); - PasswordResetTokenInfo resetInfo = storage.getPasswordResetTokenInfo( - tenantIdentifierWithStorage.toAppIdentifier(), hashedToken); + PasswordResetTokenInfo resetInfo = epStorage.getPasswordResetTokenInfo( + tenantIdentifier.toAppIdentifier(), hashedToken); if (resetInfo == null) { throw new ResetPasswordInvalidTokenException(); @@ -501,10 +499,10 @@ public static ConsumeResetPasswordTokenResult consumeResetPasswordToken( final String userId = resetInfo.userId; try { - return storage.startTransaction(con -> { + return epStorage.startTransaction(con -> { - PasswordResetTokenInfo[] allTokens = storage.getAllPasswordResetTokenInfoForUser_Transaction( - tenantIdentifierWithStorage.toAppIdentifier(), con, + PasswordResetTokenInfo[] allTokens = epStorage.getAllPasswordResetTokenInfoForUser_Transaction( + tenantIdentifier.toAppIdentifier(), con, userId); PasswordResetTokenInfo matchedToken = null; @@ -519,22 +517,21 @@ public static ConsumeResetPasswordTokenResult consumeResetPasswordToken( throw new StorageTransactionLogicException(new ResetPasswordInvalidTokenException()); } - storage.deleteAllPasswordResetTokensForUser_Transaction(tenantIdentifierWithStorage.toAppIdentifier(), + epStorage.deleteAllPasswordResetTokensForUser_Transaction(tenantIdentifier.toAppIdentifier(), con, userId); if (matchedToken.tokenExpiry < System.currentTimeMillis()) { - storage.commitTransaction(con); + epStorage.commitTransaction(con); throw new StorageTransactionLogicException(new ResetPasswordInvalidTokenException()); } - storage.commitTransaction(con); + epStorage.commitTransaction(con); if (matchedToken.email == null) { // this is possible if the token was generated before migration, and then consumed // after migration - AppIdentifierWithStorage appIdentifierWithStorage = - tenantIdentifierWithStorage.toAppIdentifierWithStorage(); - AuthRecipeUserInfo user = AuthRecipe.getUserById(appIdentifierWithStorage, userId); + AuthRecipeUserInfo user = AuthRecipe.getUserById(tenantIdentifier.toAppIdentifier(), storage, + userId); if (user == null) { throw new StorageTransactionLogicException(new ResetPasswordInvalidTokenException()); } @@ -565,25 +562,25 @@ public static void updateUsersEmailOrPassword(Main main, UnknownUserIdException, DuplicateEmailException, EmailChangeNotAllowedException { try { Storage storage = StorageLayer.getStorage(main); - updateUsersEmailOrPassword(new AppIdentifierWithStorage(null, null, storage), + updateUsersEmailOrPassword(new AppIdentifier(null, null), storage, main, userId, email, password); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static void updateUsersEmailOrPassword(AppIdentifierWithStorage appIdentifierWithStorage, Main main, + public static void updateUsersEmailOrPassword(AppIdentifier appIdentifier, Storage storage, Main main, @Nonnull String userId, @Nullable String email, @Nullable String password) throws StorageQueryException, StorageTransactionLogicException, UnknownUserIdException, DuplicateEmailException, TenantOrAppNotFoundException, EmailChangeNotAllowedException { - EmailPasswordSQLStorage storage = appIdentifierWithStorage.getEmailPasswordStorage(); - AuthRecipeSQLStorage authRecipeStorage = (AuthRecipeSQLStorage) appIdentifierWithStorage.getAuthRecipeStorage(); + EmailPasswordSQLStorage epStorage = StorageUtils.getEmailPasswordStorage(storage); + AuthRecipeSQLStorage authRecipeStorage = StorageUtils.getAuthRecipeStorage(storage); try { - storage.startTransaction(transaction -> { + epStorage.startTransaction(transaction -> { try { - AuthRecipeUserInfo user = authRecipeStorage.getPrimaryUserById_Transaction(appIdentifierWithStorage, + AuthRecipeUserInfo user = authRecipeStorage.getPrimaryUserById_Transaction(appIdentifier, transaction, userId); if (user == null) { @@ -605,7 +602,7 @@ public static void updateUsersEmailOrPassword(AppIdentifierWithStorage appIdenti for (String tenantId : user.tenantIds) { AuthRecipeUserInfo[] existingUsersWithNewEmail = authRecipeStorage.listPrimaryUsersByEmail_Transaction( - appIdentifierWithStorage, transaction, + appIdentifier, transaction, email); for (AuthRecipeUserInfo userWithSameEmail : existingUsersWithNewEmail) { @@ -621,7 +618,7 @@ public static void updateUsersEmailOrPassword(AppIdentifierWithStorage appIdenti } try { - storage.updateUsersEmail_Transaction(appIdentifierWithStorage, transaction, + epStorage.updateUsersEmail_Transaction(appIdentifier, transaction, userId, email); } catch (DuplicateEmailException e) { throw new StorageTransactionLogicException(e); @@ -630,12 +627,12 @@ public static void updateUsersEmailOrPassword(AppIdentifierWithStorage appIdenti if (password != null) { String hashedPassword = PasswordHashing.getInstance(main) - .createHashWithSalt(appIdentifierWithStorage, password); - storage.updateUsersPassword_Transaction(appIdentifierWithStorage, transaction, userId, + .createHashWithSalt(appIdentifier, password); + epStorage.updateUsersPassword_Transaction(appIdentifier, transaction, userId, hashedPassword); } - storage.commitTransaction(transaction); + epStorage.commitTransaction(transaction); return null; } catch (TenantOrAppNotFoundException e) { throw new StorageTransactionLogicException(e); @@ -661,17 +658,17 @@ public static AuthRecipeUserInfo getUserUsingId(Main main, String userId) throws StorageQueryException { try { Storage storage = StorageLayer.getStorage(main); - return getUserUsingId(new AppIdentifierWithStorage(null, null, storage), userId); + return getUserUsingId(new AppIdentifier(null, null), storage, userId); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } @Deprecated - public static AuthRecipeUserInfo getUserUsingId(AppIdentifierWithStorage appIdentifierWithStorage, String userId) + public static AuthRecipeUserInfo getUserUsingId(AppIdentifier appIdentifier, Storage storage, String userId) throws StorageQueryException, TenantOrAppNotFoundException { - AuthRecipeUserInfo result = appIdentifierWithStorage.getAuthRecipeStorage() - .getPrimaryUserById(appIdentifierWithStorage, userId); + AuthRecipeUserInfo result = StorageUtils.getAuthRecipeStorage(storage) + .getPrimaryUserById(appIdentifier, userId); if (result == null) { return null; } @@ -684,11 +681,11 @@ public static AuthRecipeUserInfo getUserUsingId(AppIdentifierWithStorage appIden } @Deprecated - public static AuthRecipeUserInfo getUserUsingEmail(TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static AuthRecipeUserInfo getUserUsingEmail(TenantIdentifier tenantIdentifier, Storage storage, String email) throws StorageQueryException, TenantOrAppNotFoundException { - AuthRecipeUserInfo[] users = tenantIdentifierWithStorage.getAuthRecipeStorage().listPrimaryUsersByEmail( - tenantIdentifierWithStorage, email); + AuthRecipeUserInfo[] users = StorageUtils.getEmailPasswordStorage(storage).listPrimaryUsersByEmail( + tenantIdentifier, email); // filter used based on login method for (AuthRecipeUserInfo user : users) { for (LoginMethod lM : user.loginMethods) { diff --git a/src/main/java/io/supertokens/session/Session.java b/src/main/java/io/supertokens/session/Session.java index 35ee2fd60..aa41b3ae8 100644 --- a/src/main/java/io/supertokens/session/Session.java +++ b/src/main/java/io/supertokens/session/Session.java @@ -29,12 +29,14 @@ import io.supertokens.multitenancy.Multitenancy; import io.supertokens.pluginInterface.STORAGE_TYPE; import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.authRecipe.AuthRecipeStorage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.authRecipe.LoginMethod; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.*; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; +import io.supertokens.pluginInterface.session.SessionStorage; import io.supertokens.pluginInterface.session.noSqlStorage.SessionNoSQLStorage_1; import io.supertokens.pluginInterface.session.sqlStorage.SessionSQLStorage; import io.supertokens.pluginInterface.sqlStorage.SQLStorage; @@ -722,7 +724,8 @@ public static String[] revokeSessionUsingSessionHandles(Main main, } public static String[] revokeSessionUsingSessionHandles(Main main, - AppIdentifierWithStorage appIdentifierWithStorage, + AppIdentifier appIdentifier, + Storage storage, String[] sessionHandles) throws StorageQueryException { @@ -745,18 +748,17 @@ public static String[] revokeSessionUsingSessionHandles(Main main, for (String tenantId : sessionHandleMap.keySet()) { String[] sessionHandlesForTenant = sessionHandleMap.get(tenantId).toArray(new String[0]); - TenantIdentifier tenantIdentifier = new TenantIdentifier(appIdentifierWithStorage.getConnectionUriDomain(), - appIdentifierWithStorage.getAppId(), tenantId); - TenantIdentifierWithStorage tenantIdentifierWithStorage = null; + TenantIdentifier tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), + appIdentifier.getAppId(), tenantId); + Storage tenantStorage = null; try { - tenantIdentifierWithStorage = tenantIdentifier.withStorage( - StorageLayer.getStorage(tenantIdentifier, main)); + tenantStorage = StorageLayer.getStorage(tenantIdentifier, main); } catch (TenantOrAppNotFoundException e) { // ignore as this can happen if the tenant has been deleted after fetching the sessionHandles continue; } - String[] sessionHandlesRevokedForTenant = revokeSessionUsingSessionHandles(tenantIdentifierWithStorage, + String[] sessionHandlesRevokedForTenant = revokeSessionUsingSessionHandles(tenantIdentifier, storage, sessionHandlesForTenant); revokedSessionHandles.addAll(Arrays.asList(sessionHandlesRevokedForTenant)); } @@ -764,7 +766,8 @@ public static String[] revokeSessionUsingSessionHandles(Main main, return revokedSessionHandles.toArray(new String[0]); } - private static String[] revokeSessionUsingSessionHandles(TenantIdentifierWithStorage tenantIdentifierWithStorage, + private static String[] revokeSessionUsingSessionHandles(TenantIdentifier tenantIdentifier, + Storage storage, String[] sessionHandles) throws StorageQueryException { Set validHandles = new HashSet<>(); @@ -774,15 +777,15 @@ private static String[] revokeSessionUsingSessionHandles(TenantIdentifierWithSto // if there is only one sessionHandle to revoke, we would know if it was valid by the number of revoked // sessions for (String sessionHandle : sessionHandles) { - if (tenantIdentifierWithStorage.getSessionStorage() - .getSession(tenantIdentifierWithStorage, sessionHandle) != null) { + if (((SessionStorage) storage) + .getSession(tenantIdentifier, sessionHandle) != null) { validHandles.add(sessionHandle); } } } - int numberOfSessionsRevoked = tenantIdentifierWithStorage.getSessionStorage() - .deleteSession(tenantIdentifierWithStorage, sessionHandles); + int numberOfSessionsRevoked = ((SessionStorage) storage) + .deleteSession(tenantIdentifier, sessionHandles); // most of the time we will enter the below if statement if (numberOfSessionsRevoked == sessionHandles.length) { @@ -795,8 +798,8 @@ private static String[] revokeSessionUsingSessionHandles(TenantIdentifierWithSto if (!validHandles.contains(sessionHandle)) { continue; // no need to check if the sessionHandle was invalid in the first place } - if (tenantIdentifierWithStorage.getSessionStorage() - .getSession(tenantIdentifierWithStorage, sessionHandle) == null) { + if (((SessionStorage) storage) + .getSession(tenantIdentifier, sessionHandle) == null) { revokedSessionHandles.add(sessionHandle); } } @@ -808,15 +811,16 @@ private static String[] revokeSessionUsingSessionHandles(TenantIdentifierWithSto public static String[] revokeAllSessionsForUser(Main main, String userId) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); return revokeAllSessionsForUser(main, - new AppIdentifierWithStorage(null, null, storage), userId, true); + new AppIdentifier(null, null), storage, userId, true); } - public static String[] revokeAllSessionsForUser(Main main, AppIdentifierWithStorage appIdentifierWithStorage, - String userId, boolean revokeSessionsForLinkedAccounts) + public static String[] revokeAllSessionsForUser(Main main, AppIdentifier appIdentifier, + Storage storage, String userId, + boolean revokeSessionsForLinkedAccounts) throws StorageQueryException { - String[] sessionHandles = getAllNonExpiredSessionHandlesForUser(main, appIdentifierWithStorage, userId, + String[] sessionHandles = getAllNonExpiredSessionHandlesForUser(main, appIdentifier, storage, userId, revokeSessionsForLinkedAccounts); - return revokeSessionUsingSessionHandles(main, appIdentifierWithStorage, sessionHandles); + return revokeSessionUsingSessionHandles(main, appIdentifier, storage, sessionHandles); } public static String[] revokeAllSessionsForUser(Main main, TenantIdentifierWithStorage tenantIdentifierWithStorage, @@ -837,20 +841,20 @@ public static String[] getAllNonExpiredSessionHandlesForUser(Main main, String u } public static String[] getAllNonExpiredSessionHandlesForUser( - Main main, AppIdentifierWithStorage appIdentifierWithStorage, String userId, + Main main, AppIdentifier appIdentifier, Storage storage, String userId, boolean fetchSessionsForAllLinkedAccounts) throws StorageQueryException { TenantConfig[] tenants = Multitenancy.getAllTenantsForApp( - appIdentifierWithStorage, main); + appIdentifier, main); List sessionHandles = new ArrayList<>(); Set userIds = new HashSet<>(); userIds.add(userId); if (fetchSessionsForAllLinkedAccounts) { - if (appIdentifierWithStorage.getStorage().getType().equals(STORAGE_TYPE.SQL)) { - AuthRecipeUserInfo primaryUser = appIdentifierWithStorage.getAuthRecipeStorage() - .getPrimaryUserById(appIdentifierWithStorage, userId); + if (storage.getType().equals(STORAGE_TYPE.SQL)) { + AuthRecipeUserInfo primaryUser = ((AuthRecipeStorage) storage) + .getPrimaryUserById(appIdentifier, userId); if (primaryUser != null) { for (LoginMethod lM : primaryUser.loginMethods) { userIds.add(lM.getSupertokensUserId()); @@ -861,12 +865,10 @@ public static String[] getAllNonExpiredSessionHandlesForUser( for (String currUserId : userIds) { for (TenantConfig tenant : tenants) { - TenantIdentifierWithStorage tenantIdentifierWithStorage = null; try { - tenantIdentifierWithStorage = tenant.tenantIdentifier.withStorage( - StorageLayer.getStorage(tenant.tenantIdentifier, main)); sessionHandles.addAll(Arrays.asList(getAllNonExpiredSessionHandlesForUser( - tenantIdentifierWithStorage, currUserId, false))); + tenant.tenantIdentifier, StorageLayer.getStorage(tenant.tenantIdentifier, main), + currUserId, false))); } catch (TenantOrAppNotFoundException e) { // this might happen when a tenant was deleted after the tenant list was fetched @@ -879,14 +881,14 @@ public static String[] getAllNonExpiredSessionHandlesForUser( } public static String[] getAllNonExpiredSessionHandlesForUser( - TenantIdentifierWithStorage tenantIdentifierWithStorage, String userId, + TenantIdentifier tenantIdentifier, Storage storage, String userId, boolean fetchSessionsForAllLinkedAccounts) throws StorageQueryException { Set userIds = new HashSet<>(); userIds.add(userId); if (fetchSessionsForAllLinkedAccounts) { - AuthRecipeUserInfo primaryUser = tenantIdentifierWithStorage.getAuthRecipeStorage() - .getPrimaryUserById(tenantIdentifierWithStorage.toAppIdentifier(), userId); + AuthRecipeUserInfo primaryUser = ((AuthRecipeStorage) storage) + .getPrimaryUserById(tenantIdentifier.toAppIdentifier(), userId); if (primaryUser != null) { for (LoginMethod lM : primaryUser.loginMethods) { userIds.add(lM.getSupertokensUserId()); @@ -895,8 +897,8 @@ public static String[] getAllNonExpiredSessionHandlesForUser( } List sessionHandles = new ArrayList<>(); for (String currUserId : userIds) { - sessionHandles.addAll(List.of(tenantIdentifierWithStorage.getSessionStorage() - .getAllNonExpiredSessionHandlesForUser(tenantIdentifierWithStorage, currUserId))); + sessionHandles.addAll(List.of(((SessionStorage) storage) + .getAllNonExpiredSessionHandlesForUser(tenantIdentifier, currUserId))); } return sessionHandles.toArray(new String[0]); } diff --git a/src/main/java/io/supertokens/storageLayer/StorageLayer.java b/src/main/java/io/supertokens/storageLayer/StorageLayer.java index ec94b05e9..517ee5d17 100644 --- a/src/main/java/io/supertokens/storageLayer/StorageLayer.java +++ b/src/main/java/io/supertokens/storageLayer/StorageLayer.java @@ -405,86 +405,119 @@ public static Storage[] getStoragesForApp(Main main, AppIdentifier appIdentifier return storages; } - public static TenantIdentifierWithStorageAndUserIdMapping getTenantIdentifierWithStorageAndUserIdMappingForUser( + public static StorageAndUserIdMapping getTenantIdentifierWithStorageAndUserIdMappingForUser( Main main, TenantIdentifier tenantIdentifier, String userId, UserIdType userIdType) throws StorageQueryException, TenantOrAppNotFoundException, UnknownUserIdException { Storage storage = getStorage(tenantIdentifier, main); - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage(storage); - UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( - tenantIdentifierWithStorage.toAppIdentifierWithStorage(), userId, userIdType); - if (mapping != null) { - return new TenantIdentifierWithStorageAndUserIdMapping(tenantIdentifierWithStorage, mapping); - } + if (userIdType == UserIdType.SUPERTOKENS) { + if (((AuthRecipeStorage) storage).doesUserIdExist(tenantIdentifier.toAppIdentifier(), userId)) { + UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( + tenantIdentifier.toAppIdentifier(), storage, userId, userIdType); + + return new StorageAndUserIdMapping(storage, mapping); + } + + } else if (userIdType == UserIdType.EXTERNAL) { + UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( + tenantIdentifier.toAppIdentifier(), storage, + userId, userIdType); + if (mapping != null) { + return new StorageAndUserIdMapping(storage, mapping); + } + } else if (userIdType == UserIdType.ANY) { + if (((AuthRecipeStorage) storage).doesUserIdExist(tenantIdentifier.toAppIdentifier(), userId)) { + UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( + tenantIdentifier.toAppIdentifier(), storage, userId, userIdType); + + return new StorageAndUserIdMapping(storage, mapping); + } - if (userIdType != UserIdType.EXTERNAL - && ((AuthRecipeStorage) storage).doesUserIdExist(tenantIdentifier.toAppIdentifier(), userId)) { - return new TenantIdentifierWithStorageAndUserIdMapping( - tenantIdentifierWithStorage, null); - } - if (userIdType != UserIdType.SUPERTOKENS) { try { io.supertokens.useridmapping.UserIdMapping.findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed( - tenantIdentifierWithStorage.toAppIdentifierWithStorage(), userId, true); + tenantIdentifier.toAppIdentifier(), storage, userId, true); } catch (ServletException e) { // this means that the userId is being used for a non auth recipe. - return new TenantIdentifierWithStorageAndUserIdMapping( - tenantIdentifierWithStorage, null); + return new StorageAndUserIdMapping( + storage, null); } + + } else { + throw new IllegalStateException("should never come here"); } throw new UnknownUserIdException(); } - public static AppIdentifierWithStorageAndUserIdMapping getAppIdentifierWithStorageAndUserIdMappingForUser( - AppIdentifierWithStorages appIdentifierWithStorages, String userId, + public static StorageAndUserIdMapping getAppIdentifierWithStorageAndUserIdMappingForUser( + AppIdentifier appIdentifier, Storage[] storages, String userId, UserIdType userIdType) throws StorageQueryException, TenantOrAppNotFoundException, UnknownUserIdException { - Storage[] storages = appIdentifierWithStorages.getStorages(); + if (userIdType == UserIdType.SUPERTOKENS) { + for (Storage storage : storages) { + if (((AuthRecipeStorage) storage).doesUserIdExist(appIdentifier, userId)) { + UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( + appIdentifier, storage, + userId, userIdType); - if (storages.length == 0) { - throw new TenantOrAppNotFoundException(appIdentifierWithStorages); - } - - AppIdentifier appIdentifier = appIdentifierWithStorages; + return new StorageAndUserIdMapping(storage, mapping); + } + } - // First look in auth recipes - for (Storage storage : storages) { - if (userIdType != UserIdType.EXTERNAL - && ((AuthRecipeStorage) storage).doesUserIdExist(appIdentifier, userId)) { - AppIdentifierWithStorage appIdentifierWithStorage = appIdentifier.withStorage(storage); + // Not found in any of the storages + throw new UnknownUserIdException(); + } else if (userIdType == UserIdType.EXTERNAL) { + for (Storage storage : storages) { UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( - appIdentifierWithStorages.withStorage(storage), + appIdentifier, storage, userId, userIdType); - return new AppIdentifierWithStorageAndUserIdMapping(appIdentifierWithStorage, mapping); + if (mapping != null) { + return new StorageAndUserIdMapping(storage, mapping); + } } - } - for (Storage storage : storages) { - UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( - appIdentifierWithStorages.withStorage(storage), - userId, userIdType); + throw new UnknownUserIdException(); + } else if (userIdType == UserIdType.ANY) { - if (mapping != null) { - AppIdentifierWithStorage appIdentifierWithStorage = appIdentifier.withStorage(storage); - return new AppIdentifierWithStorageAndUserIdMapping(appIdentifierWithStorage, mapping); + // look for the user in auth recipes as supertokens user id + for (Storage storage : storages) { + if (((AuthRecipeStorage) storage).doesUserIdExist(appIdentifier, userId)) { + UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( + appIdentifier, storage, + userId, userIdType); + + return new StorageAndUserIdMapping(storage, mapping); + } + } + + // Look for user in auth recipes using user id mapping + for (Storage storage : storages) { + UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( + appIdentifier, storage, + userId, userIdType); + + if (mapping != null) { + return new StorageAndUserIdMapping(storage, mapping); + } } - if (userIdType != UserIdType.SUPERTOKENS) { - AppIdentifierWithStorage appIdentifierWithStorage = appIdentifier.withStorage(storage); + // Look for non auth recipes + for (Storage storage : storages) { try { io.supertokens.useridmapping.UserIdMapping.findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed( - appIdentifierWithStorage, userId, true); + appIdentifier, storage, userId, true); } catch (ServletException e) { // this means that the userId is being used for a non auth recipe. - return new AppIdentifierWithStorageAndUserIdMapping(appIdentifierWithStorage, null); + return new StorageAndUserIdMapping(storage, null); } } - } - throw new UnknownUserIdException(); + throw new UnknownUserIdException(); + } else { + throw new IllegalStateException("should never come here"); + } } } diff --git a/src/main/java/io/supertokens/useridmapping/UserIdMapping.java b/src/main/java/io/supertokens/useridmapping/UserIdMapping.java index 0d82cacc5..554517681 100644 --- a/src/main/java/io/supertokens/useridmapping/UserIdMapping.java +++ b/src/main/java/io/supertokens/useridmapping/UserIdMapping.java @@ -16,9 +16,10 @@ package io.supertokens.useridmapping; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.authRecipe.AuthRecipeStorage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.authRecipe.LoginMethod; @@ -27,9 +28,8 @@ import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.jwt.JWTRecipeStorage; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorages; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.session.SessionStorage; import io.supertokens.pluginInterface.sqlStorage.TransactionConnection; @@ -51,26 +51,26 @@ public class UserIdMapping { @TestOnly - public static void createUserIdMapping(AppIdentifierWithStorages appIdentifierWithStorages, + public static void createUserIdMapping(AppIdentifier appIdentifier, Storage[] storages, String superTokensUserId, String externalUserId, String externalUserIdInfo, boolean force) throws ServletException, UnknownSuperTokensUserIdException, UserIdMappingAlreadyExistsException, StorageQueryException, TenantOrAppNotFoundException { - createUserIdMapping(appIdentifierWithStorages, superTokensUserId, externalUserId, externalUserIdInfo, + createUserIdMapping(appIdentifier, storages, superTokensUserId, externalUserId, externalUserIdInfo, force, false); } @TestOnly - public static void createUserIdMapping(Main main, AppIdentifierWithStorage appIdentifierWithStorage, String supertokensUserId, String externalUserId, String externalUserIdInfo, boolean force) + public static void createUserIdMapping(Main main, AppIdentifier appIdentifier, Storage storage, String supertokensUserId, String externalUserId, String externalUserIdInfo, boolean force) throws ServletException, UnknownSuperTokensUserIdException, UserIdMappingAlreadyExistsException, StorageQueryException, TenantOrAppNotFoundException { createUserIdMapping( - new AppIdentifierWithStorages(appIdentifierWithStorage.getConnectionUriDomain(), appIdentifierWithStorage.getAppId(), new Storage[]{appIdentifierWithStorage.getStorage()}), - supertokensUserId, externalUserId, externalUserIdInfo, force + new AppIdentifier(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId()), + new Storage[]{storage}, supertokensUserId, externalUserId, externalUserIdInfo, force ); } - public static void createUserIdMapping(AppIdentifierWithStorages appIdentifierWithStorages, + public static void createUserIdMapping(AppIdentifier appIdentifier, Storage[] storages, String superTokensUserId, String externalUserId, String externalUserIdInfo, boolean force, boolean makeExceptionForEmailVerification) throws UnknownSuperTokensUserIdException, @@ -85,9 +85,9 @@ public static void createUserIdMapping(AppIdentifierWithStorages appIdentifierWi // This issue - https://github.com/supertokens/supertokens-core/issues/610 - must be resolved when the // race condition is fixed. try { // with external id - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = + StorageAndUserIdMapping mappingAndStorage = StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( - appIdentifierWithStorages, externalUserId, UserIdType.EXTERNAL); + appIdentifier, storages, externalUserId, UserIdType.EXTERNAL); if (mappingAndStorage.userIdMapping != null) { throw new UserIdMappingAlreadyExistsException( @@ -99,15 +99,15 @@ public static void createUserIdMapping(AppIdentifierWithStorages appIdentifierWi // ignore this as we do not want external user id to exist } - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage; + StorageAndUserIdMapping mappingAndStorage; try { mappingAndStorage = StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( - appIdentifierWithStorages, superTokensUserId, UserIdType.SUPERTOKENS); + appIdentifier, storages, superTokensUserId, UserIdType.SUPERTOKENS); } catch (UnknownUserIdException e) { throw new UnknownSuperTokensUserIdException(); } - AppIdentifierWithStorage appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; + Storage userStorage = mappingAndStorage.storage; // if a userIdMapping is created with force, then we skip the following checks if (!force) { @@ -118,8 +118,8 @@ public static void createUserIdMapping(AppIdentifierWithStorages appIdentifierWi // ignore it. { - if (((AuthRecipeStorage) appIdentifierWithStorage.getStorage()).doesUserIdExist( - appIdentifierWithStorages, externalUserId)) { + if (StorageUtils.getAuthRecipeStorage(userStorage).doesUserIdExist( + appIdentifier, externalUserId)) { throw new ServletException(new WebserverAPI.BadRequestException( "Cannot create a userId mapping where the externalId is also a SuperTokens userID")); } @@ -127,7 +127,8 @@ public static void createUserIdMapping(AppIdentifierWithStorages appIdentifierWi if (makeExceptionForEmailVerification) { // check that none of the non-auth recipes are using the superTokensUserId - List storageClasses = findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed(appIdentifierWithStorage, superTokensUserId, false); + List storageClasses = findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed(appIdentifier, + userStorage, superTokensUserId, false); if (storageClasses.size() == 1 && storageClasses.get(0).equals(EmailVerificationStorage.class.getName())) { // if the userId is used in email verification, then we do an exception and update the isEmailVerified // to the externalUserId. We do this because we automatically set the isEmailVerified to true for passwordless @@ -135,7 +136,8 @@ public static void createUserIdMapping(AppIdentifierWithStorages appIdentifierWi // an exception, then the creation of userIdMapping for the user will be blocked. And, to overcome that the // email will have to be unverified first, then the userIdMapping should be created and then the email must be // verified again on the externalUserId, which is not a good user experience. - appIdentifierWithStorage.getEmailVerificationStorage().updateIsEmailVerifiedToExternalUserId(appIdentifierWithStorages, superTokensUserId, externalUserId); + StorageUtils.getEmailVerificationStorage(userStorage).updateIsEmailVerifiedToExternalUserId( + appIdentifier, superTokensUserId, externalUserId); } else if (storageClasses.size() > 0) { String recipeName = storageClasses.get(0); String[] parts = recipeName.split("[.]"); @@ -145,14 +147,15 @@ public static void createUserIdMapping(AppIdentifierWithStorages appIdentifierWi "UserId is already in use in " + recipeName + " recipe")); } } else { - findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed(appIdentifierWithStorage, superTokensUserId, true); + findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed(appIdentifier, userStorage, superTokensUserId, true); } } - appIdentifierWithStorage.getUserIdMappingStorage() - .createUserIdMapping(appIdentifierWithStorages, superTokensUserId, + StorageUtils.getUserIdMappingStorage(userStorage) + .createUserIdMapping(appIdentifier, superTokensUserId, externalUserId, externalUserIdInfo); } + @TestOnly public static void createUserIdMapping(Main main, String superTokensUserId, String externalUserId, @@ -170,7 +173,7 @@ public static void createUserIdMapping(Main main, UserIdMappingAlreadyExistsException, StorageQueryException, ServletException, UnknownUserIdException { try { Storage storage = StorageLayer.getStorage(main); - createUserIdMapping(new AppIdentifierWithStorages(null, null, new Storage[]{storage}), superTokensUserId, + createUserIdMapping(new AppIdentifier(null, null), new Storage[]{storage}, superTokensUserId, externalUserId, externalUserIdInfo, force, makeExceptionForEmailVerification); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); @@ -178,14 +181,15 @@ public static void createUserIdMapping(Main main, } public static io.supertokens.pluginInterface.useridmapping.UserIdMapping getUserIdMapping( - AppIdentifierWithStorage appIdentifierWithStorage, String userId, + AppIdentifier appIdentifier, Storage storage, String userId, UserIdType userIdType) throws StorageQueryException { - UserIdMappingSQLStorage storage = (UserIdMappingSQLStorage) appIdentifierWithStorage.getUserIdMappingStorage(); + UserIdMappingSQLStorage uidMappingStorage = + (UserIdMappingSQLStorage) storage; try { - return storage.startTransaction(con -> { - return getUserIdMapping(con, appIdentifierWithStorage, userId, userIdType); + return uidMappingStorage.startTransaction(con -> { + return getUserIdMapping(con, appIdentifier, uidMappingStorage, userId, userIdType); }); } catch (StorageTransactionLogicException e) { if (e.actualException instanceof StorageQueryException) { @@ -198,21 +202,22 @@ public static io.supertokens.pluginInterface.useridmapping.UserIdMapping getUser public static io.supertokens.pluginInterface.useridmapping.UserIdMapping getUserIdMapping( TransactionConnection con, - AppIdentifierWithStorage appIdentifierWithStorage, String userId, + AppIdentifier appIdentifier, Storage storage, String userId, UserIdType userIdType) throws StorageQueryException { - UserIdMappingSQLStorage storage = (UserIdMappingSQLStorage) appIdentifierWithStorage.getUserIdMappingStorage(); + UserIdMappingSQLStorage uidMappingStorage = + (UserIdMappingSQLStorage) storage; if (userIdType == UserIdType.SUPERTOKENS) { - return storage.getUserIdMapping_Transaction(con, appIdentifierWithStorage, userId, true); + return uidMappingStorage.getUserIdMapping_Transaction(con, appIdentifier, userId, true); } if (userIdType == UserIdType.EXTERNAL) { - return storage.getUserIdMapping_Transaction(con, appIdentifierWithStorage, userId, false); + return uidMappingStorage.getUserIdMapping_Transaction(con, appIdentifier, userId, false); } - io.supertokens.pluginInterface.useridmapping.UserIdMapping[] userIdMappings = storage.getUserIdMapping_Transaction( - con, appIdentifierWithStorage, userId); + io.supertokens.pluginInterface.useridmapping.UserIdMapping[] userIdMappings = uidMappingStorage.getUserIdMapping_Transaction( + con, appIdentifier, userId); if (userIdMappings.length == 0) { return null; @@ -239,25 +244,25 @@ public static io.supertokens.pluginInterface.useridmapping.UserIdMapping getUser UserIdType userIdType) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - return getUserIdMapping(new AppIdentifierWithStorage(null, null, storage), userId, userIdType); + return getUserIdMapping(new AppIdentifier(null, null), storage, userId, userIdType); } - public static boolean deleteUserIdMapping(AppIdentifierWithStorage appIdentifierWithStorage, String userId, + public static boolean deleteUserIdMapping(AppIdentifier appIdentifier, Storage storage, String userId, UserIdType userIdType, boolean force) throws StorageQueryException, ServletException { // referring to // https://docs.google.com/spreadsheets/d/17hYV32B0aDCeLnSxbZhfRN2Y9b0LC2xUF44vV88RNAA/edit?usp=sharing // we need to check if db is in A3 or A4. - io.supertokens.pluginInterface.useridmapping.UserIdMapping mapping = getUserIdMapping(appIdentifierWithStorage, - userId, UserIdType.ANY); - UserIdMappingStorage storage = appIdentifierWithStorage.getUserIdMappingStorage(); + io.supertokens.pluginInterface.useridmapping.UserIdMapping mapping = getUserIdMapping(appIdentifier, + storage, userId, UserIdType.ANY); + UserIdMappingStorage uidMappingStorage = StorageUtils.getUserIdMappingStorage(storage); if (mapping != null) { - if (((AuthRecipeStorage) appIdentifierWithStorage.getStorage()).doesUserIdExist( - appIdentifierWithStorage, mapping.externalUserId)) { + if (StorageUtils.getAuthRecipeStorage(storage).doesUserIdExist( + appIdentifier, mapping.externalUserId)) { // this means that the db is in state A4 - return storage.deleteUserIdMapping(appIdentifierWithStorage, mapping.superTokensUserId, true); + return uidMappingStorage.deleteUserIdMapping(appIdentifier, mapping.superTokensUserId, true); } } else { return false; @@ -268,23 +273,23 @@ public static boolean deleteUserIdMapping(AppIdentifierWithStorage appIdentifier String externalId = mapping.externalUserId; // check if externalId is used in any non-auth recipes - findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed(appIdentifierWithStorage, externalId, true); + findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed(appIdentifier, storage, externalId, true); } // db is in state A3 if (userIdType == UserIdType.SUPERTOKENS) { - return storage.deleteUserIdMapping(appIdentifierWithStorage, userId, true); + return uidMappingStorage.deleteUserIdMapping(appIdentifier, userId, true); } if (userIdType == UserIdType.EXTERNAL) { - return storage.deleteUserIdMapping(appIdentifierWithStorage, userId, false); + return uidMappingStorage.deleteUserIdMapping(appIdentifier, userId, false); } - if (((AuthRecipeStorage) appIdentifierWithStorage.getStorage()).doesUserIdExist(appIdentifierWithStorage, + if (StorageUtils.getAuthRecipeStorage(storage).doesUserIdExist(appIdentifier, userId)) { - return storage.deleteUserIdMapping(appIdentifierWithStorage, userId, true); + return uidMappingStorage.deleteUserIdMapping(appIdentifier, userId, true); } - return storage.deleteUserIdMapping(appIdentifierWithStorage, userId, false); + return uidMappingStorage.deleteUserIdMapping(appIdentifier, userId, false); } @TestOnly @@ -293,34 +298,34 @@ public static boolean deleteUserIdMapping(Main main, String userId, throws StorageQueryException, ServletException { Storage storage = StorageLayer.getStorage(main); return deleteUserIdMapping( - new AppIdentifierWithStorage(null, null, storage), userId, userIdType, force); + new AppIdentifier(null, null), storage, userId, userIdType, force); } - public static boolean updateOrDeleteExternalUserIdInfo(AppIdentifierWithStorage appIdentifierWithStorage, + public static boolean updateOrDeleteExternalUserIdInfo(AppIdentifier appIdentifier, Storage storage, String userId, UserIdType userIdType, @Nullable String externalUserIdInfo) throws StorageQueryException { - UserIdMappingStorage storage = appIdentifierWithStorage.getUserIdMappingStorage(); + UserIdMappingStorage uidMappingStorage = StorageUtils.getUserIdMappingStorage(storage); if (userIdType == UserIdType.SUPERTOKENS) { - return storage.updateOrDeleteExternalUserIdInfo(appIdentifierWithStorage, userId, true, + return uidMappingStorage.updateOrDeleteExternalUserIdInfo(appIdentifier, userId, true, externalUserIdInfo); } if (userIdType == UserIdType.EXTERNAL) { - return storage.updateOrDeleteExternalUserIdInfo(appIdentifierWithStorage, userId, false, + return uidMappingStorage.updateOrDeleteExternalUserIdInfo(appIdentifier, userId, false, externalUserIdInfo); } // userIdType == UserIdType.ANY // if userId exists in authRecipeStorage, it means it is a UserIdType.SUPERTOKENS - if (((AuthRecipeStorage) appIdentifierWithStorage.getStorage()).doesUserIdExist(appIdentifierWithStorage, + if (StorageUtils.getAuthRecipeStorage(storage).doesUserIdExist(appIdentifier, userId)) { - return storage.updateOrDeleteExternalUserIdInfo(appIdentifierWithStorage, userId, true, + return uidMappingStorage.updateOrDeleteExternalUserIdInfo(appIdentifier, userId, true, externalUserIdInfo); } // else treat it as UserIdType.EXTERNAL - return storage.updateOrDeleteExternalUserIdInfo(appIdentifierWithStorage, userId, false, + return uidMappingStorage.updateOrDeleteExternalUserIdInfo(appIdentifier, userId, false, externalUserIdInfo); } @@ -330,25 +335,16 @@ public static boolean updateOrDeleteExternalUserIdInfo(Main main, @Nullable String externalUserIdInfo) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - return updateOrDeleteExternalUserIdInfo(new AppIdentifierWithStorage( - null, null, storage), + return updateOrDeleteExternalUserIdInfo(new AppIdentifier(null, null), storage, userId, userIdType, externalUserIdInfo); } public static HashMap getUserIdMappingForSuperTokensUserIds( - TenantIdentifierWithStorage tenantIdentifierWithStorage, + Storage storage, ArrayList userIds) throws StorageQueryException { - // userIds are already filtered for a tenant, so this becomes a tenant specific operation. - return tenantIdentifierWithStorage.getUserIdMappingStorage().getUserIdMappingForSuperTokensIds(userIds); - } - - public static HashMap getUserIdMappingForSuperTokensUserIds( - AppIdentifierWithStorage appIdentifierWithStorage, - ArrayList userIds) - throws StorageQueryException { - // userIds are already filtered for a tenant, so this becomes a tenant specific operation. - return appIdentifierWithStorage.getUserIdMappingStorage().getUserIdMappingForSuperTokensIds(userIds); + // userIds are already filtered for a tenant + return StorageUtils.getUserIdMappingStorage(storage).getUserIdMappingForSuperTokensIds(userIds); } @TestOnly @@ -356,18 +352,16 @@ public static HashMap getUserIdMappingForSuperTokensUserIds(Main ArrayList userIds) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - return getUserIdMappingForSuperTokensUserIds( - new TenantIdentifierWithStorage(null, null, null, storage), userIds); + return getUserIdMappingForSuperTokensUserIds(storage, userIds); } public static List findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed( - AppIdentifierWithStorage appIdentifierWithStorage, String userId, boolean assertIfUsed) + AppIdentifier appIdentifier, Storage storage, String userId, boolean assertIfUsed) throws StorageQueryException, ServletException { - Storage storage = appIdentifierWithStorage.getStorage(); List result = new ArrayList<>(); { - if (storage.isUserIdBeingUsedInNonAuthRecipe(appIdentifierWithStorage, + if (storage.isUserIdBeingUsedInNonAuthRecipe(appIdentifier, SessionStorage.class.getName(), userId)) { result.add(SessionStorage.class.getName()); @@ -378,7 +372,7 @@ public static List findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed( } } { - if (storage.isUserIdBeingUsedInNonAuthRecipe(appIdentifierWithStorage, + if (storage.isUserIdBeingUsedInNonAuthRecipe(appIdentifier, UserMetadataStorage.class.getName(), userId)) { result.add(UserMetadataStorage.class.getName()); @@ -389,7 +383,7 @@ public static List findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed( } } { - if (storage.isUserIdBeingUsedInNonAuthRecipe(appIdentifierWithStorage, + if (storage.isUserIdBeingUsedInNonAuthRecipe(appIdentifier, UserRolesStorage.class.getName(), userId)) { result.add(UserRolesStorage.class.getName()); @@ -400,7 +394,7 @@ public static List findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed( } } { - if (storage.isUserIdBeingUsedInNonAuthRecipe(appIdentifierWithStorage, + if (storage.isUserIdBeingUsedInNonAuthRecipe(appIdentifier, EmailVerificationStorage.class.getName(), userId)) { result.add(EmailVerificationStorage.class.getName()); @@ -411,14 +405,14 @@ public static List findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed( } } { - if (storage.isUserIdBeingUsedInNonAuthRecipe(appIdentifierWithStorage, + if (storage.isUserIdBeingUsedInNonAuthRecipe(appIdentifier, JWTRecipeStorage.class.getName(), userId)) { throw new ServletException(new WebserverAPI.BadRequestException("Should never come here")); } } { - if (storage.isUserIdBeingUsedInNonAuthRecipe(appIdentifierWithStorage, TOTPStorage.class.getName(), + if (storage.isUserIdBeingUsedInNonAuthRecipe(appIdentifier, TOTPStorage.class.getName(), userId)) { result.add(TOTPStorage.class.getName()); if (assertIfUsed) { @@ -430,32 +424,7 @@ public static List findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed( return result; } - public static void populateExternalUserIdForUsers(AppIdentifierWithStorage appIdentifierWithStorage, AuthRecipeUserInfo[] users) - throws StorageQueryException { - Set userIds = new HashSet<>(); - - for (AuthRecipeUserInfo user : users) { - userIds.add(user.getSupertokensUserId()); - - for (LoginMethod lm : user.loginMethods) { - userIds.add(lm.getSupertokensUserId()); - } - } - ArrayList userIdsList = new ArrayList<>(userIds); - userIdsList.addAll(userIds); - HashMap userIdMappings = getUserIdMappingForSuperTokensUserIds(appIdentifierWithStorage, - userIdsList); - - for (AuthRecipeUserInfo user : users) { - user.setExternalUserId(userIdMappings.get(user.getSupertokensUserId())); - - for (LoginMethod lm : user.loginMethods) { - lm.setExternalUserId(userIdMappings.get(lm.getSupertokensUserId())); - } - } - } - - public static void populateExternalUserIdForUsers(TenantIdentifierWithStorage tenantIdentifierWithStorage, AuthRecipeUserInfo[] users) + public static void populateExternalUserIdForUsers(Storage storage, AuthRecipeUserInfo[] users) throws StorageQueryException { Set userIds = new HashSet<>(); @@ -468,8 +437,7 @@ public static void populateExternalUserIdForUsers(TenantIdentifierWithStorage te } ArrayList userIdsList = new ArrayList<>(userIds); userIdsList.addAll(userIds); - HashMap userIdMappings = getUserIdMappingForSuperTokensUserIds(tenantIdentifierWithStorage, - userIdsList); + HashMap userIdMappings = getUserIdMappingForSuperTokensUserIds(storage, userIdsList); for (AuthRecipeUserInfo user : users) { user.setExternalUserId(userIdMappings.get(user.getSupertokensUserId())); diff --git a/src/main/java/io/supertokens/usermetadata/UserMetadata.java b/src/main/java/io/supertokens/usermetadata/UserMetadata.java index e0f0d37fd..938f6f749 100644 --- a/src/main/java/io/supertokens/usermetadata/UserMetadata.java +++ b/src/main/java/io/supertokens/usermetadata/UserMetadata.java @@ -19,11 +19,10 @@ import com.google.gson.JsonObject; import io.supertokens.Main; import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.usermetadata.sqlStorage.UserMetadataSQLStorage; import io.supertokens.storageLayer.StorageLayer; @@ -41,28 +40,28 @@ public static JsonObject updateUserMetadata(Main main, Storage storage = StorageLayer.getStorage(main); try { return updateUserMetadata( - new AppIdentifierWithStorage(null, null, storage), + new AppIdentifier(null, null), storage, userId, metadataUpdate); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static JsonObject updateUserMetadata(AppIdentifierWithStorage appIdentifierWithStorage, + public static JsonObject updateUserMetadata(AppIdentifier appIdentifier, Storage storage, @Nonnull String userId, @Nonnull JsonObject metadataUpdate) throws StorageQueryException, StorageTransactionLogicException, TenantOrAppNotFoundException { - UserMetadataSQLStorage storage = appIdentifierWithStorage.getUserMetadataStorage(); + UserMetadataSQLStorage umdStorage = StorageUtils.getUserMetadataStorage(storage); try { - return storage.startTransaction((con) -> { - JsonObject originalMetadata = storage.getUserMetadata_Transaction(appIdentifierWithStorage, con, + return umdStorage.startTransaction((con) -> { + JsonObject originalMetadata = umdStorage.getUserMetadata_Transaction(appIdentifier, con, userId); JsonObject updatedMetadata = originalMetadata == null ? new JsonObject() : originalMetadata; MetadataUtils.shallowMergeMetadataUpdate(updatedMetadata, metadataUpdate); try { - storage.setUserMetadata_Transaction(appIdentifierWithStorage, con, userId, updatedMetadata); + umdStorage.setUserMetadata_Transaction(appIdentifier, con, userId, updatedMetadata); } catch (TenantOrAppNotFoundException e) { throw new StorageTransactionLogicException(e); } @@ -80,15 +79,15 @@ public static JsonObject updateUserMetadata(AppIdentifierWithStorage appIdentifi @TestOnly public static JsonObject getUserMetadata(Main main, @Nonnull String userId) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - return getUserMetadata(new AppIdentifierWithStorage(null, null, storage), userId); + return getUserMetadata(new AppIdentifier(null, null), storage, userId); } - public static JsonObject getUserMetadata(AppIdentifierWithStorage appIdentifierWithStorage, + public static JsonObject getUserMetadata(AppIdentifier appIdentifier, Storage storage, @Nonnull String userId) throws StorageQueryException { - UserMetadataSQLStorage storage = appIdentifierWithStorage.getUserMetadataStorage(); + UserMetadataSQLStorage umdStorage = StorageUtils.getUserMetadataStorage(storage); - JsonObject metadata = storage.getUserMetadata(appIdentifierWithStorage, userId); + JsonObject metadata = umdStorage.getUserMetadata(appIdentifier, userId); if (metadata == null) { return new JsonObject(); @@ -100,11 +99,11 @@ public static JsonObject getUserMetadata(AppIdentifierWithStorage appIdentifierW @TestOnly public static void deleteUserMetadata(Main main, @Nonnull String userId) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - deleteUserMetadata(new AppIdentifierWithStorage(null, null, storage), userId); + deleteUserMetadata(new AppIdentifier(null, null), storage, userId); } - public static void deleteUserMetadata(AppIdentifierWithStorage appIdentifierWithStorage, + public static void deleteUserMetadata(AppIdentifier appIdentifier, Storage storage, @Nonnull String userId) throws StorageQueryException { - appIdentifierWithStorage.getUserMetadataStorage().deleteUserMetadata(appIdentifierWithStorage, userId); + StorageUtils.getUserMetadataStorage(storage).deleteUserMetadata(appIdentifier, userId); } } diff --git a/src/main/java/io/supertokens/userroles/UserRoles.java b/src/main/java/io/supertokens/userroles/UserRoles.java index 6ff0b88e4..451d8f499 100644 --- a/src/main/java/io/supertokens/userroles/UserRoles.java +++ b/src/main/java/io/supertokens/userroles/UserRoles.java @@ -18,10 +18,11 @@ import io.supertokens.Main; import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.userroles.exception.DuplicateUserRoleMappingException; import io.supertokens.pluginInterface.userroles.exception.UnknownRoleException; @@ -34,11 +35,11 @@ public class UserRoles { // add a role to a user and return true, if the role is already mapped to the user return false, but if // the role does not exist, throw an UNKNOWN_ROLE_EXCEPTION error - public static boolean addRoleToUser(TenantIdentifierWithStorage tenantIdentifierWithStorage, String userId, + public static boolean addRoleToUser(TenantIdentifier tenantIdentifier, Storage storage, String userId, String role) throws StorageQueryException, UnknownRoleException, TenantOrAppNotFoundException { try { - tenantIdentifierWithStorage.getUserRolesStorage().addRoleToUser(tenantIdentifierWithStorage, userId, role); + StorageUtils.getUserRolesStorage(storage).addRoleToUser(tenantIdentifier, userId, role); return true; } catch (DuplicateUserRoleMappingException e) { // user already has role @@ -52,8 +53,8 @@ public static boolean addRoleToUser(Main main, String userId, String role) Storage storage = StorageLayer.getStorage(main); try { return addRoleToUser( - new TenantIdentifierWithStorage(null, null, null, storage), - userId, role); + new TenantIdentifier(null, null, null), + storage, userId, role); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } @@ -62,17 +63,17 @@ public static boolean addRoleToUser(Main main, String userId, String role) // create a new role if it doesn't exist and add permissions to the role. This will create the role // in the user pool associated with the tenant used to query this API, so that this role can then // be shared across any tenant in that same user pool. - public static boolean createNewRoleOrModifyItsPermissions(AppIdentifierWithStorage appIdentifierWithStorage, + public static boolean createNewRoleOrModifyItsPermissions(AppIdentifier appIdentifier, Storage storage, String role, String[] permissions) throws StorageQueryException, StorageTransactionLogicException, TenantOrAppNotFoundException { - UserRolesSQLStorage storage = appIdentifierWithStorage.getUserRolesStorage(); + UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); try { - return storage.startTransaction(con -> { + return userRolesStorage.startTransaction(con -> { boolean wasANewRoleCreated = false; try { - wasANewRoleCreated = storage.createNewRoleOrDoNothingIfExists_Transaction( - appIdentifierWithStorage, con, role); + wasANewRoleCreated = userRolesStorage.createNewRoleOrDoNothingIfExists_Transaction( + appIdentifier, con, role); } catch (TenantOrAppNotFoundException e) { throw new StorageTransactionLogicException(e); } @@ -80,14 +81,14 @@ public static boolean createNewRoleOrModifyItsPermissions(AppIdentifierWithStora if (permissions != null) { for (int i = 0; i < permissions.length; i++) { try { - storage.addPermissionToRoleOrDoNothingIfExists_Transaction(appIdentifierWithStorage, + userRolesStorage.addPermissionToRoleOrDoNothingIfExists_Transaction(appIdentifier, con, role, permissions[i]); } catch (UnknownRoleException e) { // ignore exception, should not come here since role should always exist in this transaction } } } - storage.commitTransaction(con); + userRolesStorage.commitTransaction(con); return wasANewRoleCreated; }); } catch (StorageTransactionLogicException e) { @@ -104,38 +105,38 @@ public static boolean createNewRoleOrModifyItsPermissions(Main main, throws StorageQueryException, StorageTransactionLogicException, TenantOrAppNotFoundException { Storage storage = StorageLayer.getStorage(main); return createNewRoleOrModifyItsPermissions( - new AppIdentifierWithStorage(null, null, storage), role, + new AppIdentifier(null, null), storage, role, permissions); } - public static boolean doesRoleExist(AppIdentifierWithStorage appIdentifierWithStorage, String role) + public static boolean doesRoleExist(AppIdentifier appIdentifier, Storage storage, String role) throws StorageQueryException { - UserRolesSQLStorage storage = appIdentifierWithStorage.getUserRolesStorage(); - return storage.doesRoleExist(appIdentifierWithStorage, role); + UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); + return userRolesStorage.doesRoleExist(appIdentifier, role); } @TestOnly public static boolean doesRoleExist(Main main, String role) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - return doesRoleExist(new AppIdentifierWithStorage(null, null, storage), role); + return doesRoleExist(new AppIdentifier(null, null), storage, role); } // remove a role mapped to a user, if the role doesn't exist throw a UNKNOWN_ROLE_EXCEPTION error - public static boolean removeUserRole(TenantIdentifierWithStorage tenantIdentifierWithStorage, String userId, + public static boolean removeUserRole(TenantIdentifier tenantIdentifier, Storage storage, String userId, String role) throws StorageQueryException, StorageTransactionLogicException, UnknownRoleException { - UserRolesSQLStorage storage = tenantIdentifierWithStorage.getUserRolesStorage(); + UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); try { - return storage.startTransaction(con -> { + return userRolesStorage.startTransaction(con -> { - boolean doesRoleExist = storage.doesRoleExist_Transaction( - tenantIdentifierWithStorage.toAppIdentifier(), con, role); + boolean doesRoleExist = userRolesStorage.doesRoleExist_Transaction( + tenantIdentifier.toAppIdentifier(), con, role); if (doesRoleExist) { - return storage.deleteRoleForUser_Transaction(tenantIdentifierWithStorage, con, userId, role); + return userRolesStorage.deleteRoleForUser_Transaction(tenantIdentifier, con, userId, role); } else { throw new StorageTransactionLogicException(new UnknownRoleException()); } @@ -153,14 +154,14 @@ public static boolean removeUserRole(Main main, String userId, String role) throws StorageQueryException, StorageTransactionLogicException, UnknownRoleException { Storage storage = StorageLayer.getStorage(main); return removeUserRole( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, userId, role); } // retrieve all roles associated with the user - public static String[] getRolesForUser(TenantIdentifierWithStorage tenantIdentifierWithStorage, String userId) + public static String[] getRolesForUser(TenantIdentifier tenantIdentifier, Storage storage, String userId) throws StorageQueryException { - return tenantIdentifierWithStorage.getUserRolesStorage().getRolesForUser(tenantIdentifierWithStorage, userId); + return StorageUtils.getUserRolesStorage(storage).getRolesForUser(tenantIdentifier, userId); } @TestOnly @@ -168,18 +169,18 @@ public static String[] getRolesForUser(Main main, String userId) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); return getRolesForUser( - new TenantIdentifierWithStorage(null, null, null, storage), userId); + new TenantIdentifier(null, null, null), storage, userId); } // retrieve all users who have the input role, if role does not exist then throw UNKNOWN_ROLE_EXCEPTION - public static String[] getUsersForRole(TenantIdentifierWithStorage tenantIdentifierWithStorage, String role) + public static String[] getUsersForRole(TenantIdentifier tenantIdentifier, Storage storage, String role) throws StorageQueryException, UnknownRoleException { // Since getUsersForRole does not change any data we do not use a transaction since it would not solve any // problem - UserRolesSQLStorage storage = tenantIdentifierWithStorage.getUserRolesStorage(); - boolean doesRoleExist = storage.doesRoleExist(tenantIdentifierWithStorage.toAppIdentifier(), role); + UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); + boolean doesRoleExist = userRolesStorage.doesRoleExist(tenantIdentifier.toAppIdentifier(), role); if (doesRoleExist) { - return storage.getUsersForRole(tenantIdentifierWithStorage, role); + return userRolesStorage.getUsersForRole(tenantIdentifier, role); } else { throw new UnknownRoleException(); } @@ -190,20 +191,20 @@ public static String[] getUsersForRole(Main main, String role) throws StorageQueryException, UnknownRoleException { Storage storage = StorageLayer.getStorage(main); return getUsersForRole( - new TenantIdentifierWithStorage(null, null, null, storage), role); + new TenantIdentifier(null, null, null), storage, role); } // retrieve all permissions associated with the role - public static String[] getPermissionsForRole(AppIdentifierWithStorage appIdentifierWithStorage, String role) + public static String[] getPermissionsForRole(AppIdentifier appIdentifier, Storage storage, String role) throws StorageQueryException, UnknownRoleException { // Since getPermissionsForRole does not change any data we do not use a transaction since it would not solve any // problem - UserRolesSQLStorage storage = appIdentifierWithStorage.getUserRolesStorage(); - boolean doesRoleExist = storage.doesRoleExist(appIdentifierWithStorage, role); + UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); + boolean doesRoleExist = userRolesStorage.doesRoleExist(appIdentifier, role); if (doesRoleExist) { - return appIdentifierWithStorage.getUserRolesStorage() - .getPermissionsForRole(appIdentifierWithStorage, role); + return StorageUtils.getUserRolesStorage(storage) + .getPermissionsForRole(appIdentifier, role); } else { throw new UnknownRoleException(); } @@ -214,30 +215,30 @@ public static String[] getPermissionsForRole(Main main, String role) throws StorageQueryException, UnknownRoleException { Storage storage = StorageLayer.getStorage(main); return getPermissionsForRole( - new AppIdentifierWithStorage(null, null, storage), role); + new AppIdentifier(null, null), storage, role); } // delete permissions from a role, if the role doesn't exist throw an UNKNOWN_ROLE_EXCEPTION - public static void deletePermissionsFromRole(AppIdentifierWithStorage appIdentifierWithStorage, String role, + public static void deletePermissionsFromRole(AppIdentifier appIdentifier, Storage storage, String role, @Nullable String[] permissions) throws StorageQueryException, StorageTransactionLogicException, UnknownRoleException { - UserRolesSQLStorage storage = appIdentifierWithStorage.getUserRolesStorage(); + UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); try { - storage.startTransaction(con -> { - boolean doesRoleExist = storage.doesRoleExist_Transaction(appIdentifierWithStorage, con, role); + userRolesStorage.startTransaction(con -> { + boolean doesRoleExist = userRolesStorage.doesRoleExist_Transaction(appIdentifier, con, role); if (doesRoleExist) { if (permissions == null) { - storage.deleteAllPermissionsForRole_Transaction(appIdentifierWithStorage, con, role); + userRolesStorage.deleteAllPermissionsForRole_Transaction(appIdentifier, con, role); } else { for (int i = 0; i < permissions.length; i++) { - storage.deletePermissionForRole_Transaction(appIdentifierWithStorage, con, role, + userRolesStorage.deletePermissionForRole_Transaction(appIdentifier, con, role, permissions[i]); } } } else { throw new StorageTransactionLogicException(new UnknownRoleException()); } - storage.commitTransaction(con); + userRolesStorage.commitTransaction(con); return null; }); } catch (StorageTransactionLogicException e) { @@ -253,16 +254,16 @@ public static void deletePermissionsFromRole(Main main, String role, @Nullable String[] permissions) throws StorageQueryException, StorageTransactionLogicException, UnknownRoleException { Storage storage = StorageLayer.getStorage(main); - deletePermissionsFromRole(new AppIdentifierWithStorage(null, null, storage), + deletePermissionsFromRole(new AppIdentifier(null, null), storage, role, permissions); } // retrieve roles that have the input permission - public static String[] getRolesThatHavePermission(AppIdentifierWithStorage appIdentifierWithStorage, + public static String[] getRolesThatHavePermission(AppIdentifier appIdentifier, Storage storage, String permission) throws StorageQueryException { - return appIdentifierWithStorage.getUserRolesStorage().getRolesThatHavePermission( - appIdentifierWithStorage, permission); + return StorageUtils.getUserRolesStorage(storage).getRolesThatHavePermission( + appIdentifier, permission); } @TestOnly @@ -270,38 +271,38 @@ public static String[] getRolesThatHavePermission(Main main, String permission) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); return getRolesThatHavePermission( - new AppIdentifierWithStorage(null, null, storage), permission); + new AppIdentifier(null, null), storage, permission); } // delete a role - public static boolean deleteRole(AppIdentifierWithStorage appIdentifierWithStorage, String role) + public static boolean deleteRole(AppIdentifier appIdentifier, Storage storage, String role) throws StorageQueryException { - return appIdentifierWithStorage.getUserRolesStorage().deleteRole(appIdentifierWithStorage, role); + return StorageUtils.getUserRolesStorage(storage).deleteRole(appIdentifier, role); } @TestOnly public static boolean deleteRole(Main main, String role) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - return deleteRole(new AppIdentifierWithStorage(null, null, storage), role); + return deleteRole(new AppIdentifier(null, null), storage, role); } // retrieve all roles that have been created - public static String[] getRoles(AppIdentifierWithStorage appIdentifierWithStorage) + public static String[] getRoles(AppIdentifier appIdentifier, Storage storage) throws StorageQueryException { - return appIdentifierWithStorage.getUserRolesStorage().getRoles(appIdentifierWithStorage); + return StorageUtils.getUserRolesStorage(storage).getRoles(appIdentifier); } @TestOnly public static String[] getRoles(Main main) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - return getRoles(new AppIdentifierWithStorage(null, null, storage)); + return getRoles(new AppIdentifier(null, null), storage); } // delete all roles associated with a user - public static int deleteAllRolesForUser(TenantIdentifierWithStorage tenantIdentifierWithStorage, String userId) + public static int deleteAllRolesForUser(TenantIdentifier tenantIdentifier, Storage storage, String userId) throws StorageQueryException { - return tenantIdentifierWithStorage.getUserRolesStorage().deleteAllRolesForUser( - tenantIdentifierWithStorage, userId); + return StorageUtils.getUserRolesStorage(storage).deleteAllRolesForUser( + tenantIdentifier, userId); } @TestOnly @@ -309,7 +310,7 @@ public static int deleteAllRolesForUser(Main main, String userId) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); return deleteAllRolesForUser( - new TenantIdentifierWithStorage(null, null, null, storage), userId); + new TenantIdentifier(null, null, null), storage, userId); } } diff --git a/src/main/java/io/supertokens/webserver/WebserverAPI.java b/src/main/java/io/supertokens/webserver/WebserverAPI.java index 4c4ffa5b3..edc0053ba 100644 --- a/src/main/java/io/supertokens/webserver/WebserverAPI.java +++ b/src/main/java/io/supertokens/webserver/WebserverAPI.java @@ -17,9 +17,8 @@ package io.supertokens.webserver; import com.google.gson.JsonElement; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; -import io.supertokens.TenantIdentifierWithStorageAndUserIdMapping; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.config.Config; import io.supertokens.config.CoreConfig; import io.supertokens.exceptions.QuitProgramException; @@ -43,7 +42,6 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.apache.catalina.filters.RemoteAddrFilter; -import org.jetbrains.annotations.TestOnly; import java.io.IOException; import java.util.HashSet; @@ -297,8 +295,7 @@ private String getConnectionUriDomain(HttpServletRequest req) throws ServletExce return null; } - @TestOnly - protected TenantIdentifier getTenantIdentifierFromRequest(HttpServletRequest req) throws ServletException { + protected TenantIdentifier getTenantIdentifier(HttpServletRequest req) throws ServletException { return new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), this.getTenantId(req)); } @@ -306,27 +303,24 @@ protected AppIdentifier getAppIdentifier(HttpServletRequest req) throws ServletE return new AppIdentifier(this.getConnectionUriDomain(req), this.getAppId(req)); } - protected TenantIdentifierWithStorage getTenantStorage(HttpServletRequest req) + protected Storage getTenantStorage(HttpServletRequest req) throws TenantOrAppNotFoundException, ServletException { TenantIdentifier tenantIdentifier = new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), this.getTenantId(req)); - Storage storage = StorageLayer.getStorage(tenantIdentifier, main); - return tenantIdentifier.withStorage(storage); + return StorageLayer.getStorage(tenantIdentifier, main); } - protected AppIdentifierWithStorages enforcePublicTenantAndGetAllStoragesForApp(HttpServletRequest req) + protected Storage[] enforcePublicTenantAndGetAllStoragesForApp(HttpServletRequest req) throws ServletException, BadPermissionException, TenantOrAppNotFoundException { if (getTenantId(req) != null) { throw new BadPermissionException("Only public tenantId can this app specific API"); } AppIdentifier appIdentifier = getAppIdentifier(req); - Storage[] storages = StorageLayer.getStoragesForApp(main, appIdentifier); - return new AppIdentifierWithStorages(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), - storages); + return StorageLayer.getStoragesForApp(main, appIdentifier); } - protected AppIdentifierWithStorage enforcePublicTenantAndGetPublicTenantStorage( + protected Storage enforcePublicTenantAndGetPublicTenantStorage( HttpServletRequest req) throws TenantOrAppNotFoundException, BadPermissionException, ServletException { TenantIdentifier tenantIdentifier = new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), @@ -336,22 +330,18 @@ protected AppIdentifierWithStorage enforcePublicTenantAndGetPublicTenantStorage( throw new BadPermissionException("Only public tenantId can this app specific API"); } - Storage storage = StorageLayer.getStorage(tenantIdentifier, main); - return new AppIdentifierWithStorage(tenantIdentifier.getConnectionUriDomain(), tenantIdentifier.getAppId(), - storage); + return StorageLayer.getStorage(tenantIdentifier, main); } - protected AppIdentifierWithStorage getPublicTenantStorage(HttpServletRequest req) + protected Storage getPublicTenantStorage(HttpServletRequest req) throws ServletException, TenantOrAppNotFoundException { // This is only used for update user active time AppIdentifier appIdentifier = new AppIdentifier(this.getConnectionUriDomain(req), this.getAppId(req)); - Storage storage = StorageLayer.getStorage(appIdentifier.getAsPublicTenantIdentifier(), main); - - return appIdentifier.withStorage(storage); + return StorageLayer.getStorage(appIdentifier.getAsPublicTenantIdentifier(), main); } - protected TenantIdentifierWithStorageAndUserIdMapping getStorageAndUserIdMappingForTenantSpecificApi( + protected StorageAndUserIdMapping getStorageAndUserIdMappingForTenantSpecificApi( HttpServletRequest req, String userId, UserIdType userIdType) throws StorageQueryException, TenantOrAppNotFoundException, UnknownUserIdException, ServletException { TenantIdentifier tenantIdentifier = new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), @@ -360,20 +350,21 @@ protected TenantIdentifierWithStorageAndUserIdMapping getStorageAndUserIdMapping userIdType); } - protected AppIdentifierWithStorageAndUserIdMapping getStorageAndUserIdMappingForAppSpecificApi( + protected StorageAndUserIdMapping getStorageAndUserIdMappingForAppSpecificApi( HttpServletRequest req, String userId, UserIdType userIdType) throws StorageQueryException, TenantOrAppNotFoundException, UnknownUserIdException, ServletException, BadPermissionException { // This function uses storage of the tenant from which the request came from as a priorityStorage // while searching for the user across all storages for the app - AppIdentifierWithStorages appIdentifierWithStorages = enforcePublicTenantAndGetAllStoragesForApp(req); + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage[] storages = enforcePublicTenantAndGetAllStoragesForApp(req); return StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( - appIdentifierWithStorages, userId, userIdType); + appIdentifier, storages, userId, userIdType); } protected boolean checkIPAccess(HttpServletRequest req, HttpServletResponse resp) throws TenantOrAppNotFoundException, ServletException, IOException { - CoreConfig config = Config.getConfig(getTenantStorage(req), main); + CoreConfig config = Config.getConfig(getTenantIdentifier(req), main); String allow = config.getIpAllowRegex(); String deny = config.getIpDenyRegex(); if (allow == null && deny == null) { @@ -415,16 +406,7 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws TenantIdentifier tenantIdentifier = null; try { - try { - tenantIdentifier = getTenantStorage(req); - } catch (TenantOrAppNotFoundException e) { - // we do this so that the logs that are printed out have the right "Tenant(.." info in them, - // otherwise it will assume the base tenant (with "" CUD), which may not be the one querying - // this API right now. - tenantIdentifier = new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), - this.getTenantId(req)); - throw e; - } + tenantIdentifier = getTenantIdentifier(req); if (!this.checkIPAccess(req, resp)) { // IP access denied and the filter has already sent the response diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java index 3e4104a8e..55917b79a 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java @@ -17,16 +17,17 @@ package io.supertokens.webserver.api.accountlinking; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.authRecipe.AuthRecipe; import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException; import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithPrimaryUserIdException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; @@ -54,18 +55,20 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO // API is app specific String inputRecipeUserId = InputParser.getQueryParamOrThrowError(req, "recipeUserId", false); - AppIdentifierWithStorage appIdentifierWithStorage = null; + AppIdentifier appIdentifier = this.getAppIdentifier(req); + Storage storage = null; + try { String userId = inputRecipeUserId; - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = + StorageAndUserIdMapping storageAndMapping = getStorageAndUserIdMappingForAppSpecificApi( req, inputRecipeUserId, UserIdType.ANY); - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; + storage = storageAndMapping.storage; + if (storageAndMapping.userIdMapping != null) { + userId = storageAndMapping.userIdMapping.superTokensUserId; } - appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; - AuthRecipe.CreatePrimaryUserResult result = AuthRecipe.canCreatePrimaryUser(appIdentifierWithStorage, + AuthRecipe.CreatePrimaryUserResult result = AuthRecipe.canCreatePrimaryUser(appIdentifier, storage, userId); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); @@ -80,7 +83,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject response = new JsonObject(); response.addProperty("status", "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"); io.supertokens.pluginInterface.useridmapping.UserIdMapping result = UserIdMapping.getUserIdMapping( - appIdentifierWithStorage, e.primaryUserId, + appIdentifier, storage, e.primaryUserId, UserIdType.SUPERTOKENS); if (result != null) { response.addProperty("primaryUserId", result.externalUserId); @@ -97,7 +100,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject response = new JsonObject(); response.addProperty("status", "RECIPE_USER_ID_ALREADY_LINKED_WITH_PRIMARY_USER_ID_ERROR"); io.supertokens.pluginInterface.useridmapping.UserIdMapping result = UserIdMapping.getUserIdMapping( - appIdentifierWithStorage, e.primaryUserId, + appIdentifier, storage, e.primaryUserId, UserIdType.SUPERTOKENS); if (result != null) { response.addProperty("primaryUserId", result.externalUserId); diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java index a70af4e4e..83e2671cb 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java @@ -17,18 +17,19 @@ package io.supertokens.webserver.api.accountlinking; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.authRecipe.AuthRecipe; import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException; import io.supertokens.authRecipe.exception.InputUserIdIsNotAPrimaryUserException; import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; @@ -57,42 +58,43 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO String inputRecipeUserId = InputParser.getQueryParamOrThrowError(req, "recipeUserId", false); String inputPrimaryUserId = InputParser.getQueryParamOrThrowError(req, "primaryUserId", false); - AppIdentifierWithStorage primaryUserIdAppIdentifierWithStorage = null; - AppIdentifierWithStorage recipeUserIdAppIdentifierWithStorage = null; + AppIdentifier appIdentifier = this.getAppIdentifier(req); + Storage primaryUserIdStorage = null; + Storage recipeUserIdStorage = null; try { String recipeUserId = inputRecipeUserId; { - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = + StorageAndUserIdMapping mappingAndStorage = getStorageAndUserIdMappingForAppSpecificApi( req, inputRecipeUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { recipeUserId = mappingAndStorage.userIdMapping.superTokensUserId; } - recipeUserIdAppIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; + recipeUserIdStorage = mappingAndStorage.storage; } String primaryUserId = inputPrimaryUserId; { - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = + StorageAndUserIdMapping mappingAndStorage = getStorageAndUserIdMappingForAppSpecificApi( req, inputPrimaryUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { primaryUserId = mappingAndStorage.userIdMapping.superTokensUserId; } - primaryUserIdAppIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; + primaryUserIdStorage = mappingAndStorage.storage; } // we do a check based on user pool ID and not instance reference checks cause the user // could be in the same db, but their storage layers may just have different - if (!primaryUserIdAppIdentifierWithStorage.getStorage().getUserPoolId().equals( - recipeUserIdAppIdentifierWithStorage.getStorage().getUserPoolId())) { + if (!primaryUserIdStorage.getUserPoolId().equals( + recipeUserIdStorage.getUserPoolId())) { throw new ServletException( new BadRequestException( "Cannot link users that are parts of different databases. Different pool IDs: " + - primaryUserIdAppIdentifierWithStorage.getStorage().getUserPoolId() + " AND " + - recipeUserIdAppIdentifierWithStorage.getStorage().getUserPoolId())); + primaryUserIdStorage.getUserPoolId() + " AND " + + recipeUserIdStorage.getUserPoolId())); } - AuthRecipe.CanLinkAccountsResult result = AuthRecipe.canLinkAccounts(primaryUserIdAppIdentifierWithStorage, + AuthRecipe.CanLinkAccountsResult result = AuthRecipe.canLinkAccounts(appIdentifier, primaryUserIdStorage, recipeUserId, primaryUserId); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); @@ -107,7 +109,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject response = new JsonObject(); response.addProperty("status", "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"); io.supertokens.pluginInterface.useridmapping.UserIdMapping result = UserIdMapping.getUserIdMapping( - primaryUserIdAppIdentifierWithStorage, e.primaryUserId, + appIdentifier, primaryUserIdStorage, e.primaryUserId, UserIdType.SUPERTOKENS); if (result != null) { response.addProperty("primaryUserId", result.externalUserId); @@ -123,7 +125,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { JsonObject response = new JsonObject(); response.addProperty("status", "RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"); - UserIdMapping.populateExternalUserIdForUsers(recipeUserIdAppIdentifierWithStorage, new AuthRecipeUserInfo[]{e.recipeUser}); + UserIdMapping.populateExternalUserIdForUsers(recipeUserIdStorage, + new AuthRecipeUserInfo[]{e.recipeUser}); response.addProperty("primaryUserId", e.recipeUser.getSupertokensOrExternalUserId()); response.addProperty("description", e.getMessage()); super.sendJsonResponse(200, response, resp); diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java index 7fc5e14a3..89be22302 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java @@ -17,17 +17,18 @@ package io.supertokens.webserver.api.accountlinking; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.authRecipe.AuthRecipe; import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException; import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithPrimaryUserIdException; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; @@ -56,18 +57,20 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String inputRecipeUserId = InputParser.parseStringOrThrowError(input, "recipeUserId", false); - AppIdentifierWithStorage appIdentifierWithStorage = null; + AppIdentifier appIdentifier = this.getAppIdentifier(req); + Storage storage = null; + try { String userId = inputRecipeUserId; - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = + StorageAndUserIdMapping mappingAndStorage = getStorageAndUserIdMappingForAppSpecificApi( req, inputRecipeUserId, UserIdType.ANY); + storage = mappingAndStorage.storage; if (mappingAndStorage.userIdMapping != null) { userId = mappingAndStorage.userIdMapping.superTokensUserId; } - appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; - AuthRecipe.CreatePrimaryUserResult result = AuthRecipe.createPrimaryUser(main, appIdentifierWithStorage, + AuthRecipe.CreatePrimaryUserResult result = AuthRecipe.createPrimaryUser(main, appIdentifier, storage, userId); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); @@ -89,7 +92,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject response = new JsonObject(); response.addProperty("status", "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"); io.supertokens.pluginInterface.useridmapping.UserIdMapping result = UserIdMapping.getUserIdMapping( - appIdentifierWithStorage, e.primaryUserId, + appIdentifier, storage, e.primaryUserId, UserIdType.SUPERTOKENS); if (result != null) { response.addProperty("primaryUserId", result.externalUserId); @@ -106,7 +109,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject response = new JsonObject(); response.addProperty("status", "RECIPE_USER_ID_ALREADY_LINKED_WITH_PRIMARY_USER_ID_ERROR"); io.supertokens.pluginInterface.useridmapping.UserIdMapping result = UserIdMapping.getUserIdMapping( - appIdentifierWithStorage, e.primaryUserId, + appIdentifier, storage, e.primaryUserId, UserIdType.SUPERTOKENS); if (result != null) { response.addProperty("primaryUserId", result.externalUserId); diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java index 94924f7fe..5e709fe62 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java @@ -17,8 +17,8 @@ package io.supertokens.webserver.api.accountlinking; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.authRecipe.AuthRecipe; import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException; import io.supertokens.authRecipe.exception.InputUserIdIsNotAPrimaryUserException; @@ -26,10 +26,11 @@ import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; @@ -59,46 +60,47 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String inputRecipeUserId = InputParser.parseStringOrThrowError(input, "recipeUserId", false); String inputPrimaryUserId = InputParser.parseStringOrThrowError(input, "primaryUserId", false); - AppIdentifierWithStorage primaryUserIdAppIdentifierWithStorage = null; - AppIdentifierWithStorage recipeUserIdAppIdentifierWithStorage = null; + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage primaryUserIdStorage = null; + Storage recipeUserIdStorage = null; try { String recipeUserId = inputRecipeUserId; { - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = + StorageAndUserIdMapping mappingAndStorage = getStorageAndUserIdMappingForAppSpecificApi( req, inputRecipeUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { recipeUserId = mappingAndStorage.userIdMapping.superTokensUserId; } - recipeUserIdAppIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; + recipeUserIdStorage = mappingAndStorage.storage; } String primaryUserId = inputPrimaryUserId; { - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = + StorageAndUserIdMapping mappingAndStorage = getStorageAndUserIdMappingForAppSpecificApi( req, inputPrimaryUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { primaryUserId = mappingAndStorage.userIdMapping.superTokensUserId; } - primaryUserIdAppIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; + primaryUserIdStorage = mappingAndStorage.storage; } // we do a check based on user pool ID and not instance reference checks cause the user // could be in the same db, but their storage layers may just have different - if (!primaryUserIdAppIdentifierWithStorage.getStorage().getUserPoolId().equals( - recipeUserIdAppIdentifierWithStorage.getStorage().getUserPoolId())) { + if (!primaryUserIdStorage.getUserPoolId().equals( + recipeUserIdStorage.getUserPoolId())) { throw new ServletException( new BadRequestException( "Cannot link users that are parts of different databases. Different pool IDs: " + - primaryUserIdAppIdentifierWithStorage.getStorage().getUserPoolId() + " AND " + - recipeUserIdAppIdentifierWithStorage.getStorage().getUserPoolId())); + primaryUserIdStorage.getUserPoolId() + " AND " + + recipeUserIdStorage.getUserPoolId())); } AuthRecipe.LinkAccountsResult linkAccountsResult = AuthRecipe.linkAccounts(main, - primaryUserIdAppIdentifierWithStorage, + appIdentifier, primaryUserIdStorage, recipeUserId, primaryUserId); - UserIdMapping.populateExternalUserIdForUsers(primaryUserIdAppIdentifierWithStorage, new AuthRecipeUserInfo[]{linkAccountsResult.user}); + UserIdMapping.populateExternalUserIdForUsers(primaryUserIdStorage, new AuthRecipeUserInfo[]{linkAccountsResult.user}); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); response.addProperty("accountsAlreadyLinked", linkAccountsResult.wasAlreadyLinked); @@ -114,7 +116,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject response = new JsonObject(); response.addProperty("status", "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"); io.supertokens.pluginInterface.useridmapping.UserIdMapping result = UserIdMapping.getUserIdMapping( - primaryUserIdAppIdentifierWithStorage, e.primaryUserId, + appIdentifier, primaryUserIdStorage, e.primaryUserId, UserIdType.SUPERTOKENS); if (result != null) { response.addProperty("primaryUserId", result.externalUserId); @@ -130,7 +132,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { JsonObject response = new JsonObject(); response.addProperty("status", "RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"); - UserIdMapping.populateExternalUserIdForUsers(recipeUserIdAppIdentifierWithStorage, new AuthRecipeUserInfo[]{e.recipeUser}); + UserIdMapping.populateExternalUserIdForUsers(recipeUserIdStorage, new AuthRecipeUserInfo[]{e.recipeUser}); response.addProperty("primaryUserId", e.recipeUser.getSupertokensOrExternalUserId()); response.addProperty("description", e.getMessage()); response.add("user", e.recipeUser.toJson()); diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java index 624c6aeec..8bcab2088 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java @@ -17,15 +17,16 @@ package io.supertokens.webserver.api.accountlinking; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.authRecipe.AuthRecipe; import io.supertokens.authRecipe.exception.InputUserIdIsNotAPrimaryUserException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.useridmapping.UserIdType; import io.supertokens.webserver.InputParser; @@ -53,19 +54,19 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String inputRecipeUserId = InputParser.parseStringOrThrowError(input, "recipeUserId", false); - AppIdentifierWithStorage appIdentifierWithStorage = null; + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage = null; try { String userId = inputRecipeUserId; - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = + StorageAndUserIdMapping mappingAndStorage = getStorageAndUserIdMappingForAppSpecificApi( req, inputRecipeUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { userId = mappingAndStorage.userIdMapping.superTokensUserId; } - appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; + storage = mappingAndStorage.storage; - boolean wasDeleted = AuthRecipe.unlinkAccounts(main, appIdentifierWithStorage, - userId); + boolean wasDeleted = AuthRecipe.unlinkAccounts(main, appIdentifier, storage, userId); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); response.addProperty("wasRecipeUserDeleted", wasDeleted); diff --git a/src/main/java/io/supertokens/webserver/api/core/ActiveUsersCountAPI.java b/src/main/java/io/supertokens/webserver/api/core/ActiveUsersCountAPI.java index 4e824f5b0..df20d926f 100644 --- a/src/main/java/io/supertokens/webserver/api/core/ActiveUsersCountAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/ActiveUsersCountAPI.java @@ -53,7 +53,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { int count = ActiveUsers.countUsersActiveSince( - this.enforcePublicTenantAndGetPublicTenantStorage(req), main, sinceTimestamp); + this.getAppIdentifier(req), + this.enforcePublicTenantAndGetPublicTenantStorage(req), sinceTimestamp); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); result.addProperty("count", count); diff --git a/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java b/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java index b9fdcf4b8..3eca2d329 100644 --- a/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java @@ -53,7 +53,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO String pid = InputParser.getQueryParamOrThrowError(req, "pid", false); try { - TenantIdentifier tenantIdentifier = getTenantStorage(req); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + getTenantStorage(req); // to check if tenant exists if (!tenantIdentifier.equals(new TenantIdentifier(null, null, null))) { throw new ServletException(new BadPermissionException("you can call this only from the base connection uri domain, public app and tenant")); } diff --git a/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java b/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java index a494c3cef..1348d09bb 100644 --- a/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java @@ -17,8 +17,8 @@ package io.supertokens.webserver.api.core; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.authRecipe.AuthRecipe; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; @@ -59,12 +59,12 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = + StorageAndUserIdMapping storageAndUserIdMapping = this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); - AuthRecipe.deleteUser(appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, userId, + AuthRecipe.deleteUser(getAppIdentifier(req), storageAndUserIdMapping.storage, userId, removeAllLinkedAccounts, - appIdentifierWithStorageAndUserIdMapping.userIdMapping); + storageAndUserIdMapping.userIdMapping); } catch (StorageQueryException | TenantOrAppNotFoundException | StorageTransactionLogicException | BadPermissionException e) { throw new ServletException(e); diff --git a/src/main/java/io/supertokens/webserver/api/core/EEFeatureFlagAPI.java b/src/main/java/io/supertokens/webserver/api/core/EEFeatureFlagAPI.java index c7b384dc9..b2a7b4668 100644 --- a/src/main/java/io/supertokens/webserver/api/core/EEFeatureFlagAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/EEFeatureFlagAPI.java @@ -24,6 +24,7 @@ import io.supertokens.featureflag.FeatureFlag; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.webserver.WebserverAPI; import jakarta.servlet.ServletException; @@ -48,9 +49,11 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific and can be queried only from public tenant try { - EE_FEATURES[] features = FeatureFlag.getInstance(main, this.enforcePublicTenantAndGetPublicTenantStorage(req)) + this.enforcePublicTenantAndGetPublicTenantStorage(req); // to check if app exists and enforce public tenant + AppIdentifier appIdentifier = this.getAppIdentifier(req); + EE_FEATURES[] features = FeatureFlag.getInstance(main, appIdentifier) .getEnabledFeatures(); - JsonObject stats = FeatureFlag.getInstance(main, this.enforcePublicTenantAndGetPublicTenantStorage(req)) + JsonObject stats = FeatureFlag.getInstance(main, appIdentifier) .getPaidFeatureStats(); JsonObject result = new JsonObject(); JsonArray featuresJson = new JsonArray(); diff --git a/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java b/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java index eb93d1316..ef1a53d93 100644 --- a/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java @@ -17,13 +17,14 @@ package io.supertokens.webserver.api.core; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.authRecipe.AuthRecipe; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; @@ -55,19 +56,21 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO AuthRecipeUserInfo user = null; try { - AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = + AppIdentifier appIdentifier = this.getAppIdentifier(req); + StorageAndUserIdMapping storageAndUserIdMapping = this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the getUserUsingId function - if (appIdentifierWithStorageAndUserIdMapping.userIdMapping != null) { - userId = appIdentifierWithStorageAndUserIdMapping.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - user = AuthRecipe.getUserById(appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, + user = AuthRecipe.getUserById(appIdentifier, storageAndUserIdMapping.storage, userId); // if a userIdMapping exists, set the userId in the response to the externalUserId if (user != null) { - UserIdMapping.populateExternalUserIdForUsers(appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, new AuthRecipeUserInfo[]{user}); + UserIdMapping.populateExternalUserIdForUsers( + storageAndUserIdMapping.storage, new AuthRecipeUserInfo[]{user}); } } catch (UnknownUserIdException e) { diff --git a/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java b/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java index 86f889d9d..a16587fd9 100644 --- a/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java @@ -20,8 +20,7 @@ import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorages; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.utils.RateLimiter; import io.supertokens.webserver.WebserverAPI; @@ -90,12 +89,13 @@ private void handleRequest(HttpServletRequest req, HttpServletResponse resp) thr return; } - AppIdentifierWithStorages appIdentifierWithStorages = enforcePublicTenantAndGetAllStoragesForApp(req); + Storage[] storages = enforcePublicTenantAndGetAllStoragesForApp(req); + AppIdentifier appIdentifier = getAppIdentifier(req); - for (Storage storage : appIdentifierWithStorages.getStorages()) { + for (Storage storage : storages) { // even if the public tenant does not exist, the following function will return a null // idea here is to test that the storage is working - storage.getKeyValue(appIdentifierWithStorages.getAsPublicTenantIdentifier(), "Test"); + storage.getKeyValue(appIdentifier.getAsPublicTenantIdentifier(), "Test"); } super.sendTextResponse(200, "Hello", resp); } catch (StorageQueryException | BadPermissionException | TenantOrAppNotFoundException e) { diff --git a/src/main/java/io/supertokens/webserver/api/core/LicenseKeyAPI.java b/src/main/java/io/supertokens/webserver/api/core/LicenseKeyAPI.java index 7be99709e..d9bb7ae3d 100644 --- a/src/main/java/io/supertokens/webserver/api/core/LicenseKeyAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/LicenseKeyAPI.java @@ -24,6 +24,7 @@ import io.supertokens.httpRequest.HttpResponseException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.WebserverAPI; @@ -50,12 +51,14 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String licenseKey = InputParser.parseStringOrThrowError(input, "licenseKey", true); try { + this.enforcePublicTenantAndGetPublicTenantStorage(req); // to check if app exists and enforce public tenant + AppIdentifier appIdentifier = this.getAppIdentifier(req); boolean success = false; if (licenseKey != null) { - success = FeatureFlag.getInstance(main, this.enforcePublicTenantAndGetPublicTenantStorage(req)) + success = FeatureFlag.getInstance(main, appIdentifier) .setLicenseKeyAndSyncFeatures(licenseKey); } else { - success = FeatureFlag.getInstance(main, this.enforcePublicTenantAndGetPublicTenantStorage(req)) + success = FeatureFlag.getInstance(main, appIdentifier) .syncFeatureFlagWithLicenseKey(); } JsonObject result = new JsonObject(); @@ -74,7 +77,8 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific and can be queried only from public tenant try { - FeatureFlag.getInstance(main, this.enforcePublicTenantAndGetPublicTenantStorage(req)) + this.enforcePublicTenantAndGetPublicTenantStorage(req); // to check if app exists and enforce public tenant + FeatureFlag.getInstance(main, getAppIdentifier(req)) .removeLicenseKeyAndSyncFeatures(); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); @@ -88,7 +92,8 @@ protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific and can be queried only from public tenant try { - String licenseKey = FeatureFlag.getInstance(main, this.enforcePublicTenantAndGetPublicTenantStorage(req)) + this.enforcePublicTenantAndGetPublicTenantStorage(req); // to check if app exists and enforce public tenant + String licenseKey = FeatureFlag.getInstance(main, getAppIdentifier(req)) .getLicenseKey(); JsonObject result = new JsonObject(); result.addProperty("licenseKey", licenseKey); diff --git a/src/main/java/io/supertokens/webserver/api/core/ListUsersByAccountInfoAPI.java b/src/main/java/io/supertokens/webserver/api/core/ListUsersByAccountInfoAPI.java index 779505f8a..4c002bed2 100644 --- a/src/main/java/io/supertokens/webserver/api/core/ListUsersByAccountInfoAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/ListUsersByAccountInfoAPI.java @@ -20,10 +20,10 @@ import com.google.gson.JsonObject; import io.supertokens.Main; import io.supertokens.authRecipe.AuthRecipe; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.utils.Utils; @@ -73,10 +73,12 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } try { - TenantIdentifierWithStorage tenantIdentifierWithStorage = this.getTenantStorage(req); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = this.getTenantStorage(req); AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo( - this.getTenantStorage(req), doUnionOfAccountInfo, email, phoneNumber, thirdPartyId, thirdPartyUserId); - UserIdMapping.populateExternalUserIdForUsers(tenantIdentifierWithStorage.toAppIdentifierWithStorage(), users); + tenantIdentifier, storage, doUnionOfAccountInfo, email, phoneNumber, thirdPartyId, + thirdPartyUserId); + UserIdMapping.populateExternalUserIdForUsers(storage, users); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java b/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java index 03cc3894b..5517c79b5 100644 --- a/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java @@ -21,8 +21,7 @@ import io.supertokens.output.Logging; import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorages; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.utils.RateLimiter; import io.supertokens.webserver.WebserverAPI; @@ -73,10 +72,11 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO protected void handleRequest(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // getServletPath returns the path without the base path. - AppIdentifierWithStorages appIdentifierWithStorages = null; + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage[] storages = null; try { - appIdentifierWithStorages = enforcePublicTenantAndGetAllStoragesForApp(req); + enforcePublicTenantAndGetAllStoragesForApp(req); // check if app exists and enforce public tenant } catch (TenantOrAppNotFoundException | BadPermissionException e) { // we send 500 status code throw new ServletException(e); @@ -95,10 +95,10 @@ protected void handleRequest(HttpServletRequest req, HttpServletResponse resp) t return; } - for (Storage storage : appIdentifierWithStorages.getStorages()) { + for (Storage storage : storages) { // even if the public tenant does not exist, the following function will return a null // idea here is to test that the storage is working - storage.getKeyValue(appIdentifierWithStorages.getAsPublicTenantIdentifier(), "Test"); + storage.getKeyValue(appIdentifier.getAsPublicTenantIdentifier(), "Test"); } super.sendTextResponse(200, "Hello", resp); @@ -109,7 +109,8 @@ protected void handleRequest(HttpServletRequest req, HttpServletResponse resp) t } else { super.sendTextResponse(404, "Not found", resp); - Logging.error(main, appIdentifierWithStorages.getAsPublicTenantIdentifier(), "Unknown API called: " + req.getRequestURL(), false); + Logging.error(main, appIdentifier.getAsPublicTenantIdentifier(), "Unknown API called: " + req.getRequestURL(), + false); } } diff --git a/src/main/java/io/supertokens/webserver/api/core/RequestStatsAPI.java b/src/main/java/io/supertokens/webserver/api/core/RequestStatsAPI.java index 1905ab258..080570a81 100644 --- a/src/main/java/io/supertokens/webserver/api/core/RequestStatsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/RequestStatsAPI.java @@ -45,7 +45,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific try { - AppIdentifier appIdentifier = enforcePublicTenantAndGetPublicTenantStorage(req); + enforcePublicTenantAndGetPublicTenantStorage(req); // check if app exists and enforce public tenant + AppIdentifier appIdentifier = getAppIdentifier(req); JsonObject stats = RequestStats.getInstance(main, appIdentifier).getStats(); stats.addProperty("status", "OK"); super.sendJsonResponse(200, stats, resp); diff --git a/src/main/java/io/supertokens/webserver/api/core/TelemetryAPI.java b/src/main/java/io/supertokens/webserver/api/core/TelemetryAPI.java index 2bc28379a..21af7097f 100644 --- a/src/main/java/io/supertokens/webserver/api/core/TelemetryAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/TelemetryAPI.java @@ -46,8 +46,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific try { - KeyValueInfo telemetryId = Telemetry.getTelemetryId(main, - this.enforcePublicTenantAndGetPublicTenantStorage(req)); + this.enforcePublicTenantAndGetPublicTenantStorage(req); // check if app exists and enforce public tenant + KeyValueInfo telemetryId = Telemetry.getTelemetryId(main, getAppIdentifier(req)); JsonObject result = new JsonObject(); if (telemetryId == null) { diff --git a/src/main/java/io/supertokens/webserver/api/core/UsersAPI.java b/src/main/java/io/supertokens/webserver/api/core/UsersAPI.java index fd5bb7dc9..3d2c99b29 100644 --- a/src/main/java/io/supertokens/webserver/api/core/UsersAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/UsersAPI.java @@ -25,10 +25,11 @@ import io.supertokens.authRecipe.UserPaginationToken; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.dashboard.DashboardSearchTags; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.utils.SemVer; @@ -74,9 +75,10 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } } - TenantIdentifierWithStorage tenantIdentifierWithStorage = null; + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = null; try { - tenantIdentifierWithStorage = this.getTenantStorage(req); + storage = this.getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } @@ -163,11 +165,11 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } try { - UserPaginationContainer users = AuthRecipe.getUsers(tenantIdentifierWithStorage, + UserPaginationContainer users = AuthRecipe.getUsers(tenantIdentifier, storage, limit, timeJoinedOrder, paginationToken, recipeIdsEnumBuilder.build().toArray(RECIPE_ID[]::new), searchTags); - UserIdMapping.populateExternalUserIdForUsers(tenantIdentifierWithStorage, users.users); + UserIdMapping.populateExternalUserIdForUsers(storage, users.users); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); @@ -198,7 +200,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } super.sendJsonResponse(200, result, resp); } catch (UserPaginationToken.InvalidTokenException e) { - Logging.debug(main, tenantIdentifierWithStorage, Utils.exceptionStacktraceToString(e)); + Logging.debug(main, tenantIdentifier, Utils.exceptionStacktraceToString(e)); throw new ServletException(new BadRequestException("invalid pagination token")); } catch (StorageQueryException | TenantOrAppNotFoundException e) { throw new ServletException(e); diff --git a/src/main/java/io/supertokens/webserver/api/core/UsersCountAPI.java b/src/main/java/io/supertokens/webserver/api/core/UsersCountAPI.java index 65d234260..7719d43b3 100644 --- a/src/main/java/io/supertokens/webserver/api/core/UsersCountAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/UsersCountAPI.java @@ -21,9 +21,10 @@ import io.supertokens.authRecipe.AuthRecipe; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorages; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.WebserverAPI; @@ -77,13 +78,17 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO long count; if (includeAllTenants) { - AppIdentifierWithStorages appIdentifierWithStorages = enforcePublicTenantAndGetAllStoragesForApp(req); + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage[] storages = enforcePublicTenantAndGetAllStoragesForApp(req); - count = AuthRecipe.getUsersCountAcrossAllTenants(appIdentifierWithStorages, + count = AuthRecipe.getUsersCountAcrossAllTenants(appIdentifier, storages, recipeIdsEnumBuilder.build().toArray(RECIPE_ID[]::new)); } else { - count = AuthRecipe.getUsersCountForTenant(this.getTenantStorage(req), + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); + + count = AuthRecipe.getUsersCountForTenant(tenantIdentifier, storage, recipeIdsEnumBuilder.build().toArray(RECIPE_ID[]::new)); } JsonObject result = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/dashboard/DashboardSignInAPI.java b/src/main/java/io/supertokens/webserver/api/dashboard/DashboardSignInAPI.java index 7cf68d727..f8032715c 100644 --- a/src/main/java/io/supertokens/webserver/api/dashboard/DashboardSignInAPI.java +++ b/src/main/java/io/supertokens/webserver/api/dashboard/DashboardSignInAPI.java @@ -61,7 +61,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { String sessionId = Dashboard.signInDashboardUser( - super.enforcePublicTenantAndGetPublicTenantStorage(req), main, email, password); + getAppIdentifier(req), + enforcePublicTenantAndGetPublicTenantStorage(req), main, email, password); if (sessionId == null) { JsonObject response = new JsonObject(); response.addProperty("status", "INVALID_CREDENTIALS_ERROR"); diff --git a/src/main/java/io/supertokens/webserver/api/dashboard/DashboardUserAPI.java b/src/main/java/io/supertokens/webserver/api/dashboard/DashboardUserAPI.java index 38764de5b..722fb4245 100644 --- a/src/main/java/io/supertokens/webserver/api/dashboard/DashboardUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/dashboard/DashboardUserAPI.java @@ -24,12 +24,13 @@ import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.dashboard.DashboardUser; import io.supertokens.pluginInterface.dashboard.exceptions.DuplicateEmailException; import io.supertokens.pluginInterface.dashboard.exceptions.UserIdNotFoundException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.Utils; @@ -91,7 +92,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } DashboardUser user = Dashboard.signUpDashboardUser( - this.enforcePublicTenantAndGetPublicTenantStorage(req), + getAppIdentifier(req), + enforcePublicTenantAndGetPublicTenantStorage(req), main, email, password); JsonObject userAsJsonObject = new JsonParser().parse(new Gson().toJson(user)).getAsJsonObject(); @@ -146,16 +148,15 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO } try { - AppIdentifierWithStorage appIdentifierWithStorage = - this.enforcePublicTenantAndGetPublicTenantStorage( - req); + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage = enforcePublicTenantAndGetPublicTenantStorage(req); String userId = InputParser.parseStringOrThrowError(input, "userId", true); if (userId != null) { // normalize userId userId = Utils.normalizeAndValidateStringParam(userId, "userId"); // retrieve updated user details - DashboardUser user = Dashboard.updateUsersCredentialsWithUserId(appIdentifierWithStorage, + DashboardUser user = Dashboard.updateUsersCredentialsWithUserId(appIdentifier, storage, main, userId, newEmail, newPassword); JsonObject userJsonObject = new JsonParser().parse(new Gson().toJson(user)) .getAsJsonObject(); @@ -173,14 +174,14 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO email = io.supertokens.utils.Utils.normaliseEmail(email); // check if the user exists - DashboardUser user = Dashboard.getDashboardUserByEmail(appIdentifierWithStorage, email); + DashboardUser user = Dashboard.getDashboardUserByEmail(appIdentifier, storage, email); if (user == null) { throw new UserIdNotFoundException(); } // retrieve updated user details - DashboardUser updatedUser = Dashboard.updateUsersCredentialsWithUserId(appIdentifierWithStorage, - main, user.userId, newEmail, newPassword); + DashboardUser updatedUser = Dashboard.updateUsersCredentialsWithUserId(appIdentifier, + storage, main, user.userId, newEmail, newPassword); JsonObject userJsonObject = new JsonParser().parse(new Gson().toJson(updatedUser)).getAsJsonObject(); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); @@ -216,7 +217,8 @@ protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws // normalize userId userId = Utils.normalizeAndValidateStringParam(userId, "userId"); boolean didUserExist = Dashboard.deleteUserWithUserId( - super.enforcePublicTenantAndGetPublicTenantStorage(req), userId); + getAppIdentifier(req), + enforcePublicTenantAndGetPublicTenantStorage(req), userId); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); response.addProperty("didUserExist", didUserExist); @@ -232,7 +234,8 @@ protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws email = io.supertokens.utils.Utils.normaliseEmail(email); boolean didUserExist = Dashboard.deleteUserWithEmail( - super.enforcePublicTenantAndGetPublicTenantStorage(req), email); + getAppIdentifier(req), + enforcePublicTenantAndGetPublicTenantStorage(req), email); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); response.addProperty("didUserExist", didUserExist); diff --git a/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardSessionsForUserAPI.java b/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardSessionsForUserAPI.java index 0c4958b1f..def40877c 100644 --- a/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardSessionsForUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardSessionsForUserAPI.java @@ -56,7 +56,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO JsonArray arr = new com.google.gson.JsonParser().parse(new Gson().toJson( Dashboard.getAllDashboardSessionsForUser( - super.enforcePublicTenantAndGetPublicTenantStorage(req), + getAppIdentifier(req), + enforcePublicTenantAndGetPublicTenantStorage(req), userId))).getAsJsonArray(); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardUsersAPI.java b/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardUsersAPI.java index fe3be4539..8c4333c02 100644 --- a/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardUsersAPI.java +++ b/src/main/java/io/supertokens/webserver/api/dashboard/GetDashboardUsersAPI.java @@ -51,7 +51,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO JsonArray arr = new com.google.gson.JsonParser().parse(new Gson().toJson( Dashboard.getAllDashboardUsers( - super.enforcePublicTenantAndGetPublicTenantStorage(req), main))) + getAppIdentifier(req), + enforcePublicTenantAndGetPublicTenantStorage(req), main))) .getAsJsonArray(); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/dashboard/RevokeSessionAPI.java b/src/main/java/io/supertokens/webserver/api/dashboard/RevokeSessionAPI.java index 5af0cf5a2..dcbb31918 100644 --- a/src/main/java/io/supertokens/webserver/api/dashboard/RevokeSessionAPI.java +++ b/src/main/java/io/supertokens/webserver/api/dashboard/RevokeSessionAPI.java @@ -53,7 +53,8 @@ protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws try { Dashboard.revokeSessionWithSessionId( - super.enforcePublicTenantAndGetPublicTenantStorage(req), sessionId); + getAppIdentifier(req), + enforcePublicTenantAndGetPublicTenantStorage(req), sessionId); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); super.sendJsonResponse(200, response, resp); diff --git a/src/main/java/io/supertokens/webserver/api/dashboard/VerifyDashboardUserSessionAPI.java b/src/main/java/io/supertokens/webserver/api/dashboard/VerifyDashboardUserSessionAPI.java index c01cfac15..9e0fd4287 100644 --- a/src/main/java/io/supertokens/webserver/api/dashboard/VerifyDashboardUserSessionAPI.java +++ b/src/main/java/io/supertokens/webserver/api/dashboard/VerifyDashboardUserSessionAPI.java @@ -22,8 +22,9 @@ import io.supertokens.dashboard.exceptions.UserSuspendedException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.utils.SemVer; import io.supertokens.webserver.InputParser; @@ -61,10 +62,11 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { JsonObject invalidSessionResp = new JsonObject(); invalidSessionResp.addProperty("status", "INVALID_SESSION_ERROR"); - AppIdentifierWithStorage identifierWithStorage = super.enforcePublicTenantAndGetPublicTenantStorage(req); + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage = super.enforcePublicTenantAndGetPublicTenantStorage(req); - if (Dashboard.isValidUserSession(identifierWithStorage, main, sessionId)) { - String email = Dashboard.getEmailFromSessionId(identifierWithStorage, main, sessionId); + if (Dashboard.isValidUserSession(appIdentifier, storage, main, sessionId)) { + String email = Dashboard.getEmailFromSessionId(appIdentifier, storage, sessionId); if (email == null) { super.sendJsonResponse(200, invalidSessionResp, resp); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/ConsumeResetPasswordAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/ConsumeResetPasswordAPI.java index bed18f114..d6aa86673 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/ConsumeResetPasswordAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/ConsumeResetPasswordAPI.java @@ -22,9 +22,10 @@ import io.supertokens.emailpassword.exceptions.ResetPasswordInvalidTokenException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; @@ -57,19 +58,14 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String token = InputParser.parseStringOrThrowError(input, "token", false); assert token != null; - TenantIdentifierWithStorage tenantIdentifierWithStorage = null; - try { - tenantIdentifierWithStorage = getTenantStorage(req); - } catch (TenantOrAppNotFoundException e) { - throw new ServletException(e); - } - try { + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); EmailPassword.ConsumeResetPasswordTokenResult result = EmailPassword.consumeResetPasswordToken( - tenantIdentifierWithStorage, token); + tenantIdentifier, storage, token); io.supertokens.pluginInterface.useridmapping.UserIdMapping userIdMapping = UserIdMapping.getUserIdMapping( - tenantIdentifierWithStorage.toAppIdentifierWithStorage(), result.userId, UserIdType.SUPERTOKENS); + tenantIdentifier.toAppIdentifier(), storage, result.userId, UserIdType.SUPERTOKENS); // if userIdMapping exists, pass the externalUserId to the response if (userIdMapping != null) { @@ -84,7 +80,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I super.sendJsonResponse(200, resultJson, resp); } catch (ResetPasswordInvalidTokenException e) { - Logging.debug(main, tenantIdentifierWithStorage, Utils.exceptionStacktraceToString(e)); + Logging.debug(main, getTenantIdentifier(req), Utils.exceptionStacktraceToString(e)); JsonObject result = new JsonObject(); result.addProperty("status", "RESET_PASSWORD_INVALID_TOKEN_ERROR"); super.sendJsonResponse(200, result, resp); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/GeneratePasswordResetTokenAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/GeneratePasswordResetTokenAPI.java index 27ecd6fb4..56d5bb34e 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/GeneratePasswordResetTokenAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/GeneratePasswordResetTokenAPI.java @@ -18,11 +18,12 @@ import com.google.gson.JsonObject; import io.supertokens.Main; -import io.supertokens.TenantIdentifierWithStorageAndUserIdMapping; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.emailpassword.EmailPassword; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; @@ -60,29 +61,30 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String userId = InputParser.parseStringOrThrowError(input, "userId", false); // logic according to https://github.com/supertokens/supertokens-core/issues/106 - TenantIdentifier tenantIdentifier = null; + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage; try { - tenantIdentifier = getTenantStorage(req); + storage = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } try { - TenantIdentifierWithStorageAndUserIdMapping tenantIdentifierStorageAndMapping = + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForTenantSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the generatePasswordResetToken - if (tenantIdentifierStorageAndMapping.userIdMapping != null) { - userId = tenantIdentifierStorageAndMapping.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } String token; if (getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0)) { String email = InputParser.parseStringOrThrowError(input, "email", false); token = EmailPassword.generatePasswordResetToken( - tenantIdentifierStorageAndMapping.tenantIdentifierWithStorage, super.main, userId, email); + tenantIdentifier, storageAndUserIdMapping.storage, super.main, userId, email); } else { token = EmailPassword.generatePasswordResetTokenBeforeCdi4_0( - tenantIdentifierStorageAndMapping.tenantIdentifierWithStorage, super.main, userId); + tenantIdentifier, storageAndUserIdMapping.storage, super.main, userId); } JsonObject result = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/ImportUserWithPasswordHashAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/ImportUserWithPasswordHashAPI.java index b162eb678..48b435ca0 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/ImportUserWithPasswordHashAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/ImportUserWithPasswordHashAPI.java @@ -23,10 +23,11 @@ import io.supertokens.emailpassword.exceptions.UnsupportedPasswordHashingFormatException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.utils.SemVer; @@ -94,9 +95,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - TenantIdentifierWithStorage tenant = this.getTenantStorage(req); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = this.getTenantStorage(req); EmailPassword.ImportUserResponse importUserResponse = EmailPassword.importUserWithPasswordHash( - tenant, main, email, + tenantIdentifier, storage, main, email, passwordHash, passwordHashingAlgorithm); UserIdMapping.populateExternalUserIdForUsers(getTenantStorage(req), new AuthRecipeUserInfo[]{importUserResponse.user}); JsonObject response = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/ResetPasswordAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/ResetPasswordAPI.java index 66f92e0b0..8eb6ce88d 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/ResetPasswordAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/ResetPasswordAPI.java @@ -22,9 +22,10 @@ import io.supertokens.emailpassword.exceptions.ResetPasswordInvalidTokenException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; @@ -73,18 +74,19 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I throw new ServletException(new WebserverAPI.BadRequestException("Password cannot be an empty string")); } - TenantIdentifierWithStorage tenantIdentifierWithStorage = null; + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage; try { - tenantIdentifierWithStorage = getTenantStorage(req); + storage = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } try { - String userId = EmailPassword.resetPassword(tenantIdentifierWithStorage, super.main, token, newPassword); + String userId = EmailPassword.resetPassword(tenantIdentifier, storage, super.main, token, newPassword); io.supertokens.pluginInterface.useridmapping.UserIdMapping userIdMapping = UserIdMapping.getUserIdMapping( - tenantIdentifierWithStorage.toAppIdentifierWithStorage(), userId, UserIdType.SUPERTOKENS); + tenantIdentifier.toAppIdentifier(), storage, userId, UserIdType.SUPERTOKENS); // if userIdMapping exists, pass the externalUserId to the response if (userIdMapping != null) { @@ -106,7 +108,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I super.sendJsonResponse(200, result, resp); } catch (ResetPasswordInvalidTokenException e) { - Logging.debug(main, tenantIdentifierWithStorage, Utils.exceptionStacktraceToString(e)); + Logging.debug(main, tenantIdentifier, Utils.exceptionStacktraceToString(e)); JsonObject result = new JsonObject(); result.addProperty("status", "RESET_PASSWORD_INVALID_TOKEN_ERROR"); super.sendJsonResponse(200, result, resp); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java index cabca592c..38aea50e1 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java @@ -24,10 +24,11 @@ import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.authRecipe.LoginMethod; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.utils.SemVer; import io.supertokens.utils.Utils; @@ -65,19 +66,21 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String normalisedEmail = Utils.normaliseEmail(email); - TenantIdentifierWithStorage tenantIdentifierWithStorage = null; + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage; try { - tenantIdentifierWithStorage = getTenantStorage(req); + storage = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } try { - AuthRecipeUserInfo user = EmailPassword.signIn(tenantIdentifierWithStorage, super.main, normalisedEmail, + AuthRecipeUserInfo user = EmailPassword.signIn(tenantIdentifier, storage, super.main, normalisedEmail, password); - io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(tenantIdentifierWithStorage, new AuthRecipeUserInfo[]{user}); + io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(storage, + new AuthRecipeUserInfo[]{user}); - ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, + ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), this.getPublicTenantStorage(req), user.getSupertokensUserId()); // use the internal user id JsonObject result = new JsonObject(); @@ -100,7 +103,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I super.sendJsonResponse(200, result, resp); } catch (WrongCredentialsException e) { - Logging.debug(main, tenantIdentifierWithStorage, Utils.exceptionStacktraceToString(e)); + Logging.debug(main, tenantIdentifier, Utils.exceptionStacktraceToString(e)); JsonObject result = new JsonObject(); result.addProperty("status", "WRONG_CREDENTIALS_ERROR"); super.sendJsonResponse(200, result, resp); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java index 165e618e5..972d9cac9 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java @@ -23,11 +23,11 @@ import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.utils.SemVer; import io.supertokens.utils.Utils; @@ -69,18 +69,20 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I throw new ServletException(new WebserverAPI.BadRequestException("Password cannot be an empty string")); } - TenantIdentifier tenantIdentifier = null; + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage; try { - tenantIdentifier = getTenantStorage(req); + storage = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } try { - TenantIdentifierWithStorage tenant = this.getTenantStorage(req); - AuthRecipeUserInfo user = EmailPassword.signUp(tenant, super.main, normalisedEmail, password); + AuthRecipeUserInfo user = EmailPassword.signUp(tenantIdentifier, storage, super.main, normalisedEmail, + password); - ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, user.getSupertokensUserId()); + ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), this.getPublicTenantStorage(req), + user.getSupertokensUserId()); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java index 079183928..1974d22d6 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java @@ -17,20 +17,21 @@ package io.supertokens.webserver.api.emailpassword; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.emailpassword.EmailPassword; import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; @@ -77,35 +78,37 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { // API is app specific for get by UserId AuthRecipeUserInfo user = null; + AppIdentifier appIdentifier = getAppIdentifier(req); try { if (userId != null) { // Query by userId - AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = + StorageAndUserIdMapping storageAndUserIdMapping = this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the getUserUsingId function - if (appIdentifierWithStorageAndUserIdMapping.userIdMapping != null) { - userId = appIdentifierWithStorageAndUserIdMapping.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } user = EmailPassword.getUserUsingId( - appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, userId); + appIdentifier, + storageAndUserIdMapping.storage, userId); if (user != null) { - UserIdMapping.populateExternalUserIdForUsers(appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, new AuthRecipeUserInfo[]{user}); + UserIdMapping.populateExternalUserIdForUsers(storageAndUserIdMapping.storage, + new AuthRecipeUserInfo[]{user}); } } else { // API is tenant specific for get by Email // Query by email String normalisedEmail = Utils.normaliseEmail(email); - TenantIdentifierWithStorage tenantIdentifierWithStorage = - this.getTenantStorage( - req); - user = EmailPassword.getUserUsingEmail(tenantIdentifierWithStorage, normalisedEmail); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = this.getTenantStorage(req); + user = EmailPassword.getUserUsingEmail(tenantIdentifier, storage, normalisedEmail); // if a userIdMapping exists, set the userId in the response to the externalUserId if (user != null) { - UserIdMapping.populateExternalUserIdForUsers(tenantIdentifierWithStorage, new AuthRecipeUserInfo[]{user}); + UserIdMapping.populateExternalUserIdForUsers(storage, new AuthRecipeUserInfo[]{user}); } } } catch (UnknownUserIdException e) { @@ -162,15 +165,16 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO AppIdentifier appIdentifier = this.getAppIdentifier(req); try { - AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = + StorageAndUserIdMapping storageAndUserIdMapping = this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the updateUsersEmailOrPassword - if (appIdentifierWithStorageAndUserIdMapping.userIdMapping != null) { - userId = appIdentifierWithStorageAndUserIdMapping.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } EmailPassword.updateUsersEmailOrPassword( - appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, + appIdentifier, + storageAndUserIdMapping.storage, main, userId, email, password); JsonObject result = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java b/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java index 1200a4ddd..195f314c9 100644 --- a/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java +++ b/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java @@ -18,12 +18,12 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; import io.supertokens.webserver.InputParser; @@ -85,11 +85,12 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = + StorageAndUserIdMapping storageAndUserIdMapping = this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType); boolean didMappingExist = UserIdMapping.deleteUserIdMapping( - appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, userId, userIdType, force); + getAppIdentifier(req), + storageAndUserIdMapping.storage, userId, userIdType, force); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); response.addProperty("didMappingExist", didMappingExist); diff --git a/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java b/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java index d8896a7ee..cde30fc02 100644 --- a/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java +++ b/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java @@ -18,12 +18,12 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; import io.supertokens.webserver.InputParser; @@ -94,11 +94,12 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO } try { - AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = + StorageAndUserIdMapping storageAndUserIdMapping = this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType); if (UserIdMapping.updateOrDeleteExternalUserIdInfo( - appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, userId, userIdType, externalUserIdInfo)) { + getAppIdentifier(req), + storageAndUserIdMapping.storage, userId, userIdType, externalUserIdInfo)) { JsonObject response = new JsonObject(); response.addProperty("status", "OK"); super.sendJsonResponse(200, response, resp); diff --git a/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java b/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java index 1756ba315..07ca76829 100644 --- a/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java +++ b/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java @@ -18,6 +18,7 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; @@ -25,7 +26,6 @@ import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.useridmapping.exception.UnknownSuperTokensUserIdException; import io.supertokens.pluginInterface.useridmapping.exception.UserIdMappingAlreadyExistsException; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; import io.supertokens.utils.SemVer; @@ -95,7 +95,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - UserIdMapping.createUserIdMapping(enforcePublicTenantAndGetAllStoragesForApp(req), + UserIdMapping.createUserIdMapping( + getAppIdentifier(req), enforcePublicTenantAndGetAllStoragesForApp(req), superTokensUserId, externalUserId, externalUserIdInfo, force, getVersionFromRequest(req).greaterThanOrEqualTo( SemVer.v4_0)); @@ -161,7 +162,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO // Request from (app1, tenant1) will return user1 and request from (app1, tenant2) will return user2 // Request from (app1, tenant3) may result in either user1 or user2 - AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = + StorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType); if (appIdentifierWithStorageAndUserIdMapping.userIdMapping == null) { diff --git a/src/test/java/io/supertokens/test/PathRouterTest.java b/src/test/java/io/supertokens/test/PathRouterTest.java index e72daae9b..d6185d0b1 100644 --- a/src/test/java/io/supertokens/test/PathRouterTest.java +++ b/src/test/java/io/supertokens/test/PathRouterTest.java @@ -20,7 +20,6 @@ import com.google.gson.JsonPrimitive; import io.supertokens.ProcessState; import io.supertokens.ProcessState.PROCESS_STATE; -import io.supertokens.config.Config; import io.supertokens.featureflag.EE_FEATURES; import io.supertokens.featureflag.FeatureFlagTestContent; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; @@ -51,7 +50,6 @@ import org.mockito.Mockito; import java.io.IOException; -import java.util.ArrayList; import java.util.HashMap; import static org.junit.Assert.*; @@ -139,8 +137,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), resp); + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); } @@ -310,8 +308,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), resp); + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); } @@ -482,8 +480,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), resp); + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); } @@ -665,8 +663,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), resp); + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); } @@ -848,8 +846,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), resp); + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); } @@ -1013,8 +1011,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId() + + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId() + ",", resp); } @@ -1036,8 +1034,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId() + + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId() + ",r1", resp); } @@ -1061,8 +1059,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), resp); + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); @@ -1131,8 +1129,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId() + + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId() + ",", resp); } @@ -1157,8 +1155,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), resp); + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); fail(); @@ -1196,8 +1194,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId() + ",", + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId() + ",", resp); } }, new WebserverAPI(process.getProcess(), "r1") { @@ -1218,8 +1216,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId() + ",r1", + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId() + ",r1", resp); } })); @@ -1248,8 +1246,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId() + ",", + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId() + ",", resp); } }, new WebserverAPI(process.getProcess(), "r1") { @@ -1270,8 +1268,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId() + ",r1", + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId() + ",r1", resp); } })); @@ -1360,8 +1358,8 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, super.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), resp); + super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); @@ -1473,8 +1471,8 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, super.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), + super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); @@ -1589,8 +1587,8 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, super.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), + super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); @@ -1729,9 +1727,9 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getAppId() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), resp); + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getAppId() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); } @@ -2030,9 +2028,9 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getAppId() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), resp); + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getAppId() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); } @@ -2315,9 +2313,9 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - this.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getAppId() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), resp); + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getAppId() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); } @@ -2561,9 +2559,9 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, super.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getAppId() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), + super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getAppId() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); @@ -2710,9 +2708,9 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, super.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getAppId() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), + super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getAppId() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); @@ -2857,9 +2855,9 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, super.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - this.getTenantIdentifierFromRequest(req).getAppId() + "," + - this.getTenantIdentifierFromRequest(req).getTenantId(), + super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getAppId() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); } }); diff --git a/src/test/java/io/supertokens/test/multitenant/RequestConnectionUriDomainTest.java b/src/test/java/io/supertokens/test/multitenant/RequestConnectionUriDomainTest.java index c222b64c1..8e3702751 100644 --- a/src/test/java/io/supertokens/test/multitenant/RequestConnectionUriDomainTest.java +++ b/src/test/java/io/supertokens/test/multitenant/RequestConnectionUriDomainTest.java @@ -19,7 +19,6 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import io.supertokens.ProcessState; -import io.supertokens.config.Config; import io.supertokens.featureflag.EE_FEATURES; import io.supertokens.featureflag.FeatureFlagTestContent; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; @@ -37,7 +36,6 @@ import io.supertokens.test.TestingProcessManager; import io.supertokens.test.Utils; import io.supertokens.test.httpRequest.HttpRequestForTesting; -import io.supertokens.test.multitenant.api.TestMultitenancyAPIHelper; import io.supertokens.thirdparty.InvalidProviderConfigException; import io.supertokens.webserver.Webserver; import io.supertokens.webserver.WebserverAPI; @@ -90,7 +88,7 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, getTenantIdentifierFromRequest(req).getConnectionUriDomain(), resp); + super.sendTextResponse(200, getTenantIdentifier(req).getConnectionUriDomain(), resp); } }); @@ -162,8 +160,8 @@ public String getPath() { protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - super.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - super.getTenantIdentifierFromRequest(req).getTenantId(), resp); + super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + super.getTenantIdentifier(req).getTenantId(), resp); } }); @@ -288,8 +286,8 @@ public String getPath() { protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { super.sendTextResponse(200, - super.getTenantIdentifierFromRequest(req).getConnectionUriDomain() + "," + - super.getTenantIdentifierFromRequest(req).getTenantId(), resp); + super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + super.getTenantIdentifier(req).getTenantId(), resp); } }); From fadf205fbebfd6bb5edbfed8ef0c4e9cc316dfcb Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 1 Mar 2024 14:27:22 +0530 Subject: [PATCH 04/31] fix: thirdparty changes --- .../io/supertokens/thirdparty/ThirdParty.java | 92 +++++++++---------- .../api/thirdparty/GetUsersByEmailAPI.java | 13 ++- .../webserver/api/thirdparty/SignInUpAPI.java | 21 +++-- .../webserver/api/thirdparty/UserAPI.java | 21 +++-- 4 files changed, 80 insertions(+), 67 deletions(-) diff --git a/src/main/java/io/supertokens/thirdparty/ThirdParty.java b/src/main/java/io/supertokens/thirdparty/ThirdParty.java index 69bdcf193..d49f0a93c 100644 --- a/src/main/java/io/supertokens/thirdparty/ThirdParty.java +++ b/src/main/java/io/supertokens/thirdparty/ThirdParty.java @@ -22,9 +22,11 @@ import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.authRecipe.LoginMethod; import io.supertokens.pluginInterface.authRecipe.sqlStorage.AuthRecipeSQLStorage; +import io.supertokens.pluginInterface.emailverification.sqlStorage.EmailVerificationSQLStorage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.*; @@ -58,13 +60,13 @@ public SignInUpResponse(boolean createdNewUser, AuthRecipeUserInfo user) { // as seen below. But then, in newer versions, we stopped doing that cause of // https://github.com/supertokens/supertokens-core/issues/295, so we changed the API spec. @Deprecated - public static SignInUpResponse signInUp2_7(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, + public static SignInUpResponse signInUp2_7(TenantIdentifier tenantIdentifier, Storage storage, String thirdPartyId, String thirdPartyUserId, String email, boolean isEmailVerified) throws StorageQueryException, TenantOrAppNotFoundException { SignInUpResponse response = null; try { - response = signInUpHelper(tenantIdentifierWithStorage, main, thirdPartyId, thirdPartyUserId, + response = signInUpHelper(tenantIdentifier, storage, thirdPartyId, thirdPartyUserId, email); } catch (EmailChangeNotAllowedException e) { throw new RuntimeException(e); @@ -73,16 +75,16 @@ public static SignInUpResponse signInUp2_7(TenantIdentifierWithStorage tenantIde if (isEmailVerified) { try { SignInUpResponse finalResponse = response; - tenantIdentifierWithStorage.getEmailVerificationStorage().startTransaction(con -> { + EmailVerificationSQLStorage evStorage = StorageUtils.getEmailVerificationStorage(storage); + + evStorage.startTransaction(con -> { try { // this assert is there cause this function should only be used for older CDIs in which // account linking was not available. So loginMethod length will always be 1. assert (finalResponse.user.loginMethods.length == 1); - tenantIdentifierWithStorage.getEmailVerificationStorage() - .updateIsEmailVerified_Transaction(tenantIdentifierWithStorage.toAppIdentifier(), con, + evStorage.updateIsEmailVerified_Transaction(tenantIdentifier.toAppIdentifier(), con, finalResponse.user.getSupertokensUserId(), finalResponse.user.loginMethods[0].email, true); - tenantIdentifierWithStorage.getEmailVerificationStorage() - .commitTransaction(con); + evStorage.commitTransaction(con); return null; } catch (TenantOrAppNotFoundException e) { throw new StorageTransactionLogicException(e); @@ -106,7 +108,7 @@ public static SignInUpResponse signInUp2_7(Main main, try { Storage storage = StorageLayer.getStorage(main); return signInUp2_7( - new TenantIdentifierWithStorage(null, null, null, storage), main, + new TenantIdentifier(null, null, null), storage, thirdPartyId, thirdPartyUserId, email, isEmailVerified); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); @@ -119,7 +121,7 @@ public static SignInUpResponse signInUp(Main main, String thirdPartyId, String t try { Storage storage = StorageLayer.getStorage(main); return signInUp( - new TenantIdentifierWithStorage(null, null, null, storage), main, + new TenantIdentifier(null, null, null), storage, main, thirdPartyId, thirdPartyUserId, email, false); } catch (TenantOrAppNotFoundException | BadPermissionException e) { throw new IllegalStateException(e); @@ -132,7 +134,7 @@ public static SignInUpResponse signInUp(Main main, String thirdPartyId, String t try { Storage storage = StorageLayer.getStorage(main); return signInUp( - new TenantIdentifierWithStorage(null, null, null, storage), main, + new TenantIdentifier(null, null, null), storage, main, thirdPartyId, thirdPartyUserId, email, isEmailVerified); } catch (TenantOrAppNotFoundException | BadPermissionException e) { throw new IllegalStateException(e); @@ -140,42 +142,41 @@ public static SignInUpResponse signInUp(Main main, String thirdPartyId, String t } @TestOnly - public static SignInUpResponse signInUp(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, + public static SignInUpResponse signInUp(TenantIdentifier tenantIdentifier, Storage storage, Main main, String thirdPartyId, String thirdPartyUserId, String email) throws StorageQueryException, TenantOrAppNotFoundException, BadPermissionException, EmailChangeNotAllowedException { - return signInUp(tenantIdentifierWithStorage, main, thirdPartyId, thirdPartyUserId, email, false); + return signInUp(tenantIdentifier, storage, main, thirdPartyId, thirdPartyUserId, email, false); } - public static SignInUpResponse signInUp(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, + public static SignInUpResponse signInUp(TenantIdentifier tenantIdentifier, Storage storage, Main main, String thirdPartyId, String thirdPartyUserId, String email, boolean isEmailVerified) throws StorageQueryException, TenantOrAppNotFoundException, BadPermissionException, EmailChangeNotAllowedException { - TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifierWithStorage); + TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifier); if (config == null) { - throw new TenantOrAppNotFoundException(tenantIdentifierWithStorage); + throw new TenantOrAppNotFoundException(tenantIdentifier); } if (!config.thirdPartyConfig.enabled) { throw new BadPermissionException("Third Party login not enabled for tenant"); } - SignInUpResponse response = signInUpHelper(tenantIdentifierWithStorage, main, thirdPartyId, thirdPartyUserId, + SignInUpResponse response = signInUpHelper(tenantIdentifier, storage, thirdPartyId, thirdPartyUserId, email); if (isEmailVerified) { for (LoginMethod lM : response.user.loginMethods) { if (lM.thirdParty != null && lM.thirdParty.id.equals(thirdPartyId) && lM.thirdParty.userId.equals(thirdPartyUserId)) { try { - tenantIdentifierWithStorage.getEmailVerificationStorage().startTransaction(con -> { + EmailVerificationSQLStorage evStorage = StorageUtils.getEmailVerificationStorage(storage); + evStorage.startTransaction(con -> { try { - tenantIdentifierWithStorage.getEmailVerificationStorage() - .updateIsEmailVerified_Transaction(tenantIdentifierWithStorage.toAppIdentifier(), con, + evStorage.updateIsEmailVerified_Transaction(tenantIdentifier.toAppIdentifier(), con, lM.getSupertokensUserId(), lM.email, true); - tenantIdentifierWithStorage.getEmailVerificationStorage() - .commitTransaction(con); + evStorage.commitTransaction(con); return null; } catch (TenantOrAppNotFoundException e) { @@ -197,11 +198,11 @@ public static SignInUpResponse signInUp(TenantIdentifierWithStorage tenantIdenti return response; } - private static SignInUpResponse signInUpHelper(TenantIdentifierWithStorage tenantIdentifierWithStorage, - Main main, String thirdPartyId, String thirdPartyUserId, + private static SignInUpResponse signInUpHelper(TenantIdentifier tenantIdentifier, Storage storage, + String thirdPartyId, String thirdPartyUserId, String email) throws StorageQueryException, TenantOrAppNotFoundException, EmailChangeNotAllowedException { - ThirdPartySQLStorage storage = tenantIdentifierWithStorage.getThirdPartyStorage(); + ThirdPartySQLStorage tpStorage = StorageUtils.getThirdPartyStorage(storage); while (true) { // loop for sign in + sign up @@ -211,7 +212,7 @@ private static SignInUpResponse signInUpHelper(TenantIdentifierWithStorage tenan long timeJoined = System.currentTimeMillis(); try { - AuthRecipeUserInfo createdUser = storage.signUp(tenantIdentifierWithStorage, userId, email, + AuthRecipeUserInfo createdUser = tpStorage.signUp(tenantIdentifier, userId, email, new LoginMethod.ThirdParty(thirdPartyId, thirdPartyUserId), timeJoined); return new SignInUpResponse(true, createdUser); @@ -224,9 +225,8 @@ private static SignInUpResponse signInUpHelper(TenantIdentifierWithStorage tenan } // we try to get user and update their email - AppIdentifier appIdentifier = tenantIdentifierWithStorage.toAppIdentifier(); - AuthRecipeSQLStorage authRecipeStorage = - (AuthRecipeSQLStorage) tenantIdentifierWithStorage.getAuthRecipeStorage(); + AppIdentifier appIdentifier = tenantIdentifier.toAppIdentifier(); + AuthRecipeSQLStorage authRecipeStorage = StorageUtils.getAuthRecipeStorage(storage); { // Try without transaction, because in most cases we might not need to update the email AuthRecipeUserInfo userFromDb = null; @@ -235,7 +235,7 @@ private static SignInUpResponse signInUpHelper(TenantIdentifierWithStorage tenan appIdentifier, thirdPartyId, thirdPartyUserId); for (AuthRecipeUserInfo user : usersFromDb) { - if (user.tenantIds.contains(tenantIdentifierWithStorage.getTenantId())) { + if (user.tenantIds.contains(tenantIdentifier.getTenantId())) { if (userFromDb != null) { throw new IllegalStateException("Should never happen"); } @@ -265,7 +265,7 @@ private static SignInUpResponse signInUpHelper(TenantIdentifierWithStorage tenan // Email needs updating, so repeat everything in a transaction try { - storage.startTransaction(con -> { + tpStorage.startTransaction(con -> { AuthRecipeUserInfo userFromDb1 = null; AuthRecipeUserInfo[] usersFromDb1 = authRecipeStorage.listPrimaryUsersByThirdPartyInfo_Transaction( @@ -273,7 +273,7 @@ private static SignInUpResponse signInUpHelper(TenantIdentifierWithStorage tenan con, thirdPartyId, thirdPartyUserId); for (AuthRecipeUserInfo user : usersFromDb1) { - if (user.tenantIds.contains(tenantIdentifierWithStorage.getTenantId())) { + if (user.tenantIds.contains(tenantIdentifier.getTenantId())) { if (userFromDb1 != null) { throw new IllegalStateException("Should never happen"); } @@ -282,7 +282,7 @@ private static SignInUpResponse signInUpHelper(TenantIdentifierWithStorage tenan } if (userFromDb1 == null) { - storage.commitTransaction(con); + tpStorage.commitTransaction(con); return null; } @@ -320,11 +320,11 @@ private static SignInUpResponse signInUpHelper(TenantIdentifierWithStorage tenan } } } - storage.updateUserEmail_Transaction(appIdentifier, con, + tpStorage.updateUserEmail_Transaction(appIdentifier, con, thirdPartyId, thirdPartyUserId, email); } - storage.commitTransaction(con); + tpStorage.commitTransaction(con); return null; }); } catch (StorageTransactionLogicException e) { @@ -336,16 +336,16 @@ private static SignInUpResponse signInUpHelper(TenantIdentifierWithStorage tenan } } - AuthRecipeUserInfo user = getUser(tenantIdentifierWithStorage, thirdPartyId, thirdPartyUserId); + AuthRecipeUserInfo user = getUser(tenantIdentifier, storage, thirdPartyId, thirdPartyUserId); return new SignInUpResponse(false, user); } } @Deprecated - public static AuthRecipeUserInfo getUser(AppIdentifierWithStorage appIdentifierWithStorage, String userId) + public static AuthRecipeUserInfo getUser(AppIdentifier appIdentifier, Storage storage, String userId) throws StorageQueryException { - AuthRecipeUserInfo result = appIdentifierWithStorage.getAuthRecipeStorage() - .getPrimaryUserById(appIdentifierWithStorage, userId); + AuthRecipeUserInfo result = StorageUtils.getAuthRecipeStorage(storage) + .getPrimaryUserById(appIdentifier, userId); if (result == null) { return null; } @@ -362,15 +362,15 @@ public static AuthRecipeUserInfo getUser(AppIdentifierWithStorage appIdentifierW @TestOnly public static AuthRecipeUserInfo getUser(Main main, String userId) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - return getUser(new AppIdentifierWithStorage(null, null, storage), userId); + return getUser(new AppIdentifier(null, null), storage, userId); } - public static AuthRecipeUserInfo getUser(TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static AuthRecipeUserInfo getUser(TenantIdentifier tenantIdentifier, Storage storage, String thirdPartyId, String thirdPartyUserId) throws StorageQueryException { - return tenantIdentifierWithStorage.getThirdPartyStorage() - .getPrimaryUserByThirdPartyInfo(tenantIdentifierWithStorage, thirdPartyId, thirdPartyUserId); + return StorageUtils.getThirdPartyStorage(storage) + .getPrimaryUserByThirdPartyInfo(tenantIdentifier, thirdPartyId, thirdPartyUserId); } @TestOnly @@ -378,16 +378,16 @@ public static AuthRecipeUserInfo getUser(Main main, String thirdPartyId, String throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); return getUser( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, thirdPartyId, thirdPartyUserId); } @Deprecated - public static AuthRecipeUserInfo[] getUsersByEmail(TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static AuthRecipeUserInfo[] getUsersByEmail(TenantIdentifier tenantIdentifier, Storage storage, @Nonnull String email) throws StorageQueryException { - AuthRecipeUserInfo[] users = tenantIdentifierWithStorage.getThirdPartyStorage() - .listPrimaryUsersByEmail(tenantIdentifierWithStorage, email); + AuthRecipeUserInfo[] users = StorageUtils.getThirdPartyStorage(storage) + .listPrimaryUsersByEmail(tenantIdentifier, email); List result = new ArrayList<>(); for (AuthRecipeUserInfo user : users) { for (LoginMethod lM : user.loginMethods) { diff --git a/src/main/java/io/supertokens/webserver/api/thirdparty/GetUsersByEmailAPI.java b/src/main/java/io/supertokens/webserver/api/thirdparty/GetUsersByEmailAPI.java index d880a9686..66fcc8758 100644 --- a/src/main/java/io/supertokens/webserver/api/thirdparty/GetUsersByEmailAPI.java +++ b/src/main/java/io/supertokens/webserver/api/thirdparty/GetUsersByEmailAPI.java @@ -21,10 +21,10 @@ import com.google.gson.JsonObject; import io.supertokens.Main; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.thirdparty.ThirdParty; import io.supertokens.useridmapping.UserIdMapping; @@ -55,14 +55,13 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // this API is tenant specific try { - TenantIdentifierWithStorage tenantIdentifierWithStorage = this.getTenantStorage( - req); - AppIdentifierWithStorage appIdentifierWithStorage = tenantIdentifierWithStorage.toAppIdentifierWithStorage(); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); String email = InputParser.getQueryParamOrThrowError(req, "email", false); email = Utils.normaliseEmail(email); - AuthRecipeUserInfo[] users = ThirdParty.getUsersByEmail(tenantIdentifierWithStorage, email); - UserIdMapping.populateExternalUserIdForUsers(tenantIdentifierWithStorage, users); + AuthRecipeUserInfo[] users = ThirdParty.getUsersByEmail(tenantIdentifier, storage, email); + UserIdMapping.populateExternalUserIdForUsers(storage, users); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java b/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java index 4e47b6303..2962d92e1 100644 --- a/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java +++ b/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java @@ -22,9 +22,11 @@ import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.authRecipe.LoginMethod; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.thirdparty.ThirdParty; import io.supertokens.useridmapping.UserIdMapping; @@ -74,13 +76,15 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I email = Utils.normaliseEmail(email); try { + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); ThirdParty.SignInUpResponse response = ThirdParty.signInUp2_7( - this.getTenantStorage(req), super.main, - thirdPartyId, - thirdPartyUserId, email, isEmailVerified); + tenantIdentifier, storage, + thirdPartyId, thirdPartyUserId, email, isEmailVerified); UserIdMapping.populateExternalUserIdForUsers(this.getTenantStorage(req), new AuthRecipeUserInfo[]{response.user}); - ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, response.user.getSupertokensUserId()); + ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), getPublicTenantStorage(req), + response.user.getSupertokensUserId()); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); @@ -133,12 +137,15 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I email = Utils.normaliseEmail(email); try { + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); ThirdParty.SignInUpResponse response = ThirdParty.signInUp( - this.getTenantStorage(req), super.main, thirdPartyId, thirdPartyUserId, + tenantIdentifier, storage, super.main, thirdPartyId, thirdPartyUserId, email, isEmailVerified); - UserIdMapping.populateExternalUserIdForUsers(this.getTenantStorage(req), new AuthRecipeUserInfo[]{response.user}); + UserIdMapping.populateExternalUserIdForUsers(storage, new AuthRecipeUserInfo[]{response.user}); - ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, response.user.getSupertokensUserId()); + ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), this.getPublicTenantStorage(req), + response.user.getSupertokensUserId()); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java b/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java index a819aeb6f..efd0f81c6 100644 --- a/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java @@ -17,13 +17,16 @@ package io.supertokens.webserver.api.thirdparty; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.thirdparty.ThirdParty; import io.supertokens.useridmapping.UserIdMapping; @@ -75,24 +78,28 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO AuthRecipeUserInfo user = null; if (userId != null) { // Query by userId + AppIdentifier appIdentifier = getAppIdentifier(req); try { - AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = + StorageAndUserIdMapping storageAndUserIdMapping = this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the getUserUsingId function - if (appIdentifierWithStorageAndUserIdMapping.userIdMapping != null) { - userId = appIdentifierWithStorageAndUserIdMapping.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - user = ThirdParty.getUser(appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, + user = ThirdParty.getUser(appIdentifier, storageAndUserIdMapping.storage, userId); if (user != null) { - UserIdMapping.populateExternalUserIdForUsers(appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, new AuthRecipeUserInfo[]{user}); + UserIdMapping.populateExternalUserIdForUsers(storageAndUserIdMapping.storage, + new AuthRecipeUserInfo[]{user}); } } catch (UnknownUserIdException e) { // let the user be null } } else { - user = ThirdParty.getUser(this.getTenantStorage(req), thirdPartyId, + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); + user = ThirdParty.getUser(tenantIdentifier, storage, thirdPartyId, thirdPartyUserId); if (user != null) { UserIdMapping.populateExternalUserIdForUsers(getTenantStorage(req), new AuthRecipeUserInfo[]{user}); From 9a0ff85c1dc5b4d73c7bbd3711d8ad25ef5c0920 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 1 Mar 2024 14:42:00 +0530 Subject: [PATCH 05/31] fix: passwordless changes --- .../passwordless/Passwordless.java | 222 +++++++++--------- .../api/passwordless/ConsumeCodeAPI.java | 6 +- .../api/passwordless/CreateCodeAPI.java | 5 +- .../api/passwordless/DeleteCodeAPI.java | 2 +- .../api/passwordless/DeleteCodesAPI.java | 6 +- .../api/passwordless/GetCodesAPI.java | 20 +- .../webserver/api/passwordless/UserAPI.java | 43 ++-- 7 files changed, 166 insertions(+), 138 deletions(-) diff --git a/src/main/java/io/supertokens/passwordless/Passwordless.java b/src/main/java/io/supertokens/passwordless/Passwordless.java index f4003e302..7d51f1c9a 100644 --- a/src/main/java/io/supertokens/passwordless/Passwordless.java +++ b/src/main/java/io/supertokens/passwordless/Passwordless.java @@ -25,17 +25,19 @@ import io.supertokens.passwordless.exceptions.*; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.authRecipe.LoginMethod; import io.supertokens.pluginInterface.authRecipe.sqlStorage.AuthRecipeSQLStorage; import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException; import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateUserIdException; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; +import io.supertokens.pluginInterface.emailverification.sqlStorage.EmailVerificationSQLStorage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.TenantConfig; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.passwordless.PasswordlessCode; import io.supertokens.pluginInterface.passwordless.PasswordlessDevice; @@ -71,14 +73,14 @@ public static CreateCodeResponse createCode(Main main, String email, String phon try { Storage storage = StorageLayer.getStorage(main); return createCode( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, main, email, phoneNumber, deviceId, userInputCode); } catch (TenantOrAppNotFoundException | BadPermissionException e) { throw new IllegalStateException(e); } } - public static CreateCodeResponse createCode(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, + public static CreateCodeResponse createCode(TenantIdentifier tenantIdentifier, Storage storage, Main main, String email, String phoneNumber, @Nullable String deviceId, @Nullable String userInputCode) @@ -86,20 +88,20 @@ public static CreateCodeResponse createCode(TenantIdentifierWithStorage tenantId StorageQueryException, NoSuchAlgorithmException, InvalidKeyException, IOException, Base64EncodingException, TenantOrAppNotFoundException, BadPermissionException { - TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifierWithStorage); + TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifier); if (config == null) { - throw new TenantOrAppNotFoundException(tenantIdentifierWithStorage); + throw new TenantOrAppNotFoundException(tenantIdentifier); } if (!config.passwordlessConfig.enabled) { throw new BadPermissionException("Passwordless login not enabled for tenant"); } - PasswordlessSQLStorage passwordlessStorage = tenantIdentifierWithStorage.getPasswordlessStorage(); + PasswordlessSQLStorage passwordlessStorage = StorageUtils.getPasswordlessStorage(storage); if (deviceId == null) { while (true) { CreateCodeInfo info = CreateCodeInfo.generate(userInputCode); try { - passwordlessStorage.createDeviceWithCode(tenantIdentifierWithStorage, email, phoneNumber, + passwordlessStorage.createDeviceWithCode(tenantIdentifier, email, phoneNumber, info.linkCodeSalt.encode(), info.code); return info.resp; @@ -112,7 +114,7 @@ public static CreateCodeResponse createCode(TenantIdentifierWithStorage tenantId } else { PasswordlessDeviceId parsedDeviceId = PasswordlessDeviceId.decodeString(deviceId); - PasswordlessDevice device = passwordlessStorage.getDevice(tenantIdentifierWithStorage, + PasswordlessDevice device = passwordlessStorage.getDevice(tenantIdentifier, parsedDeviceId.getHash().encode()); if (device == null) { throw new RestartFlowException(); @@ -120,7 +122,7 @@ public static CreateCodeResponse createCode(TenantIdentifierWithStorage tenantId while (true) { CreateCodeInfo info = CreateCodeInfo.generate(userInputCode, deviceId, device.linkCodeSalt); try { - passwordlessStorage.createCode(tenantIdentifierWithStorage, info.code); + passwordlessStorage.createCode(tenantIdentifier, info.code); return info.resp; } catch (DuplicateLinkCodeHashException e) { @@ -150,9 +152,9 @@ private static String generateUserInputCode() { } public static DeviceWithCodes getDeviceWithCodesById( - TenantIdentifierWithStorage tenantIdentifierWithStorage, String deviceId) + TenantIdentifier tenantIdentifier, Storage storage, String deviceId) throws StorageQueryException, NoSuchAlgorithmException, Base64EncodingException { - return getDeviceWithCodesByIdHash(tenantIdentifierWithStorage, + return getDeviceWithCodesByIdHash(tenantIdentifier, storage, PasswordlessDeviceId.decodeString(deviceId).getHash().encode()); } @@ -161,7 +163,7 @@ public static DeviceWithCodes getDeviceWithCodesById(Main main, String deviceId) NoSuchAlgorithmException, Base64EncodingException { Storage storage = StorageLayer.getStorage(main); return getDeviceWithCodesById( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, deviceId); } @@ -170,34 +172,34 @@ public static DeviceWithCodes getDeviceWithCodesByIdHash(Main main, String devic throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); return getDeviceWithCodesByIdHash( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, deviceIdHash); } - public static DeviceWithCodes getDeviceWithCodesByIdHash(TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static DeviceWithCodes getDeviceWithCodesByIdHash(TenantIdentifier tenantIdentifier, Storage storage, String deviceIdHash) throws StorageQueryException { - PasswordlessSQLStorage passwordlessStorage = tenantIdentifierWithStorage.getPasswordlessStorage(); + PasswordlessSQLStorage passwordlessStorage = StorageUtils.getPasswordlessStorage(storage); - PasswordlessDevice device = passwordlessStorage.getDevice(tenantIdentifierWithStorage, deviceIdHash); + PasswordlessDevice device = passwordlessStorage.getDevice(tenantIdentifier, deviceIdHash); if (device == null) { return null; } - PasswordlessCode[] codes = passwordlessStorage.getCodesOfDevice(tenantIdentifierWithStorage, deviceIdHash); + PasswordlessCode[] codes = passwordlessStorage.getCodesOfDevice(tenantIdentifier, deviceIdHash); return new DeviceWithCodes(device, codes); } public static List getDevicesWithCodesByEmail( - TenantIdentifierWithStorage tenantIdentifierWithStorage, String email) + TenantIdentifier tenantIdentifier, Storage storage, String email) throws StorageQueryException { - PasswordlessSQLStorage passwordlessStorage = tenantIdentifierWithStorage.getPasswordlessStorage(); + PasswordlessSQLStorage passwordlessStorage = StorageUtils.getPasswordlessStorage(storage); - PasswordlessDevice[] devices = passwordlessStorage.getDevicesByEmail(tenantIdentifierWithStorage, email); + PasswordlessDevice[] devices = passwordlessStorage.getDevicesByEmail(tenantIdentifier, email); ArrayList result = new ArrayList(); for (PasswordlessDevice device : devices) { - PasswordlessCode[] codes = passwordlessStorage.getCodesOfDevice(tenantIdentifierWithStorage, + PasswordlessCode[] codes = passwordlessStorage.getCodesOfDevice(tenantIdentifier, device.deviceIdHash); result.add(new DeviceWithCodes(device, codes)); } @@ -210,19 +212,19 @@ public static List getDevicesWithCodesByEmail(Main main, String throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); return getDevicesWithCodesByEmail( - new TenantIdentifierWithStorage(null, null, null, storage), email); + new TenantIdentifier(null, null, null), storage, email); } public static List getDevicesWithCodesByPhoneNumber( - TenantIdentifierWithStorage tenantIdentifierWithStorage, String phoneNumber) + TenantIdentifier tenantIdentifier, Storage storage, String phoneNumber) throws StorageQueryException { - PasswordlessSQLStorage passwordlessStorage = tenantIdentifierWithStorage.getPasswordlessStorage(); + PasswordlessSQLStorage passwordlessStorage = StorageUtils.getPasswordlessStorage(storage); - PasswordlessDevice[] devices = passwordlessStorage.getDevicesByPhoneNumber(tenantIdentifierWithStorage, + PasswordlessDevice[] devices = passwordlessStorage.getDevicesByPhoneNumber(tenantIdentifier, phoneNumber); ArrayList result = new ArrayList(); for (PasswordlessDevice device : devices) { - PasswordlessCode[] codes = passwordlessStorage.getCodesOfDevice(tenantIdentifierWithStorage, + PasswordlessCode[] codes = passwordlessStorage.getCodesOfDevice(tenantIdentifier, device.deviceIdHash); result.add(new DeviceWithCodes(device, codes)); } @@ -235,7 +237,7 @@ public static List getDevicesWithCodesByPhoneNumber(Main main, throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); return getDevicesWithCodesByPhoneNumber( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, phoneNumber); } @@ -249,7 +251,7 @@ public static ConsumeCodeResponse consumeCode(Main main, try { Storage storage = StorageLayer.getStorage(main); return consumeCode( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, main, deviceId, deviceIdHashFromUser, userInputCode, linkCode, false); } catch (TenantOrAppNotFoundException | BadPermissionException e) { throw new IllegalStateException(e); @@ -266,7 +268,7 @@ public static ConsumeCodeResponse consumeCode(Main main, try { Storage storage = StorageLayer.getStorage(main); return consumeCode( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, main, deviceId, deviceIdHashFromUser, userInputCode, linkCode, setEmailVerified); } catch (TenantOrAppNotFoundException | BadPermissionException e) { throw new IllegalStateException(e); @@ -274,18 +276,18 @@ public static ConsumeCodeResponse consumeCode(Main main, } @TestOnly - public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, + public static ConsumeCodeResponse consumeCode(TenantIdentifier tenantIdentifier, Storage storage, Main main, String deviceId, String deviceIdHashFromUser, String userInputCode, String linkCode) throws RestartFlowException, ExpiredUserInputCodeException, IncorrectUserInputCodeException, DeviceIdHashMismatchException, StorageTransactionLogicException, StorageQueryException, NoSuchAlgorithmException, InvalidKeyException, IOException, Base64EncodingException, TenantOrAppNotFoundException, BadPermissionException { - return consumeCode(tenantIdentifierWithStorage, main, deviceId, deviceIdHashFromUser, userInputCode, linkCode, + return consumeCode(tenantIdentifier, storage, main, deviceId, deviceIdHashFromUser, userInputCode, linkCode, false); } - public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, + public static ConsumeCodeResponse consumeCode(TenantIdentifier tenantIdentifier, Storage storage, Main main, String deviceId, String deviceIdHashFromUser, String userInputCode, String linkCode, boolean setEmailVerified) throws RestartFlowException, ExpiredUserInputCodeException, @@ -293,18 +295,18 @@ public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenant StorageQueryException, NoSuchAlgorithmException, InvalidKeyException, IOException, Base64EncodingException, TenantOrAppNotFoundException, BadPermissionException { - TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifierWithStorage); + TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifier); if (config == null) { - throw new TenantOrAppNotFoundException(tenantIdentifierWithStorage); + throw new TenantOrAppNotFoundException(tenantIdentifier); } if (!config.passwordlessConfig.enabled) { throw new BadPermissionException("Passwordless login not enabled for tenant"); } - PasswordlessSQLStorage passwordlessStorage = tenantIdentifierWithStorage.getPasswordlessStorage(); - long passwordlessCodeLifetime = Config.getConfig(tenantIdentifierWithStorage, main) + PasswordlessSQLStorage passwordlessStorage = StorageUtils.getPasswordlessStorage(storage); + long passwordlessCodeLifetime = Config.getConfig(tenantIdentifier, main) .getPasswordlessCodeLifetime(); - int maxCodeInputAttempts = Config.getConfig(tenantIdentifierWithStorage, main) + int maxCodeInputAttempts = Config.getConfig(tenantIdentifier, main) .getPasswordlessMaxCodeInputAttempts(); PasswordlessDeviceIdHash deviceIdHash; @@ -313,7 +315,7 @@ public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenant PasswordlessLinkCode parsedCode = PasswordlessLinkCode.decodeString(linkCode); linkCodeHash = parsedCode.getHash(); - PasswordlessCode code = passwordlessStorage.getCodeByLinkCodeHash(tenantIdentifierWithStorage, + PasswordlessCode code = passwordlessStorage.getCodeByLinkCodeHash(tenantIdentifier, linkCodeHash.encode()); if (code == null || code.createdAt < (System.currentTimeMillis() - passwordlessCodeLifetime)) { throw new RestartFlowException(); @@ -324,7 +326,7 @@ public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenant PasswordlessDeviceId parsedDeviceId = PasswordlessDeviceId.decodeString(deviceId); deviceIdHash = parsedDeviceId.getHash(); - PasswordlessDevice device = passwordlessStorage.getDevice(tenantIdentifierWithStorage, + PasswordlessDevice device = passwordlessStorage.getDevice(tenantIdentifier, deviceIdHash.encode()); if (device == null) { throw new RestartFlowException(); @@ -340,21 +342,21 @@ public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenant PasswordlessDevice consumedDevice; try { consumedDevice = passwordlessStorage.startTransaction(con -> { - PasswordlessDevice device = passwordlessStorage.getDevice_Transaction(tenantIdentifierWithStorage, con, + PasswordlessDevice device = passwordlessStorage.getDevice_Transaction(tenantIdentifier, con, deviceIdHash.encode()); if (device == null) { throw new StorageTransactionLogicException(new RestartFlowException()); } if (device.failedAttempts >= maxCodeInputAttempts) { // This can happen if the configured maxCodeInputAttempts changes - passwordlessStorage.deleteDevice_Transaction(tenantIdentifierWithStorage, con, + passwordlessStorage.deleteDevice_Transaction(tenantIdentifier, con, deviceIdHash.encode()); passwordlessStorage.commitTransaction(con); throw new StorageTransactionLogicException(new RestartFlowException()); } PasswordlessCode code = passwordlessStorage.getCodeByLinkCodeHash_Transaction( - tenantIdentifierWithStorage, con, + tenantIdentifier, con, linkCodeHash.encode()); if (code == null || code.createdAt < System.currentTimeMillis() - passwordlessCodeLifetime) { if (deviceId != null) { @@ -362,13 +364,13 @@ public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenant // the code expired. This means that we need to increment failedAttempts or clean up the device // if it would exceed the configured max. if (device.failedAttempts + 1 >= maxCodeInputAttempts) { - passwordlessStorage.deleteDevice_Transaction(tenantIdentifierWithStorage, con, + passwordlessStorage.deleteDevice_Transaction(tenantIdentifier, con, deviceIdHash.encode()); passwordlessStorage.commitTransaction(con); throw new StorageTransactionLogicException(new RestartFlowException()); } else { passwordlessStorage.incrementDeviceFailedAttemptCount_Transaction( - tenantIdentifierWithStorage, con, + tenantIdentifier, con, deviceIdHash.encode()); passwordlessStorage.commitTransaction(con); @@ -385,10 +387,10 @@ public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenant } if (device.email != null) { - passwordlessStorage.deleteDevicesByEmail_Transaction(tenantIdentifierWithStorage, con, + passwordlessStorage.deleteDevicesByEmail_Transaction(tenantIdentifier, con, device.email); } else if (device.phoneNumber != null) { - passwordlessStorage.deleteDevicesByPhoneNumber_Transaction(tenantIdentifierWithStorage, con, + passwordlessStorage.deleteDevicesByPhoneNumber_Transaction(tenantIdentifier, con, device.phoneNumber); } @@ -412,11 +414,11 @@ public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenant AuthRecipeUserInfo user = null; LoginMethod loginMethod = null; if (consumedDevice.email != null) { - AuthRecipeUserInfo[] users = passwordlessStorage.listPrimaryUsersByEmail(tenantIdentifierWithStorage, + AuthRecipeUserInfo[] users = passwordlessStorage.listPrimaryUsersByEmail(tenantIdentifier, consumedDevice.email); for (AuthRecipeUserInfo currUser : users) { for (LoginMethod currLM : currUser.loginMethods) { - if (currLM.recipeId == RECIPE_ID.PASSWORDLESS && currLM.email != null && currLM.email.equals(consumedDevice.email) && currLM.tenantIds.contains(tenantIdentifierWithStorage.getTenantId())) { + if (currLM.recipeId == RECIPE_ID.PASSWORDLESS && currLM.email != null && currLM.email.equals(consumedDevice.email) && currLM.tenantIds.contains(tenantIdentifier.getTenantId())) { user = currUser; loginMethod = currLM; break; @@ -424,12 +426,12 @@ public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenant } } } else { - AuthRecipeUserInfo[] users = passwordlessStorage.listPrimaryUsersByPhoneNumber(tenantIdentifierWithStorage, + AuthRecipeUserInfo[] users = passwordlessStorage.listPrimaryUsersByPhoneNumber(tenantIdentifier, consumedDevice.phoneNumber); for (AuthRecipeUserInfo currUser : users) { for (LoginMethod currLM : currUser.loginMethods) { if (currLM.recipeId == RECIPE_ID.PASSWORDLESS && - currLM.phoneNumber != null && currLM.phoneNumber.equals(consumedDevice.phoneNumber) && currLM.tenantIds.contains(tenantIdentifierWithStorage.getTenantId())) { + currLM.phoneNumber != null && currLM.phoneNumber.equals(consumedDevice.phoneNumber) && currLM.tenantIds.contains(tenantIdentifier.getTenantId())) { user = currUser; loginMethod = currLM; break; @@ -443,20 +445,21 @@ public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenant try { String userId = Utils.getUUID(); long timeJoined = System.currentTimeMillis(); - user = passwordlessStorage.createUser(tenantIdentifierWithStorage, userId, consumedDevice.email, + user = passwordlessStorage.createUser(tenantIdentifier, userId, consumedDevice.email, consumedDevice.phoneNumber, timeJoined); // Set email as verified, if using email if (setEmailVerified && consumedDevice.email != null) { try { AuthRecipeUserInfo finalUser = user; - tenantIdentifierWithStorage.getEmailVerificationStorage().startTransaction(con -> { + EmailVerificationSQLStorage evStorage = StorageUtils.getEmailVerificationStorage(storage); + + evStorage.startTransaction(con -> { try { - tenantIdentifierWithStorage.getEmailVerificationStorage() - .updateIsEmailVerified_Transaction(tenantIdentifierWithStorage.toAppIdentifier(), con, - finalUser.getSupertokensUserId(), consumedDevice.email, true); - tenantIdentifierWithStorage.getEmailVerificationStorage() - .commitTransaction(con); + evStorage.updateIsEmailVerified_Transaction( + tenantIdentifier.toAppIdentifier(), con, finalUser.getSupertokensUserId(), + consumedDevice.email, true); + evStorage.commitTransaction(con); return null; } catch (TenantOrAppNotFoundException e) { @@ -492,13 +495,13 @@ public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenant // Set email verification try { LoginMethod finalLoginMethod = loginMethod; - tenantIdentifierWithStorage.getEmailVerificationStorage().startTransaction(con -> { + EmailVerificationSQLStorage evStorage = StorageUtils.getEmailVerificationStorage(storage); + evStorage.startTransaction(con -> { try { - tenantIdentifierWithStorage.getEmailVerificationStorage() - .updateIsEmailVerified_Transaction(tenantIdentifierWithStorage.toAppIdentifier(), con, - finalLoginMethod.getSupertokensUserId(), consumedDevice.email, true); - tenantIdentifierWithStorage.getEmailVerificationStorage() - .commitTransaction(con); + evStorage.updateIsEmailVerified_Transaction( + tenantIdentifier.toAppIdentifier(), con, finalLoginMethod.getSupertokensUserId(), + consumedDevice.email, true); + evStorage.commitTransaction(con); return null; } catch (TenantOrAppNotFoundException e) { @@ -515,10 +518,10 @@ public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenant } if (loginMethod.email != null && !loginMethod.email.equals(consumedDevice.email)) { - removeCodesByEmail(tenantIdentifierWithStorage, loginMethod.email); + removeCodesByEmail(tenantIdentifier, storage, loginMethod.email); } if (loginMethod.phoneNumber != null && !loginMethod.phoneNumber.equals(consumedDevice.phoneNumber)) { - removeCodesByPhoneNumber(tenantIdentifierWithStorage, loginMethod.phoneNumber); + removeCodesByPhoneNumber(tenantIdentifier, storage, loginMethod.phoneNumber); } } return new ConsumeCodeResponse(false, user, consumedDevice.email, consumedDevice.phoneNumber); @@ -528,15 +531,15 @@ public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenant public static void removeCode(Main main, String codeId) throws StorageQueryException, StorageTransactionLogicException { Storage storage = StorageLayer.getStorage(main); - removeCode(new TenantIdentifierWithStorage(null, null, null, storage), + removeCode(new TenantIdentifier(null, null, null), storage, codeId); } - public static void removeCode(TenantIdentifierWithStorage tenantIdentifierWithStorage, String codeId) + public static void removeCode(TenantIdentifier tenantIdentifier, Storage storage, String codeId) throws StorageQueryException, StorageTransactionLogicException { - PasswordlessSQLStorage passwordlessStorage = tenantIdentifierWithStorage.getPasswordlessStorage(); + PasswordlessSQLStorage passwordlessStorage = StorageUtils.getPasswordlessStorage(storage); - PasswordlessCode code = passwordlessStorage.getCode(tenantIdentifierWithStorage, codeId); + PasswordlessCode code = passwordlessStorage.getCode(tenantIdentifier, codeId); if (code == null) { return; @@ -544,9 +547,9 @@ public static void removeCode(TenantIdentifierWithStorage tenantIdentifierWithSt passwordlessStorage.startTransaction(con -> { // Locking the device - passwordlessStorage.getDevice_Transaction(tenantIdentifierWithStorage, con, code.deviceIdHash); + passwordlessStorage.getDevice_Transaction(tenantIdentifier, con, code.deviceIdHash); - PasswordlessCode[] allCodes = passwordlessStorage.getCodesOfDevice_Transaction(tenantIdentifierWithStorage, + PasswordlessCode[] allCodes = passwordlessStorage.getCodesOfDevice_Transaction(tenantIdentifier, con, code.deviceIdHash); if (!Stream.of(allCodes).anyMatch(code::equals)) { @@ -556,10 +559,10 @@ public static void removeCode(TenantIdentifierWithStorage tenantIdentifierWithSt if (allCodes.length == 1) { // If the device contains only the current code we should delete the device as well. - passwordlessStorage.deleteDevice_Transaction(tenantIdentifierWithStorage, con, code.deviceIdHash); + passwordlessStorage.deleteDevice_Transaction(tenantIdentifier, con, code.deviceIdHash); } else { // Otherwise we can just delete the code - passwordlessStorage.deleteCode_Transaction(tenantIdentifierWithStorage, con, codeId); + passwordlessStorage.deleteCode_Transaction(tenantIdentifier, con, codeId); } passwordlessStorage.commitTransaction(con); return null; @@ -571,15 +574,15 @@ public static void removeCodesByEmail(Main main, String email) throws StorageQueryException, StorageTransactionLogicException { Storage storage = StorageLayer.getStorage(main); removeCodesByEmail( - new TenantIdentifierWithStorage(null, null, null, storage), email); + new TenantIdentifier(null, null, null), storage, email); } - public static void removeCodesByEmail(TenantIdentifierWithStorage tenantIdentifierWithStorage, String email) + public static void removeCodesByEmail(TenantIdentifier tenantIdentifier, Storage storage, String email) throws StorageQueryException, StorageTransactionLogicException { - PasswordlessSQLStorage passwordlessStorage = tenantIdentifierWithStorage.getPasswordlessStorage(); + PasswordlessSQLStorage passwordlessStorage = StorageUtils.getPasswordlessStorage(storage); passwordlessStorage.startTransaction(con -> { - passwordlessStorage.deleteDevicesByEmail_Transaction(tenantIdentifierWithStorage, con, email); + passwordlessStorage.deleteDevicesByEmail_Transaction(tenantIdentifier, con, email); passwordlessStorage.commitTransaction(con); return null; }); @@ -591,17 +594,17 @@ public static void removeCodesByPhoneNumber(Main main, throws StorageQueryException, StorageTransactionLogicException { Storage storage = StorageLayer.getStorage(main); removeCodesByPhoneNumber( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, phoneNumber); } - public static void removeCodesByPhoneNumber(TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static void removeCodesByPhoneNumber(TenantIdentifier tenantIdentifier, Storage storage, String phoneNumber) throws StorageQueryException, StorageTransactionLogicException { - PasswordlessSQLStorage passwordlessStorage = tenantIdentifierWithStorage.getPasswordlessStorage(); + PasswordlessSQLStorage passwordlessStorage = StorageUtils.getPasswordlessStorage(storage); passwordlessStorage.startTransaction(con -> { - passwordlessStorage.deleteDevicesByPhoneNumber_Transaction(tenantIdentifierWithStorage, con, phoneNumber); + passwordlessStorage.deleteDevicesByPhoneNumber_Transaction(tenantIdentifier, con, phoneNumber); passwordlessStorage.commitTransaction(con); return null; }); @@ -613,14 +616,14 @@ public static AuthRecipeUserInfo getUserById(Main main, String userId) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); return getUserById( - new AppIdentifierWithStorage(null, null, storage), userId); + new AppIdentifier(null, null), storage, userId); } @Deprecated - public static AuthRecipeUserInfo getUserById(AppIdentifierWithStorage appIdentifierWithStorage, String userId) + public static AuthRecipeUserInfo getUserById(AppIdentifier appIdentifier, Storage storage, String userId) throws StorageQueryException { - AuthRecipeUserInfo result = appIdentifierWithStorage.getAuthRecipeStorage() - .getPrimaryUserById(appIdentifierWithStorage, userId); + AuthRecipeUserInfo result = StorageUtils.getAuthRecipeStorage(storage) + .getPrimaryUserById(appIdentifier, userId); if (result == null) { return null; } @@ -638,15 +641,15 @@ public static AuthRecipeUserInfo getUserByPhoneNumber(Main main, String phoneNumber) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); return getUserByPhoneNumber( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, phoneNumber); } @Deprecated - public static AuthRecipeUserInfo getUserByPhoneNumber(TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static AuthRecipeUserInfo getUserByPhoneNumber(TenantIdentifier tenantIdentifier, Storage storage, String phoneNumber) throws StorageQueryException { - AuthRecipeUserInfo[] users = tenantIdentifierWithStorage.getPasswordlessStorage() - .listPrimaryUsersByPhoneNumber(tenantIdentifierWithStorage, phoneNumber); + AuthRecipeUserInfo[] users = StorageUtils.getPasswordlessStorage(storage) + .listPrimaryUsersByPhoneNumber(tenantIdentifier, phoneNumber); for (AuthRecipeUserInfo user : users) { for (LoginMethod lM : user.loginMethods) { if (lM.recipeId == RECIPE_ID.PASSWORDLESS && lM.phoneNumber.equals(phoneNumber)) { @@ -663,15 +666,15 @@ public static AuthRecipeUserInfo getUserByEmail(Main main, String email) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); return getUserByEmail( - new TenantIdentifierWithStorage(null, null, null, storage), email); + new TenantIdentifier(null, null, null), storage, email); } @Deprecated - public static AuthRecipeUserInfo getUserByEmail(TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static AuthRecipeUserInfo getUserByEmail(TenantIdentifier tenantIdentifier, Storage storage, String email) throws StorageQueryException { - AuthRecipeUserInfo[] users = tenantIdentifierWithStorage.getPasswordlessStorage() - .listPrimaryUsersByEmail(tenantIdentifierWithStorage, email); + AuthRecipeUserInfo[] users = StorageUtils.getPasswordlessStorage(storage) + .listPrimaryUsersByEmail(tenantIdentifier, email); for (AuthRecipeUserInfo user : users) { for (LoginMethod lM : user.loginMethods) { if (lM.recipeId == RECIPE_ID.PASSWORDLESS && lM.email.equals(email)) { @@ -689,20 +692,20 @@ public static void updateUser(Main main, String userId, DuplicatePhoneNumberException, UserWithoutContactInfoException, EmailChangeNotAllowedException, PhoneNumberChangeNotAllowedException { Storage storage = StorageLayer.getStorage(main); - updateUser(new AppIdentifierWithStorage(null, null, storage), + updateUser(new AppIdentifier(null, null), storage, userId, emailUpdate, phoneNumberUpdate); } - public static void updateUser(AppIdentifierWithStorage appIdentifierWithStorage, String recipeUserId, + public static void updateUser(AppIdentifier appIdentifier, Storage storage, String recipeUserId, FieldUpdate emailUpdate, FieldUpdate phoneNumberUpdate) throws StorageQueryException, UnknownUserIdException, DuplicateEmailException, DuplicatePhoneNumberException, UserWithoutContactInfoException, EmailChangeNotAllowedException, PhoneNumberChangeNotAllowedException { - PasswordlessSQLStorage storage = appIdentifierWithStorage.getPasswordlessStorage(); + PasswordlessSQLStorage plStorage = StorageUtils.getPasswordlessStorage(storage); // We do not lock the user here, because we decided that even if the device cleanup used outdated information // it wouldn't leave the system in an incosistent state/cause problems. - AuthRecipeUserInfo user = AuthRecipe.getUserById(appIdentifierWithStorage, recipeUserId); + AuthRecipeUserInfo user = AuthRecipe.getUserById(appIdentifier, storage, recipeUserId); if (user == null) { throw new UnknownUserIdException(); } @@ -722,15 +725,14 @@ public static void updateUser(AppIdentifierWithStorage appIdentifierWithStorage, throw new UserWithoutContactInfoException(); } try { - AuthRecipeSQLStorage authRecipeSQLStorage = - (AuthRecipeSQLStorage) appIdentifierWithStorage.getAuthRecipeStorage(); - storage.startTransaction(con -> { + AuthRecipeSQLStorage authRecipeSQLStorage = StorageUtils.getAuthRecipeStorage(storage); + plStorage.startTransaction(con -> { if (emailUpdate != null && !Objects.equals(emailUpdate.newValue, lM.email)) { if (user.isPrimaryUser) { for (String tenantId : user.tenantIds) { AuthRecipeUserInfo[] existingUsersWithNewEmail = authRecipeSQLStorage.listPrimaryUsersByEmail_Transaction( - appIdentifierWithStorage, con, + appIdentifier, con, emailUpdate.newValue); for (AuthRecipeUserInfo userWithSameEmail : existingUsersWithNewEmail) { @@ -745,17 +747,17 @@ public static void updateUser(AppIdentifierWithStorage appIdentifierWithStorage, } } try { - storage.updateUserEmail_Transaction(appIdentifierWithStorage, con, recipeUserId, + plStorage.updateUserEmail_Transaction(appIdentifier, con, recipeUserId, emailUpdate.newValue); } catch (UnknownUserIdException | DuplicateEmailException e) { throw new StorageTransactionLogicException(e); } if (lM.email != null) { - storage.deleteDevicesByEmail_Transaction(appIdentifierWithStorage, con, lM.email, + plStorage.deleteDevicesByEmail_Transaction(appIdentifier, con, lM.email, recipeUserId); } if (emailUpdate.newValue != null) { - storage.deleteDevicesByEmail_Transaction(appIdentifierWithStorage, con, + plStorage.deleteDevicesByEmail_Transaction(appIdentifier, con, emailUpdate.newValue, recipeUserId); } } @@ -764,7 +766,7 @@ public static void updateUser(AppIdentifierWithStorage appIdentifierWithStorage, for (String tenantId : user.tenantIds) { AuthRecipeUserInfo[] existingUsersWithNewPhoneNumber = authRecipeSQLStorage.listPrimaryUsersByPhoneNumber_Transaction( - appIdentifierWithStorage, con, + appIdentifier, con, phoneNumberUpdate.newValue); for (AuthRecipeUserInfo userWithSamePhoneNumber : existingUsersWithNewPhoneNumber) { @@ -779,21 +781,21 @@ public static void updateUser(AppIdentifierWithStorage appIdentifierWithStorage, } } try { - storage.updateUserPhoneNumber_Transaction(appIdentifierWithStorage, con, recipeUserId, + plStorage.updateUserPhoneNumber_Transaction(appIdentifier, con, recipeUserId, phoneNumberUpdate.newValue); } catch (UnknownUserIdException | DuplicatePhoneNumberException e) { throw new StorageTransactionLogicException(e); } if (lM.phoneNumber != null) { - storage.deleteDevicesByPhoneNumber_Transaction(appIdentifierWithStorage, con, + plStorage.deleteDevicesByPhoneNumber_Transaction(appIdentifier, con, lM.phoneNumber, recipeUserId); } if (phoneNumberUpdate.newValue != null) { - storage.deleteDevicesByPhoneNumber_Transaction(appIdentifierWithStorage, con, + plStorage.deleteDevicesByPhoneNumber_Transaction(appIdentifier, con, phoneNumberUpdate.newValue, recipeUserId); } } - storage.commitTransaction(con); + plStorage.commitTransaction(con); return null; }); } catch (StorageTransactionLogicException e) { diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java index 299f66b7f..0adfa76cc 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java @@ -28,6 +28,7 @@ import io.supertokens.pluginInterface.authRecipe.LoginMethod; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.utils.SemVer; import io.supertokens.webserver.InputParser; @@ -81,7 +82,9 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); ConsumeCodeResponse consumeCodeResponse = Passwordless.consumeCode( + tenantIdentifier, this.getTenantStorage(req), main, deviceId, deviceIdHash, userInputCode, linkCode, @@ -89,7 +92,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0)); io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(this.getTenantStorage(req), new AuthRecipeUserInfo[]{consumeCodeResponse.user}); - ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, consumeCodeResponse.user.getSupertokensUserId()); + ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), this.getPublicTenantStorage(req), + consumeCodeResponse.user.getSupertokensUserId()); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/CreateCodeAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/CreateCodeAPI.java index 16e182073..7821a4477 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/CreateCodeAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/CreateCodeAPI.java @@ -26,6 +26,7 @@ import io.supertokens.passwordless.exceptions.RestartFlowException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.passwordless.exception.DuplicateLinkCodeHashException; import io.supertokens.utils.Utils; @@ -78,11 +79,13 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); CreateCodeResponse createCodeResponse = Passwordless.createCode( + tenantIdentifier, this.getTenantStorage(req), main, email, phoneNumber, deviceId, userInputCode); - long passwordlessCodeLifetime = Config.getConfig(this.getTenantStorage(req), main) + long passwordlessCodeLifetime = Config.getConfig(tenantIdentifier, main) .getPasswordlessCodeLifetime(); JsonObject result = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodeAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodeAPI.java index 6a557759c..ea3b76fce 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodeAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodeAPI.java @@ -53,7 +53,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String codeId = InputParser.parseStringOrThrowError(input, "codeId", false); try { - Passwordless.removeCode(this.getTenantStorage(req), codeId); + Passwordless.removeCode(getTenantIdentifier(req), getTenantStorage(req), codeId); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodesAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodesAPI.java index 21b579abc..0af938ab5 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodesAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/DeleteCodesAPI.java @@ -18,6 +18,7 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.passwordless.Passwordless; import io.supertokens.pluginInterface.RECIPE_ID; @@ -62,11 +63,12 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I throw new ServletException(new BadRequestException("Please provide exactly one of email or phoneNumber")); } try { + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); if (email != null) { email = Utils.normaliseEmail(email); - Passwordless.removeCodesByEmail(this.getTenantStorage(req), email); + Passwordless.removeCodesByEmail(tenantIdentifier, getTenantStorage(req), email); } else { - Passwordless.removeCodesByPhoneNumber(this.getTenantStorage(req), phoneNumber); + Passwordless.removeCodesByPhoneNumber(tenantIdentifier, getTenantStorage(req), phoneNumber); } } catch (StorageTransactionLogicException | StorageQueryException | TenantOrAppNotFoundException e) { throw new ServletException(e); diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/GetCodesAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/GetCodesAPI.java index 84c0f3a4f..48ff84fa0 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/GetCodesAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/GetCodesAPI.java @@ -20,6 +20,8 @@ import com.google.gson.JsonObject; import io.supertokens.Main; import io.supertokens.config.Config; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.passwordless.Passwordless; import io.supertokens.passwordless.Passwordless.DeviceWithCodes; @@ -70,25 +72,29 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } try { - long passwordlessCodeLifetime = Config.getConfig(this.getTenantStorage(req), main) + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); + + long passwordlessCodeLifetime = Config.getConfig(tenantIdentifier, main) .getPasswordlessCodeLifetime(); List devicesInfos; if (deviceId != null) { - DeviceWithCodes deviceWithCodes = Passwordless.getDeviceWithCodesById(this.getTenantStorage(req), - deviceId); + DeviceWithCodes deviceWithCodes = Passwordless.getDeviceWithCodesById( + tenantIdentifier, storage, deviceId); devicesInfos = deviceWithCodes == null ? Collections.emptyList() : Collections.singletonList(deviceWithCodes); } else if (deviceIdHash != null) { DeviceWithCodes deviceWithCodes = Passwordless.getDeviceWithCodesByIdHash( - this.getTenantStorage(req), deviceIdHash); + tenantIdentifier, storage, deviceIdHash); devicesInfos = deviceWithCodes == null ? Collections.emptyList() : Collections.singletonList(deviceWithCodes); } else if (email != null) { email = Utils.normaliseEmail(email); - devicesInfos = Passwordless.getDevicesWithCodesByEmail(this.getTenantStorage(req), email); + devicesInfos = Passwordless.getDevicesWithCodesByEmail( + tenantIdentifier, storage, email); } else { - devicesInfos = Passwordless.getDevicesWithCodesByPhoneNumber(this.getTenantStorage(req), - phoneNumber); + devicesInfos = Passwordless.getDevicesWithCodesByPhoneNumber( + tenantIdentifier, storage, phoneNumber); } JsonObject result = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java index b4d17a9c3..98e61b06d 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java @@ -17,8 +17,8 @@ package io.supertokens.webserver.api.passwordless; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.passwordless.Passwordless; @@ -26,10 +26,13 @@ import io.supertokens.passwordless.exceptions.PhoneNumberChangeNotAllowedException; import io.supertokens.passwordless.exceptions.UserWithoutContactInfoException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.passwordless.exception.DuplicatePhoneNumberException; import io.supertokens.useridmapping.UserIdType; @@ -77,32 +80,39 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO AuthRecipeUserInfo user; if (userId != null) { try { - AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = + AppIdentifier appIdentifier = getAppIdentifier(req); + StorageAndUserIdMapping storageAndUserIdMapping = this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); - if (appIdentifierWithStorageAndUserIdMapping.userIdMapping != null) { - userId = appIdentifierWithStorageAndUserIdMapping.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - user = Passwordless.getUserById(appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, - userId); + user = Passwordless.getUserById(appIdentifier, storageAndUserIdMapping.storage, userId); // if the userIdMapping exists set the userId in the response to the externalUserId if (user != null) { - io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, new AuthRecipeUserInfo[]{user}); + io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers( + storageAndUserIdMapping.storage, new AuthRecipeUserInfo[]{user}); } } catch (UnknownUserIdException e) { user = null; } } else if (email != null) { + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); email = Utils.normaliseEmail(email); - user = Passwordless.getUserByEmail(this.getTenantStorage(req), email); + user = Passwordless.getUserByEmail(tenantIdentifier, storage, email); if (user != null) { - io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(this.getTenantStorage(req), new AuthRecipeUserInfo[]{user}); + io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(storage, + new AuthRecipeUserInfo[]{user}); } } else { - user = Passwordless.getUserByPhoneNumber(this.getTenantStorage(req), - phoneNumber); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); + + user = Passwordless.getUserByPhoneNumber(tenantIdentifier, storage, phoneNumber); if (user != null) { - io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(this.getTenantStorage(req), new AuthRecipeUserInfo[]{user}); + io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(storage, + new AuthRecipeUserInfo[]{user}); } } @@ -153,14 +163,15 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO : Utils.normalizeIfPhoneNumber(InputParser.parseStringOrThrowError(input, "phoneNumber", false))); try { - AppIdentifierWithStorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = + AppIdentifier appIdentifier = getAppIdentifier(req); + StorageAndUserIdMapping storageAndUserIdMapping = this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the updateUser - if (appIdentifierWithStorageAndUserIdMapping.userIdMapping != null) { - userId = appIdentifierWithStorageAndUserIdMapping.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - Passwordless.updateUser(appIdentifierWithStorageAndUserIdMapping.appIdentifierWithStorage, + Passwordless.updateUser(appIdentifier, storageAndUserIdMapping.storage, userId, emailUpdate, phoneNumberUpdate); JsonObject result = new JsonObject(); From 89fd936600c803591c9e36801b55c52a3abba36e Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 1 Mar 2024 14:44:59 +0530 Subject: [PATCH 06/31] fix: active users --- src/main/java/io/supertokens/ActiveUsers.java | 5 +++-- src/main/java/io/supertokens/webserver/WebserverAPI.java | 8 -------- .../webserver/api/emailpassword/SignInAPI.java | 2 +- .../webserver/api/emailpassword/SignUpAPI.java | 2 +- .../webserver/api/passwordless/ConsumeCodeAPI.java | 2 +- .../supertokens/webserver/api/thirdparty/SignInUpAPI.java | 4 ++-- 6 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/main/java/io/supertokens/ActiveUsers.java b/src/main/java/io/supertokens/ActiveUsers.java index 1083d7077..78d9885a4 100644 --- a/src/main/java/io/supertokens/ActiveUsers.java +++ b/src/main/java/io/supertokens/ActiveUsers.java @@ -12,8 +12,9 @@ public class ActiveUsers { - public static void updateLastActive(AppIdentifier appIdentifier, Storage storage, String userId) + public static void updateLastActive(AppIdentifier appIdentifier, Main main, String userId) throws TenantOrAppNotFoundException { + Storage storage = StorageLayer.getStorage(appIdentifier.getAsPublicTenantIdentifier(), main); try { StorageUtils.getActiveUsersStorage(storage).updateLastActive(appIdentifier, userId); } catch (StorageQueryException ignored) { @@ -24,7 +25,7 @@ public static void updateLastActive(AppIdentifier appIdentifier, Storage storage public static void updateLastActive(Main main, String userId) { try { ActiveUsers.updateLastActive(new AppIdentifier(null, null), - StorageLayer.getStorage(main), userId); + main, userId); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } diff --git a/src/main/java/io/supertokens/webserver/WebserverAPI.java b/src/main/java/io/supertokens/webserver/WebserverAPI.java index edc0053ba..c31d9508f 100644 --- a/src/main/java/io/supertokens/webserver/WebserverAPI.java +++ b/src/main/java/io/supertokens/webserver/WebserverAPI.java @@ -333,14 +333,6 @@ protected Storage enforcePublicTenantAndGetPublicTenantStorage( return StorageLayer.getStorage(tenantIdentifier, main); } - protected Storage getPublicTenantStorage(HttpServletRequest req) - throws ServletException, TenantOrAppNotFoundException { - // This is only used for update user active time - AppIdentifier appIdentifier = new AppIdentifier(this.getConnectionUriDomain(req), this.getAppId(req)); - - return StorageLayer.getStorage(appIdentifier.getAsPublicTenantIdentifier(), main); - } - protected StorageAndUserIdMapping getStorageAndUserIdMappingForTenantSpecificApi( HttpServletRequest req, String userId, UserIdType userIdType) throws StorageQueryException, TenantOrAppNotFoundException, UnknownUserIdException, ServletException { diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java index 38aea50e1..707adfd6f 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java @@ -80,7 +80,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(storage, new AuthRecipeUserInfo[]{user}); - ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), this.getPublicTenantStorage(req), + ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), main, user.getSupertokensUserId()); // use the internal user id JsonObject result = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java index 972d9cac9..8c58c760a 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java @@ -81,7 +81,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I AuthRecipeUserInfo user = EmailPassword.signUp(tenantIdentifier, storage, super.main, normalisedEmail, password); - ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), this.getPublicTenantStorage(req), + ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), main, user.getSupertokensUserId()); JsonObject result = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java index 0adfa76cc..492ed49ad 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java @@ -92,7 +92,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0)); io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(this.getTenantStorage(req), new AuthRecipeUserInfo[]{consumeCodeResponse.user}); - ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), this.getPublicTenantStorage(req), + ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), main, consumeCodeResponse.user.getSupertokensUserId()); JsonObject result = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java b/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java index 2962d92e1..7d85c2e61 100644 --- a/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java +++ b/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java @@ -83,7 +83,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I thirdPartyId, thirdPartyUserId, email, isEmailVerified); UserIdMapping.populateExternalUserIdForUsers(this.getTenantStorage(req), new AuthRecipeUserInfo[]{response.user}); - ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), getPublicTenantStorage(req), + ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), main, response.user.getSupertokensUserId()); JsonObject result = new JsonObject(); @@ -144,7 +144,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I email, isEmailVerified); UserIdMapping.populateExternalUserIdForUsers(storage, new AuthRecipeUserInfo[]{response.user}); - ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), this.getPublicTenantStorage(req), + ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), main, response.user.getSupertokensUserId()); JsonObject result = new JsonObject(); From 458c3b62e86f3ef8956c735103696009d2160599 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 1 Mar 2024 15:44:20 +0530 Subject: [PATCH 07/31] fix: session changes --- .../java/io/supertokens/session/Session.java | 229 +++++++++--------- .../webserver/api/session/HandshakeAPI.java | 8 +- .../webserver/api/session/JWTDataAPI.java | 27 ++- .../api/session/RefreshSessionAPI.java | 18 +- .../webserver/api/session/SessionAPI.java | 34 +-- .../webserver/api/session/SessionDataAPI.java | 27 ++- .../api/session/SessionRegenerateAPI.java | 1 - .../api/session/SessionRemoveAPI.java | 26 +- .../webserver/api/session/SessionUserAPI.java | 10 +- 9 files changed, 199 insertions(+), 181 deletions(-) diff --git a/src/main/java/io/supertokens/session/Session.java b/src/main/java/io/supertokens/session/Session.java index aa41b3ae8..66aea184a 100644 --- a/src/main/java/io/supertokens/session/Session.java +++ b/src/main/java/io/supertokens/session/Session.java @@ -29,6 +29,7 @@ import io.supertokens.multitenancy.Multitenancy; import io.supertokens.pluginInterface.STORAGE_TYPE; import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.authRecipe.AuthRecipeStorage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.authRecipe.LoginMethod; @@ -66,7 +67,7 @@ public class Session { @TestOnly - public static SessionInformationHolder createNewSession(TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static SessionInformationHolder createNewSession(TenantIdentifier tenantIdentifier, Storage storage, Main main, @Nonnull String recipeUserId, @Nonnull JsonObject userDataInJWT, @@ -76,9 +77,8 @@ public static SessionInformationHolder createNewSession(TenantIdentifierWithStor BadPaddingException, InvalidAlgorithmParameterException, NoSuchPaddingException, UnauthorisedException, JWT.JWTException, UnsupportedJWTSigningAlgorithmException, AccessTokenPayloadError { try { - return createNewSession(tenantIdentifierWithStorage, main, recipeUserId, userDataInJWT, userDataInDatabase, - false, - AccessToken.getLatestVersion(), false); + return createNewSession(tenantIdentifier, storage, main, recipeUserId, userDataInJWT, userDataInDatabase, + false, AccessToken.getLatestVersion(), false); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } @@ -96,7 +96,7 @@ public static SessionInformationHolder createNewSession(Main main, Storage storage = StorageLayer.getStorage(main); try { return createNewSession( - new TenantIdentifierWithStorage(null, null, null, storage), main, + new TenantIdentifier(null, null, null), storage, main, recipeUserId, userDataInJWT, userDataInDatabase, false, AccessToken.getLatestVersion(), false); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); @@ -116,14 +116,14 @@ public static SessionInformationHolder createNewSession(Main main, @Nonnull Stri Storage storage = StorageLayer.getStorage(main); try { return createNewSession( - new TenantIdentifierWithStorage(null, null, null, storage), main, + new TenantIdentifier(null, null, null), storage, main, recipeUserId, userDataInJWT, userDataInDatabase, enableAntiCsrf, version, useStaticKey); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static SessionInformationHolder createNewSession(TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static SessionInformationHolder createNewSession(TenantIdentifier tenantIdentifier, Storage storage, Main main, @Nonnull String recipeUserId, @Nonnull JsonObject userDataInJWT, @Nonnull JsonObject userDataInDatabase, @@ -134,30 +134,30 @@ public static SessionInformationHolder createNewSession(TenantIdentifierWithStor BadPaddingException, InvalidAlgorithmParameterException, NoSuchPaddingException, AccessTokenPayloadError, UnsupportedJWTSigningAlgorithmException, TenantOrAppNotFoundException { String sessionHandle = UUID.randomUUID().toString(); - if (!tenantIdentifierWithStorage.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID)) { - sessionHandle += "_" + tenantIdentifierWithStorage.getTenantId(); + if (!tenantIdentifier.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID)) { + sessionHandle += "_" + tenantIdentifier.getTenantId(); } String primaryUserId = recipeUserId; - if (tenantIdentifierWithStorage.getStorage().getType().equals(STORAGE_TYPE.SQL)) { - primaryUserId = tenantIdentifierWithStorage.getAuthRecipeStorage() - .getPrimaryUserIdStrForUserId(tenantIdentifierWithStorage.toAppIdentifier(), recipeUserId); + if (storage.getType().equals(STORAGE_TYPE.SQL)) { + primaryUserId = StorageUtils.getAuthRecipeStorage(storage) + .getPrimaryUserIdStrForUserId(tenantIdentifier.toAppIdentifier(), recipeUserId); if (primaryUserId == null) { primaryUserId = recipeUserId; } } String antiCsrfToken = enableAntiCsrf ? UUID.randomUUID().toString() : null; - final TokenInfo refreshToken = RefreshToken.createNewRefreshToken(tenantIdentifierWithStorage, main, + final TokenInfo refreshToken = RefreshToken.createNewRefreshToken(tenantIdentifier, main, sessionHandle, recipeUserId, null, antiCsrfToken); - TokenInfo accessToken = AccessToken.createNewAccessToken(tenantIdentifierWithStorage, main, sessionHandle, + TokenInfo accessToken = AccessToken.createNewAccessToken(tenantIdentifier, main, sessionHandle, recipeUserId, primaryUserId, Utils.hashSHA256(refreshToken.token), null, userDataInJWT, antiCsrfToken, null, version, useStaticKey); - tenantIdentifierWithStorage.getSessionStorage() - .createNewSession(tenantIdentifierWithStorage, sessionHandle, recipeUserId, + StorageUtils.getSessionStorage(storage) + .createNewSession(tenantIdentifier, sessionHandle, recipeUserId, Utils.hashSHA256(Utils.hashSHA256(refreshToken.token)), userDataInDatabase, refreshToken.expiry, userDataInJWT, refreshToken.createdTime, useStaticKey); @@ -165,7 +165,7 @@ public static SessionInformationHolder createNewSession(TenantIdentifierWithStor refreshToken.createdTime); return new SessionInformationHolder( new SessionInfo(sessionHandle, primaryUserId, recipeUserId, userDataInJWT, - tenantIdentifierWithStorage.getTenantId()), + tenantIdentifier.getTenantId()), accessToken, refreshToken, idRefreshToken, antiCsrfToken); } @@ -212,13 +212,13 @@ public static SessionInformationHolder regenerateToken(AppIdentifier appIdentifi // We assume the token has already been verified at this point. It may be expired or JWT signing key may have // changed for it... AccessTokenInfo accessToken = AccessToken.getInfoFromAccessTokenWithoutVerifying(appIdentifier, token); - TenantIdentifierWithStorage tenantIdentifierWithStorage = accessToken.tenantIdentifier.withStorage( - StorageLayer.getStorage(accessToken.tenantIdentifier, main)); - io.supertokens.pluginInterface.session.SessionInfo sessionInfo = getSession(tenantIdentifierWithStorage, + TenantIdentifier tenantIdentifier = accessToken.tenantIdentifier; + Storage storage = StorageLayer.getStorage(accessToken.tenantIdentifier, main); + io.supertokens.pluginInterface.session.SessionInfo sessionInfo = getSession(tenantIdentifier, storage, accessToken.sessionHandle); JsonObject newJWTUserPayload = userDataInJWT == null ? sessionInfo.userDataInJWT : userDataInJWT; - updateSession(tenantIdentifierWithStorage, accessToken.sessionHandle, null, newJWTUserPayload, + updateSession(tenantIdentifier, storage, accessToken.sessionHandle, null, newJWTUserPayload, accessToken.version); // if the above succeeds but the below fails, it's OK since the client will get server error and will try @@ -230,11 +230,11 @@ public static SessionInformationHolder regenerateToken(AppIdentifier appIdentifi return new SessionInformationHolder( new SessionInfo(accessToken.sessionHandle, accessToken.primaryUserId, accessToken.recipeUserId, newJWTUserPayload, - tenantIdentifierWithStorage.getTenantId()), null, null, null, + tenantIdentifier.getTenantId()), null, null, null, null); } - TokenInfo newAccessToken = AccessToken.createNewAccessToken(tenantIdentifierWithStorage, main, + TokenInfo newAccessToken = AccessToken.createNewAccessToken(tenantIdentifier, main, accessToken.sessionHandle, accessToken.recipeUserId, accessToken.primaryUserId, accessToken.refreshTokenHash1, accessToken.parentRefreshTokenHash1, newJWTUserPayload, accessToken.antiCsrfToken, accessToken.expiryTime, accessToken.version, sessionInfo.useStaticKey); @@ -242,7 +242,7 @@ public static SessionInformationHolder regenerateToken(AppIdentifier appIdentifi return new SessionInformationHolder( new SessionInfo(accessToken.sessionHandle, accessToken.primaryUserId, accessToken.recipeUserId, newJWTUserPayload, - tenantIdentifierWithStorage.getTenantId()), + tenantIdentifier.getTenantId()), new TokenInfo(newAccessToken.token, newAccessToken.expiry, newAccessToken.createdTime), null, null, null); } @@ -260,14 +260,14 @@ public static SessionInformationHolder regenerateTokenBeforeCDI2_21(AppIdentifie // We assume the token has already been verified at this point. It may be expired or JWT signing key may have // changed for it... AccessTokenInfo accessToken = AccessToken.getInfoFromAccessTokenWithoutVerifying(appIdentifier, token); - TenantIdentifierWithStorage tenantIdentifierWithStorage = accessToken.tenantIdentifier.withStorage( - StorageLayer.getStorage(accessToken.tenantIdentifier, main)); - io.supertokens.pluginInterface.session.SessionInfo sessionInfo = getSession(tenantIdentifierWithStorage, + TenantIdentifier tenantIdentifier = accessToken.tenantIdentifier; + Storage storage = StorageLayer.getStorage(accessToken.tenantIdentifier, main); + io.supertokens.pluginInterface.session.SessionInfo sessionInfo = getSession(tenantIdentifier, storage, accessToken.sessionHandle); JsonObject newJWTUserPayload = userDataInJWT == null ? sessionInfo.userDataInJWT : userDataInJWT; updateSessionBeforeCDI2_21( - tenantIdentifierWithStorage, + tenantIdentifier, storage, accessToken.sessionHandle, null, newJWTUserPayload); // if the above succeeds but the below fails, it's OK since the client will get server error and will try @@ -279,7 +279,7 @@ public static SessionInformationHolder regenerateTokenBeforeCDI2_21(AppIdentifie return new SessionInformationHolder( new SessionInfo(accessToken.sessionHandle, accessToken.primaryUserId, accessToken.recipeUserId, newJWTUserPayload, - tenantIdentifierWithStorage.getTenantId()), null, null, null, + tenantIdentifier.getTenantId()), null, null, null, null); } @@ -292,7 +292,7 @@ public static SessionInformationHolder regenerateTokenBeforeCDI2_21(AppIdentifie return new SessionInformationHolder( new SessionInfo(accessToken.sessionHandle, accessToken.primaryUserId, accessToken.recipeUserId, newJWTUserPayload, - tenantIdentifierWithStorage.getTenantId()), + tenantIdentifier.getTenantId()), new TokenInfo(newAccessToken.token, newAccessToken.expiry, newAccessToken.createdTime), null, null, null); } @@ -322,8 +322,8 @@ public static SessionInformationHolder getSession(AppIdentifier appIdentifier, M AccessTokenInfo accessToken = AccessToken.getInfoFromAccessToken(appIdentifier, main, token, doAntiCsrfCheck && enableAntiCsrf); - TenantIdentifierWithStorage tenantIdentifierWithStorage = accessToken.tenantIdentifier.withStorage( - StorageLayer.getStorage(accessToken.tenantIdentifier, main)); + TenantIdentifier tenantIdentifier = accessToken.tenantIdentifier; + Storage storage = StorageLayer.getStorage(accessToken.tenantIdentifier, main); if (enableAntiCsrf && doAntiCsrfCheck && (antiCsrfToken == null || !antiCsrfToken.equals(accessToken.antiCsrfToken))) { @@ -332,8 +332,8 @@ public static SessionInformationHolder getSession(AppIdentifier appIdentifier, M io.supertokens.pluginInterface.session.SessionInfo sessionInfoForBlacklisting = null; if (checkDatabase) { - sessionInfoForBlacklisting = tenantIdentifierWithStorage.getSessionStorage() - .getSession(tenantIdentifierWithStorage, accessToken.sessionHandle); + sessionInfoForBlacklisting = StorageUtils.getSessionStorage(storage) + .getSession(tenantIdentifier, accessToken.sessionHandle); if (sessionInfoForBlacklisting == null) { throw new UnauthorisedException("Either the session has ended or has been blacklisted"); } @@ -347,25 +347,25 @@ public static SessionInformationHolder getSession(AppIdentifier appIdentifier, M return new SessionInformationHolder( new SessionInfo(accessToken.sessionHandle, accessToken.primaryUserId, accessToken.recipeUserId, accessToken.userData, - tenantIdentifierWithStorage.getTenantId()), null, null, + tenantIdentifier.getTenantId()), null, null, null, null); } ProcessState.getInstance(main).addState(ProcessState.PROCESS_STATE.GET_SESSION_NEW_TOKENS, null); - if (tenantIdentifierWithStorage.getSessionStorage().getType() == STORAGE_TYPE.SQL) { - SessionSQLStorage storage = (SessionSQLStorage) tenantIdentifierWithStorage.getSessionStorage(); + if (StorageUtils.getSessionStorage(storage).getType() == STORAGE_TYPE.SQL) { + SessionSQLStorage sessionStorage = (SessionSQLStorage) StorageUtils.getSessionStorage(storage); try { - CoreConfig config = Config.getConfig(tenantIdentifierWithStorage, main); - return storage.startTransaction(con -> { + CoreConfig config = Config.getConfig(tenantIdentifier, main); + return sessionStorage.startTransaction(con -> { try { - io.supertokens.pluginInterface.session.SessionInfo sessionInfo = storage - .getSessionInfo_Transaction(tenantIdentifierWithStorage, con, + io.supertokens.pluginInterface.session.SessionInfo sessionInfo = sessionStorage + .getSessionInfo_Transaction(tenantIdentifier, con, accessToken.sessionHandle); if (sessionInfo == null) { - storage.commitTransaction(con); + sessionStorage.commitTransaction(con); throw new UnauthorisedException("Session missing in db"); } @@ -375,23 +375,23 @@ public static SessionInformationHolder getSession(AppIdentifier appIdentifier, M || sessionInfo.refreshTokenHash2.equals(Utils.hashSHA256(accessToken.refreshTokenHash1)) || JWTPayloadNeedsUpdating) { if (promote) { - storage.updateSessionInfo_Transaction(tenantIdentifierWithStorage, con, + sessionStorage.updateSessionInfo_Transaction(tenantIdentifier, con, accessToken.sessionHandle, Utils.hashSHA256(accessToken.refreshTokenHash1), System.currentTimeMillis() + config.getRefreshTokenValidity()); } - storage.commitTransaction(con); + sessionStorage.commitTransaction(con); TokenInfo newAccessToken; if (AccessToken.getAccessTokenVersion(accessToken) == AccessToken.VERSION.V1) { - newAccessToken = AccessToken.createNewAccessTokenV1(tenantIdentifierWithStorage, + newAccessToken = AccessToken.createNewAccessTokenV1(tenantIdentifier, main, accessToken.sessionHandle, accessToken.recipeUserId, accessToken.refreshTokenHash1, null, sessionInfo.userDataInJWT, accessToken.antiCsrfToken); } else { - newAccessToken = AccessToken.createNewAccessToken(tenantIdentifierWithStorage, main, + newAccessToken = AccessToken.createNewAccessToken(tenantIdentifier, main, accessToken.sessionHandle, accessToken.recipeUserId, accessToken.primaryUserId, accessToken.refreshTokenHash1, null, @@ -402,17 +402,17 @@ public static SessionInformationHolder getSession(AppIdentifier appIdentifier, M return new SessionInformationHolder( new SessionInfo(accessToken.sessionHandle, accessToken.primaryUserId, accessToken.recipeUserId, - sessionInfo.userDataInJWT, tenantIdentifierWithStorage.getTenantId()), + sessionInfo.userDataInJWT, tenantIdentifier.getTenantId()), new TokenInfo(newAccessToken.token, newAccessToken.expiry, newAccessToken.createdTime), null, null, null); } - storage.commitTransaction(con); + sessionStorage.commitTransaction(con); return new SessionInformationHolder( new SessionInfo(accessToken.sessionHandle, accessToken.primaryUserId, accessToken.recipeUserId, accessToken.userData, - tenantIdentifierWithStorage.getTenantId()), + tenantIdentifier.getTenantId()), // here we purposely use accessToken.userData instead of sessionInfo.userDataInJWT // because we are not returning a new access token null, null, null, null); @@ -434,13 +434,13 @@ public static SessionInformationHolder getSession(AppIdentifier appIdentifier, M } throw e; } - } else if (tenantIdentifierWithStorage.getSessionStorage().getType() == + } else if (StorageUtils.getSessionStorage(storage).getType() == STORAGE_TYPE.NOSQL_1) { - SessionNoSQLStorage_1 storage = (SessionNoSQLStorage_1) tenantIdentifierWithStorage.getSessionStorage(); + SessionNoSQLStorage_1 sessionStorage = (SessionNoSQLStorage_1) StorageUtils.getSessionStorage(storage); while (true) { try { - io.supertokens.pluginInterface.session.noSqlStorage.SessionInfoWithLastUpdated sessionInfo = storage + io.supertokens.pluginInterface.session.noSqlStorage.SessionInfoWithLastUpdated sessionInfo = sessionStorage .getSessionInfo_Transaction(accessToken.sessionHandle); if (sessionInfo == null) { @@ -452,9 +452,9 @@ public static SessionInformationHolder getSession(AppIdentifier appIdentifier, M if (promote || sessionInfo.refreshTokenHash2.equals(Utils.hashSHA256(accessToken.refreshTokenHash1)) || JWTPayloadNeedsUpdating) { if (promote) { - boolean success = storage.updateSessionInfo_Transaction(accessToken.sessionHandle, + boolean success = sessionStorage.updateSessionInfo_Transaction(accessToken.sessionHandle, Utils.hashSHA256(accessToken.refreshTokenHash1), - System.currentTimeMillis() + Config.getConfig(tenantIdentifierWithStorage, main) + System.currentTimeMillis() + Config.getConfig(tenantIdentifier, main) .getRefreshTokenValidity(), sessionInfo.lastUpdatedSign); if (!success) { @@ -464,13 +464,13 @@ public static SessionInformationHolder getSession(AppIdentifier appIdentifier, M TokenInfo newAccessToken; if (accessToken.version == AccessToken.VERSION.V1) { - newAccessToken = AccessToken.createNewAccessTokenV1(tenantIdentifierWithStorage, main, + newAccessToken = AccessToken.createNewAccessTokenV1(tenantIdentifier, main, accessToken.sessionHandle, accessToken.recipeUserId, accessToken.refreshTokenHash1, null, sessionInfo.userDataInJWT, accessToken.antiCsrfToken); } else { - newAccessToken = AccessToken.createNewAccessToken(tenantIdentifierWithStorage, main, + newAccessToken = AccessToken.createNewAccessToken(tenantIdentifier, main, accessToken.sessionHandle, accessToken.recipeUserId, accessToken.primaryUserId, accessToken.refreshTokenHash1, null, sessionInfo.userDataInJWT, @@ -480,7 +480,7 @@ public static SessionInformationHolder getSession(AppIdentifier appIdentifier, M return new SessionInformationHolder( new SessionInfo(accessToken.sessionHandle, accessToken.primaryUserId, accessToken.recipeUserId, - sessionInfo.userDataInJWT, tenantIdentifierWithStorage.getTenantId()), + sessionInfo.userDataInJWT, tenantIdentifier.getTenantId()), new TokenInfo(newAccessToken.token, newAccessToken.expiry, newAccessToken.createdTime), null, null, null); } @@ -488,7 +488,7 @@ public static SessionInformationHolder getSession(AppIdentifier appIdentifier, M return new SessionInformationHolder( new SessionInfo(accessToken.sessionHandle, accessToken.primaryUserId, accessToken.recipeUserId, accessToken.userData, - tenantIdentifierWithStorage.getTenantId()), + tenantIdentifier.getTenantId()), // here we purposely use accessToken.userData instead of sessionInfo.userDataInJWT // because we are not returning a new access token null, null, null, null); @@ -534,13 +534,14 @@ public static SessionInformationHolder refreshSession(AppIdentifier appIdentifie } } - return refreshSessionHelper(refreshTokenInfo.tenantIdentifier.withStorage( - StorageLayer.getStorage(refreshTokenInfo.tenantIdentifier, main)), - main, refreshToken, refreshTokenInfo, enableAntiCsrf, accessTokenVersion); + TenantIdentifier tenantIdentifier = refreshTokenInfo.tenantIdentifier; + Storage storage = StorageLayer.getStorage(refreshTokenInfo.tenantIdentifier, main); + return refreshSessionHelper( + tenantIdentifier, storage, main, refreshToken, refreshTokenInfo, enableAntiCsrf, accessTokenVersion); } private static SessionInformationHolder refreshSessionHelper( - TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, String refreshToken, + TenantIdentifier tenantIdentifier, Storage storage, Main main, String refreshToken, RefreshToken.RefreshTokenInfo refreshTokenInfo, boolean enableAntiCsrf, AccessToken.VERSION accessTokenVersion) @@ -553,31 +554,31 @@ private static SessionInformationHolder refreshSessionHelper( ////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////// - if (tenantIdentifierWithStorage.getSessionStorage().getType() == STORAGE_TYPE.SQL) { - SessionSQLStorage storage = (SessionSQLStorage) tenantIdentifierWithStorage.getSessionStorage(); + if (StorageUtils.getSessionStorage(storage).getType() == STORAGE_TYPE.SQL) { + SessionSQLStorage sessionStorage = (SessionSQLStorage) StorageUtils.getSessionStorage(storage); try { - CoreConfig config = Config.getConfig(tenantIdentifierWithStorage, main); - return storage.startTransaction(con -> { + CoreConfig config = Config.getConfig(tenantIdentifier, main); + return sessionStorage.startTransaction(con -> { try { String sessionHandle = refreshTokenInfo.sessionHandle; - io.supertokens.pluginInterface.session.SessionInfo sessionInfo = storage - .getSessionInfo_Transaction(tenantIdentifierWithStorage, con, sessionHandle); + io.supertokens.pluginInterface.session.SessionInfo sessionInfo = sessionStorage + .getSessionInfo_Transaction(tenantIdentifier, con, sessionHandle); if (sessionInfo == null || sessionInfo.expiry < System.currentTimeMillis()) { - storage.commitTransaction(con); + sessionStorage.commitTransaction(con); throw new UnauthorisedException("Session missing in db or has expired"); } if (sessionInfo.refreshTokenHash2.equals(Utils.hashSHA256(Utils.hashSHA256(refreshToken)))) { // at this point, the input refresh token is the parent one. - storage.commitTransaction(con); + sessionStorage.commitTransaction(con); String antiCsrfToken = enableAntiCsrf ? UUID.randomUUID().toString() : null; final TokenInfo newRefreshToken = RefreshToken.createNewRefreshToken( - tenantIdentifierWithStorage, main, sessionHandle, + tenantIdentifier, main, sessionHandle, sessionInfo.recipeUserId, Utils.hashSHA256(refreshToken), antiCsrfToken); - TokenInfo newAccessToken = AccessToken.createNewAccessToken(tenantIdentifierWithStorage, + TokenInfo newAccessToken = AccessToken.createNewAccessToken(tenantIdentifier, main, sessionHandle, sessionInfo.recipeUserId, sessionInfo.userId, Utils.hashSHA256(newRefreshToken.token), @@ -590,7 +591,7 @@ private static SessionInformationHolder refreshSessionHelper( return new SessionInformationHolder( new SessionInfo(sessionHandle, sessionInfo.userId, sessionInfo.recipeUserId, sessionInfo.userDataInJWT, - tenantIdentifierWithStorage.getTenantId()), + tenantIdentifier.getTenantId()), newAccessToken, newRefreshToken, idRefreshToken, antiCsrfToken); } @@ -600,18 +601,18 @@ private static SessionInformationHolder refreshSessionHelper( || (refreshTokenInfo.parentRefreshTokenHash1 != null && Utils.hashSHA256(refreshTokenInfo.parentRefreshTokenHash1) .equals(sessionInfo.refreshTokenHash2))) { - storage.updateSessionInfo_Transaction(tenantIdentifierWithStorage, con, sessionHandle, + sessionStorage.updateSessionInfo_Transaction(tenantIdentifier, con, sessionHandle, Utils.hashSHA256(Utils.hashSHA256(refreshToken)), System.currentTimeMillis() + config.getRefreshTokenValidity()); - storage.commitTransaction(con); + sessionStorage.commitTransaction(con); - return refreshSessionHelper(tenantIdentifierWithStorage, main, refreshToken, + return refreshSessionHelper(tenantIdentifier, storage, main, refreshToken, refreshTokenInfo, enableAntiCsrf, accessTokenVersion); } - storage.commitTransaction(con); + sessionStorage.commitTransaction(con); throw new TokenTheftDetectedException(sessionHandle, sessionInfo.recipeUserId, sessionInfo.userId); @@ -644,13 +645,13 @@ private static SessionInformationHolder refreshSessionHelper( ////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////// - } else if (tenantIdentifierWithStorage.getSessionStorage().getType() == + } else if (StorageUtils.getSessionStorage(storage).getType() == STORAGE_TYPE.NOSQL_1) { - SessionNoSQLStorage_1 storage = (SessionNoSQLStorage_1) tenantIdentifierWithStorage.getSessionStorage(); + SessionNoSQLStorage_1 sessionStorage = (SessionNoSQLStorage_1) StorageUtils.getSessionStorage(storage); while (true) { try { String sessionHandle = refreshTokenInfo.sessionHandle; - io.supertokens.pluginInterface.session.noSqlStorage.SessionInfoWithLastUpdated sessionInfo = storage + io.supertokens.pluginInterface.session.noSqlStorage.SessionInfoWithLastUpdated sessionInfo = sessionStorage .getSessionInfo_Transaction(sessionHandle); if (sessionInfo == null || sessionInfo.expiry < System.currentTimeMillis()) { @@ -662,9 +663,9 @@ private static SessionInformationHolder refreshSessionHelper( String antiCsrfToken = enableAntiCsrf ? UUID.randomUUID().toString() : null; final TokenInfo newRefreshToken = RefreshToken.createNewRefreshToken( - tenantIdentifierWithStorage, main, sessionHandle, + tenantIdentifier, main, sessionHandle, sessionInfo.recipeUserId, Utils.hashSHA256(refreshToken), antiCsrfToken); - TokenInfo newAccessToken = AccessToken.createNewAccessToken(tenantIdentifierWithStorage, main, + TokenInfo newAccessToken = AccessToken.createNewAccessToken(tenantIdentifier, main, sessionHandle, sessionInfo.recipeUserId, sessionInfo.userId, Utils.hashSHA256(newRefreshToken.token), Utils.hashSHA256(refreshToken), sessionInfo.userDataInJWT, antiCsrfToken, @@ -676,7 +677,7 @@ private static SessionInformationHolder refreshSessionHelper( return new SessionInformationHolder( new SessionInfo(sessionHandle, sessionInfo.userId, sessionInfo.recipeUserId, sessionInfo.userDataInJWT, - tenantIdentifierWithStorage.getTenantId()), + tenantIdentifier.getTenantId()), newAccessToken, newRefreshToken, idRefreshToken, antiCsrfToken); } @@ -686,15 +687,15 @@ private static SessionInformationHolder refreshSessionHelper( || (refreshTokenInfo.parentRefreshTokenHash1 != null && Utils.hashSHA256(refreshTokenInfo.parentRefreshTokenHash1) .equals(sessionInfo.refreshTokenHash2))) { - boolean success = storage.updateSessionInfo_Transaction(sessionHandle, + boolean success = sessionStorage.updateSessionInfo_Transaction(sessionHandle, Utils.hashSHA256(Utils.hashSHA256(refreshToken)), System.currentTimeMillis() + - Config.getConfig(tenantIdentifierWithStorage, main).getRefreshTokenValidity(), + Config.getConfig(tenantIdentifier, main).getRefreshTokenValidity(), sessionInfo.lastUpdatedSign); if (!success) { continue; } - return refreshSessionHelper(tenantIdentifierWithStorage, main, refreshToken, refreshTokenInfo, + return refreshSessionHelper(tenantIdentifier, storage, main, refreshToken, refreshTokenInfo, enableAntiCsrf, accessTokenVersion); } @@ -719,7 +720,7 @@ public static String[] revokeSessionUsingSessionHandles(Main main, throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); return revokeSessionUsingSessionHandles(main, - new AppIdentifierWithStorage(null, null, storage), + new AppIdentifier(null, null), storage, sessionHandles); } @@ -823,12 +824,12 @@ public static String[] revokeAllSessionsForUser(Main main, AppIdentifier appIden return revokeSessionUsingSessionHandles(main, appIdentifier, storage, sessionHandles); } - public static String[] revokeAllSessionsForUser(Main main, TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static String[] revokeAllSessionsForUser(Main main, TenantIdentifier tenantIdentifier, Storage storage, String userId, boolean revokeSessionsForLinkedAccounts) throws StorageQueryException { - String[] sessionHandles = getAllNonExpiredSessionHandlesForUser(tenantIdentifierWithStorage, userId, + String[] sessionHandles = getAllNonExpiredSessionHandlesForUser(tenantIdentifier, storage, userId, revokeSessionsForLinkedAccounts); - return revokeSessionUsingSessionHandles(main, tenantIdentifierWithStorage.toAppIdentifierWithStorage(), + return revokeSessionUsingSessionHandles(main, tenantIdentifier.toAppIdentifier(), storage, sessionHandles); } @@ -837,7 +838,7 @@ public static String[] getAllNonExpiredSessionHandlesForUser(Main main, String u throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); return getAllNonExpiredSessionHandlesForUser(main, - new AppIdentifierWithStorage(null, null, storage), userId, true); + new AppIdentifier(null, null), storage, userId, true); } public static String[] getAllNonExpiredSessionHandlesForUser( @@ -908,16 +909,16 @@ public static JsonObject getSessionData(Main main, String sessionHandle) throws StorageQueryException, UnauthorisedException { Storage storage = StorageLayer.getStorage(main); return getSessionData( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, sessionHandle); } @Deprecated - public static JsonObject getSessionData(TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static JsonObject getSessionData(TenantIdentifier tenantIdentifier, Storage storage, String sessionHandle) throws StorageQueryException, UnauthorisedException { - io.supertokens.pluginInterface.session.SessionInfo session = tenantIdentifierWithStorage.getSessionStorage() - .getSession(tenantIdentifierWithStorage, sessionHandle); + io.supertokens.pluginInterface.session.SessionInfo session = StorageUtils.getSessionStorage(storage) + .getSession(tenantIdentifier, sessionHandle); if (session == null || session.expiry <= System.currentTimeMillis()) { throw new UnauthorisedException("Session does not exist."); } @@ -929,15 +930,15 @@ public static JsonObject getJWTData(Main main, String sessionHandle) throws StorageQueryException, UnauthorisedException { Storage storage = StorageLayer.getStorage(main); return getJWTData( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, sessionHandle); } @Deprecated - public static JsonObject getJWTData(TenantIdentifierWithStorage tenantIdentifierWithStorage, String sessionHandle) + public static JsonObject getJWTData(TenantIdentifier tenantIdentifier, Storage storage, String sessionHandle) throws StorageQueryException, UnauthorisedException { - io.supertokens.pluginInterface.session.SessionInfo session = tenantIdentifierWithStorage.getSessionStorage() - .getSession(tenantIdentifierWithStorage, sessionHandle); + io.supertokens.pluginInterface.session.SessionInfo session = StorageUtils.getSessionStorage(storage) + .getSession(tenantIdentifier, sessionHandle); if (session == null || session.expiry <= System.currentTimeMillis()) { throw new UnauthorisedException("Session does not exist."); } @@ -949,7 +950,7 @@ public static io.supertokens.pluginInterface.session.SessionInfo getSession(Main throws StorageQueryException, UnauthorisedException { Storage storage = StorageLayer.getStorage(main); return getSession( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, sessionHandle); } @@ -959,10 +960,10 @@ public static io.supertokens.pluginInterface.session.SessionInfo getSession(Main * - /recipe/session GET */ public static io.supertokens.pluginInterface.session.SessionInfo getSession( - TenantIdentifierWithStorage tenantIdentifierWithStorage, String sessionHandle) + TenantIdentifier tenantIdentifier, Storage storage, String sessionHandle) throws StorageQueryException, UnauthorisedException { - io.supertokens.pluginInterface.session.SessionInfo session = tenantIdentifierWithStorage.getSessionStorage() - .getSession(tenantIdentifierWithStorage, sessionHandle); + io.supertokens.pluginInterface.session.SessionInfo session = StorageUtils.getSessionStorage(storage) + .getSession(tenantIdentifier, sessionHandle); // If there is no session, or session is expired if (session == null || session.expiry <= System.currentTimeMillis()) { @@ -979,11 +980,11 @@ public static void updateSession(Main main, String sessionHandle, AccessToken.VERSION version) throws StorageQueryException, UnauthorisedException, AccessTokenPayloadError { Storage storage = StorageLayer.getStorage(main); - updateSession(new TenantIdentifierWithStorage(null, null, null, storage), + updateSession(new TenantIdentifier(null, null, null), storage, sessionHandle, sessionData, jwtData, version); } - public static void updateSession(TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static void updateSession(TenantIdentifier tenantIdentifier, Storage storage, String sessionHandle, @Nullable JsonObject sessionData, @Nullable JsonObject jwtData, AccessToken.VERSION version) throws StorageQueryException, UnauthorisedException, AccessTokenPayloadError { @@ -992,35 +993,35 @@ public static void updateSession(TenantIdentifierWithStorage tenantIdentifierWit throw new AccessTokenPayloadError("The user payload contains protected field"); } - io.supertokens.pluginInterface.session.SessionInfo session = tenantIdentifierWithStorage.getSessionStorage() - .getSession(tenantIdentifierWithStorage, sessionHandle); + io.supertokens.pluginInterface.session.SessionInfo session = StorageUtils.getSessionStorage(storage) + .getSession(tenantIdentifier, sessionHandle); // If there is no session, or session is expired if (session == null || session.expiry <= System.currentTimeMillis()) { throw new UnauthorisedException("Session does not exist."); } - int numberOfRowsAffected = tenantIdentifierWithStorage.getSessionStorage() - .updateSession(tenantIdentifierWithStorage, sessionHandle, sessionData, jwtData); + int numberOfRowsAffected = StorageUtils.getSessionStorage(storage) + .updateSession(tenantIdentifier, sessionHandle, sessionData, jwtData); if (numberOfRowsAffected != 1) { throw new UnauthorisedException("Session does not exist."); } } @Deprecated - public static void updateSessionBeforeCDI2_21(TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static void updateSessionBeforeCDI2_21(TenantIdentifier tenantIdentifier, Storage storage, String sessionHandle, @Nullable JsonObject sessionData, @Nullable JsonObject jwtData) throws StorageQueryException, UnauthorisedException { - io.supertokens.pluginInterface.session.SessionInfo session = tenantIdentifierWithStorage.getSessionStorage() - .getSession(tenantIdentifierWithStorage, sessionHandle); + io.supertokens.pluginInterface.session.SessionInfo session = StorageUtils.getSessionStorage(storage) + .getSession(tenantIdentifier, sessionHandle); // If there is no session, or session is expired if (session == null || session.expiry <= System.currentTimeMillis()) { throw new UnauthorisedException("Session does not exist."); } - int numberOfRowsAffected = tenantIdentifierWithStorage.getSessionStorage() - .updateSession(tenantIdentifierWithStorage, sessionHandle, sessionData, + int numberOfRowsAffected = StorageUtils.getSessionStorage(storage) + .updateSession(tenantIdentifier, sessionHandle, sessionData, jwtData); if (numberOfRowsAffected != 1) { throw new UnauthorisedException("Session does not exist."); diff --git a/src/main/java/io/supertokens/webserver/api/session/HandshakeAPI.java b/src/main/java/io/supertokens/webserver/api/session/HandshakeAPI.java index 7646ef968..f0b177292 100644 --- a/src/main/java/io/supertokens/webserver/api/session/HandshakeAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/HandshakeAPI.java @@ -23,6 +23,7 @@ import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.utils.SemVer; import io.supertokens.utils.Utils; @@ -60,14 +61,15 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I Utils.addLegacySigningKeyInfos(this.getAppIdentifier(req), main, result, super.getVersionFromRequest(req).betweenInclusive(SemVer.v2_9, SemVer.v2_21)); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); result.addProperty("accessTokenBlacklistingEnabled", - Config.getConfig(this.getTenantStorage(req), main) + Config.getConfig(tenantIdentifier, main) .getAccessTokenBlacklisting()); result.addProperty("accessTokenValidity", - Config.getConfig(this.getTenantStorage(req), main) + Config.getConfig(tenantIdentifier, main) .getAccessTokenValidity()); result.addProperty("refreshTokenValidity", - Config.getConfig(this.getTenantStorage(req), main) + Config.getConfig(tenantIdentifier, main) .getRefreshTokenValidity()); super.sendJsonResponse(200, result, resp); } catch (StorageQueryException | StorageTransactionLogicException | TenantOrAppNotFoundException | UnsupportedJWTSigningAlgorithmException e) { diff --git a/src/main/java/io/supertokens/webserver/api/session/JWTDataAPI.java b/src/main/java/io/supertokens/webserver/api/session/JWTDataAPI.java index a4b121496..c87c1eeb5 100644 --- a/src/main/java/io/supertokens/webserver/api/session/JWTDataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/JWTDataAPI.java @@ -23,11 +23,10 @@ import io.supertokens.exceptions.UnauthorisedException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.session.Session; import io.supertokens.session.accessToken.AccessToken; @@ -65,11 +64,12 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject userDataInJWT = InputParser.parseJsonObjectOrThrowError(input, "userDataInJWT", false); assert userDataInJWT != null; - TenantIdentifierWithStorage tenantIdentifierWithStorage = null; + TenantIdentifier tenantIdentifier; + Storage storage; try { AppIdentifier appIdentifier = getAppIdentifier(req); - TenantIdentifier tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), Session.getTenantIdFromSessionHandle(sessionHandle)); - tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); + tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), Session.getTenantIdFromSessionHandle(sessionHandle)); + storage = StorageLayer.getStorage(tenantIdentifier, main); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } @@ -77,10 +77,10 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO try { if (getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v2_21)) { AccessToken.VERSION version = AccessToken.getAccessTokenVersionForCDI(getVersionFromRequest(req)); - Session.updateSession(tenantIdentifierWithStorage, sessionHandle, null, + Session.updateSession(tenantIdentifier, storage, sessionHandle, null, userDataInJWT, version); } else { - Session.updateSessionBeforeCDI2_21(tenantIdentifierWithStorage, sessionHandle, + Session.updateSessionBeforeCDI2_21(tenantIdentifier, storage, sessionHandle, null, userDataInJWT); } @@ -94,7 +94,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO } catch (AccessTokenPayloadError e) { throw new ServletException(new BadRequestException(e.getMessage())); } catch (UnauthorisedException e) { - Logging.debug(main, tenantIdentifierWithStorage, Utils.exceptionStacktraceToString(e)); + Logging.debug(main, tenantIdentifier, Utils.exceptionStacktraceToString(e)); JsonObject reply = new JsonObject(); reply.addProperty("status", "UNAUTHORISED"); reply.addProperty("message", e.getMessage()); @@ -109,17 +109,18 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO String sessionHandle = InputParser.getQueryParamOrThrowError(req, "sessionHandle", false); assert sessionHandle != null; - TenantIdentifierWithStorage tenantIdentifierWithStorage = null; + TenantIdentifier tenantIdentifier; + Storage storage; try { AppIdentifier appIdentifier = getAppIdentifier(req); - TenantIdentifier tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), Session.getTenantIdFromSessionHandle(sessionHandle)); - tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); + tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), Session.getTenantIdFromSessionHandle(sessionHandle)); + storage = StorageLayer.getStorage(tenantIdentifier, main); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } try { - JsonElement jwtPayload = Session.getJWTData(tenantIdentifierWithStorage, sessionHandle); + JsonElement jwtPayload = Session.getJWTData(tenantIdentifier, storage, sessionHandle); JsonObject result = new JsonObject(); @@ -130,7 +131,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } catch (StorageQueryException e) { throw new ServletException(e); } catch (UnauthorisedException e) { - Logging.debug(main, tenantIdentifierWithStorage, Utils.exceptionStacktraceToString(e)); + Logging.debug(main, tenantIdentifier, Utils.exceptionStacktraceToString(e)); JsonObject reply = new JsonObject(); reply.addProperty("status", "UNAUTHORISED"); reply.addProperty("message", e.getMessage()); diff --git a/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java b/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java index 26d2f7328..1813769a7 100644 --- a/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java @@ -26,10 +26,11 @@ import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.useridmapping.UserIdMapping; import io.supertokens.session.Session; @@ -78,19 +79,18 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I SessionInformationHolder sessionInfo = Session.refreshSession(appIdentifier, main, refreshToken, antiCsrfToken, enableAntiCsrf, accessTokenVersion); + TenantIdentifier tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), + appIdentifier.getAppId(), sessionInfo.session.tenantId); + Storage storage = StorageLayer.getStorage(tenantIdentifier, main); - if (StorageLayer.getStorage(this.getTenantStorage(req), main).getType() == - STORAGE_TYPE.SQL) { + if (storage.getType() == STORAGE_TYPE.SQL) { try { UserIdMapping userIdMapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( - this.getTenantStorage(req).toAppIdentifierWithStorage(), - sessionInfo.session.userId, UserIdType.ANY); + appIdentifier, storage, sessionInfo.session.userId, UserIdType.ANY); if (userIdMapping != null) { - ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, - userIdMapping.superTokensUserId); + ActiveUsers.updateLastActive(appIdentifier, main, userIdMapping.superTokensUserId); } else { - ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, - sessionInfo.session.userId); + ActiveUsers.updateLastActive(appIdentifier, main, sessionInfo.session.userId); } } catch (StorageQueryException ignored) { } diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionAPI.java index 5b6ce77b6..7af0fa841 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionAPI.java @@ -27,12 +27,11 @@ import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.session.SessionInfo; import io.supertokens.session.Session; @@ -86,7 +85,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I assert userDataInDatabase != null; try { - boolean useStaticSigningKey = !Config.getConfig(this.getTenantStorage(req), main) + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); + + boolean useStaticSigningKey = !Config.getConfig(tenantIdentifier, main) .getAccessTokenSigningKeyDynamic(); if (version.greaterThanOrEqualTo(SemVer.v2_21)) { Boolean useDynamicSigningKey = InputParser.parseBooleanOrThrowError(input, "useDynamicSigningKey", @@ -99,22 +101,21 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I AccessToken.VERSION accessTokenVersion = AccessToken.getAccessTokenVersionForCDI(version); SessionInformationHolder sessionInfo = Session.createNewSession( - this.getTenantStorage(req), main, userId, userDataInJWT, + tenantIdentifier, storage, main, userId, userDataInJWT, userDataInDatabase, enableAntiCsrf, accessTokenVersion, useStaticSigningKey); - if (StorageLayer.getStorage(this.getTenantStorage(req), main).getType() == - STORAGE_TYPE.SQL) { + if (storage.getType() == STORAGE_TYPE.SQL) { try { io.supertokens.pluginInterface.useridmapping.UserIdMapping userIdMapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( - this.getTenantStorage(req).toAppIdentifierWithStorage(), + tenantIdentifier.toAppIdentifier(), storage, sessionInfo.session.userId, UserIdType.ANY); if (userIdMapping != null) { - ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, + ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), main, userIdMapping.superTokensUserId); } else { - ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, + ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), main, sessionInfo.session.userId); } } catch (StorageQueryException ignored) { @@ -135,7 +136,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I if (super.getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v2_21)) { result.remove("idRefreshToken"); } else { - Utils.addLegacySigningKeyInfos(this.getTenantStorage(req).toAppIdentifier(), main, result, + Utils.addLegacySigningKeyInfos(tenantIdentifier.toAppIdentifier(), main, result, super.getVersionFromRequest(req).betweenInclusive(SemVer.v2_9, SemVer.v2_21)); } @@ -156,18 +157,19 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO String sessionHandle = InputParser.getQueryParamOrThrowError(req, "sessionHandle", false); assert sessionHandle != null; - TenantIdentifierWithStorage tenantIdentifierWithStorage = null; + TenantIdentifier tenantIdentifier; + Storage storage; try { AppIdentifier appIdentifier = getAppIdentifier(req); - TenantIdentifier tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), + tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), Session.getTenantIdFromSessionHandle(sessionHandle)); - tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); + storage = StorageLayer.getStorage(tenantIdentifier, main); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } try { - SessionInfo sessionInfo = Session.getSession(tenantIdentifierWithStorage, sessionHandle); + SessionInfo sessionInfo = Session.getSession(tenantIdentifier, storage, sessionHandle); JsonObject result = new Gson().toJsonTree(sessionInfo).getAsJsonObject(); result.add("userDataInJWT", Utils.toJsonTreeWithNulls(sessionInfo.userDataInJWT)); @@ -176,7 +178,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO result.addProperty("status", "OK"); if (getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v3_0)) { - result.addProperty("tenantId", tenantIdentifierWithStorage.getTenantId()); + result.addProperty("tenantId", tenantIdentifier.getTenantId()); } if (getVersionFromRequest(req).lesserThan(SemVer.v4_0)) { result.remove("recipeUserId"); @@ -187,7 +189,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } catch (StorageQueryException e) { throw new ServletException(e); } catch (UnauthorisedException e) { - Logging.debug(main, tenantIdentifierWithStorage, Utils.exceptionStacktraceToString(e)); + Logging.debug(main, tenantIdentifier, Utils.exceptionStacktraceToString(e)); JsonObject reply = new JsonObject(); reply.addProperty("status", "UNAUTHORISED"); reply.addProperty("message", e.getMessage()); diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionDataAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionDataAPI.java index 29971d899..12d512227 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionDataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionDataAPI.java @@ -22,11 +22,10 @@ import io.supertokens.exceptions.UnauthorisedException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.session.Session; import io.supertokens.session.accessToken.AccessToken; @@ -60,17 +59,18 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO String sessionHandle = InputParser.getQueryParamOrThrowError(req, "sessionHandle", false); assert sessionHandle != null; - TenantIdentifierWithStorage tenantIdentifierWithStorage = null; + TenantIdentifier tenantIdentifier; + Storage storage; try { AppIdentifier appIdentifier = getAppIdentifier(req); - TenantIdentifier tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), Session.getTenantIdFromSessionHandle(sessionHandle)); - tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); + tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), Session.getTenantIdFromSessionHandle(sessionHandle)); + storage = StorageLayer.getStorage(tenantIdentifier, main); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } try { - JsonObject userDataInDatabase = Session.getSessionData(tenantIdentifierWithStorage, sessionHandle); + JsonObject userDataInDatabase = Session.getSessionData(tenantIdentifier, storage, sessionHandle); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); @@ -80,7 +80,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } catch (StorageQueryException e) { throw new ServletException(e); } catch (UnauthorisedException e) { - Logging.debug(main, tenantIdentifierWithStorage, Utils.exceptionStacktraceToString(e)); + Logging.debug(main, tenantIdentifier, Utils.exceptionStacktraceToString(e)); JsonObject reply = new JsonObject(); reply.addProperty("status", "UNAUTHORISED"); reply.addProperty("message", e.getMessage()); @@ -97,11 +97,12 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject userDataInDatabase = InputParser.parseJsonObjectOrThrowError(input, "userDataInDatabase", false); assert userDataInDatabase != null; - TenantIdentifierWithStorage tenantIdentifierWithStorage = null; + TenantIdentifier tenantIdentifier; + Storage storage; try { AppIdentifier appIdentifier = getAppIdentifier(req); - TenantIdentifier tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), Session.getTenantIdFromSessionHandle(sessionHandle)); - tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); + tenantIdentifier = new TenantIdentifier(appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), Session.getTenantIdFromSessionHandle(sessionHandle)); + storage = StorageLayer.getStorage(tenantIdentifier, main); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } @@ -111,10 +112,10 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO // which is always null here if (getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v2_21)) { AccessToken.VERSION version = AccessToken.getAccessTokenVersionForCDI(getVersionFromRequest(req)); - Session.updateSession(tenantIdentifierWithStorage, sessionHandle, + Session.updateSession(tenantIdentifier, storage, sessionHandle, userDataInDatabase, null, version); } else { - Session.updateSessionBeforeCDI2_21(tenantIdentifierWithStorage, sessionHandle, + Session.updateSessionBeforeCDI2_21(tenantIdentifier, storage, sessionHandle, userDataInDatabase, null); } @@ -127,7 +128,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO } catch (AccessTokenPayloadError e) { throw new ServletException(new BadRequestException(e.getMessage())); } catch (UnauthorisedException e) { - Logging.debug(main, tenantIdentifierWithStorage, Utils.exceptionStacktraceToString(e)); + Logging.debug(main, tenantIdentifier, Utils.exceptionStacktraceToString(e)); JsonObject reply = new JsonObject(); reply.addProperty("status", "UNAUTHORISED"); reply.addProperty("message", e.getMessage()); diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionRegenerateAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionRegenerateAPI.java index c480b194c..58b110cfe 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionRegenerateAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionRegenerateAPI.java @@ -27,7 +27,6 @@ import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.session.Session; import io.supertokens.session.info.SessionInformationHolder; diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java index 1beeec007..12b1cec58 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java @@ -23,7 +23,10 @@ import io.supertokens.Main; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.useridmapping.UserIdMapping; import io.supertokens.session.Session; @@ -99,27 +102,27 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I if (userId != null) { try { + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); + String[] sessionHandlesRevoked; if (revokeAcrossAllTenants) { sessionHandlesRevoked = Session.revokeAllSessionsForUser( - main, this.getTenantStorage(req).toAppIdentifierWithStorage(), userId, revokeSessionsForLinkedAccounts); + main, tenantIdentifier.toAppIdentifier(), storage, userId, revokeSessionsForLinkedAccounts); } else { sessionHandlesRevoked = Session.revokeAllSessionsForUser( - main, this.getTenantStorage(req), userId, - revokeSessionsForLinkedAccounts); + main, tenantIdentifier, storage, userId, revokeSessionsForLinkedAccounts); } - if (StorageLayer.getStorage(this.getTenantStorage(req), main).getType() == - STORAGE_TYPE.SQL) { + if (storage.getType() == STORAGE_TYPE.SQL) { try { UserIdMapping userIdMapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( - this.getTenantStorage(req).toAppIdentifierWithStorage(), - userId, UserIdType.ANY); + tenantIdentifier.toAppIdentifier(), storage, userId, UserIdType.ANY); if (userIdMapping != null) { - ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, + ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), main, userIdMapping.superTokensUserId); } else { - ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, userId); + ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), main, userId); } } catch (StorageQueryException ignored) { } @@ -137,8 +140,11 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } } else { try { + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage = getTenantStorage(req); + String[] sessionHandlesRevoked = Session.revokeSessionUsingSessionHandles(main, - this.getTenantStorage(req).toAppIdentifierWithStorage(), sessionHandles); + appIdentifier, storage, sessionHandles); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); JsonArray sessionHandlesRevokedJSON = new JsonArray(); diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java index bb5ccd837..ec0ad8dff 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java @@ -21,7 +21,10 @@ import com.google.gson.JsonPrimitive; import io.supertokens.Main; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.session.Session; import io.supertokens.webserver.InputParser; @@ -67,12 +70,15 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { String[] sessionHandles; + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); + if (fetchAcrossAllTenants) { sessionHandles = Session.getAllNonExpiredSessionHandlesForUser( - main, this.getTenantStorage(req).toAppIdentifierWithStorage(), userId, fetchSessionsForAllLinkedAccounts); + main, tenantIdentifier.toAppIdentifier(), storage, userId, fetchSessionsForAllLinkedAccounts); } else { sessionHandles = Session.getAllNonExpiredSessionHandlesForUser( - this.getTenantStorage(req), userId, fetchSessionsForAllLinkedAccounts); + tenantIdentifier, storage, userId, fetchSessionsForAllLinkedAccounts); } JsonObject result = new JsonObject(); From 9eb76a1f011e1e247768b1a0d46c7afb6f6981fb Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 1 Mar 2024 15:49:13 +0530 Subject: [PATCH 08/31] fix: user metadata --- .../usermetadata/RemoveUserMetadataAPI.java | 13 +++++--- .../api/usermetadata/UserMetadataAPI.java | 30 ++++++++++--------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java b/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java index 4ef1bc926..8e6a91a24 100644 --- a/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java @@ -19,8 +19,11 @@ import com.google.gson.JsonObject; import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; @@ -52,15 +55,17 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I // API is app specific JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String userId = InputParser.parseStringOrThrowError(input, "userId", false); + + AppIdentifier appIdentifier = getAppIdentifier(req); try { try { - AppIdentifierWithStorageAndUserIdMapping appIdStorageAndMapping = + StorageAndUserIdMapping storageAndUserIdMapping = this.getStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); - UserMetadata.deleteUserMetadata(appIdStorageAndMapping.appIdentifierWithStorage, userId); + UserMetadata.deleteUserMetadata(appIdentifier, storageAndUserIdMapping.storage, userId); } catch (UnknownUserIdException e) { - AppIdentifierWithStorage appIdentifierWithStorage = this.enforcePublicTenantAndGetPublicTenantStorage(req); - UserMetadata.deleteUserMetadata(appIdentifierWithStorage, userId); + Storage storage = this.enforcePublicTenantAndGetPublicTenantStorage(req); + UserMetadata.deleteUserMetadata(appIdentifier, storage, userId); } JsonObject response = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java b/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java index 022e41f07..4444d0551 100644 --- a/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java @@ -17,11 +17,12 @@ package io.supertokens.webserver.api.usermetadata; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -52,16 +53,16 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific String userId = InputParser.getQueryParamOrThrowError(req, "userId", false); + AppIdentifier appIdentifier = getAppIdentifier(req); try { JsonObject metadata; try { - AppIdentifierWithStorageAndUserIdMapping appIdStorageAndMapping = - this.getStorageAndUserIdMappingForAppSpecificApi( - req, userId, UserIdType.ANY); - metadata = UserMetadata.getUserMetadata(appIdStorageAndMapping.appIdentifierWithStorage, userId); + StorageAndUserIdMapping storageAndUserIdMapping = this.getStorageAndUserIdMappingForAppSpecificApi( + req, userId, UserIdType.ANY); + metadata = UserMetadata.getUserMetadata(appIdentifier, storageAndUserIdMapping.storage, userId); } catch (UnknownUserIdException e) { - AppIdentifierWithStorage appIdentifierWithStorage = this.enforcePublicTenantAndGetPublicTenantStorage(req); - metadata = UserMetadata.getUserMetadata(appIdentifierWithStorage, userId); + Storage storage = this.enforcePublicTenantAndGetPublicTenantStorage(req); + metadata = UserMetadata.getUserMetadata(appIdentifier, storage, userId); } JsonObject response = new JsonObject(); @@ -79,18 +80,19 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String userId = InputParser.parseStringOrThrowError(input, "userId", false); JsonObject update = InputParser.parseJsonObjectOrThrowError(input, "metadataUpdate", false); + + AppIdentifier appIdentifier = getAppIdentifier(req); try { JsonObject metadata; try { - AppIdentifierWithStorageAndUserIdMapping appIdStorageAndMapping = - this.getStorageAndUserIdMappingForAppSpecificApi( - req, userId, UserIdType.ANY); - metadata = UserMetadata.updateUserMetadata(appIdStorageAndMapping.appIdentifierWithStorage, userId, + StorageAndUserIdMapping storageAndUserIdMapping = this.getStorageAndUserIdMappingForAppSpecificApi( + req, userId, UserIdType.ANY); + metadata = UserMetadata.updateUserMetadata(appIdentifier, storageAndUserIdMapping.storage, userId, update); } catch (UnknownUserIdException e) { - AppIdentifierWithStorage appIdentifierWithStorage = this.enforcePublicTenantAndGetPublicTenantStorage(req); - metadata = UserMetadata.updateUserMetadata(appIdentifierWithStorage, userId, update); + Storage storage = this.enforcePublicTenantAndGetPublicTenantStorage(req); + metadata = UserMetadata.updateUserMetadata(appIdentifier, storage, userId, update); } JsonObject response = new JsonObject(); From 4843083e2e40553152137dfb20eacb43ff2ca04d Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 1 Mar 2024 15:56:36 +0530 Subject: [PATCH 09/31] fix: user roles --- .../webserver/api/userroles/AddUserRoleAPI.java | 10 +++++++--- .../webserver/api/userroles/CreateRoleAPI.java | 6 +++++- .../api/userroles/GetPermissionsForRoleAPI.java | 7 ++++++- .../webserver/api/userroles/GetRolesAPI.java | 6 +++++- .../api/userroles/GetRolesForPermissionAPI.java | 6 +++++- .../webserver/api/userroles/GetRolesForUserAPI.java | 10 ++++++---- .../webserver/api/userroles/GetUsersForRoleAPI.java | 9 ++++++--- .../api/userroles/RemovePermissionsForRoleAPI.java | 7 ++++++- .../webserver/api/userroles/RemoveRoleAPI.java | 7 ++++++- .../webserver/api/userroles/RemoveUserRoleAPI.java | 9 ++++++--- 10 files changed, 58 insertions(+), 19 deletions(-) diff --git a/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java index 397091c47..7d2b7f2b7 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java @@ -18,6 +18,8 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -48,7 +50,7 @@ public String getPath() { @Override protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - // API is tenant specific, but uses public tenant storage + // API is tenant specific JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String userId = InputParser.parseStringOrThrowError(input, "userId", false); String role = InputParser.parseStringOrThrowError(input, "role", false); @@ -60,9 +62,11 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO } try { + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); + boolean didUserAlreadyHaveRole = !UserRoles.addRoleToUser( - this.getTenantStorage(req).withStorage(this.getPublicTenantStorage(req).getStorage()), - userId, role); + tenantIdentifier, storage, userId, role); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); response.addProperty("didUserAlreadyHaveRole", didUserAlreadyHaveRole); diff --git a/src/main/java/io/supertokens/webserver/api/userroles/CreateRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/CreateRoleAPI.java index 082969848..24b74473a 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/CreateRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/CreateRoleAPI.java @@ -20,6 +20,8 @@ import com.google.gson.JsonObject; import io.supertokens.Main; import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -81,8 +83,10 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO } try { + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage = enforcePublicTenantAndGetPublicTenantStorage(req); boolean createdNewRole = UserRoles.createNewRoleOrModifyItsPermissions( - this.enforcePublicTenantAndGetPublicTenantStorage(req), role, permissions); + appIdentifier, storage, role, permissions); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/userroles/GetPermissionsForRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/GetPermissionsForRoleAPI.java index e20641b51..7b9fab585 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/GetPermissionsForRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/GetPermissionsForRoleAPI.java @@ -21,6 +21,8 @@ import com.google.gson.JsonPrimitive; import io.supertokens.Main; import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -60,7 +62,10 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } try { - String[] permissions = UserRoles.getPermissionsForRole(this.enforcePublicTenantAndGetPublicTenantStorage(req), role); + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage = enforcePublicTenantAndGetPublicTenantStorage(req); + + String[] permissions = UserRoles.getPermissionsForRole(appIdentifier, storage, role); JsonArray arr = new JsonArray(); for (String permission : permissions) { arr.add(new JsonPrimitive(permission)); diff --git a/src/main/java/io/supertokens/webserver/api/userroles/GetRolesAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/GetRolesAPI.java index 20ba99bc9..21ca5d73b 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/GetRolesAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/GetRolesAPI.java @@ -21,6 +21,8 @@ import com.google.gson.JsonPrimitive; import io.supertokens.Main; import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -50,8 +52,10 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific try { + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage = enforcePublicTenantAndGetPublicTenantStorage(req); - String[] roles = UserRoles.getRoles(this.enforcePublicTenantAndGetPublicTenantStorage(req)); + String[] roles = UserRoles.getRoles(appIdentifier, storage); JsonArray arr = new JsonArray(); for (String s : roles) { diff --git a/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForPermissionAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForPermissionAPI.java index df64526d6..6577c93b5 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForPermissionAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForPermissionAPI.java @@ -21,6 +21,8 @@ import com.google.gson.JsonPrimitive; import io.supertokens.Main; import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -60,8 +62,10 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } try { + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage = enforcePublicTenantAndGetPublicTenantStorage(req); - String[] roles = UserRoles.getRolesThatHavePermission(this.enforcePublicTenantAndGetPublicTenantStorage(req), permission); + String[] roles = UserRoles.getRolesThatHavePermission(appIdentifier, storage, permission); JsonArray arr = new JsonArray(); for (String s : roles) { diff --git a/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForUserAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForUserAPI.java index 4ce961a6a..ebc500f21 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/GetRolesForUserAPI.java @@ -20,6 +20,8 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import io.supertokens.Main; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -48,12 +50,12 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - // API is tenant specific, but using the public tenant storage + // API is tenant specific String userId = InputParser.getQueryParamOrThrowError(req, "userId", false); try { - String[] userRoles = UserRoles.getRolesForUser( - this.getTenantStorage(req).withStorage(this.getPublicTenantStorage(req).getStorage()), - userId); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); + String[] userRoles = UserRoles.getRolesForUser(tenantIdentifier, storage, userId); JsonArray arr = new JsonArray(); for (String s : userRoles) { arr.add(new JsonPrimitive(s)); diff --git a/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java index 6743f89c0..c1c6cd0d1 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java @@ -20,6 +20,8 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import io.supertokens.Main; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -60,9 +62,10 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } try { - String[] roleUsers = UserRoles.getUsersForRole( - this.getTenantStorage(req).withStorage(this.getPublicTenantStorage(req).getStorage()), - role); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); + + String[] roleUsers = UserRoles.getUsersForRole(tenantIdentifier, storage, role); JsonArray arr = new JsonArray(); for (String s : roleUsers) { diff --git a/src/main/java/io/supertokens/webserver/api/userroles/RemovePermissionsForRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/RemovePermissionsForRoleAPI.java index 0c68d365d..7300e9b6b 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/RemovePermissionsForRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/RemovePermissionsForRoleAPI.java @@ -20,6 +20,8 @@ import com.google.gson.JsonObject; import io.supertokens.Main; import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -81,7 +83,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - UserRoles.deletePermissionsFromRole(this.enforcePublicTenantAndGetPublicTenantStorage(req), role, permissions); + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage = enforcePublicTenantAndGetPublicTenantStorage(req); + + UserRoles.deletePermissionsFromRole(appIdentifier, storage, role, permissions); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); super.sendJsonResponse(200, response, resp); diff --git a/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java index b49446b04..acc130085 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java @@ -19,6 +19,8 @@ import com.google.gson.JsonObject; import io.supertokens.Main; import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -58,7 +60,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - boolean didRoleExist = UserRoles.deleteRole(this.enforcePublicTenantAndGetPublicTenantStorage(req), role); + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage = enforcePublicTenantAndGetPublicTenantStorage(req); + + boolean didRoleExist = UserRoles.deleteRole(appIdentifier, storage, role); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java index 4eb665fd9..ff94b4bbd 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java @@ -18,6 +18,8 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -60,9 +62,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - boolean didUserHaveRole = UserRoles.removeUserRole( - this.getTenantStorage(req).withStorage(this.getPublicTenantStorage(req).getStorage()), - userId, role); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); + + boolean didUserHaveRole = UserRoles.removeUserRole(tenantIdentifier, storage, userId, role); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); From 69a2466e68ecbdf107ce7fdae9dee37c8a56b72d Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 1 Mar 2024 16:08:18 +0530 Subject: [PATCH 10/31] fix: totp --- src/main/java/io/supertokens/totp/Totp.java | 94 +++++++++---------- .../api/totp/CreateOrUpdateTotpDeviceAPI.java | 38 ++++---- .../webserver/api/totp/GetTotpDevicesAPI.java | 21 +++-- .../api/totp/RemoveTotpDeviceAPI.java | 21 +++-- .../webserver/api/totp/VerifyTotpAPI.java | 18 ++-- .../api/totp/VerifyTotpDeviceAPI.java | 18 ++-- .../usermetadata/RemoveUserMetadataAPI.java | 2 - 7 files changed, 111 insertions(+), 101 deletions(-) diff --git a/src/main/java/io/supertokens/totp/Totp.java b/src/main/java/io/supertokens/totp/Totp.java index 307f49471..58d252410 100644 --- a/src/main/java/io/supertokens/totp/Totp.java +++ b/src/main/java/io/supertokens/totp/Totp.java @@ -6,11 +6,12 @@ import io.supertokens.featureflag.EE_FEATURES; import io.supertokens.featureflag.FeatureFlag; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.TOTPDevice; import io.supertokens.pluginInterface.totp.TOTPUsedCode; @@ -88,34 +89,34 @@ public static TOTPDevice registerDevice(Main main, String userId, throws StorageQueryException, DeviceAlreadyExistsException, NoSuchAlgorithmException, FeatureNotEnabledException { try { - return registerDevice(new AppIdentifierWithStorage(null, null, StorageLayer.getStorage(main)), main, userId, - deviceName, skew, period); + return registerDevice(new AppIdentifier(null, null), StorageLayer.getStorage(main), + main, userId, deviceName, skew, period); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static TOTPDevice registerDevice(AppIdentifierWithStorage appIdentifierWithStorage, Main main, String userId, + public static TOTPDevice registerDevice(AppIdentifier appIdentifier, Storage storage, Main main, String userId, String deviceName, int skew, int period) throws StorageQueryException, DeviceAlreadyExistsException, NoSuchAlgorithmException, FeatureNotEnabledException, TenantOrAppNotFoundException { - if (!isTotpEnabled(appIdentifierWithStorage, main)) { + if (!isTotpEnabled(appIdentifier, main)) { throw new FeatureNotEnabledException( "TOTP feature is not enabled. Please subscribe to a SuperTokens core license key to enable this " + "feature."); } - TOTPSQLStorage totpStorage = appIdentifierWithStorage.getTOTPStorage(); + TOTPSQLStorage totpStorage = StorageUtils.getTOTPStorage(storage); String secret = generateSecret(); TOTPDevice device = new TOTPDevice(userId, deviceName, secret, period, skew, false); - totpStorage.createDevice(appIdentifierWithStorage, device); + totpStorage.createDevice(appIdentifier, device); return device; } - private static void checkAndStoreCode(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, + private static void checkAndStoreCode(TenantIdentifier tenantIdentifier, Storage storage, Main main, String userId, TOTPDevice[] devices, String code) throws InvalidTotpException, TotpNotEnabledException, @@ -154,23 +155,22 @@ private static void checkAndStoreCode(TenantIdentifierWithStorage tenantIdentifi // That's why we need to fetch all the codes (expired + non-expired). // TOTPUsedCode[] usedCodes = - TOTPSQLStorage totpSQLStorage = tenantIdentifierWithStorage.getTOTPStorage(); + TOTPSQLStorage totpSQLStorage = StorageUtils.getTOTPStorage(storage); while (true) { try { totpSQLStorage.startTransaction(con -> { try { TOTPUsedCode[] usedCodes = totpSQLStorage.getAllUsedCodesDescOrder_Transaction(con, - tenantIdentifierWithStorage, - userId); + tenantIdentifier, userId); // N represents # of invalid attempts that will trigger rate limiting: - int N = Config.getConfig(tenantIdentifierWithStorage, main).getTotpMaxAttempts(); // (Default 5) + int N = Config.getConfig(tenantIdentifier, main).getTotpMaxAttempts(); // (Default 5) // Count # of contiguous invalids in latest N attempts (stop at first valid): long invalidOutOfN = Arrays.stream(usedCodes).limit(N).takeWhile(usedCode -> !usedCode.isValid) .count(); int rateLimitResetTimeInMs = - Config.getConfig(tenantIdentifierWithStorage, main).getTotpRateLimitCooldownTimeSec() * + Config.getConfig(tenantIdentifier, main).getTotpRateLimitCooldownTimeSec() * 1000; // (Default // 15 mins) @@ -239,7 +239,7 @@ private static void checkAndStoreCode(TenantIdentifierWithStorage tenantIdentifi code, isValid, now + 1000 * expireInSec, now); try { - totpSQLStorage.insertUsedCode_Transaction(con, tenantIdentifierWithStorage, newCode); + totpSQLStorage.insertUsedCode_Transaction(con, tenantIdentifier, newCode); totpSQLStorage.commitTransaction(con); } catch (UsedCodeAlreadyExistsException | TotpNotEnabledException e) { throw new StorageTransactionLogicException(e); @@ -287,14 +287,14 @@ public static boolean verifyDevice(Main main, throws TotpNotEnabledException, UnknownDeviceException, InvalidTotpException, LimitReachedException, StorageQueryException, StorageTransactionLogicException { try { - return verifyDevice(new TenantIdentifierWithStorage(null, null, null, StorageLayer.getStorage(main)), main, - userId, deviceName, code); + return verifyDevice(new TenantIdentifier(null, null, null), + StorageLayer.getStorage(main), main, userId, deviceName, code); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static boolean verifyDevice(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, + public static boolean verifyDevice(TenantIdentifier tenantIdentifier, Storage storage, Main main, String userId, String deviceName, String code) throws TotpNotEnabledException, UnknownDeviceException, InvalidTotpException, LimitReachedException, StorageQueryException, StorageTransactionLogicException, @@ -302,7 +302,7 @@ public static boolean verifyDevice(TenantIdentifierWithStorage tenantIdentifierW // Here boolean return value tells whether the device has been // newly verified (true) OR it was already verified (false) - TOTPSQLStorage totpStorage = tenantIdentifierWithStorage.getTOTPStorage(); + TOTPSQLStorage totpStorage = StorageUtils.getTOTPStorage(storage); TOTPDevice matchingDevice = null; // Here one race condition is that the same device @@ -310,7 +310,7 @@ public static boolean verifyDevice(TenantIdentifierWithStorage tenantIdentifierW // both the API calls will return true, but that's okay. // Check if the user has any devices: - TOTPDevice[] devices = totpStorage.getDevices(tenantIdentifierWithStorage.toAppIdentifier(), userId); + TOTPDevice[] devices = totpStorage.getDevices(tenantIdentifier.toAppIdentifier(), userId); if (devices.length == 0) { throw new TotpNotEnabledException(); } @@ -337,10 +337,10 @@ public static boolean verifyDevice(TenantIdentifierWithStorage tenantIdentifierW // verified in the devices table (because it was deleted/renamed). So the user // gets a UnknownDevceException. // This behaviour is okay so we can ignore it. - checkAndStoreCode(tenantIdentifierWithStorage, main, userId, new TOTPDevice[]{matchingDevice}, + checkAndStoreCode(tenantIdentifier, storage, main, userId, new TOTPDevice[]{matchingDevice}, code); // Will reach here only if the code is valid: - totpStorage.markDeviceAsVerified(tenantIdentifierWithStorage.toAppIdentifier(), userId, deviceName); + totpStorage.markDeviceAsVerified(tenantIdentifier.toAppIdentifier(), userId, deviceName); return true; // Newly verified } @@ -350,29 +350,29 @@ public static void verifyCode(Main main, String userId, throws TotpNotEnabledException, InvalidTotpException, LimitReachedException, StorageQueryException, StorageTransactionLogicException, FeatureNotEnabledException { try { - verifyCode(new TenantIdentifierWithStorage(null, null, null, StorageLayer.getStorage(main)), main, - userId, code, allowUnverifiedDevices); + verifyCode(new TenantIdentifier(null, null, null), + StorageLayer.getStorage(main), main, userId, code, allowUnverifiedDevices); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static void verifyCode(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, String userId, + public static void verifyCode(TenantIdentifier tenantIdentifier, Storage storage, Main main, String userId, String code, boolean allowUnverifiedDevices) throws TotpNotEnabledException, InvalidTotpException, LimitReachedException, StorageQueryException, StorageTransactionLogicException, FeatureNotEnabledException, TenantOrAppNotFoundException { - if (!isTotpEnabled(tenantIdentifierWithStorage.toAppIdentifierWithStorage(), main)) { + if (!isTotpEnabled(tenantIdentifier.toAppIdentifier(), main)) { throw new FeatureNotEnabledException( "TOTP feature is not enabled. Please subscribe to a SuperTokens core license key to enable this " + "feature."); } - TOTPSQLStorage totpStorage = tenantIdentifierWithStorage.getTOTPStorage(); + TOTPSQLStorage totpStorage = StorageUtils.getTOTPStorage(storage); // Check if the user has any devices: - TOTPDevice[] devices = totpStorage.getDevices(tenantIdentifierWithStorage.toAppIdentifier(), userId); + TOTPDevice[] devices = totpStorage.getDevices(tenantIdentifier.toAppIdentifier(), userId); if (devices.length == 0) { throw new TotpNotEnabledException(); } @@ -386,7 +386,7 @@ public static void verifyCode(TenantIdentifierWithStorage tenantIdentifierWithSt // another API call. We will still check the code against the updated set of // devices and store it in the used codes table. This behaviour is okay so we // can ignore it. - checkAndStoreCode(tenantIdentifierWithStorage, main, userId, devices, code); + checkAndStoreCode(tenantIdentifier, storage, main, userId, devices, code); } @TestOnly @@ -395,7 +395,7 @@ public static void removeDevice(Main main, String userId, throws StorageQueryException, UnknownDeviceException, TotpNotEnabledException, StorageTransactionLogicException { try { - removeDevice(new AppIdentifierWithStorage(null, null, StorageLayer.getStorage(main)), + removeDevice(new AppIdentifier(null, null), StorageLayer.getStorage(main), userId, deviceName); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); @@ -405,35 +405,35 @@ public static void removeDevice(Main main, String userId, /** * Delete device and also delete the user if deleting the last device */ - public static void removeDevice(AppIdentifierWithStorage appIdentifierWithStorage, String userId, + public static void removeDevice(AppIdentifier appIdentifier, Storage storage, String userId, String deviceName) throws StorageQueryException, UnknownDeviceException, TotpNotEnabledException, StorageTransactionLogicException, TenantOrAppNotFoundException { - TOTPSQLStorage storage = appIdentifierWithStorage.getTOTPStorage(); + TOTPSQLStorage totpStorage = StorageUtils.getTOTPStorage(storage); try { - storage.startTransaction(con -> { - int deletedCount = storage.deleteDevice_Transaction(con, appIdentifierWithStorage, userId, deviceName); + totpStorage.startTransaction(con -> { + int deletedCount = totpStorage.deleteDevice_Transaction(con, appIdentifier, userId, deviceName); if (deletedCount == 0) { throw new StorageTransactionLogicException(new UnknownDeviceException()); } // Some device(s) were deleted. Check if user has any other device left: // This also takes a lock on the user devices. - TOTPDevice[] devices = storage.getDevices_Transaction(con, appIdentifierWithStorage, userId); + TOTPDevice[] devices = totpStorage.getDevices_Transaction(con, appIdentifier, userId); if (devices.length == 0) { // no device left. delete user - storage.removeUser_Transaction(con, appIdentifierWithStorage, userId); + totpStorage.removeUser_Transaction(con, appIdentifier, userId); } - storage.commitTransaction(con); + totpStorage.commitTransaction(con); return null; }); return; } catch (StorageTransactionLogicException e) { if (e.actualException instanceof UnknownDeviceException) { // Check if any device exists for the user: - TOTPDevice[] devices = storage.getDevices(appIdentifierWithStorage, userId); + TOTPDevice[] devices = totpStorage.getDevices(appIdentifier, userId); if (devices.length == 0) { throw new TotpNotEnabledException(); } @@ -451,23 +451,23 @@ public static void updateDeviceName(Main main, String userId, throws StorageQueryException, DeviceAlreadyExistsException, UnknownDeviceException, TotpNotEnabledException { try { - updateDeviceName(new AppIdentifierWithStorage(null, null, StorageLayer.getStorage(main)), + updateDeviceName(new AppIdentifier(null, null), StorageLayer.getStorage(main), userId, oldDeviceName, newDeviceName); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static void updateDeviceName(AppIdentifierWithStorage appIdentifierWithStorage, String userId, + public static void updateDeviceName(AppIdentifier appIdentifier, Storage storage, String userId, String oldDeviceName, String newDeviceName) throws StorageQueryException, DeviceAlreadyExistsException, UnknownDeviceException, TotpNotEnabledException, TenantOrAppNotFoundException { - TOTPSQLStorage totpStorage = appIdentifierWithStorage.getTOTPStorage(); + TOTPSQLStorage totpStorage = StorageUtils.getTOTPStorage(storage); try { - totpStorage.updateDeviceName(appIdentifierWithStorage, userId, oldDeviceName, newDeviceName); + totpStorage.updateDeviceName(appIdentifier, userId, oldDeviceName, newDeviceName); } catch (UnknownDeviceException e) { // Check if any device exists for the user: - TOTPDevice[] devices = totpStorage.getDevices(appIdentifierWithStorage, userId); + TOTPDevice[] devices = totpStorage.getDevices(appIdentifier, userId); if (devices.length == 0) { throw new TotpNotEnabledException(); } else { @@ -480,18 +480,18 @@ public static void updateDeviceName(AppIdentifierWithStorage appIdentifierWithSt public static TOTPDevice[] getDevices(Main main, String userId) throws StorageQueryException, TotpNotEnabledException { try { - return getDevices(new AppIdentifierWithStorage(null, null, StorageLayer.getStorage(main)), + return getDevices(new AppIdentifier(null, null), StorageLayer.getStorage(main), userId); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static TOTPDevice[] getDevices(AppIdentifierWithStorage appIdentifierWithStorage, String userId) + public static TOTPDevice[] getDevices(AppIdentifier appIdentifier, Storage storage, String userId) throws StorageQueryException, TotpNotEnabledException, TenantOrAppNotFoundException { - TOTPSQLStorage totpStorage = appIdentifierWithStorage.getTOTPStorage(); + TOTPSQLStorage totpStorage = StorageUtils.getTOTPStorage(storage); - TOTPDevice[] devices = totpStorage.getDevices(appIdentifierWithStorage, userId); + TOTPDevice[] devices = totpStorage.getDevices(appIdentifier, userId); if (devices.length == 0) { throw new TotpNotEnabledException(); } diff --git a/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java index 08dfdca21..31c0c8ee9 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java @@ -1,14 +1,15 @@ package io.supertokens.webserver.api.totp; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.TOTPDevice; import io.supertokens.pluginInterface.totp.exception.DeviceAlreadyExistsException; @@ -66,26 +67,26 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject result = new JsonObject(); try { - AppIdentifierWithStorage appIdentifierWithStorage; + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage; try { // This step is required only because user_last_active table stores supertokens internal user id. // While sending the usage stats we do a join, so totp tables also must use internal user id. // Try to find the appIdentifier with right storage based on the userId - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getStorageAndUserIdMappingForAppSpecificApi( - req, userId, UserIdType.ANY); + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForAppSpecificApi( + req, userId, UserIdType.ANY); - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; + storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the public tenant storage - appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); + storage = enforcePublicTenantAndGetPublicTenantStorage(req); } - TOTPDevice device = Totp.registerDevice(appIdentifierWithStorage, main, userId, deviceName, skew, period); + TOTPDevice device = Totp.registerDevice(appIdentifier, storage, main, userId, deviceName, skew, period); result.addProperty("status", "OK"); result.addProperty("secret", device.secretKey); @@ -121,26 +122,27 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject result = new JsonObject(); try { - AppIdentifierWithStorage appIdentifierWithStorage; + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage; try { // This step is required only because user_last_active table stores supertokens internal user id. // While sending the usage stats we do a join, so totp tables also must use internal user id. // Try to find the appIdentifier with right storage based on the userId - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; + storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the public storage - appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); + storage = enforcePublicTenantAndGetPublicTenantStorage(req); } - Totp.updateDeviceName(appIdentifierWithStorage, userId, existingDeviceName, newDeviceName); + Totp.updateDeviceName(appIdentifier, storage, userId, existingDeviceName, newDeviceName); result.addProperty("status", "OK"); super.sendJsonResponse(200, result, resp); diff --git a/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java b/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java index 7cc254c7a..400674c70 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java @@ -2,13 +2,14 @@ import com.google.gson.JsonArray; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.TOTPDevice; import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException; @@ -46,26 +47,26 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject result = new JsonObject(); try { - AppIdentifierWithStorage appIdentifierWithStorage; + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage; try { // This step is required only because user_last_active table stores supertokens internal user id. // While sending the usage stats we do a join, so totp tables also must use internal user id. // Try to find the appIdentifier with right storage based on the userId - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = getStorageAndUserIdMappingForAppSpecificApi( + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; + storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest - appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); + storage = enforcePublicTenantAndGetPublicTenantStorage(req); } - TOTPDevice[] devices = Totp.getDevices(appIdentifierWithStorage, - userId); + TOTPDevice[] devices = Totp.getDevices(appIdentifier, storage, userId); JsonArray devicesArray = new JsonArray(); for (TOTPDevice d : devices) { diff --git a/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java index b4eac5b5a..fd56fdcd4 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java @@ -1,14 +1,15 @@ package io.supertokens.webserver.api.totp; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException; import io.supertokens.pluginInterface.totp.exception.UnknownDeviceException; @@ -52,26 +53,26 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject result = new JsonObject(); try { - AppIdentifierWithStorage appIdentifierWithStorage; + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage; try { // This step is required only because user_last_active table stores supertokens internal user id. // While sending the usage stats we do a join, so totp tables also must use internal user id. // Try to find the appIdentifier with right storage based on the userId - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getStorageAndUserIdMappingForAppSpecificApi( + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; + storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest - appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); + storage = enforcePublicTenantAndGetPublicTenantStorage(req); } - Totp.removeDevice(appIdentifierWithStorage, userId, deviceName); + Totp.removeDevice(appIdentifier, storage, userId, deviceName); result.addProperty("status", "OK"); result.addProperty("didDeviceExist", true); diff --git a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java index 6e3916672..0653f03d3 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java @@ -5,12 +5,15 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.TenantIdentifierWithStorageAndUserIdMapping; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException; @@ -56,24 +59,25 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject result = new JsonObject(); try { - TenantIdentifierWithStorage tenantIdentifierWithStorage; + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage; try { // This step is required only because user_last_active table stores supertokens internal user id. // While sending the usage stats we do a join, so totp tables also must use internal user id. - TenantIdentifierWithStorageAndUserIdMapping mappingAndStorage = getStorageAndUserIdMappingForTenantSpecificApi( + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForTenantSpecificApi( req, userId, UserIdType.ANY); - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - tenantIdentifierWithStorage = mappingAndStorage.tenantIdentifierWithStorage; + storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest - tenantIdentifierWithStorage = getTenantStorage(req); + storage = getTenantStorage(req); } - Totp.verifyCode(tenantIdentifierWithStorage, main, userId, totp, allowUnverifiedDevices); + Totp.verifyCode(tenantIdentifier, storage, main, userId, totp, allowUnverifiedDevices); result.addProperty("status", "OK"); super.sendJsonResponse(200, result, resp); diff --git a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java index b15e86d32..b4bf1eb8b 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java @@ -5,11 +5,14 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.TenantIdentifierWithStorageAndUserIdMapping; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException; @@ -58,23 +61,24 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject result = new JsonObject(); try { - TenantIdentifierWithStorage tenantIdentifierWithStorage; + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage; try { // This step is required only because user_last_active table stores supertokens internal user id. // While sending the usage stats we do a join, so totp tables also must use internal user id. - TenantIdentifierWithStorageAndUserIdMapping mappingAndStorage = getStorageAndUserIdMappingForTenantSpecificApi( + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForTenantSpecificApi( req, userId, UserIdType.ANY); - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - tenantIdentifierWithStorage = mappingAndStorage.tenantIdentifierWithStorage; + storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest - tenantIdentifierWithStorage = getTenantStorage(req); + storage = getTenantStorage(req); } - boolean isNewlyVerified = Totp.verifyDevice(tenantIdentifierWithStorage, main, userId, deviceName, totp); + boolean isNewlyVerified = Totp.verifyDevice(tenantIdentifier, storage, main, userId, deviceName, totp); result.addProperty("status", "OK"); result.addProperty("wasAlreadyVerified", !isNewlyVerified); diff --git a/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java b/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java index 8e6a91a24..47a6e0ad0 100644 --- a/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java @@ -17,14 +17,12 @@ package io.supertokens.webserver.api.usermetadata; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; import io.supertokens.StorageAndUserIdMapping; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; From 67286656cb670cbb39970c3ea83edf8b97eee949 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 1 Mar 2024 16:17:34 +0530 Subject: [PATCH 11/31] fix: email verification --- .../emailverification/EmailVerification.java | 70 +++++++++---------- .../GenerateEmailVerificationTokenAPI.java | 12 ++-- .../RevokeAllTokensForUserAPI.java | 2 +- .../emailverification/UnverifyEmailAPI.java | 16 +++-- .../api/emailverification/VerifyEmailAPI.java | 28 ++++---- 5 files changed, 66 insertions(+), 62 deletions(-) diff --git a/src/main/java/io/supertokens/emailverification/EmailVerification.java b/src/main/java/io/supertokens/emailverification/EmailVerification.java index 14bcca800..9999599f4 100644 --- a/src/main/java/io/supertokens/emailverification/EmailVerification.java +++ b/src/main/java/io/supertokens/emailverification/EmailVerification.java @@ -21,14 +21,14 @@ import io.supertokens.emailverification.exception.EmailAlreadyVerifiedException; import io.supertokens.emailverification.exception.EmailVerificationInvalidTokenException; import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.emailverification.EmailVerificationTokenInfo; import io.supertokens.pluginInterface.emailverification.exception.DuplicateEmailVerificationTokenException; import io.supertokens.pluginInterface.emailverification.sqlStorage.EmailVerificationSQLStorage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.storageLayer.StorageLayer; import io.supertokens.utils.Utils; @@ -43,9 +43,8 @@ public class EmailVerification { @TestOnly public static long getEmailVerificationTokenLifetimeForTests(Main main) { try { - Storage storage = StorageLayer.getStorage(main); return getEmailVerificationTokenLifetime( - new TenantIdentifierWithStorage(null, null, null, storage), main); + new TenantIdentifier(null, null, null), main); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } @@ -63,20 +62,20 @@ public static String generateEmailVerificationToken(Main main, String userId, St try { Storage storage = StorageLayer.getStorage(main); return generateEmailVerificationToken( - new TenantIdentifierWithStorage(null, null, null, storage), + new TenantIdentifier(null, null, null), storage, main, userId, email); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static String generateEmailVerificationToken(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, + public static String generateEmailVerificationToken(TenantIdentifier tenantIdentifier, Storage storage, Main main, String userId, String email) throws InvalidKeySpecException, NoSuchAlgorithmException, StorageQueryException, EmailAlreadyVerifiedException, TenantOrAppNotFoundException { - if (tenantIdentifierWithStorage.getEmailVerificationStorage() - .isEmailVerified(tenantIdentifierWithStorage.toAppIdentifier(), userId, email)) { + if (StorageUtils.getEmailVerificationStorage(storage) + .isEmailVerified(tenantIdentifier.toAppIdentifier(), userId, email)) { throw new EmailAlreadyVerifiedException(); } @@ -102,11 +101,11 @@ public static String generateEmailVerificationToken(TenantIdentifierWithStorage String hashedToken = getHashedToken(token); try { - tenantIdentifierWithStorage.getEmailVerificationStorage() - .addEmailVerificationToken(tenantIdentifierWithStorage, + StorageUtils.getEmailVerificationStorage(storage) + .addEmailVerificationToken(tenantIdentifier, new EmailVerificationTokenInfo(userId, hashedToken, System.currentTimeMillis() + - getEmailVerificationTokenLifetime(tenantIdentifierWithStorage, main), email)); + getEmailVerificationTokenLifetime(tenantIdentifier, main), email)); return token; } catch (DuplicateEmailVerificationTokenException ignored) { } @@ -119,23 +118,23 @@ public static User verifyEmail(Main main, String token) EmailVerificationInvalidTokenException, NoSuchAlgorithmException, StorageTransactionLogicException { try { Storage storage = StorageLayer.getStorage(main); - return verifyEmail(new TenantIdentifierWithStorage(null, null, null, storage), token); + return verifyEmail(new TenantIdentifier(null, null, null), storage, token); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static User verifyEmail(TenantIdentifierWithStorage tenantIdentifierWithStorage, String token) + public static User verifyEmail(TenantIdentifier tenantIdentifier, Storage storage, String token) throws StorageQueryException, EmailVerificationInvalidTokenException, NoSuchAlgorithmException, StorageTransactionLogicException, TenantOrAppNotFoundException { String hashedToken = getHashedToken(token); - EmailVerificationSQLStorage storage = tenantIdentifierWithStorage.getEmailVerificationStorage(); + EmailVerificationSQLStorage evStorage = StorageUtils.getEmailVerificationStorage(storage); - final EmailVerificationTokenInfo tokenInfo = storage.getEmailVerificationTokenInfo( - tenantIdentifierWithStorage, hashedToken); + final EmailVerificationTokenInfo tokenInfo = evStorage.getEmailVerificationTokenInfo( + tenantIdentifier, hashedToken); if (tokenInfo == null) { throw new EmailVerificationInvalidTokenException(); } @@ -143,10 +142,10 @@ public static User verifyEmail(TenantIdentifierWithStorage tenantIdentifierWithS final String userId = tokenInfo.userId; try { - return storage.startTransaction(con -> { + return evStorage.startTransaction(con -> { - EmailVerificationTokenInfo[] allTokens = storage - .getAllEmailVerificationTokenInfoForUser_Transaction(tenantIdentifierWithStorage, con, + EmailVerificationTokenInfo[] allTokens = evStorage + .getAllEmailVerificationTokenInfoForUser_Transaction(tenantIdentifier, con, userId, tokenInfo.email); EmailVerificationTokenInfo matchedToken = null; @@ -161,22 +160,22 @@ public static User verifyEmail(TenantIdentifierWithStorage tenantIdentifierWithS throw new StorageTransactionLogicException(new EmailVerificationInvalidTokenException()); } - storage.deleteAllEmailVerificationTokensForUser_Transaction(tenantIdentifierWithStorage, con, + evStorage.deleteAllEmailVerificationTokensForUser_Transaction(tenantIdentifier, con, userId, tokenInfo.email); if (matchedToken.tokenExpiry < System.currentTimeMillis()) { - storage.commitTransaction(con); + evStorage.commitTransaction(con); throw new StorageTransactionLogicException(new EmailVerificationInvalidTokenException()); } try { - storage.updateIsEmailVerified_Transaction(tenantIdentifierWithStorage.toAppIdentifier(), con, userId, + evStorage.updateIsEmailVerified_Transaction(tenantIdentifier.toAppIdentifier(), con, userId, tokenInfo.email, true); } catch (TenantOrAppNotFoundException e) { throw new StorageTransactionLogicException(e); } - storage.commitTransaction(con); + evStorage.commitTransaction(con); return new User(userId, tokenInfo.email); }); @@ -194,28 +193,28 @@ public static User verifyEmail(TenantIdentifierWithStorage tenantIdentifierWithS public static boolean isEmailVerified(Main main, String userId, String email) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - return isEmailVerified(new AppIdentifierWithStorage(null, null, storage), + return isEmailVerified(new AppIdentifier(null, null), storage, userId, email); } - public static boolean isEmailVerified(AppIdentifierWithStorage appIdentifierWithStorage, String userId, + public static boolean isEmailVerified(AppIdentifier appIdentifier, Storage storage, String userId, String email) throws StorageQueryException { - return appIdentifierWithStorage.getEmailVerificationStorage() - .isEmailVerified(appIdentifierWithStorage, userId, email); + return StorageUtils.getEmailVerificationStorage(storage) + .isEmailVerified(appIdentifier, userId, email); } @TestOnly public static void revokeAllTokens(Main main, String userId, String email) throws StorageQueryException { Storage storage = StorageLayer.getStorage(main); - revokeAllTokens(new TenantIdentifierWithStorage(null, null, null, storage), + revokeAllTokens(new TenantIdentifier(null, null, null), storage, userId, email); } - public static void revokeAllTokens(TenantIdentifierWithStorage tenantIdentifierWithStorage, String userId, + public static void revokeAllTokens(TenantIdentifier tenantIdentifier, Storage storage, String userId, String email) throws StorageQueryException { - tenantIdentifierWithStorage.getEmailVerificationStorage() - .revokeAllTokens(tenantIdentifierWithStorage, userId, email); + StorageUtils.getEmailVerificationStorage(storage) + .revokeAllTokens(tenantIdentifier, userId, email); } @TestOnly @@ -223,17 +222,16 @@ public static void unverifyEmail(Main main, String userId, String email) throws StorageQueryException { try { Storage storage = StorageLayer.getStorage(main); - unverifyEmail(new AppIdentifierWithStorage(null, null, storage), - userId, email); + unverifyEmail(new AppIdentifier(null, null), storage, userId, email); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static void unverifyEmail(AppIdentifierWithStorage appIdentifierWithStorage, String userId, + public static void unverifyEmail(AppIdentifier appIdentifier, Storage storage, String userId, String email) throws StorageQueryException, TenantOrAppNotFoundException { - appIdentifierWithStorage.getEmailVerificationStorage() - .unverifyEmail(appIdentifierWithStorage, userId, email); + StorageUtils.getEmailVerificationStorage(storage) + .unverifyEmail(appIdentifier, userId, email); } private static String getHashedToken(String token) throws NoSuchAlgorithmException { diff --git a/src/main/java/io/supertokens/webserver/api/emailverification/GenerateEmailVerificationTokenAPI.java b/src/main/java/io/supertokens/webserver/api/emailverification/GenerateEmailVerificationTokenAPI.java index eaee7d8c9..f7f3b8bfb 100644 --- a/src/main/java/io/supertokens/webserver/api/emailverification/GenerateEmailVerificationTokenAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailverification/GenerateEmailVerificationTokenAPI.java @@ -20,7 +20,8 @@ import io.supertokens.Main; import io.supertokens.emailverification.EmailVerification; import io.supertokens.emailverification.exception.EmailAlreadyVerifiedException; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; @@ -59,9 +60,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I assert email != null; email = Utils.normaliseEmail(email); - TenantIdentifierWithStorage tenantIdentifierWithStorage = null; + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage; try { - tenantIdentifierWithStorage = getTenantStorage(req); + storage = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } @@ -70,7 +72,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I // but then changed slightly when extracting this into its own recipe try { - String token = EmailVerification.generateEmailVerificationToken(tenantIdentifierWithStorage, super.main, + String token = EmailVerification.generateEmailVerificationToken(tenantIdentifier, storage, super.main, userId, email); JsonObject result = new JsonObject(); @@ -78,7 +80,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I result.addProperty("token", token); super.sendJsonResponse(200, result, resp); } catch (EmailAlreadyVerifiedException e) { - Logging.debug(main, tenantIdentifierWithStorage, Utils.exceptionStacktraceToString(e)); + Logging.debug(main, tenantIdentifier, Utils.exceptionStacktraceToString(e)); JsonObject result = new JsonObject(); result.addProperty("status", "EMAIL_ALREADY_VERIFIED_ERROR"); super.sendJsonResponse(200, result, resp); diff --git a/src/main/java/io/supertokens/webserver/api/emailverification/RevokeAllTokensForUserAPI.java b/src/main/java/io/supertokens/webserver/api/emailverification/RevokeAllTokensForUserAPI.java index b5de5e342..d61824d06 100644 --- a/src/main/java/io/supertokens/webserver/api/emailverification/RevokeAllTokensForUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailverification/RevokeAllTokensForUserAPI.java @@ -52,7 +52,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I email = Utils.normaliseEmail(email); try { - EmailVerification.revokeAllTokens(this.getTenantStorage(req), userId, email); + EmailVerification.revokeAllTokens(getTenantIdentifier(req), getTenantStorage(req), userId, email); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java b/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java index 7eb92e42f..454936944 100644 --- a/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java @@ -17,12 +17,13 @@ package io.supertokens.webserver.api.emailverification; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.emailverification.EmailVerification; import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -57,15 +58,16 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I email = Utils.normaliseEmail(email); try { - AppIdentifierWithStorage appIdentifierWithStorage; + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage; try { - AppIdentifierWithStorageAndUserIdMapping storageAndUidMapping = getStorageAndUserIdMappingForAppSpecificApi( + StorageAndUserIdMapping storageAndUidMapping = getStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); - appIdentifierWithStorage = storageAndUidMapping.appIdentifierWithStorage; + storage = storageAndUidMapping.storage; } catch (UnknownUserIdException e) { - appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); + storage = enforcePublicTenantAndGetPublicTenantStorage(req); } - EmailVerification.unverifyEmail(appIdentifierWithStorage, userId, email); + EmailVerification.unverifyEmail(appIdentifier, storage, userId, email); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java b/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java index 1eefac604..ecc08be38 100644 --- a/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java @@ -17,15 +17,16 @@ package io.supertokens.webserver.api.emailverification; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.emailverification.EmailVerification; import io.supertokens.emailverification.User; import io.supertokens.emailverification.exception.EmailVerificationInvalidTokenException; import io.supertokens.multitenancy.exception.BadPermissionException; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.RECIPE_ID; @@ -70,15 +71,16 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I throw new ServletException(new BadRequestException("Unsupported method for email verification")); } - TenantIdentifierWithStorage tenantIdentifierWithStorage = null; + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage; try { - tenantIdentifierWithStorage = this.getTenantStorage(req); + storage = this.getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } try { - User user = EmailVerification.verifyEmail(tenantIdentifierWithStorage, token); + User user = EmailVerification.verifyEmail(tenantIdentifier, storage, token); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); @@ -87,7 +89,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I super.sendJsonResponse(200, result, resp); } catch (EmailVerificationInvalidTokenException e) { - Logging.debug(main, tenantIdentifierWithStorage, Utils.exceptionStacktraceToString(e)); + Logging.debug(main, tenantIdentifier, Utils.exceptionStacktraceToString(e)); JsonObject result = new JsonObject(); result.addProperty("status", "EMAIL_VERIFICATION_INVALID_TOKEN_ERROR"); super.sendJsonResponse(200, result, resp); @@ -106,16 +108,16 @@ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws Servl assert email != null; try { - AppIdentifierWithStorage appIdentifierWithStorage; + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage; try { - AppIdentifierWithStorageAndUserIdMapping storageAndUidMapping = getStorageAndUserIdMappingForAppSpecificApi( + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); - appIdentifierWithStorage = storageAndUidMapping.appIdentifierWithStorage; + storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { - appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); + storage = enforcePublicTenantAndGetPublicTenantStorage(req); } - boolean isVerified = EmailVerification.isEmailVerified(appIdentifierWithStorage, userId, - email); + boolean isVerified = EmailVerification.isEmailVerified(appIdentifier, storage, userId, email); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); From c61c7d76d91440c00c685d6935e01f53fddaddcd Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 1 Mar 2024 16:42:42 +0530 Subject: [PATCH 12/31] fix: multitenancy and other minor fixes --- .../multitenancy/Multitenancy.java | 30 ++++++++++--------- .../io/supertokens/webserver/Webserver.java | 3 +- .../webserver/api/jwt/JWKSAPI.java | 3 +- .../webserver/api/jwt/JWTSigningAPI.java | 3 +- .../AssociateUserToTenantAPI.java | 13 ++++---- .../multitenancy/CreateOrUpdateAppAPI.java | 5 ++-- .../CreateOrUpdateConnectionUriDomainAPI.java | 4 +-- .../CreateOrUpdateTenantOrGetTenantAPI.java | 8 ++--- .../DisassociateUserFromTenant.java | 11 +++---- .../api/multitenancy/ListAppsAPI.java | 14 ++++----- .../ListConnectionUriDomainsAPI.java | 10 +++---- .../api/multitenancy/ListTenantsAPI.java | 12 ++++---- .../api/multitenancy/RemoveAppAPI.java | 3 +- .../RemoveConnectionUriDomainAPI.java | 3 +- .../api/multitenancy/RemoveTenantAPI.java | 3 +- .../CreateOrUpdateThirdPartyConfigAPI.java | 2 +- .../thirdparty/RemoveThirdPartyConfigAPI.java | 5 ++-- .../webserver/api/totp/VerifyTotpAPI.java | 2 -- .../api/totp/VerifyTotpDeviceAPI.java | 2 -- 19 files changed, 71 insertions(+), 65 deletions(-) diff --git a/src/main/java/io/supertokens/multitenancy/Multitenancy.java b/src/main/java/io/supertokens/multitenancy/Multitenancy.java index e97d3edf1..15666cc21 100644 --- a/src/main/java/io/supertokens/multitenancy/Multitenancy.java +++ b/src/main/java/io/supertokens/multitenancy/Multitenancy.java @@ -28,6 +28,8 @@ import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.multitenancy.exception.*; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.authRecipe.LoginMethod; import io.supertokens.pluginInterface.authRecipe.sqlStorage.AuthRecipeSQLStorage; @@ -387,7 +389,7 @@ public static boolean deleteConnectionUriDomain(String connectionUriDomain, Main return didExist; } - public static boolean addUserIdToTenant(Main main, TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static boolean addUserIdToTenant(Main main, TenantIdentifier tenantIdentifier, Storage storage, String userId) throws TenantOrAppNotFoundException, UnknownUserIdException, StorageQueryException, FeatureNotEnabledException, DuplicateEmailException, DuplicatePhoneNumberException, @@ -399,11 +401,11 @@ public static boolean addUserIdToTenant(Main main, TenantIdentifierWithStorage t throw new FeatureNotEnabledException(EE_FEATURES.MULTI_TENANCY); } - AuthRecipeSQLStorage storage = (AuthRecipeSQLStorage) tenantIdentifierWithStorage.getAuthRecipeStorage(); + AuthRecipeSQLStorage authRecipeStorage = StorageUtils.getAuthRecipeStorage(storage); try { - return storage.startTransaction(con -> { - String tenantId = tenantIdentifierWithStorage.getTenantId(); - AuthRecipeUserInfo userToAssociate = storage.getPrimaryUserById_Transaction(tenantIdentifierWithStorage.toAppIdentifier(), con, userId); + return authRecipeStorage.startTransaction(con -> { + String tenantId = tenantIdentifier.getTenantId(); + AuthRecipeUserInfo userToAssociate = authRecipeStorage.getPrimaryUserById_Transaction(tenantIdentifier.toAppIdentifier(), con, userId); if (userToAssociate != null && userToAssociate.isPrimaryUser) { Set emails = new HashSet<>(); @@ -424,7 +426,7 @@ public static boolean addUserIdToTenant(Main main, TenantIdentifierWithStorage t } for (String email : emails) { - AuthRecipeUserInfo[] usersWithSameEmail = storage.listPrimaryUsersByEmail_Transaction(tenantIdentifierWithStorage.toAppIdentifier(), con, email); + AuthRecipeUserInfo[] usersWithSameEmail = authRecipeStorage.listPrimaryUsersByEmail_Transaction(tenantIdentifier.toAppIdentifier(), con, email); for (AuthRecipeUserInfo userWithSameEmail : usersWithSameEmail) { if (userWithSameEmail.getSupertokensUserId().equals(userToAssociate.getSupertokensUserId())) { continue; // it's the same user, no need to check anything @@ -445,7 +447,7 @@ public static boolean addUserIdToTenant(Main main, TenantIdentifierWithStorage t } for (String phoneNumber : phoneNumbers) { - AuthRecipeUserInfo[] usersWithSamePhoneNumber = storage.listPrimaryUsersByPhoneNumber_Transaction(tenantIdentifierWithStorage.toAppIdentifier(), con, phoneNumber); + AuthRecipeUserInfo[] usersWithSamePhoneNumber = authRecipeStorage.listPrimaryUsersByPhoneNumber_Transaction(tenantIdentifier.toAppIdentifier(), con, phoneNumber); for (AuthRecipeUserInfo userWithSamePhoneNumber : usersWithSamePhoneNumber) { if (userWithSamePhoneNumber.getSupertokensUserId().equals(userToAssociate.getSupertokensUserId())) { continue; // it's the same user, no need to check anything @@ -466,7 +468,7 @@ public static boolean addUserIdToTenant(Main main, TenantIdentifierWithStorage t } for (LoginMethod.ThirdParty tp : thirdParties) { - AuthRecipeUserInfo[] usersWithSameThirdPartyInfo = storage.listPrimaryUsersByThirdPartyInfo_Transaction(tenantIdentifierWithStorage.toAppIdentifier(), con, tp.id, tp.userId); + AuthRecipeUserInfo[] usersWithSameThirdPartyInfo = authRecipeStorage.listPrimaryUsersByThirdPartyInfo_Transaction(tenantIdentifier.toAppIdentifier(), con, tp.id, tp.userId); for (AuthRecipeUserInfo userWithSameThirdPartyInfo : usersWithSameThirdPartyInfo) { if (userWithSameThirdPartyInfo.getSupertokensUserId().equals(userToAssociate.getSupertokensUserId())) { continue; // it's the same user, no need to check anything @@ -492,8 +494,8 @@ public static boolean addUserIdToTenant(Main main, TenantIdentifierWithStorage t // associate it. This happens only in CDI 3.0 where we allow disassociation from all tenants // This will not happen in CDI >= 4.0 because we will not allow disassociation from all tenants try { - boolean result = ((MultitenancySQLStorage) storage).addUserIdToTenant_Transaction(tenantIdentifierWithStorage, con, userId); - storage.commitTransaction(con); + boolean result = ((MultitenancySQLStorage) storage).addUserIdToTenant_Transaction(tenantIdentifier, con, userId); + authRecipeStorage.commitTransaction(con); return result; } catch (TenantOrAppNotFoundException | UnknownUserIdException | DuplicatePhoneNumberException | DuplicateThirdPartyUserException | DuplicateEmailException e) { @@ -522,7 +524,7 @@ public static boolean addUserIdToTenant(Main main, TenantIdentifierWithStorage t } } - public static boolean removeUserIdFromTenant(Main main, TenantIdentifierWithStorage tenantIdentifierWithStorage, + public static boolean removeUserIdFromTenant(Main main, TenantIdentifier tenantIdentifier, Storage storage, String userId, String externalUserId) throws FeatureNotEnabledException, TenantOrAppNotFoundException, StorageQueryException, UnknownUserIdException { @@ -532,12 +534,12 @@ public static boolean removeUserIdFromTenant(Main main, TenantIdentifierWithStor } boolean finalDidExist = false; - boolean didExist = AuthRecipe.deleteNonAuthRecipeUser(tenantIdentifierWithStorage, + boolean didExist = AuthRecipe.deleteNonAuthRecipeUser(tenantIdentifier, storage, externalUserId == null ? userId : externalUserId); finalDidExist = finalDidExist || didExist; - didExist = tenantIdentifierWithStorage.getMultitenancyStorageWithTargetStorage() - .removeUserIdFromTenant(tenantIdentifierWithStorage, userId); + didExist = StorageUtils.getMultitenancyStorage(storage) + .removeUserIdFromTenant(tenantIdentifier, userId); finalDidExist = finalDidExist || didExist; return finalDidExist; diff --git a/src/main/java/io/supertokens/webserver/Webserver.java b/src/main/java/io/supertokens/webserver/Webserver.java index 8763843e2..104121d72 100644 --- a/src/main/java/io/supertokens/webserver/Webserver.java +++ b/src/main/java/io/supertokens/webserver/Webserver.java @@ -24,7 +24,6 @@ import io.supertokens.exceptions.QuitProgramException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.webserver.api.accountlinking.*; import io.supertokens.webserver.api.core.*; @@ -144,7 +143,7 @@ public void start() { tomcat.start(); } catch (LifecycleException e) { // reusing same port OR not right permissions given. - Logging.error(main, TenantIdentifierWithStorage.BASE_TENANT, null, false, e); + Logging.error(main, TenantIdentifier.BASE_TENANT, null, false, e); throw new QuitProgramException( "Error while starting webserver. Possible reasons:\n- Another instance of SuperTokens is already " + "running on the same port. If you want to run another instance, please pass a new config " diff --git a/src/main/java/io/supertokens/webserver/api/jwt/JWKSAPI.java b/src/main/java/io/supertokens/webserver/api/jwt/JWKSAPI.java index 49b197e45..cd686c401 100644 --- a/src/main/java/io/supertokens/webserver/api/jwt/JWKSAPI.java +++ b/src/main/java/io/supertokens/webserver/api/jwt/JWKSAPI.java @@ -55,7 +55,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific try { - List jwks = SigningKeys.getInstance(this.enforcePublicTenantAndGetPublicTenantStorage(req), main).getJWKS(); + enforcePublicTenantAndGetPublicTenantStorage(req); + List jwks = SigningKeys.getInstance(getAppIdentifier(req), main).getJWKS(); JsonObject reply = new JsonObject(); JsonArray jwksJsonArray = new JsonParser().parse(new Gson().toJson(jwks)).getAsJsonArray(); reply.add("keys", jwksJsonArray); diff --git a/src/main/java/io/supertokens/webserver/api/jwt/JWTSigningAPI.java b/src/main/java/io/supertokens/webserver/api/jwt/JWTSigningAPI.java index 464b01926..778a68654 100644 --- a/src/main/java/io/supertokens/webserver/api/jwt/JWTSigningAPI.java +++ b/src/main/java/io/supertokens/webserver/api/jwt/JWTSigningAPI.java @@ -79,7 +79,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - String jwt = JWTSigningFunctions.createJWTToken(this.enforcePublicTenantAndGetPublicTenantStorage(req), main, + this.enforcePublicTenantAndGetPublicTenantStorage(req); + String jwt = JWTSigningFunctions.createJWTToken(getAppIdentifier(req), main, algorithm.toUpperCase(), payload, jwksDomain, validity, useDynamicKey); JsonObject reply = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/AssociateUserToTenantAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/AssociateUserToTenantAPI.java index 5cd0efa99..1891aeebe 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/AssociateUserToTenantAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/AssociateUserToTenantAPI.java @@ -17,19 +17,18 @@ package io.supertokens.webserver.api.multitenancy; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.multitenancy.Multitenancy; import io.supertokens.multitenancy.exception.AnotherPrimaryUserWithEmailAlreadyExistsException; import io.supertokens.multitenancy.exception.AnotherPrimaryUserWithPhoneNumberAlreadyExistsException; import io.supertokens.multitenancy.exception.AnotherPrimaryUserWithThirdPartyInfoAlreadyExistsException; -import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.passwordless.exception.DuplicatePhoneNumberException; import io.supertokens.pluginInterface.thirdparty.exception.DuplicateThirdPartyUserException; @@ -76,15 +75,17 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - AppIdentifierWithStorage appIdentifierWithStorage = getTenantStorage(req).toAppIdentifierWithStorage(); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); + io.supertokens.pluginInterface.useridmapping.UserIdMapping mapping = UserIdMapping.getUserIdMapping( - appIdentifierWithStorage, userId, UserIdType.ANY); + tenantIdentifier.toAppIdentifier(), storage, userId, UserIdType.ANY); if (mapping != null) { userId = mapping.superTokensUserId; } boolean addedToTenant = Multitenancy.addUserIdToTenant(main, - getTenantStorage(req), userId); + tenantIdentifier, storage, userId); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java index fdfe474de..92c514126 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java @@ -54,9 +54,10 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO Boolean passwordlessEnabled = InputParser.parseBooleanOrThrowError(input, "passwordlessEnabled", true); JsonObject coreConfig = InputParser.parseJsonObjectOrThrowError(input, "coreConfig", true); - TenantIdentifier sourceTenantIdentifier; + TenantIdentifier sourceTenantIdentifier = getTenantIdentifier(req); + try { - sourceTenantIdentifier = this.getTenantStorage(req); + getTenantStorage(req); // ensure source tenant exists } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java index 1e28287ab..553bb5cc1 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java @@ -54,9 +54,9 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO Boolean passwordlessEnabled = InputParser.parseBooleanOrThrowError(input, "passwordlessEnabled", true); JsonObject coreConfig = InputParser.parseJsonObjectOrThrowError(input, "coreConfig", true); - TenantIdentifier sourceTenantIdentifier; + TenantIdentifier sourceTenantIdentifier = getTenantIdentifier(req); try { - sourceTenantIdentifier = this.getTenantStorage(req); + this.getTenantStorage(req); // ensure source tenant exists } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java index 3e193398a..c75eb0380 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java @@ -57,9 +57,9 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO Boolean passwordlessEnabled = InputParser.parseBooleanOrThrowError(input, "passwordlessEnabled", true); JsonObject coreConfig = InputParser.parseJsonObjectOrThrowError(input, "coreConfig", true); - TenantIdentifier sourceTenantIdentifier; + TenantIdentifier sourceTenantIdentifier = getTenantIdentifier(req); try { - sourceTenantIdentifier = this.getTenantStorage(req); + this.getTenantStorage(req); // ensure source tenant exists } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } @@ -74,13 +74,13 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { try { - TenantIdentifierWithStorage tenantIdentifier = this.getTenantStorage(req); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifier); if (config == null) { throw new TenantOrAppNotFoundException(tenantIdentifier); } boolean shouldProtect = shouldProtectProtectedConfig(req); - JsonObject result = config.toJson(shouldProtect, tenantIdentifier.getStorage(), CoreConfig.PROTECTED_CONFIGS); + JsonObject result = config.toJson(shouldProtect, getTenantStorage(req), CoreConfig.PROTECTED_CONFIGS); result.addProperty("status", "OK"); super.sendJsonResponse(200, result, resp); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/DisassociateUserFromTenant.java b/src/main/java/io/supertokens/webserver/api/multitenancy/DisassociateUserFromTenant.java index 17a55c88a..7f28a1d56 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/DisassociateUserFromTenant.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/DisassociateUserFromTenant.java @@ -17,14 +17,14 @@ package io.supertokens.webserver.api.multitenancy; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.multitenancy.Multitenancy; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; @@ -68,17 +68,18 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); String externalUserId = null; - AppIdentifierWithStorage appIdentifierWithStorage = getTenantStorage(req).toAppIdentifierWithStorage(); io.supertokens.pluginInterface.useridmapping.UserIdMapping mapping = UserIdMapping.getUserIdMapping( - appIdentifierWithStorage, userId, UserIdType.ANY); + tenantIdentifier.toAppIdentifier(), storage, userId, UserIdType.ANY); if (mapping != null) { userId = mapping.superTokensUserId; externalUserId = mapping.externalUserId; } boolean wasAssociated = Multitenancy.removeUserIdFromTenant(main, - getTenantStorage(req), userId, externalUserId); + tenantIdentifier, storage, userId, externalUserId); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/ListAppsAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/ListAppsAPI.java index b8966b1b9..823873e14 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/ListAppsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/ListAppsAPI.java @@ -23,9 +23,9 @@ import io.supertokens.multitenancy.Multitenancy; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.multitenancy.TenantConfig; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.webserver.WebserverAPI; import jakarta.servlet.ServletException; @@ -52,18 +52,18 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - TenantIdentifierWithStorage tenantIdentifierWithStorage; + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); try { - tenantIdentifierWithStorage = this.getTenantStorage(req); + Storage storage = this.getTenantStorage(req); - if (!tenantIdentifierWithStorage.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID) - || !tenantIdentifierWithStorage.getAppId().equals(TenantIdentifier.DEFAULT_APP_ID)) { + if (!tenantIdentifier.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID) + || !tenantIdentifier.getAppId().equals(TenantIdentifier.DEFAULT_APP_ID)) { throw new BadPermissionException("Only the public tenantId and public appId is allowed to list " + "all apps associated with this connection uri domain"); } TenantConfig[] tenantConfigs = Multitenancy.getAllAppsAndTenantsForConnectionUriDomain( - tenantIdentifierWithStorage.getConnectionUriDomain(), main); + tenantIdentifier.getConnectionUriDomain(), main); Map> appsToTenants = new HashMap<>(); for (TenantConfig tenantConfig : tenantConfigs) { @@ -82,7 +82,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO JsonArray tenantsArray = new JsonArray(); for (TenantConfig tenantConfig : entry.getValue()) { JsonObject tenantConfigJson = tenantConfig.toJson(shouldProtect, - tenantIdentifierWithStorage.getStorage(), CoreConfig.PROTECTED_CONFIGS); + storage, CoreConfig.PROTECTED_CONFIGS); tenantsArray.add(tenantConfigJson); } appObject.add("tenants", tenantsArray); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/ListConnectionUriDomainsAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/ListConnectionUriDomainsAPI.java index 29551e3c5..076880827 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/ListConnectionUriDomainsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/ListConnectionUriDomainsAPI.java @@ -23,9 +23,9 @@ import io.supertokens.multitenancy.Multitenancy; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.multitenancy.TenantConfig; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.webserver.WebserverAPI; import jakarta.servlet.ServletException; @@ -52,11 +52,11 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - TenantIdentifierWithStorage tenantIdentifierWithStorage; try { - tenantIdentifierWithStorage = this.getTenantStorage(req); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = this.getTenantStorage(req); - if (!tenantIdentifierWithStorage.equals(new TenantIdentifier(null, null, null))) { + if (!tenantIdentifier.equals(new TenantIdentifier(null, null, null))) { throw new BadPermissionException( "Only the public tenantId, public appId and default connectionUriDomain is allowed to list all " + "connectionUriDomains and appIds associated with this " + @@ -95,7 +95,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO JsonArray tenantsArray = new JsonArray(); for (TenantConfig tenantConfig : entry2.getValue()) { JsonObject tenantConfigJson = tenantConfig.toJson(shouldProtect, - tenantIdentifierWithStorage.getStorage(), CoreConfig.PROTECTED_CONFIGS); + storage, CoreConfig.PROTECTED_CONFIGS); tenantsArray.add(tenantConfigJson); } appObject.add("tenants", tenantsArray); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/ListTenantsAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/ListTenantsAPI.java index f72c9421d..b2fe19ef6 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/ListTenantsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/ListTenantsAPI.java @@ -23,9 +23,9 @@ import io.supertokens.multitenancy.Multitenancy; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.multitenancy.TenantConfig; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.webserver.WebserverAPI; import jakarta.servlet.ServletException; @@ -48,22 +48,22 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - TenantIdentifierWithStorage tenantIdentifierWithStorage; try { - tenantIdentifierWithStorage = this.getTenantStorage(req); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); - if (!tenantIdentifierWithStorage.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID)) { + if (!tenantIdentifier.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID)) { throw new BadPermissionException("Only the public tenantId is allowed to list all tenants " + "associated with this app"); } - TenantConfig[] tenantConfigs = Multitenancy.getAllTenantsForApp(tenantIdentifierWithStorage.toAppIdentifier(), main); + TenantConfig[] tenantConfigs = Multitenancy.getAllTenantsForApp(tenantIdentifier.toAppIdentifier(), main); JsonArray tenantsArray = new JsonArray(); boolean shouldProtect = shouldProtectProtectedConfig(req); for (TenantConfig tenantConfig : tenantConfigs) { JsonObject tenantConfigJson = tenantConfig.toJson(shouldProtect, - tenantIdentifierWithStorage.getStorage(), CoreConfig.PROTECTED_CONFIGS); + storage, CoreConfig.PROTECTED_CONFIGS); tenantsArray.add(tenantConfigJson); } diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java index 321d97779..8d413070a 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java @@ -59,7 +59,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - TenantIdentifier sourceTenantIdentifier = this.getTenantStorage(req); + TenantIdentifier sourceTenantIdentifier = this.getTenantIdentifier(req); + getTenantStorage(req); // ensure the tenant exists if (!sourceTenantIdentifier.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID) || !sourceTenantIdentifier.getAppId().equals(TenantIdentifier.DEFAULT_APP_ID)) { throw new BadPermissionException("Only the public tenantId and public appId is allowed to delete an app"); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java index 275e82dd7..e507b9156 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java @@ -58,7 +58,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - TenantIdentifier sourceTenantIdentifier = this.getTenantStorage(req); + TenantIdentifier sourceTenantIdentifier = this.getTenantIdentifier(req); + getTenantStorage(req); // ensure tenant exists if (!sourceTenantIdentifier.equals(new TenantIdentifier(null, null, null))) { throw new BadPermissionException( "Only the public tenantId, public appId and default connectionUriDomain is allowed to delete a connectionUriDomain"); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveTenantAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveTenantAPI.java index 06446f647..e2f3da76b 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveTenantAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveTenantAPI.java @@ -58,7 +58,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - TenantIdentifier sourceTenantIdentifier = this.getTenantStorage(req); + TenantIdentifier sourceTenantIdentifier = this.getTenantIdentifier(req); + getTenantStorage(req); // ensure the tenant exists if (!sourceTenantIdentifier.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID)) { throw new BadPermissionException("Only the public tenantId is allowed to delete a tenant"); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/CreateOrUpdateThirdPartyConfigAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/CreateOrUpdateThirdPartyConfigAPI.java index 2b4e9a146..18eff9b7c 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/CreateOrUpdateThirdPartyConfigAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/CreateOrUpdateThirdPartyConfigAPI.java @@ -70,7 +70,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO } try { - TenantIdentifierWithStorage tenantIdentifier = this.getTenantStorage(req); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); if (!tenantIdentifier.equals(TenantIdentifier.BASE_TENANT)) { if (Arrays.stream(FeatureFlag.getInstance(main, new AppIdentifier(null, null)).getEnabledFeatures()) diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/RemoveThirdPartyConfigAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/RemoveThirdPartyConfigAPI.java index f5a371c6c..3fe12ea24 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/RemoveThirdPartyConfigAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/thirdparty/RemoveThirdPartyConfigAPI.java @@ -26,7 +26,7 @@ import io.supertokens.pluginInterface.exceptions.InvalidConfigException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.TenantConfig; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.ThirdPartyConfig; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.thirdparty.InvalidProviderConfigException; @@ -59,7 +59,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I thirdPartyId = thirdPartyId.trim(); try { - TenantIdentifierWithStorage tenantIdentifier = this.getTenantStorage(req); + TenantIdentifier tenantIdentifier = this.getTenantIdentifier(req); + TenantConfig config = Multitenancy.getTenantInfo(main, tenantIdentifier); if (config == null) { throw new TenantOrAppNotFoundException(tenantIdentifier); diff --git a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java index 0653f03d3..46adb2cc8 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java @@ -6,7 +6,6 @@ import io.supertokens.Main; import io.supertokens.StorageAndUserIdMapping; -import io.supertokens.TenantIdentifierWithStorageAndUserIdMapping; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.Storage; @@ -14,7 +13,6 @@ import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException; import io.supertokens.totp.Totp; diff --git a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java index b4bf1eb8b..3728119cf 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java @@ -6,14 +6,12 @@ import io.supertokens.Main; import io.supertokens.StorageAndUserIdMapping; -import io.supertokens.TenantIdentifierWithStorageAndUserIdMapping; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException; import io.supertokens.pluginInterface.totp.exception.UnknownDeviceException; From c1edaba015f78f82cb7e59e1fbd181bcfb9b9095 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 1 Mar 2024 18:02:14 +0530 Subject: [PATCH 13/31] fix: compile errors --- .../io/supertokens/test/FeatureFlagTest.java | 31 +-- .../accountlinking/CreatePrimaryUserTest.java | 19 +- .../GetUserByAccountInfoTest.java | 148 +++++++++----- .../test/accountlinking/LinkAccountsTest.java | 17 +- .../test/accountlinking/MultitenantTest.java | 190 +++++++++++------- .../test/accountlinking/SessionTests.java | 111 +++++----- .../test/accountlinking/TimeJoinedTest.java | 36 ++-- .../api/CreatePrimaryUserAPITest.java | 5 +- .../api/GetUserByAccountInfoTest.java | 16 -- .../test/accountlinking/api/SessionTests.java | 16 -- .../test/authRecipe/MultitenantAPITest.java | 40 ++-- .../test/authRecipe/UserPaginationTest.java | 16 +- .../dashboard/apis/MultitenantAPITest.java | 6 +- .../test/emailpassword/EmailPasswordTest.java | 23 ++- .../MultitenantEmailPasswordTest.java | 137 +++++++------ .../emailpassword/api/MultitenantAPITest.java | 2 +- .../test/multitenant/AppTenantUserTest.java | 37 ++-- .../test/multitenant/TestAppData.java | 53 ++--- .../test/multitenant/api/TestApp.java | 3 +- .../api/TestConnectionUriDomain.java | 3 +- .../test/multitenant/api/TestTenant.java | 3 +- .../TestTenantIdIsNotPresentForOlderCDI.java | 15 +- .../api/TestTenantUserAssociation.java | 91 +++++---- .../api/TestWithNonAuthRecipes.java | 25 ++- .../test/totp/api/MultitenantAPITest.java | 2 +- 25 files changed, 595 insertions(+), 450 deletions(-) diff --git a/src/test/java/io/supertokens/test/FeatureFlagTest.java b/src/test/java/io/supertokens/test/FeatureFlagTest.java index b8ba04caf..d6d324a13 100644 --- a/src/test/java/io/supertokens/test/FeatureFlagTest.java +++ b/src/test/java/io/supertokens/test/FeatureFlagTest.java @@ -21,10 +21,6 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import io.supertokens.ProcessState; -import io.supertokens.cronjobs.CronTask; -import io.supertokens.cronjobs.CronTaskTest; -import io.supertokens.cronjobs.Cronjobs; -import io.supertokens.cronjobs.syncCoreConfigWithDb.SyncCoreConfigWithDb; import io.supertokens.emailpassword.EmailPassword; import io.supertokens.featureflag.EE_FEATURES; import io.supertokens.featureflag.FeatureFlag; @@ -32,9 +28,8 @@ import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.featureflag.exceptions.NoLicenseKeyFoundException; import io.supertokens.multitenancy.Multitenancy; -import io.supertokens.multitenancy.MultitenancyHelper; import io.supertokens.pluginInterface.STORAGE_TYPE; -import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.*; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; @@ -362,15 +357,17 @@ public void testThatMultitenantStatsAreAccurate() throws Exception { ) ); - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage( + Storage tenantIdentifierWithStorage = ( StorageLayer.getStorage(tenantIdentifier, process.getProcess())); if (i % 3 == 0) { // Create a user EmailPassword.signUp( - tenantIdentifierWithStorage, process.getProcess(), "user@example.com", "password"); + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "user@example.com", + "password"); } else if (i % 3 == 1) { // Create a session - Session.createNewSession(tenantIdentifierWithStorage, process.getProcess(), "userid", new JsonObject(), + Session.createNewSession( + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "userid", new JsonObject(), new JsonObject()); } else { // Create an enterprise provider @@ -479,15 +476,17 @@ public void testThatMultitenantStatsAreAccurateForAnApp() throws Exception { ) ); - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage( + Storage tenantIdentifierWithStorage = ( StorageLayer.getStorage(tenantIdentifier, process.getProcess())); if (i % 3 == 0) { // Create a user EmailPassword.signUp( - tenantIdentifierWithStorage, process.getProcess(), "user@example.com", "password"); + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "user@example.com", + "password"); } else if (i % 3 == 1) { // Create a session - Session.createNewSession(tenantIdentifierWithStorage, process.getProcess(), "userid", new JsonObject(), + Session.createNewSession( + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "userid", new JsonObject(), new JsonObject()); } else { // Create an enterprise provider @@ -606,15 +605,17 @@ public void testThatMultitenantStatsAreAccurateForACud() throws Exception { ) ); - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage( + Storage tenantIdentifierWithStorage = ( StorageLayer.getStorage(tenantIdentifier, process.getProcess())); if (i % 3 == 0) { // Create a user EmailPassword.signUp( - tenantIdentifierWithStorage, process.getProcess(), "user@example.com", "password"); + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "user@example.com", + "password"); } else if (i % 3 == 1) { // Create a session - Session.createNewSession(tenantIdentifierWithStorage, process.getProcess(), "userid", new JsonObject(), + Session.createNewSession( + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "userid", new JsonObject(), new JsonObject()); } else { // Create an enterprise provider diff --git a/src/test/java/io/supertokens/test/accountlinking/CreatePrimaryUserTest.java b/src/test/java/io/supertokens/test/accountlinking/CreatePrimaryUserTest.java index 5614de91d..72b15214e 100644 --- a/src/test/java/io/supertokens/test/accountlinking/CreatePrimaryUserTest.java +++ b/src/test/java/io/supertokens/test/accountlinking/CreatePrimaryUserTest.java @@ -29,6 +29,7 @@ import io.supertokens.passwordless.Passwordless; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.multitenancy.*; @@ -137,7 +138,7 @@ public void testThatCreationOfPrimaryUserRequiresAccountLinkingFeatureToBeEnable try { AuthRecipe.createPrimaryUser(process.main, - new AppIdentifierWithStorage(null, null, StorageLayer.getStorage(process.main)), ""); + new AppIdentifier(null, null), StorageLayer.getStorage(process.main), ""); assert (false); } catch (FeatureNotEnabledException e) { assert (e.getMessage() @@ -424,9 +425,9 @@ public void makePrimaryUserFailsCauseAnotherAccountWithSameEmailAlreadyAPrimaryU new ThirdPartyConfig(true, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(true), new JsonObject())); - TenantIdentifierWithStorage tenantIdentifierWithStorage = new TenantIdentifierWithStorage(null, null, "t1", - StorageLayer.getStorage(process.main)); - AuthRecipeUserInfo emailPasswordUser = EmailPassword.signUp(tenantIdentifierWithStorage, process.getProcess(), + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(process.main)); + AuthRecipeUserInfo emailPasswordUser = EmailPassword.signUp(new TenantIdentifier(null, null, "t1"), + tenantIdentifierWithStorage, process.getProcess(), "test@example.com", "pass1234"); @@ -436,7 +437,9 @@ public void makePrimaryUserFailsCauseAnotherAccountWithSameEmailAlreadyAPrimaryU ThirdParty.SignInUpResponse signInUpResponse = ThirdParty.signInUp(process.main, "google", "user-google", "test@example.com"); - Multitenancy.addUserIdToTenant(process.main, tenantIdentifierWithStorage, signInUpResponse.user.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.main, new TenantIdentifier(null, null, "t1"), + tenantIdentifierWithStorage, + signInUpResponse.user.getSupertokensUserId()); try { AuthRecipe.createPrimaryUser(process.main, signInUpResponse.user.getSupertokensUserId()); @@ -470,9 +473,9 @@ public void makePrimarySucceedsEvenIfAnotherAccountWithSameEmailButInADifferentT new ThirdPartyConfig(true, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(true), new JsonObject())); - TenantIdentifierWithStorage tenantIdentifierWithStorage = new TenantIdentifierWithStorage(null, null, "t1", - StorageLayer.getStorage(process.main)); - AuthRecipeUserInfo emailPasswordUser = EmailPassword.signUp(tenantIdentifierWithStorage, process.getProcess(), + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(process.main)); + AuthRecipeUserInfo emailPasswordUser = EmailPassword.signUp(new TenantIdentifier(null, null, "t1"), + tenantIdentifierWithStorage, process.getProcess(), "test@example.com", "pass1234"); diff --git a/src/test/java/io/supertokens/test/accountlinking/GetUserByAccountInfoTest.java b/src/test/java/io/supertokens/test/accountlinking/GetUserByAccountInfoTest.java index ca1cb8d1d..59afa63d8 100644 --- a/src/test/java/io/supertokens/test/accountlinking/GetUserByAccountInfoTest.java +++ b/src/test/java/io/supertokens/test/accountlinking/GetUserByAccountInfoTest.java @@ -27,12 +27,12 @@ import io.supertokens.passwordless.exceptions.*; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.passwordless.exception.DuplicateLinkCodeHashException; import io.supertokens.storageLayer.StorageLayer; import io.supertokens.test.TestingProcessManager; @@ -114,9 +114,10 @@ public void testListUsersByAccountInfoForUnlinkedAccounts() throws Exception { AuthRecipeUserInfo user3 = createPasswordlessUserWithEmail(process.getProcess(), "test3@example.com"); AuthRecipeUserInfo user4 = createPasswordlessUserWithPhone(process.getProcess(), "+919876543210"); - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage(StorageLayer.getBaseStorage(process.getProcess())); + Storage tenantIdentifierWithStorage = (StorageLayer.getBaseStorage(process.getProcess())); - AuthRecipeUserInfo userToTest = AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + AuthRecipeUserInfo userToTest = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test1@example.com", null, null, null)[0]; assertNotNull(userToTest.getSupertokensUserId()); assertFalse(userToTest.isPrimaryUser); @@ -128,19 +129,30 @@ public void testListUsersByAccountInfoForUnlinkedAccounts() throws Exception { assert(userToTest.loginMethods[0].timeJoined > 0); // test for result - assertEquals(user1, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, "test1@example.com", null, null, null)[0]); - assertEquals(user2, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, null, null, "google", "userid1")[0]); - assertEquals(user2, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, "test2@example.com", null, "google", "userid1")[0]); - assertEquals(user3, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, "test3@example.com", null, null, null)[0]); - assertEquals(user4, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, null, "+919876543210", null, null)[0]); + assertEquals(user1, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage + , false, "test1@example.com", null, null, null)[0]); + assertEquals(user2, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage + , false, null, null, "google", "userid1")[0]); + assertEquals(user2, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage + , false, "test2@example.com", null, "google", "userid1")[0]); + assertEquals(user3, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage + , false, "test3@example.com", null, null, null)[0]); + assertEquals(user4, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage + , false, null, "+919876543210", null, null)[0]); // test for no result - assertEquals(0, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, "test1@example.com", "+919876543210", null, null).length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, "test2@example.com", "+919876543210", null, null).length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, "test3@example.com", "+919876543210", null, null).length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, null, "+919876543210", "google", "userid1").length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, "test1@gmail.com", null, "google", "userid1").length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, "test3@gmail.com", null, "google", "userid1").length); + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + false, "test1@example.com", "+919876543210", null, null).length); + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + false, "test2@example.com", "+919876543210", null, null).length); + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + false, "test3@example.com", "+919876543210", null, null).length); + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + false, null, "+919876543210", "google", "userid1").length); + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + false, "test1@gmail.com", null, "google", "userid1").length); + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + false, "test3@gmail.com", null, "google", "userid1").length); process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); @@ -165,27 +177,31 @@ public void testListUsersByAccountInfoForUnlinkedAccountsWithUnionOption() throw AuthRecipeUserInfo user3 = createPasswordlessUserWithEmail(process.getProcess(), "test3@example.com"); AuthRecipeUserInfo user4 = createPasswordlessUserWithPhone(process.getProcess(), "+919876543210"); - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage(StorageLayer.getBaseStorage(process.getProcess())); + Storage tenantIdentifierWithStorage = (StorageLayer.getBaseStorage(process.getProcess())); { - AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, true, "test1@example.com", "+919876543210", null, null); + AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, true, "test1@example.com", "+919876543210", null, null); assertEquals(2, users.length); assertTrue(Arrays.asList(users).contains(user1)); assertTrue(Arrays.asList(users).contains(user4)); } { - AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, true, "test1@example.com", null, "google", "userid1"); + AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, true, "test1@example.com", null, "google", "userid1"); assertEquals(2, users.length); assertTrue(Arrays.asList(users).contains(user1)); assertTrue(Arrays.asList(users).contains(user2)); } { - AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, true, null, "+919876543210", "google", "userid1"); + AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, true, null, "+919876543210", "google", "userid1"); assertEquals(2, users.length); assertTrue(Arrays.asList(users).contains(user4)); assertTrue(Arrays.asList(users).contains(user2)); } { - AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, true, "test1@example.com", "+919876543210", "google", "userid1"); + AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, true, "test1@example.com", "+919876543210", "google", "userid1"); assertEquals(3, users.length); assertTrue(Arrays.asList(users).contains(user1)); assertTrue(Arrays.asList(users).contains(user2)); @@ -210,11 +226,15 @@ public void testUnknownAccountInfo() throws Exception { return; } - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage(StorageLayer.getBaseStorage(process.getProcess())); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, "test1@example.com", null, null, null).length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, null, null, "google", "userid1").length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, "test3@example.com", null, null, null).length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, null, "+919876543210", null, null).length); + Storage tenantIdentifierWithStorage = (StorageLayer.getBaseStorage(process.getProcess())); + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + false, "test1@example.com", null, null, null).length); + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + false, null, null, "google", "userid1").length); + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + false, "test3@example.com", null, null, null).length); + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + false, null, "+919876543210", null, null).length); process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); @@ -241,20 +261,25 @@ public void testListUserByAccountInfoWhenAccountsAreLinked1() throws Exception { AuthRecipeUserInfo primaryUser = AuthRecipe.createPrimaryUser(process.getProcess(), user1.getSupertokensUserId()).user; AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage( + Storage tenantIdentifierWithStorage = ( StorageLayer.getBaseStorage(process.getProcess())); primaryUser = AuthRecipe.getUserById(process.getProcess(), user1.getSupertokensUserId()); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test1@example.com", null, null, null)[0]); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test2@example.com", null, null, null)[0]); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, null, null, "google", "userid1")[0]); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test1@example.com", null, "google", "userid1")[0]); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test2@example.com", null, "google", "userid1")[0]); process.kill(); @@ -282,14 +307,16 @@ public void testListUserByAccountInfoWhenAccountsAreLinked2() throws Exception { AuthRecipeUserInfo primaryUser = AuthRecipe.createPrimaryUser(process.getProcess(), user1.getSupertokensUserId()).user; AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage( + Storage tenantIdentifierWithStorage = ( StorageLayer.getBaseStorage(process.getProcess())); primaryUser = AuthRecipe.getUserById(process.getProcess(), user1.getSupertokensUserId()); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test1@example.com", null, null, null)[0]); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test2@example.com", null, null, null)[0]); process.kill(); @@ -317,14 +344,16 @@ public void testListUserByAccountInfoWhenAccountsAreLinked3() throws Exception { AuthRecipeUserInfo primaryUser = AuthRecipe.createPrimaryUser(process.getProcess(), user1.getSupertokensUserId()).user; AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage( + Storage tenantIdentifierWithStorage = ( StorageLayer.getBaseStorage(process.getProcess())); primaryUser = AuthRecipe.getUserById(process.getProcess(), user1.getSupertokensUserId()); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test1@example.com", null, null, null)[0]); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test2@example.com", null, null, null)[0]); process.kill(); @@ -352,16 +381,19 @@ public void testListUserByAccountInfoWhenAccountsAreLinked4() throws Exception { AuthRecipeUserInfo primaryUser = AuthRecipe.createPrimaryUser(process.getProcess(), user1.getSupertokensUserId()).user; AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage( + Storage tenantIdentifierWithStorage = ( StorageLayer.getBaseStorage(process.getProcess())); primaryUser = AuthRecipe.getUserById(process.getProcess(), user1.getSupertokensUserId()); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test1@example.com", null, null, null)[0]); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, null, "+919876543210", null, null)[0]); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test1@example.com", "+919876543210", null, null)[0]); process.kill(); @@ -389,20 +421,25 @@ public void testListUserByAccountInfoWhenAccountsAreLinked5() throws Exception { AuthRecipeUserInfo primaryUser = AuthRecipe.createPrimaryUser(process.getProcess(), user1.getSupertokensUserId()).user; AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage( + Storage tenantIdentifierWithStorage = ( StorageLayer.getBaseStorage(process.getProcess())); primaryUser = AuthRecipe.getUserById(process.getProcess(), user1.getSupertokensUserId()); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test1@example.com", null, null, null)[0]); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test2@example.com", null, null, null)[0]); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, null, null, "google", "userid1")[0]); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test1@example.com", null, "google", "userid1")[0]); - assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test2@example.com", null, "google", "userid1")[0]); process.kill(); @@ -436,20 +473,23 @@ public void testForEmptyResults() throws Exception { AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); AuthRecipe.linkAccounts(process.getProcess(), user3.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage( + Storage tenantIdentifierWithStorage = ( StorageLayer.getBaseStorage(process.getProcess())); { - AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test5@example.com", null, null, null); assertEquals(0, users.length); } { - AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, null, null, "google", "userid5"); assertEquals(0, users.length); } { - AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, + AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, null, "+9876", null, null); assertEquals(0, users.length); } @@ -491,11 +531,12 @@ public void testGetUserByAccountInfoOrdersUserBasedOnTimeJoined() throws Excepti AuthRecipe.createPrimaryUser(process.getProcess(), user4.getSupertokensUserId()); - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage( + Storage tenantIdentifierWithStorage = ( StorageLayer.getBaseStorage(process.getProcess())); { - AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, true, "test1@example.com", null, + AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, true, "test1@example.com", null, null, null); assertEquals(3, users.length); @@ -504,7 +545,8 @@ public void testGetUserByAccountInfoOrdersUserBasedOnTimeJoined() throws Excepti } { - AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(tenantIdentifierWithStorage, false, "test1@example.com", null, + AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, + tenantIdentifierWithStorage, false, "test1@example.com", null, null, null); assertEquals(3, users.length); diff --git a/src/test/java/io/supertokens/test/accountlinking/LinkAccountsTest.java b/src/test/java/io/supertokens/test/accountlinking/LinkAccountsTest.java index aab79a23a..10066d51f 100644 --- a/src/test/java/io/supertokens/test/accountlinking/LinkAccountsTest.java +++ b/src/test/java/io/supertokens/test/accountlinking/LinkAccountsTest.java @@ -29,6 +29,7 @@ import io.supertokens.multitenancy.Multitenancy; import io.supertokens.passwordless.Passwordless; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.multitenancy.*; @@ -467,17 +468,19 @@ public void linkAccountFailureCauseAccountInfoAssociatedWithAPrimaryUserEvenIfIn new ThirdPartyConfig(true, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(true), new JsonObject())); - TenantIdentifierWithStorage tenantIdentifierWithStorage = new TenantIdentifierWithStorage(null, null, "t1", - StorageLayer.getStorage(process.main)); + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(process.main)); - AuthRecipeUserInfo user = EmailPassword.signUp(tenantIdentifierWithStorage, process.getProcess(), + AuthRecipeUserInfo user = + EmailPassword.signUp(new TenantIdentifier(null, null, "t1"), tenantIdentifierWithStorage, + process.getProcess(), "test@example.com", "password"); assert (!user.isPrimaryUser); AuthRecipe.createPrimaryUser(process.main, user.getSupertokensUserId()); Thread.sleep(50); - ThirdParty.SignInUpResponse signInUpResponse = ThirdParty.signInUp(tenantIdentifierWithStorage, + ThirdParty.SignInUpResponse signInUpResponse = ThirdParty.signInUp( + new TenantIdentifier(null, null, "t1"), tenantIdentifierWithStorage, process.getProcess(), "google", "user-google", "test@example.com"); @@ -520,10 +523,10 @@ public void linkAccountSuccessAcrossTenants() throws Exception { new ThirdPartyConfig(true, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(true), new JsonObject())); - TenantIdentifierWithStorage tenantIdentifierWithStorage = new TenantIdentifierWithStorage(null, null, "t1", - StorageLayer.getStorage(process.main)); + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(process.main)); - AuthRecipeUserInfo user = EmailPassword.signUp(tenantIdentifierWithStorage, process.getProcess(), + AuthRecipeUserInfo user = EmailPassword.signUp(new TenantIdentifier(null, null, "t1"), + tenantIdentifierWithStorage, process.getProcess(), "test@example.com", "password"); assert (!user.isPrimaryUser); AuthRecipe.createPrimaryUser(process.main, user.getSupertokensUserId()); diff --git a/src/test/java/io/supertokens/test/accountlinking/MultitenantTest.java b/src/test/java/io/supertokens/test/accountlinking/MultitenantTest.java index 438aea250..c804492c7 100644 --- a/src/test/java/io/supertokens/test/accountlinking/MultitenantTest.java +++ b/src/test/java/io/supertokens/test/accountlinking/MultitenantTest.java @@ -33,6 +33,7 @@ import io.supertokens.passwordless.Passwordless; import io.supertokens.passwordless.exceptions.PhoneNumberChangeNotAllowedException; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.authRecipe.LoginMethod; import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException; @@ -184,23 +185,27 @@ public void testUserAreNotAutomaticallySharedBetweenTenantsOfLinkedAccountsForPl t1 = new TenantIdentifier(null, "a1", null); t2 = new TenantIdentifier(null, "a1", "t1"); - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); - TenantIdentifierWithStorage t2WithStorage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t1WithStorage, process.getProcess(), "test@example.com", "password"); - Passwordless.CreateCodeResponse user2Code = Passwordless.createCode(t1WithStorage, process.getProcess(), + AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", + "password"); + Passwordless.CreateCodeResponse user2Code = Passwordless.createCode(t1, t1WithStorage, process.getProcess(), "test@example.com", null, null, null); - AuthRecipeUserInfo user2 = Passwordless.consumeCode(t1WithStorage, process.getProcess(), user2Code.deviceId, user2Code.deviceIdHash, user2Code.userInputCode, null).user; + AuthRecipeUserInfo user2 = Passwordless.consumeCode(t1, t1WithStorage, process.getProcess(), user2Code.deviceId, + user2Code.deviceIdHash, user2Code.userInputCode, null).user; - AuthRecipe.createPrimaryUser(process.getProcess(), t1WithStorage.toAppIdentifierWithStorage(), user1.getSupertokensUserId()); - AuthRecipe.linkAccounts(process.getProcess(), t1WithStorage.toAppIdentifierWithStorage(), user2.getSupertokensUserId(), user1.getSupertokensUserId()); + AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, + user1.getSupertokensUserId()); + AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, user2.getSupertokensUserId(), + user1.getSupertokensUserId()); - Multitenancy.addUserIdToTenant(process.getProcess(), t2WithStorage, user1.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, user1.getSupertokensUserId()); { // user2 should not be shared in tenant2 - Passwordless.CreateCodeResponse user3Code = Passwordless.createCode(t2WithStorage, process.getProcess(), + Passwordless.CreateCodeResponse user3Code = Passwordless.createCode(t2, t2WithStorage, process.getProcess(), "test@example.com", null, null, null); - Passwordless.ConsumeCodeResponse res = Passwordless.consumeCode(t2WithStorage, process.getProcess(), + Passwordless.ConsumeCodeResponse res = Passwordless.consumeCode(t2, t2WithStorage, process.getProcess(), user3Code.deviceId, user3Code.deviceIdHash, user3Code.userInputCode, null); assertTrue(res.createdNewUser); } @@ -228,19 +233,23 @@ public void testUserAreNotAutomaticallySharedBetweenTenantsOfLinkedAccountsForTP t1 = new TenantIdentifier(null, "a1", null); t2 = new TenantIdentifier(null, "a1", "t1"); - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); - TenantIdentifierWithStorage t2WithStorage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t1WithStorage, process.getProcess(), "test@example.com", "password"); - AuthRecipeUserInfo user2 = ThirdParty.signInUp(t1WithStorage, process.getProcess(), "google", "googleid1", "test@example.com").user; + AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", + "password"); + AuthRecipeUserInfo user2 = ThirdParty.signInUp(t1, t1WithStorage, process.getProcess(), "google", "googleid1", + "test@example.com").user; - AuthRecipe.createPrimaryUser(process.getProcess(), t1WithStorage.toAppIdentifierWithStorage(), user1.getSupertokensUserId()); - AuthRecipe.linkAccounts(process.getProcess(), t1WithStorage.toAppIdentifierWithStorage(), user2.getSupertokensUserId(), user1.getSupertokensUserId()); + AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, + user1.getSupertokensUserId()); + AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, user2.getSupertokensUserId(), + user1.getSupertokensUserId()); - Multitenancy.addUserIdToTenant(process.getProcess(), t2WithStorage, user1.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, user1.getSupertokensUserId()); { // user2 should not be shared in tenant2 - ThirdParty.SignInUpResponse res = ThirdParty.signInUp(t2WithStorage, process.getProcess(), "google", + ThirdParty.SignInUpResponse res = ThirdParty.signInUp(t2, t2WithStorage, process.getProcess(), "google", "googleid1", "test@example.com"); assertTrue(res.createdNewUser); } @@ -268,23 +277,29 @@ public void testTenantDeletionWithAccountLinking() throws Exception { t1 = new TenantIdentifier(null, "a1", null); t2 = new TenantIdentifier(null, "a1", "t1"); - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); - TenantIdentifierWithStorage t2WithStorage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t2WithStorage, process.getProcess(), "test@example.com", "password"); - AuthRecipeUserInfo user2 = ThirdParty.signInUp(t2WithStorage, process.getProcess(), "google", "googleid1", "test@example.com").user; + AuthRecipeUserInfo user1 = EmailPassword.signUp(t2, t2WithStorage, process.getProcess(), "test@example.com", + "password"); + AuthRecipeUserInfo user2 = ThirdParty.signInUp(t2, t2WithStorage, process.getProcess(), "google", "googleid1", + "test@example.com").user; - AuthRecipe.createPrimaryUser(process.getProcess(), t2WithStorage.toAppIdentifierWithStorage(), user1.getSupertokensUserId()); - AuthRecipe.linkAccounts(process.getProcess(), t2WithStorage.toAppIdentifierWithStorage(), user2.getSupertokensUserId(), user1.getSupertokensUserId()); + AuthRecipe.createPrimaryUser(process.getProcess(), t2.toAppIdentifier(), t2WithStorage, + user1.getSupertokensUserId()); + AuthRecipe.linkAccounts(process.getProcess(), t2.toAppIdentifier(), t2WithStorage, user2.getSupertokensUserId(), + user1.getSupertokensUserId()); Multitenancy.deleteTenant(t2, process.getProcess()); - AuthRecipeUserInfo getUser1 = AuthRecipe.getUserById(t1WithStorage.toAppIdentifierWithStorage(), user1.getSupertokensUserId()); + AuthRecipeUserInfo getUser1 = AuthRecipe.getUserById(t1.toAppIdentifier(), t1WithStorage, + user1.getSupertokensUserId()); for (LoginMethod lm : getUser1.loginMethods) { assertEquals(0, lm.tenantIds.size()); } - AuthRecipeUserInfo getUser2 = AuthRecipe.getUserById(t1WithStorage.toAppIdentifierWithStorage(), user2.getSupertokensUserId()); + AuthRecipeUserInfo getUser2 = AuthRecipe.getUserById(t1.toAppIdentifier(), t1WithStorage, + user2.getSupertokensUserId()); for (LoginMethod lm : getUser2.loginMethods) { assertEquals(0, lm.tenantIds.size()); } @@ -312,36 +327,44 @@ public void testTenantDeletionWithAccountLinkingWithUserRoles() throws Exception t1 = new TenantIdentifier(null, "a1", null); t2 = new TenantIdentifier(null, "a1", "t1"); - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); - TenantIdentifierWithStorage t2WithStorage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t2WithStorage, process.getProcess(), "test@example.com", "password"); - AuthRecipeUserInfo user2 = ThirdParty.signInUp(t2WithStorage, process.getProcess(), "google", "googleid1", "test@example.com").user; + AuthRecipeUserInfo user1 = EmailPassword.signUp(t2, t2WithStorage, process.getProcess(), "test@example.com", + "password"); + AuthRecipeUserInfo user2 = ThirdParty.signInUp(t2, t2WithStorage, process.getProcess(), "google", "googleid1", + "test@example.com").user; - AuthRecipe.createPrimaryUser(process.getProcess(), t2WithStorage.toAppIdentifierWithStorage(), user1.getSupertokensUserId()); - AuthRecipe.linkAccounts(process.getProcess(), t2WithStorage.toAppIdentifierWithStorage(), user2.getSupertokensUserId(), user1.getSupertokensUserId()); + AuthRecipe.createPrimaryUser(process.getProcess(), t2.toAppIdentifier(), t2WithStorage, + user1.getSupertokensUserId()); + AuthRecipe.linkAccounts(process.getProcess(), t2.toAppIdentifier(), t2WithStorage, user2.getSupertokensUserId(), + user1.getSupertokensUserId()); - UserRoles.createNewRoleOrModifyItsPermissions(t2WithStorage.toAppIdentifierWithStorage(), "admin", new String[]{"p1"}); - UserRoles.addRoleToUser(t2WithStorage, user1.getSupertokensUserId(), "admin"); + UserRoles.createNewRoleOrModifyItsPermissions(t2.toAppIdentifier(), t2WithStorage, "admin", new String[]{"p1"}); + UserRoles.addRoleToUser(t2, t2WithStorage, user1.getSupertokensUserId(), "admin"); Multitenancy.deleteTenant(t2, process.getProcess()); createTenants(process.getProcess()); // create the tenant again - Multitenancy.addUserIdToTenant(process.getProcess(), t2WithStorage, user1.getSupertokensUserId()); // add the user to the tenant again - Multitenancy.addUserIdToTenant(process.getProcess(), t2WithStorage, user2.getSupertokensUserId()); // add the user to the tenant again + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, user1.getSupertokensUserId()); // add + // the user to the tenant again + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, user2.getSupertokensUserId()); // add + // the user to the tenant again - AuthRecipeUserInfo getUser1 = AuthRecipe.getUserById(t1WithStorage.toAppIdentifierWithStorage(), user1.getSupertokensUserId()); + AuthRecipeUserInfo getUser1 = AuthRecipe.getUserById(t1.toAppIdentifier(), t1WithStorage, + user1.getSupertokensUserId()); for (LoginMethod lm : getUser1.loginMethods) { assertEquals(1, lm.tenantIds.size()); } - AuthRecipeUserInfo getUser2 = AuthRecipe.getUserById(t1WithStorage.toAppIdentifierWithStorage(), user2.getSupertokensUserId()); + AuthRecipeUserInfo getUser2 = AuthRecipe.getUserById(t1.toAppIdentifier(), t1WithStorage, + user2.getSupertokensUserId()); for (LoginMethod lm : getUser2.loginMethods) { assertEquals(1, lm.tenantIds.size()); } - String[] roles = UserRoles.getRolesForUser(t2WithStorage, user1.getSupertokensUserId()); + String[] roles = UserRoles.getRolesForUser(t2, t2WithStorage, user1.getSupertokensUserId()); assertEquals(0, roles.length); // must be deleted with tenant process.kill(); @@ -691,8 +714,9 @@ public void testVariousCases() throws Exception { new TestCaseStep() { @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, main)); - AuthRecipeUserInfo user = AuthRecipe.getUserById(t1WithStorage.toAppIdentifierWithStorage(), TestCase.users.get(0).getSupertokensUserId()); + Storage t1WithStorage = (StorageLayer.getStorage(t1, main)); + AuthRecipeUserInfo user = AuthRecipe.getUserById(t1.toAppIdentifier(), t1WithStorage, + TestCase.users.get(0).getSupertokensUserId()); assertEquals(2, user.loginMethods.length); assertTrue(user.loginMethods[0].tenantIds.contains(t2.getTenantId())); assertTrue(user.loginMethods[1].tenantIds.contains(t1.getTenantId())); @@ -732,15 +756,17 @@ public void execute(Main main) throws Exception { new TestCaseStep() { @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, main)); - AuthRecipe.deleteUser(t1WithStorage.toAppIdentifierWithStorage(), TestCase.users.get(1).getSupertokensUserId()); + Storage t1WithStorage = (StorageLayer.getStorage(t1, main)); + AuthRecipe.deleteUser(t1.toAppIdentifier(), t1WithStorage, + TestCase.users.get(1).getSupertokensUserId()); } }, new TestCaseStep() { @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, main)); - AuthRecipeUserInfo user = AuthRecipe.getUserById(t1WithStorage.toAppIdentifierWithStorage(), TestCase.users.get(0).getSupertokensUserId()); + Storage t1WithStorage = (StorageLayer.getStorage(t1, main)); + AuthRecipeUserInfo user = AuthRecipe.getUserById(t1.toAppIdentifier(), t1WithStorage, + TestCase.users.get(0).getSupertokensUserId()); assertNull(user); } } @@ -902,8 +928,9 @@ public CreateEmailPasswordUser(TenantIdentifier tenantIdentifier, String email) @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); - AuthRecipeUserInfo user = EmailPassword.signUp(tenantIdentifierWithStorage, main, email, "password"); + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); + AuthRecipeUserInfo user = EmailPassword.signUp(tenantIdentifier, tenantIdentifierWithStorage, main, email, + "password"); TestCase.addUser(user); } } @@ -919,10 +946,13 @@ public CreatePlessUserWithEmail(TenantIdentifier tenantIdentifier, String email) @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); - Passwordless.CreateCodeResponse code = Passwordless.createCode(tenantIdentifierWithStorage, main, + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); + Passwordless.CreateCodeResponse code = Passwordless.createCode(tenantIdentifier, + tenantIdentifierWithStorage, main, email, null, null, null); - AuthRecipeUserInfo user = Passwordless.consumeCode(tenantIdentifierWithStorage, main, code.deviceId, code.deviceIdHash, code.userInputCode, null).user; + AuthRecipeUserInfo user = Passwordless.consumeCode(tenantIdentifier, tenantIdentifierWithStorage, main, + code.deviceId, + code.deviceIdHash, code.userInputCode, null).user; TestCase.addUser(user); } } @@ -938,10 +968,13 @@ public CreatePlessUserWithPhone(TenantIdentifier tenantIdentifier, String phoneN @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); - Passwordless.CreateCodeResponse code = Passwordless.createCode(tenantIdentifierWithStorage, main, + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); + Passwordless.CreateCodeResponse code = Passwordless.createCode(tenantIdentifier, + tenantIdentifierWithStorage, main, null, phoneNumber, null, null); - AuthRecipeUserInfo user = Passwordless.consumeCode(tenantIdentifierWithStorage, main, code.deviceId, code.deviceIdHash, code.userInputCode, null).user; + AuthRecipeUserInfo user = Passwordless.consumeCode(tenantIdentifier, tenantIdentifierWithStorage, main, + code.deviceId, + code.deviceIdHash, code.userInputCode, null).user; TestCase.addUser(user); } } @@ -961,8 +994,10 @@ public CreateThirdPartyUser(TenantIdentifier tenantIdentifier, String thirdParty @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); - AuthRecipeUserInfo user = ThirdParty.signInUp(tenantIdentifierWithStorage, main, thirdPartyId, thirdPartyUserId, email).user; + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); + AuthRecipeUserInfo user = ThirdParty.signInUp(tenantIdentifier, tenantIdentifierWithStorage, main, + thirdPartyId, + thirdPartyUserId, email).user; TestCase.addUser(user); } } @@ -978,8 +1013,9 @@ public MakePrimaryUser(TenantIdentifier tenantIdentifier, int userIndex) { @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); - AuthRecipe.createPrimaryUser(main, tenantIdentifierWithStorage.toAppIdentifierWithStorage(), TestCase.users.get(userIndex).getSupertokensUserId()); + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); + AuthRecipe.createPrimaryUser(main, tenantIdentifier.toAppIdentifier(), tenantIdentifierWithStorage, + TestCase.users.get(userIndex).getSupertokensUserId()); } } @@ -996,8 +1032,9 @@ public LinkAccounts(TenantIdentifier tenantIdentifier, int primaryUserIndex, int @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); - AuthRecipe.linkAccounts(main, tenantIdentifierWithStorage.toAppIdentifierWithStorage(), TestCase.users.get(recipeUserIndex).getSupertokensUserId(), TestCase.users.get(primaryUserIndex).getSupertokensUserId()); + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); + AuthRecipe.linkAccounts(main, tenantIdentifier.toAppIdentifier(), tenantIdentifierWithStorage, + TestCase.users.get(recipeUserIndex).getSupertokensUserId(), TestCase.users.get(primaryUserIndex).getSupertokensUserId()); } } @@ -1012,8 +1049,9 @@ public AssociateUserToTenant(TenantIdentifier tenantIdentifier, int userIndex) { @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); - Multitenancy.addUserIdToTenant(main, tenantIdentifierWithStorage, TestCase.users.get(userIndex).getSupertokensUserId()); + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); + Multitenancy.addUserIdToTenant(main, tenantIdentifier, tenantIdentifierWithStorage, + TestCase.users.get(userIndex).getSupertokensUserId()); } } @@ -1030,8 +1068,9 @@ public UpdateEmailPasswordUserEmail(TenantIdentifier tenantIdentifier, int userI @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); - EmailPassword.updateUsersEmailOrPassword(tenantIdentifierWithStorage.toAppIdentifierWithStorage(), main, TestCase.users.get(userIndex).getSupertokensUserId(), email, null); + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); + EmailPassword.updateUsersEmailOrPassword(tenantIdentifier.toAppIdentifier(), tenantIdentifierWithStorage, + main, TestCase.users.get(userIndex).getSupertokensUserId(), email, null); } } @@ -1048,8 +1087,9 @@ public UpdatePlessUserEmail(TenantIdentifier tenantIdentifier, int userIndex, St @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); - Passwordless.updateUser(tenantIdentifierWithStorage.toAppIdentifierWithStorage(), TestCase.users.get(userIndex).getSupertokensUserId(), new Passwordless.FieldUpdate(email), null); + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); + Passwordless.updateUser(tenantIdentifier.toAppIdentifier(), tenantIdentifierWithStorage, + TestCase.users.get(userIndex).getSupertokensUserId(), new Passwordless.FieldUpdate(email), null); } } @@ -1066,8 +1106,9 @@ public UpdatePlessUserPhone(TenantIdentifier tenantIdentifier, int userIndex, St @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); - Passwordless.updateUser(tenantIdentifierWithStorage.toAppIdentifierWithStorage(), TestCase.users.get(userIndex).getSupertokensUserId(), null, new Passwordless.FieldUpdate(phoneNumber)); + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); + Passwordless.updateUser(tenantIdentifier.toAppIdentifier(), tenantIdentifierWithStorage, + TestCase.users.get(userIndex).getSupertokensUserId(), null, new Passwordless.FieldUpdate(phoneNumber)); } } @@ -1082,8 +1123,9 @@ public UnlinkAccount(TenantIdentifier tenantIdentifier, int userIndex) { @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); - AuthRecipe.unlinkAccounts(main, tenantIdentifierWithStorage.toAppIdentifierWithStorage(), TestCase.users.get(userIndex).getSupertokensUserId()); + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); + AuthRecipe.unlinkAccounts(main, tenantIdentifier.toAppIdentifier(), tenantIdentifierWithStorage, + TestCase.users.get(userIndex).getSupertokensUserId()); } } @@ -1098,8 +1140,9 @@ public SignInEmailPasswordUser(TenantIdentifier tenantIdentifier, int userIndex) @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); - EmailPassword.signIn(tenantIdentifierWithStorage, main, TestCase.users.get(userIndex).loginMethods[0].email, "password"); + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); + EmailPassword.signIn(tenantIdentifier, tenantIdentifierWithStorage, main, + TestCase.users.get(userIndex).loginMethods[0].email, "password"); } } @@ -1114,8 +1157,9 @@ public DisassociateUserFromTenant(TenantIdentifier tenantIdentifier, int userInd @Override public void execute(Main main) throws Exception { - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, main)); - Multitenancy.removeUserIdFromTenant(main, tenantIdentifierWithStorage, TestCase.users.get(userIndex).getSupertokensUserId(), null); + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); + Multitenancy.removeUserIdFromTenant(main, tenantIdentifier, tenantIdentifierWithStorage, + TestCase.users.get(userIndex).getSupertokensUserId(), null); } } } diff --git a/src/test/java/io/supertokens/test/accountlinking/SessionTests.java b/src/test/java/io/supertokens/test/accountlinking/SessionTests.java index 8938c2700..2633d5b33 100644 --- a/src/test/java/io/supertokens/test/accountlinking/SessionTests.java +++ b/src/test/java/io/supertokens/test/accountlinking/SessionTests.java @@ -29,6 +29,7 @@ import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.multitenancy.exception.CannotModifyBaseConfigException; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.exceptions.InvalidConfigException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -282,23 +283,27 @@ public void testSessionBehaviourWhenUserBelongsTo2TenantsAndThenLinkedToSomeOthe createTenants(process.getProcess()); - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); - TenantIdentifierWithStorage t2WithStorage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t1WithStorage, process.getProcess(), "test@example.com", "password"); - AuthRecipeUserInfo user2 = EmailPassword.signUp(t1WithStorage, process.getProcess(), "test1@example.com", "password"); + AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", + "password"); + AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test1@example.com", + "password"); - AuthRecipe.createPrimaryUser(process.getProcess(), t1WithStorage.toAppIdentifierWithStorage(), user2.getSupertokensUserId()); - Multitenancy.addUserIdToTenant(process.getProcess(), t2WithStorage, user1.getSupertokensUserId()); + AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), + t1WithStorage, user2.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, user1.getSupertokensUserId()); - SessionInformationHolder session1 = Session.createNewSession(t2WithStorage, process.getProcess(), + SessionInformationHolder session1 = Session.createNewSession(t2, t2WithStorage, process.getProcess(), user1.getSupertokensUserId(), new JsonObject(), new JsonObject()); // Linking user1 to user2 on t1 should revoke the session - AuthRecipe.linkAccounts(process.getProcess(), t1WithStorage.toAppIdentifierWithStorage(), user1.getSupertokensUserId(), user2.getSupertokensUserId()); + AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, + user1.getSupertokensUserId(), user2.getSupertokensUserId()); try { - Session.getSession(t2WithStorage, session1.session.handle); + Session.getSession(t2, t2WithStorage, session1.session.handle); fail(); } catch (UnauthorisedException e) { // ok @@ -324,23 +329,27 @@ public void testSessionBehaviourWhenUserBelongsTo2TenantsAndThenLinkedToSomeOthe createTenants(process.getProcess()); - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); - TenantIdentifierWithStorage t2WithStorage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t1WithStorage, process.getProcess(), "test@example.com", "password"); - AuthRecipeUserInfo user2 = EmailPassword.signUp(t1WithStorage, process.getProcess(), "test1@example.com", "password"); + AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", + "password"); + AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test1@example.com", + "password"); - AuthRecipe.createPrimaryUser(process.getProcess(), t1WithStorage.toAppIdentifierWithStorage(), user2.getSupertokensUserId()); + AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), + t1WithStorage, user2.getSupertokensUserId()); - SessionInformationHolder session1 = Session.createNewSession(t2WithStorage, process.getProcess(), + SessionInformationHolder session1 = Session.createNewSession(t2, t2WithStorage, process.getProcess(), user1.getSupertokensUserId(), new JsonObject(), new JsonObject()); // Linking user1 to user2 on t1 should revoke the session - AuthRecipe.linkAccounts(process.getProcess(), t1WithStorage.toAppIdentifierWithStorage(), user1.getSupertokensUserId(), user2.getSupertokensUserId()); + AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, + user1.getSupertokensUserId(), user2.getSupertokensUserId()); try { // session gets removed on t2 as well - Session.getSession(t2WithStorage, session1.session.handle); + Session.getSession(t2, t2WithStorage, session1.session.handle); fail(); } catch (UnauthorisedException e) { // ok @@ -366,22 +375,26 @@ public void testSessionBehaviourWhenUserBelongsTo2TenantsAndThenLinkedToSomeOthe createTenants(process.getProcess()); - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); - TenantIdentifierWithStorage t2WithStorage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t1WithStorage, process.getProcess(), "test@example.com", "password"); - AuthRecipeUserInfo user2 = EmailPassword.signUp(t1WithStorage, process.getProcess(), "test1@example.com", "password"); + AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", + "password"); + AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test1@example.com", + "password"); - AuthRecipe.createPrimaryUser(process.getProcess(), t1WithStorage.toAppIdentifierWithStorage(), user2.getSupertokensUserId()); - AuthRecipe.linkAccounts(process.getProcess(), t1WithStorage.toAppIdentifierWithStorage(), user1.getSupertokensUserId(), user2.getSupertokensUserId()); + AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, + user2.getSupertokensUserId()); + AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, user1.getSupertokensUserId(), + user2.getSupertokensUserId()); - SessionInformationHolder session1 = Session.createNewSession(t2WithStorage, process.getProcess(), + SessionInformationHolder session1 = Session.createNewSession(t2, t2WithStorage, process.getProcess(), user1.getSupertokensUserId(), new JsonObject(), new JsonObject()); - AuthRecipe.unlinkAccounts(process.getProcess(), t1WithStorage.toAppIdentifierWithStorage(), user2.getSupertokensUserId()); + AuthRecipe.unlinkAccounts(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, user2.getSupertokensUserId()); // session must be intact - Session.getSession(t2WithStorage, session1.session.handle); + Session.getSession(t2, t2WithStorage, session1.session.handle); process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); @@ -403,16 +416,20 @@ public void testCreateSessionUsesPrimaryUserIdEvenWhenTheUserIsNotInThatTenant() createTenants(process.getProcess()); - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); - TenantIdentifierWithStorage t2WithStorage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t1WithStorage, process.getProcess(), "test@example.com", "password"); - AuthRecipeUserInfo user2 = EmailPassword.signUp(t1WithStorage, process.getProcess(), "test1@example.com", "password"); + AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", + "password"); + AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test1@example.com", + "password"); - AuthRecipe.createPrimaryUser(process.getProcess(), t1WithStorage.toAppIdentifierWithStorage(), user2.getSupertokensUserId()); - AuthRecipe.linkAccounts(process.getProcess(), t1WithStorage.toAppIdentifierWithStorage(), user1.getSupertokensUserId(), user2.getSupertokensUserId()); + AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, + user2.getSupertokensUserId()); + AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, user1.getSupertokensUserId(), + user2.getSupertokensUserId()); - SessionInformationHolder session1 = Session.createNewSession(t2WithStorage, process.getProcess(), + SessionInformationHolder session1 = Session.createNewSession(t2, t2WithStorage, process.getProcess(), user1.getSupertokensUserId(), new JsonObject(), new JsonObject()); // Should still consider the primaryUserId @@ -448,28 +465,30 @@ public void testGetSessionForUserWithAndWithoutIncludingAllLinkedAccounts() thro new JsonObject(), new JsonObject()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage(StorageLayer.getBaseStorage(process.getProcess())); + Storage baseTenant = (StorageLayer.getBaseStorage(process.getProcess())); { - String[] sessions = Session.getAllNonExpiredSessionHandlesForUser(baseTenant, user1.getSupertokensUserId(), + String[] sessions = Session.getAllNonExpiredSessionHandlesForUser(TenantIdentifier.BASE_TENANT, baseTenant, + user1.getSupertokensUserId(), false); assertEquals(1, sessions.length); assertEquals(session1.session.handle, sessions[0]); } { - String[] sessions = Session.getAllNonExpiredSessionHandlesForUser(baseTenant, user2.getSupertokensUserId(), + String[] sessions = Session.getAllNonExpiredSessionHandlesForUser(TenantIdentifier.BASE_TENANT, baseTenant, + user2.getSupertokensUserId(), false); assertEquals(1, sessions.length); assertEquals(session2.session.handle, sessions[0]); } { - String[] sessions = Session.getAllNonExpiredSessionHandlesForUser(baseTenant, user1.getSupertokensUserId(), + String[] sessions = Session.getAllNonExpiredSessionHandlesForUser(TenantIdentifier.BASE_TENANT, baseTenant, user1.getSupertokensUserId(), true); assertEquals(2, sessions.length); } { - String[] sessions = Session.getAllNonExpiredSessionHandlesForUser(baseTenant, user2.getSupertokensUserId(), + String[] sessions = Session.getAllNonExpiredSessionHandlesForUser(TenantIdentifier.BASE_TENANT, baseTenant, user2.getSupertokensUserId(), true); assertEquals(2, sessions.length); } @@ -507,9 +526,9 @@ public void testRevokeSessionsForUserWithAndWithoutIncludingAllLinkedAccounts() new JsonObject(), new JsonObject()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage( + Storage baseTenant = ( StorageLayer.getBaseStorage(process.getProcess())); - Session.revokeAllSessionsForUser(process.getProcess(), baseTenant, user1.getSupertokensUserId(), true); + Session.revokeAllSessionsForUser(process.getProcess(), TenantIdentifier.BASE_TENANT, baseTenant, user1.getSupertokensUserId(), true); try { Session.getSession(process.getProcess(), session1.session.handle); @@ -533,9 +552,9 @@ public void testRevokeSessionsForUserWithAndWithoutIncludingAllLinkedAccounts() user2.getSupertokensUserId(), new JsonObject(), new JsonObject()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage( + Storage baseTenant = ( StorageLayer.getBaseStorage(process.getProcess())); - Session.revokeAllSessionsForUser(process.getProcess(), baseTenant, user2.getSupertokensUserId(), true); + Session.revokeAllSessionsForUser(process.getProcess(), TenantIdentifier.BASE_TENANT, baseTenant, user2.getSupertokensUserId(), true); try { Session.getSession(process.getProcess(), session1.session.handle); @@ -559,9 +578,9 @@ public void testRevokeSessionsForUserWithAndWithoutIncludingAllLinkedAccounts() user2.getSupertokensUserId(), new JsonObject(), new JsonObject()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage( + Storage baseTenant = ( StorageLayer.getBaseStorage(process.getProcess())); - Session.revokeAllSessionsForUser(process.getProcess(), baseTenant, user1.getSupertokensUserId(), false); + Session.revokeAllSessionsForUser(process.getProcess(), TenantIdentifier.BASE_TENANT, baseTenant, user1.getSupertokensUserId(), false); try { Session.getSession(process.getProcess(), session1.session.handle); @@ -581,9 +600,9 @@ public void testRevokeSessionsForUserWithAndWithoutIncludingAllLinkedAccounts() user2.getSupertokensUserId(), new JsonObject(), new JsonObject()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage( + Storage baseTenant = ( StorageLayer.getBaseStorage(process.getProcess())); - Session.revokeAllSessionsForUser(process.getProcess(), baseTenant, user2.getSupertokensUserId(), false); + Session.revokeAllSessionsForUser(process.getProcess(), TenantIdentifier.BASE_TENANT, baseTenant, user2.getSupertokensUserId(), false); Session.getSession(process.getProcess(), session1.session.handle); diff --git a/src/test/java/io/supertokens/test/accountlinking/TimeJoinedTest.java b/src/test/java/io/supertokens/test/accountlinking/TimeJoinedTest.java index e8bf436eb..d13fbca07 100644 --- a/src/test/java/io/supertokens/test/accountlinking/TimeJoinedTest.java +++ b/src/test/java/io/supertokens/test/accountlinking/TimeJoinedTest.java @@ -24,10 +24,10 @@ import io.supertokens.featureflag.FeatureFlagTestContent; import io.supertokens.multitenancy.Multitenancy; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.dashboard.DashboardSearchTags; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.storageLayer.StorageLayer; import io.supertokens.test.TestingProcessManager; import io.supertokens.test.Utils; @@ -120,24 +120,28 @@ public void testThatTimeJoinedIsCorrectWhileAssociatingTenants() throws Exceptio assertEquals(user1.timeJoined, userInfo.timeJoined); } - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage(StorageLayer.getStorage(process.getProcess())); + Storage baseTenant = (StorageLayer.getStorage(process.getProcess())); - Multitenancy.removeUserIdFromTenant(process.getProcess(), baseTenant, user1.getSupertokensUserId(), null); - Multitenancy.removeUserIdFromTenant(process.getProcess(), baseTenant, user2.getSupertokensUserId(), null); + Multitenancy.removeUserIdFromTenant(process.getProcess(), TenantIdentifier.BASE_TENANT, baseTenant, + user1.getSupertokensUserId(), null); + Multitenancy.removeUserIdFromTenant(process.getProcess(), TenantIdentifier.BASE_TENANT, baseTenant, + user2.getSupertokensUserId(), null); { AuthRecipeUserInfo userInfo = AuthRecipe.getUserById(process.getProcess(), user2.getSupertokensUserId()); assertEquals(user1.timeJoined, userInfo.timeJoined); } - Multitenancy.addUserIdToTenant(process.getProcess(), baseTenant, user2.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.getProcess(), TenantIdentifier.BASE_TENANT, baseTenant, + user2.getSupertokensUserId()); { AuthRecipeUserInfo userInfo = AuthRecipe.getUserById(process.getProcess(), user2.getSupertokensUserId()); assertEquals(user1.timeJoined, userInfo.timeJoined); } - Multitenancy.addUserIdToTenant(process.getProcess(), baseTenant, user1.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.getProcess(), TenantIdentifier.BASE_TENANT, baseTenant, + user1.getSupertokensUserId()); { AuthRecipeUserInfo userInfo = AuthRecipe.getUserById(process.getProcess(), user2.getSupertokensUserId()); @@ -169,8 +173,6 @@ public void testUserPaginationIsFineWithUnlinkAndUnlinkAccounts() throws Excepti AuthRecipe.createPrimaryUser(process.getProcess(), user2.getSupertokensUserId()); AuthRecipe.linkAccounts(process.getProcess(), user1.getSupertokensUserId(), user2.getSupertokensUserId()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage(StorageLayer.getStorage(process.getProcess())); - { UserPaginationContainer users = AuthRecipe.getUsers(process.getProcess(), 10, "DESC", null, null, null); @@ -218,7 +220,7 @@ public void testUserPaginationIsFineWithTenantAssociation() throws Exception { AuthRecipe.createPrimaryUser(process.getProcess(), user2.getSupertokensUserId()); AuthRecipe.linkAccounts(process.getProcess(), user1.getSupertokensUserId(), user2.getSupertokensUserId()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage(StorageLayer.getStorage(process.getProcess())); + Storage baseTenant = (StorageLayer.getStorage(process.getProcess())); { UserPaginationContainer users = AuthRecipe.getUsers(process.getProcess(), 10, "DESC", @@ -226,7 +228,8 @@ public void testUserPaginationIsFineWithTenantAssociation() throws Exception { assertEquals(1, users.users.length); } - Multitenancy.removeUserIdFromTenant(process.getProcess(), baseTenant, user1.getSupertokensUserId(), null); + Multitenancy.removeUserIdFromTenant(process.getProcess(), TenantIdentifier.BASE_TENANT, baseTenant, + user1.getSupertokensUserId(), null); { UserPaginationContainer users = AuthRecipe.getUsers(process.getProcess(), 10, "DESC", @@ -234,7 +237,8 @@ public void testUserPaginationIsFineWithTenantAssociation() throws Exception { assertEquals(1, users.users.length); } - Multitenancy.addUserIdToTenant(process.getProcess(), baseTenant, user1.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.getProcess(), TenantIdentifier.BASE_TENANT, baseTenant, + user1.getSupertokensUserId()); { UserPaginationContainer users = AuthRecipe.getUsers(process.getProcess(), 10, "DESC", @@ -267,8 +271,6 @@ public void testUserSearchWorksWithUnlinkAndLinkAccounts() throws Exception { AuthRecipe.createPrimaryUser(process.getProcess(), user2.getSupertokensUserId()); AuthRecipe.linkAccounts(process.getProcess(), user1.getSupertokensUserId(), user2.getSupertokensUserId()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage(StorageLayer.getStorage(process.getProcess())); - { ArrayList emails = new ArrayList<>(); emails.add("test"); @@ -322,7 +324,7 @@ public void testUserSearchWorksWithTenantAssociation() throws Exception { AuthRecipe.createPrimaryUser(process.getProcess(), user1.getSupertokensUserId()); AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), user1.getSupertokensUserId()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage(StorageLayer.getStorage(process.getProcess())); + Storage baseTenant = (StorageLayer.getStorage(process.getProcess())); { ArrayList emails = new ArrayList<>(); @@ -332,7 +334,8 @@ public void testUserSearchWorksWithTenantAssociation() throws Exception { assertEquals(1, users.users.length); } - Multitenancy.removeUserIdFromTenant(process.getProcess(), baseTenant, user2.getSupertokensUserId(), null); + Multitenancy.removeUserIdFromTenant(process.getProcess(), TenantIdentifier.BASE_TENANT, baseTenant, + user2.getSupertokensUserId(), null); { ArrayList emails = new ArrayList<>(); @@ -342,7 +345,8 @@ public void testUserSearchWorksWithTenantAssociation() throws Exception { assertEquals(1, users.users.length); } - Multitenancy.addUserIdToTenant(process.getProcess(), baseTenant, user2.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.getProcess(), TenantIdentifier.BASE_TENANT, baseTenant, + user2.getSupertokensUserId()); { ArrayList emails = new ArrayList<>(); diff --git a/src/test/java/io/supertokens/test/accountlinking/api/CreatePrimaryUserAPITest.java b/src/test/java/io/supertokens/test/accountlinking/api/CreatePrimaryUserAPITest.java index ce4dd6010..8746b2f86 100644 --- a/src/test/java/io/supertokens/test/accountlinking/api/CreatePrimaryUserAPITest.java +++ b/src/test/java/io/supertokens/test/accountlinking/api/CreatePrimaryUserAPITest.java @@ -457,7 +457,7 @@ public void createPrimaryUserInTenantWithAnotherStorage() throws Exception { ); AuthRecipeUserInfo user = EmailPassword.signUp( - tenantIdentifier.withStorage(StorageLayer.getStorage(tenantIdentifier, process.main)), + tenantIdentifier, StorageLayer.getStorage(tenantIdentifier, process.main), process.getProcess(), "test@example.com", "abcd1234"); JsonObject userObj; @@ -497,7 +497,8 @@ public void createPrimaryUserInTenantWithAnotherStorage() throws Exception { } AuthRecipe.createPrimaryUser(process.main, - tenantIdentifier.toAppIdentifier().withStorage(StorageLayer.getStorage(tenantIdentifier, process.main)), + tenantIdentifier.toAppIdentifier(), (StorageLayer.getStorage(tenantIdentifier, + process.main)), user.getSupertokensUserId()); { diff --git a/src/test/java/io/supertokens/test/accountlinking/api/GetUserByAccountInfoTest.java b/src/test/java/io/supertokens/test/accountlinking/api/GetUserByAccountInfoTest.java index fc775fec1..e86763772 100644 --- a/src/test/java/io/supertokens/test/accountlinking/api/GetUserByAccountInfoTest.java +++ b/src/test/java/io/supertokens/test/accountlinking/api/GetUserByAccountInfoTest.java @@ -32,8 +32,6 @@ import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.passwordless.exception.DuplicateLinkCodeHashException; import io.supertokens.storageLayer.StorageLayer; import io.supertokens.test.TestingProcessManager; @@ -224,7 +222,6 @@ public void testListUsersByAccountInfoForUnlinkedAccountsWithUnionOption() throw JsonObject user3json = getUserById(process.getProcess(), user3.getSupertokensUserId()); JsonObject user4json = getUserById(process.getProcess(), user4.getSupertokensUserId()); - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage(StorageLayer.getBaseStorage(process.getProcess())); { JsonArray users = getUsersByAccountInfo(process.getProcess(), true, "test1@example.com", "+919876543210", null, null); assertEquals(2, users.size()); @@ -269,7 +266,6 @@ public void testUnknownAccountInfo() throws Exception { return; } - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage(StorageLayer.getBaseStorage(process.getProcess())); assertEquals(0, getUsersByAccountInfo(process.getProcess(), false, "test1@example.com", null, null, null).size()); assertEquals(0, getUsersByAccountInfo(process.getProcess(), false, null, null, "google", "userid1").size()); assertEquals(0, getUsersByAccountInfo(process.getProcess(), false, "test3@example.com", null, null, null).size()); @@ -300,9 +296,6 @@ public void testListUserByAccountInfoWhenAccountsAreLinked1() throws Exception { AuthRecipeUserInfo primaryUser = AuthRecipe.createPrimaryUser(process.getProcess(), user1.getSupertokensUserId()).user; AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage( - StorageLayer.getBaseStorage(process.getProcess())); - JsonObject primaryUserJson = getUserById(process.getProcess(), user1.getSupertokensUserId()); assertEquals(primaryUserJson, getUsersByAccountInfo(process.getProcess(), false, @@ -373,9 +366,6 @@ public void testListUserByAccountInfoWhenAccountsAreLinked3() throws Exception { AuthRecipeUserInfo primaryUser = AuthRecipe.createPrimaryUser(process.getProcess(), user1.getSupertokensUserId()).user; AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage( - StorageLayer.getBaseStorage(process.getProcess())); - JsonObject primaryUserJson = getUserById(process.getProcess(), user1.getSupertokensUserId()); assertEquals(primaryUserJson, getUsersByAccountInfo(process.getProcess(), false, @@ -408,9 +398,6 @@ public void testListUserByAccountInfoWhenAccountsAreLinked4() throws Exception { AuthRecipeUserInfo primaryUser = AuthRecipe.createPrimaryUser(process.getProcess(), user1.getSupertokensUserId()).user; AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage( - StorageLayer.getBaseStorage(process.getProcess())); - JsonObject primaryUserJson = getUserById(process.getProcess(), user1.getSupertokensUserId()); assertEquals(primaryUserJson, getUsersByAccountInfo(process.getProcess(), false, @@ -445,9 +432,6 @@ public void testListUserByAccountInfoWhenAccountsAreLinked5() throws Exception { AuthRecipeUserInfo primaryUser = AuthRecipe.createPrimaryUser(process.getProcess(), user1.getSupertokensUserId()).user; AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - TenantIdentifierWithStorage tenantIdentifierWithStorage = TenantIdentifier.BASE_TENANT.withStorage( - StorageLayer.getBaseStorage(process.getProcess())); - JsonObject primaryUserJson = getUserById(process.getProcess(), user1.getSupertokensUserId()); assertEquals(primaryUserJson, getUsersByAccountInfo(process.getProcess(), false, diff --git a/src/test/java/io/supertokens/test/accountlinking/api/SessionTests.java b/src/test/java/io/supertokens/test/accountlinking/api/SessionTests.java index 96ef02b93..52d03a87d 100644 --- a/src/test/java/io/supertokens/test/accountlinking/api/SessionTests.java +++ b/src/test/java/io/supertokens/test/accountlinking/api/SessionTests.java @@ -27,8 +27,6 @@ import io.supertokens.featureflag.FeatureFlagTestContent; import io.supertokens.pluginInterface.STORAGE_TYPE; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.session.Session; import io.supertokens.session.info.SessionInformationHolder; import io.supertokens.storageLayer.StorageLayer; @@ -122,8 +120,6 @@ public void testGetSessionForUserWithAndWithoutIncludingAllLinkedAccounts() thro new JsonObject(), new JsonObject()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage(StorageLayer.getBaseStorage(process.getProcess())); - { String[] sessions = getSessionsForUser(process.getProcess(), user1.getSupertokensUserId(), false); @@ -191,8 +187,6 @@ public void testRevokeSessionsForUserWithAndWithoutIncludingAllLinkedAccounts() new JsonObject(), new JsonObject()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage( - StorageLayer.getBaseStorage(process.getProcess())); revokeSessionsForUser(process.getProcess(), user1.getSupertokensUserId(), true); try { @@ -217,8 +211,6 @@ public void testRevokeSessionsForUserWithAndWithoutIncludingAllLinkedAccounts() user2.getSupertokensUserId(), new JsonObject(), new JsonObject()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage( - StorageLayer.getBaseStorage(process.getProcess())); revokeSessionsForUser(process.getProcess(), user2.getSupertokensUserId(), true); try { @@ -244,8 +236,6 @@ public void testRevokeSessionsForUserWithAndWithoutIncludingAllLinkedAccounts() new JsonObject(), new JsonObject()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage( - StorageLayer.getBaseStorage(process.getProcess())); revokeSessionsForUser(process.getProcess(), user1.getSupertokensUserId(), null); try { @@ -270,8 +260,6 @@ public void testRevokeSessionsForUserWithAndWithoutIncludingAllLinkedAccounts() user2.getSupertokensUserId(), new JsonObject(), new JsonObject()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage( - StorageLayer.getBaseStorage(process.getProcess())); revokeSessionsForUser(process.getProcess(), user2.getSupertokensUserId(), null); try { @@ -296,8 +284,6 @@ public void testRevokeSessionsForUserWithAndWithoutIncludingAllLinkedAccounts() user2.getSupertokensUserId(), new JsonObject(), new JsonObject()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage( - StorageLayer.getBaseStorage(process.getProcess())); revokeSessionsForUser(process.getProcess(), user1.getSupertokensUserId(), false); try { @@ -318,8 +304,6 @@ public void testRevokeSessionsForUserWithAndWithoutIncludingAllLinkedAccounts() user2.getSupertokensUserId(), new JsonObject(), new JsonObject()); - TenantIdentifierWithStorage baseTenant = TenantIdentifier.BASE_TENANT.withStorage( - StorageLayer.getBaseStorage(process.getProcess())); revokeSessionsForUser(process.getProcess(), user2.getSupertokensUserId(), false); Session.getSession(process.getProcess(), session1.session.handle); diff --git a/src/test/java/io/supertokens/test/authRecipe/MultitenantAPITest.java b/src/test/java/io/supertokens/test/authRecipe/MultitenantAPITest.java index c2e58abfd..9742481d0 100644 --- a/src/test/java/io/supertokens/test/authRecipe/MultitenantAPITest.java +++ b/src/test/java/io/supertokens/test/authRecipe/MultitenantAPITest.java @@ -31,6 +31,7 @@ import io.supertokens.passwordless.Passwordless; import io.supertokens.passwordless.exceptions.*; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException; import io.supertokens.pluginInterface.exceptions.InvalidConfigException; @@ -190,7 +191,7 @@ private void createUsers() } AuthRecipeUserInfo user1 = EmailPassword.signUp( - tenant.withStorage(StorageLayer.getStorage(tenant, process.getProcess())), + tenant, (StorageLayer.getStorage(tenant, process.getProcess())), process.getProcess(), "user@example.com", "password" + (pcount++) @@ -198,7 +199,7 @@ private void createUsers() tenantToUsers.get(tenant).add(user1.getSupertokensUserId()); recipeToUsers.get("emailpassword").add(user1.getSupertokensUserId()); AuthRecipeUserInfo user2 = EmailPassword.signUp( - tenant.withStorage(StorageLayer.getStorage(tenant, process.getProcess())), + tenant, (StorageLayer.getStorage(tenant, process.getProcess())), process.getProcess(), "user@gmail.com", "password2" + (pcount++) @@ -210,7 +211,7 @@ private void createUsers() { // passwordless users recipeToUsers.put("passwordless", new ArrayList<>()); for (TenantIdentifier tenant : new TenantIdentifier[]{t1, t2, t3}) { - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenant.withStorage( + Storage tenantIdentifierWithStorage = ( StorageLayer.getStorage(tenant, process.getProcess())); { if (tenantToUsers.get(tenant) == null) { @@ -218,13 +219,15 @@ private void createUsers() } Passwordless.CreateCodeResponse codeResponse = Passwordless.createCode( + tenant, tenantIdentifierWithStorage, process.getProcess(), "user@example.com", null, null, "abcd" ); - Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode(tenantIdentifierWithStorage, + Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode( + tenant, tenantIdentifierWithStorage, process.getProcess(), codeResponse.deviceId, codeResponse.deviceIdHash, "abcd", null); tenantToUsers.get(tenant).add(response.user.getSupertokensUserId()); @@ -232,13 +235,14 @@ private void createUsers() } { Passwordless.CreateCodeResponse codeResponse = Passwordless.createCode( - tenantIdentifierWithStorage, + tenant, tenantIdentifierWithStorage, process.getProcess(), "user@gmail.com", null, null, "abcd" ); - Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode(tenantIdentifierWithStorage, + Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode( + tenant, tenantIdentifierWithStorage, process.getProcess(), codeResponse.deviceId, codeResponse.deviceIdHash, "abcd", null); tenantToUsers.get(tenant).add(response.user.getSupertokensUserId()); @@ -246,13 +250,14 @@ private void createUsers() } { Passwordless.CreateCodeResponse codeResponse = Passwordless.createCode( - tenantIdentifierWithStorage, + tenant, tenantIdentifierWithStorage, process.getProcess(), null, "+1234567890", null, "abcd" ); - Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode(tenantIdentifierWithStorage, + Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode( + tenant, tenantIdentifierWithStorage, process.getProcess(), codeResponse.deviceId, codeResponse.deviceIdHash, "abcd", null); tenantToUsers.get(tenant).add(response.user.getSupertokensUserId()); @@ -260,13 +265,14 @@ private void createUsers() } { Passwordless.CreateCodeResponse codeResponse = Passwordless.createCode( - tenantIdentifierWithStorage, + tenant, tenantIdentifierWithStorage, process.getProcess(), null, "+9876543210", null, "abcd" ); - Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode(tenantIdentifierWithStorage, + Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode( + tenant, tenantIdentifierWithStorage, process.getProcess(), codeResponse.deviceId, codeResponse.deviceIdHash, "abcd", null); tenantToUsers.get(tenant).add(response.user.getSupertokensUserId()); @@ -282,25 +288,29 @@ private void createUsers() tenantToUsers.put(tenant, new ArrayList<>()); } - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenant.withStorage( + Storage tenantIdentifierWithStorage = ( StorageLayer.getStorage(tenant, process.getProcess())); - ThirdParty.SignInUpResponse user1 = ThirdParty.signInUp(tenantIdentifierWithStorage, + ThirdParty.SignInUpResponse user1 = ThirdParty.signInUp( + tenant, tenantIdentifierWithStorage, process.getProcess(), "google", "googleid1", "user@example.com"); tenantToUsers.get(tenant).add(user1.user.getSupertokensUserId()); recipeToUsers.get("thirdparty").add(user1.user.getSupertokensUserId()); - ThirdParty.SignInUpResponse user2 = ThirdParty.signInUp(tenantIdentifierWithStorage, + ThirdParty.SignInUpResponse user2 = ThirdParty.signInUp( + tenant, tenantIdentifierWithStorage, process.getProcess(), "google", "googleid2", "user@gmail.com"); tenantToUsers.get(tenant).add(user2.user.getSupertokensUserId()); recipeToUsers.get("thirdparty").add(user2.user.getSupertokensUserId()); - ThirdParty.SignInUpResponse user3 = ThirdParty.signInUp(tenantIdentifierWithStorage, + ThirdParty.SignInUpResponse user3 = ThirdParty.signInUp( + tenant, tenantIdentifierWithStorage, process.getProcess(), "facebook", "facebookid1", "user@example.com"); tenantToUsers.get(tenant).add(user3.user.getSupertokensUserId()); recipeToUsers.get("thirdparty").add(user3.user.getSupertokensUserId()); - ThirdParty.SignInUpResponse user4 = ThirdParty.signInUp(tenantIdentifierWithStorage, + ThirdParty.SignInUpResponse user4 = ThirdParty.signInUp( + tenant, tenantIdentifierWithStorage, process.getProcess(), "facebook", "facebookid2", "user@gmail.com"); tenantToUsers.get(tenant).add(user4.user.getSupertokensUserId()); recipeToUsers.get("thirdparty").add(user4.user.getSupertokensUserId()); diff --git a/src/test/java/io/supertokens/test/authRecipe/UserPaginationTest.java b/src/test/java/io/supertokens/test/authRecipe/UserPaginationTest.java index 0e7f5e8d5..1a38a670a 100644 --- a/src/test/java/io/supertokens/test/authRecipe/UserPaginationTest.java +++ b/src/test/java/io/supertokens/test/authRecipe/UserPaginationTest.java @@ -31,6 +31,7 @@ import io.supertokens.passwordless.Passwordless; import io.supertokens.passwordless.exceptions.*; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException; import io.supertokens.pluginInterface.exceptions.InvalidConfigException; @@ -181,12 +182,12 @@ private void createUsers(TenantIdentifier tenantIdentifier, int numUsers, String tenantToUsers.put(tenantIdentifier, new ArrayList<>()); } - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage( + Storage tenantIdentifierWithStorage = ( StorageLayer.getStorage(tenantIdentifier, process.getProcess())); for (int i = 0; i < numUsers; i++) { { AuthRecipeUserInfo user = EmailPassword.signUp( - tenantIdentifierWithStorage, process.getProcess(), + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), prefix + "epuser" + i + "@example.com", "password" + i); tenantToUsers.get(tenantIdentifier).add(user.getSupertokensUserId()); if (!recipeToUsers.containsKey("emailpassword")) { @@ -196,13 +197,14 @@ private void createUsers(TenantIdentifier tenantIdentifier, int numUsers, String } { Passwordless.CreateCodeResponse codeResponse = Passwordless.createCode( - tenantIdentifierWithStorage, + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), prefix + "pluser" + i + "@example.com", null, null, "abcd" ); - Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode(tenantIdentifierWithStorage, + Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode( + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), codeResponse.deviceId, codeResponse.deviceIdHash, "abcd", null); tenantToUsers.get(tenantIdentifier).add(response.user.getSupertokensUserId()); @@ -213,10 +215,12 @@ private void createUsers(TenantIdentifier tenantIdentifier, int numUsers, String recipeToUsers.get("passwordless").add(response.user.getSupertokensUserId()); } { - ThirdParty.SignInUpResponse user1 = ThirdParty.signInUp(tenantIdentifierWithStorage, + ThirdParty.SignInUpResponse user1 = ThirdParty.signInUp( + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "google", "googleid" + i, prefix + "tpuser" + i + "@example.com"); tenantToUsers.get(tenantIdentifier).add(user1.user.getSupertokensUserId()); - ThirdParty.SignInUpResponse user2 = ThirdParty.signInUp(tenantIdentifierWithStorage, + ThirdParty.SignInUpResponse user2 = ThirdParty.signInUp( + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "facebook", "fbid" + i, prefix + "tpuser" + i + "@example.com"); tenantToUsers.get(tenantIdentifier).add(user2.user.getSupertokensUserId()); diff --git a/src/test/java/io/supertokens/test/dashboard/apis/MultitenantAPITest.java b/src/test/java/io/supertokens/test/dashboard/apis/MultitenantAPITest.java index a8dab3316..bdf0e47c1 100644 --- a/src/test/java/io/supertokens/test/dashboard/apis/MultitenantAPITest.java +++ b/src/test/java/io/supertokens/test/dashboard/apis/MultitenantAPITest.java @@ -26,6 +26,7 @@ import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.multitenancy.exception.CannotModifyBaseConfigException; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.InvalidConfigException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.*; @@ -169,9 +170,10 @@ public void testSessionBehavior() throws Exception { String email = "test@example.com"; String password = "testPass123"; - AppIdentifierWithStorage appIdentifierWithStorage = t1.toAppIdentifier().withStorage( + Storage appIdentifierWithStorage = ( StorageLayer.getStorage(t1, process.getProcess())); - Dashboard.signUpDashboardUser(appIdentifierWithStorage, process.getProcess(), email, password); + Dashboard.signUpDashboardUser(t1.toAppIdentifier(), appIdentifierWithStorage, process.getProcess(), email, + password); // create a session String sessionId; diff --git a/src/test/java/io/supertokens/test/emailpassword/EmailPasswordTest.java b/src/test/java/io/supertokens/test/emailpassword/EmailPasswordTest.java index b9f9387bc..79da774a1 100644 --- a/src/test/java/io/supertokens/test/emailpassword/EmailPasswordTest.java +++ b/src/test/java/io/supertokens/test/emailpassword/EmailPasswordTest.java @@ -29,6 +29,8 @@ import io.supertokens.featureflag.FeatureFlagTestContent; import io.supertokens.multitenancy.Multitenancy; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.authRecipe.AuthRecipeStorage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.PasswordResetTokenInfo; @@ -85,14 +87,12 @@ public void testStorageLayerGetMailPasswordStorageLayerThrowsExceptionIfTypeIsNo if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { try { - new TenantIdentifierWithStorage(null, null, null, - StorageLayer.getStorage(process.getProcess())).getEmailPasswordStorage(); + StorageUtils.getEmailPasswordStorage(StorageLayer.getStorage(process.getProcess())); throw new Exception("Should not come here"); } catch (UnsupportedOperationException e) { } } else { - new TenantIdentifierWithStorage(null, null, null, - StorageLayer.getStorage(process.getProcess())).getEmailPasswordStorage(); + StorageUtils.getEmailPasswordStorage(StorageLayer.getStorage(process.getProcess())); } process.kill(); @@ -938,9 +938,9 @@ public void updateEmailSucceedsIfEmailUsedByOtherPrimaryUserInDifferentTenantWhi new ThirdPartyConfig(true, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(true), new JsonObject())); - TenantIdentifierWithStorage tenantIdentifierWithStorage = new TenantIdentifierWithStorage(null, null, "t1", - StorageLayer.getStorage(process.main)); - AuthRecipeUserInfo user0 = EmailPassword.signUp(tenantIdentifierWithStorage, process.getProcess(), + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(process.main)); + AuthRecipeUserInfo user0 = EmailPassword.signUp( + new TenantIdentifier(null, null, "t1"), tenantIdentifierWithStorage, process.getProcess(), "someemail1@gmail.com", "pass1234"); @@ -975,9 +975,9 @@ public void updateEmailFailsIfEmailUsedByOtherPrimaryUserInDifferentTenant() new ThirdPartyConfig(true, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(true), new JsonObject())); - TenantIdentifierWithStorage tenantIdentifierWithStorage = new TenantIdentifierWithStorage(null, null, "t1", - StorageLayer.getStorage(process.main)); - AuthRecipeUserInfo user0 = EmailPassword.signUp(tenantIdentifierWithStorage, process.getProcess(), + Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(process.main)); + AuthRecipeUserInfo user0 = EmailPassword.signUp( + new TenantIdentifier(null, null, "t1"), tenantIdentifierWithStorage, process.getProcess(), "someemail1@gmail.com", "pass1234"); @@ -986,7 +986,8 @@ public void updateEmailFailsIfEmailUsedByOtherPrimaryUserInDifferentTenant() AuthRecipeUserInfo user = EmailPassword.signUp(process.getProcess(), "someemail@gmail.com", "somePass"); AuthRecipe.createPrimaryUser(process.main, user.getSupertokensUserId()); - Multitenancy.addUserIdToTenant(process.main, tenantIdentifierWithStorage, user.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.main, + new TenantIdentifier(null, null, "t1"), tenantIdentifierWithStorage, user.getSupertokensUserId()); try { EmailPassword.updateUsersEmailOrPassword(process.main, user.getSupertokensUserId(), "someemail1@gmail.com", null); diff --git a/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java b/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java index 7d75a27b2..455feda14 100644 --- a/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java +++ b/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java @@ -151,29 +151,29 @@ public void testSignUpAndLoginInDifferentTenants() createTenants(process); TenantIdentifier t1 = new TenantIdentifier(null, "a1", null); - TenantIdentifierWithStorage t1storage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); + Storage t1storage = (StorageLayer.getStorage(t1, process.getProcess())); TenantIdentifier t2 = new TenantIdentifier(null, "a1", "t1"); - TenantIdentifierWithStorage t2storage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t2storage = (StorageLayer.getStorage(t2, process.getProcess())); TenantIdentifier t3 = new TenantIdentifier(null, "a1", "t2"); - TenantIdentifierWithStorage t3storage = t3.withStorage(StorageLayer.getStorage(t3, process.getProcess())); + Storage t3storage = (StorageLayer.getStorage(t3, process.getProcess())); { - EmailPassword.signUp(t1storage, process.getProcess(), "user1@example.com", "password1"); - AuthRecipeUserInfo userInfo = EmailPassword.signIn(t1storage, process.getProcess(), "user1@example.com", + EmailPassword.signUp(t1, t1storage, process.getProcess(), "user1@example.com", "password1"); + AuthRecipeUserInfo userInfo = EmailPassword.signIn(t1, t1storage, process.getProcess(), "user1@example.com", "password1"); assertEquals("user1@example.com", userInfo.loginMethods[0].email); } { - EmailPassword.signUp(t2storage, process.getProcess(), "user2@example.com", "password2"); - AuthRecipeUserInfo userInfo = EmailPassword.signIn(t2storage, process.getProcess(), "user2@example.com", + EmailPassword.signUp(t2, t2storage, process.getProcess(), "user2@example.com", "password2"); + AuthRecipeUserInfo userInfo = EmailPassword.signIn(t2, t2storage, process.getProcess(), "user2@example.com", "password2"); assertEquals("user2@example.com", userInfo.loginMethods[0].email); } { - EmailPassword.signUp(t3storage, process.getProcess(), "user3@example.com", "password3"); - AuthRecipeUserInfo userInfo = EmailPassword.signIn(t3storage, process.getProcess(), "user3@example.com", + EmailPassword.signUp(t3, t3storage, process.getProcess(), "user3@example.com", "password3"); + AuthRecipeUserInfo userInfo = EmailPassword.signIn(t3, t3storage, process.getProcess(), "user3@example.com", "password3"); assertEquals("user3@example.com", userInfo.loginMethods[0].email); } @@ -203,31 +203,31 @@ public void testSameEmailWithDifferentPasswordsOnDifferentTenantsWorksCorrectly( createTenants(process); TenantIdentifier t1 = new TenantIdentifier(null, "a1", null); - TenantIdentifierWithStorage t1storage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); + Storage t1storage = (StorageLayer.getStorage(t1, process.getProcess())); TenantIdentifier t2 = new TenantIdentifier(null, "a1", "t1"); - TenantIdentifierWithStorage t2storage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t2storage = (StorageLayer.getStorage(t2, process.getProcess())); TenantIdentifier t3 = new TenantIdentifier(null, "a1", "t2"); - TenantIdentifierWithStorage t3storage = t3.withStorage(StorageLayer.getStorage(t3, process.getProcess())); + Storage t3storage = (StorageLayer.getStorage(t3, process.getProcess())); - EmailPassword.signUp(t1storage, process.getProcess(), "user@example.com", "password1"); - EmailPassword.signUp(t2storage, process.getProcess(), "user@example.com", "password2"); - EmailPassword.signUp(t3storage, process.getProcess(), "user@example.com", "password3"); + EmailPassword.signUp(t1, t1storage, process.getProcess(), "user@example.com", "password1"); + EmailPassword.signUp(t2, t2storage, process.getProcess(), "user@example.com", "password2"); + EmailPassword.signUp(t3, t3storage, process.getProcess(), "user@example.com", "password3"); { - AuthRecipeUserInfo userInfo = EmailPassword.signIn(t1storage, process.getProcess(), "user@example.com", + AuthRecipeUserInfo userInfo = EmailPassword.signIn(t1, t1storage, process.getProcess(), "user@example.com", "password1"); assertEquals("user@example.com", userInfo.loginMethods[0].email); } { - AuthRecipeUserInfo userInfo = EmailPassword.signIn(t2storage, process.getProcess(), "user@example.com", + AuthRecipeUserInfo userInfo = EmailPassword.signIn(t2, t2storage, process.getProcess(), "user@example.com", "password2"); assertEquals("user@example.com", userInfo.loginMethods[0].email); } { - AuthRecipeUserInfo userInfo = EmailPassword.signIn(t3storage, process.getProcess(), "user@example.com", + AuthRecipeUserInfo userInfo = EmailPassword.signIn(t3, t3storage, process.getProcess(), "user@example.com", "password3"); assertEquals("user@example.com", userInfo.loginMethods[0].email); } @@ -257,42 +257,48 @@ public void testGetUserUsingIdReturnsCorrectUser() createTenants(process); TenantIdentifier t1 = new TenantIdentifier(null, "a1", null); - TenantIdentifierWithStorage t1storage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); + Storage t1storage = (StorageLayer.getStorage(t1, process.getProcess())); TenantIdentifier t2 = new TenantIdentifier(null, "a1", "t1"); - TenantIdentifierWithStorage t2storage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t2storage = (StorageLayer.getStorage(t2, process.getProcess())); TenantIdentifier t3 = new TenantIdentifier(null, "a1", "t2"); - TenantIdentifierWithStorage t3storage = t3.withStorage(StorageLayer.getStorage(t3, process.getProcess())); + Storage t3storage = (StorageLayer.getStorage(t3, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t1storage, process.getProcess(), "user1@example.com", "password1"); - AuthRecipeUserInfo user2 = EmailPassword.signUp(t2storage, process.getProcess(), "user2@example.com", "password2"); - AuthRecipeUserInfo user3 = EmailPassword.signUp(t3storage, process.getProcess(), "user3@example.com", "password3"); + AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1storage, process.getProcess(), "user1@example.com", + "password1"); + AuthRecipeUserInfo user2 = EmailPassword.signUp(t2, t2storage, process.getProcess(), "user2@example.com", + "password2"); + AuthRecipeUserInfo user3 = EmailPassword.signUp(t3, t3storage, process.getProcess(), "user3@example.com", + "password3"); Storage storage = StorageLayer.getStorage(process.getProcess()); { AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingId( + new AppIdentifier(null, "a1"), StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( - new AppIdentifierWithStorages(null, "a1", new Storage[]{storage}), + new AppIdentifier(null, "a1"), new Storage[]{storage}, user1.getSupertokensUserId(), - UserIdType.SUPERTOKENS).appIdentifierWithStorage, user1.getSupertokensUserId()); + UserIdType.SUPERTOKENS).storage, user1.getSupertokensUserId()); assertEquals(user1, userInfo); } { AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingId( + new AppIdentifier(null, "a1"), StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( - new AppIdentifierWithStorages(null, "a1", new Storage[]{storage}), + new AppIdentifier(null, "a1"), new Storage[]{storage}, user2.getSupertokensUserId(), - UserIdType.SUPERTOKENS).appIdentifierWithStorage, user2.getSupertokensUserId()); + UserIdType.SUPERTOKENS).storage, user2.getSupertokensUserId()); assertEquals(user2, userInfo); } { AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingId( + new AppIdentifier(null, "a1"), StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( - new AppIdentifierWithStorages(null, "a1", new Storage[]{storage}), + new AppIdentifier(null, "a1"), new Storage[]{storage}, user3.getSupertokensUserId(), - UserIdType.SUPERTOKENS).appIdentifierWithStorage, user3.getSupertokensUserId()); + UserIdType.SUPERTOKENS).storage, user3.getSupertokensUserId()); assertEquals(user3, userInfo); } @@ -320,28 +326,31 @@ public void testGetUserUsingEmailReturnsTheUserFromTheSpecificTenant() createTenants(process); TenantIdentifier t1 = new TenantIdentifier(null, "a1", null); - TenantIdentifierWithStorage t1storage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); + Storage t1storage = (StorageLayer.getStorage(t1, process.getProcess())); TenantIdentifier t2 = new TenantIdentifier(null, "a1", "t1"); - TenantIdentifierWithStorage t2storage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t2storage = (StorageLayer.getStorage(t2, process.getProcess())); TenantIdentifier t3 = new TenantIdentifier(null, "a1", "t2"); - TenantIdentifierWithStorage t3storage = t3.withStorage(StorageLayer.getStorage(t3, process.getProcess())); + Storage t3storage = (StorageLayer.getStorage(t3, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t1storage, process.getProcess(), "user@example.com", "password1"); - AuthRecipeUserInfo user2 = EmailPassword.signUp(t2storage, process.getProcess(), "user@example.com", "password2"); - AuthRecipeUserInfo user3 = EmailPassword.signUp(t3storage, process.getProcess(), "user@example.com", "password3"); + AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1storage, process.getProcess(), "user@example.com", + "password1"); + AuthRecipeUserInfo user2 = EmailPassword.signUp(t2, t2storage, process.getProcess(), "user@example.com", + "password2"); + AuthRecipeUserInfo user3 = EmailPassword.signUp(t3, t3storage, process.getProcess(), "user@example.com", + "password3"); { - AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingEmail(t1storage, user1.loginMethods[0].email); + AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingEmail(t1, t1storage, user1.loginMethods[0].email); assertEquals(user1, userInfo); } { - AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingEmail(t2storage, user2.loginMethods[0].email); + AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingEmail(t2, t2storage, user2.loginMethods[0].email); assertEquals(user2, userInfo); } { - AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingEmail(t3storage, user3.loginMethods[0].email); + AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingEmail(t3, t3storage, user3.loginMethods[0].email); assertEquals(user3, userInfo); } @@ -371,57 +380,65 @@ public void testUpdatePasswordWorksCorrectlyAcrossAllTenants() createTenants(process); TenantIdentifier t1 = new TenantIdentifier(null, "a1", null); - TenantIdentifierWithStorage t1storage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); + Storage t1storage = (StorageLayer.getStorage(t1, process.getProcess())); TenantIdentifier t2 = new TenantIdentifier(null, "a1", "t1"); - TenantIdentifierWithStorage t2storage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t2storage = (StorageLayer.getStorage(t2, process.getProcess())); TenantIdentifier t3 = new TenantIdentifier(null, "a1", "t2"); - TenantIdentifierWithStorage t3storage = t3.withStorage(StorageLayer.getStorage(t3, process.getProcess())); + Storage t3storage = (StorageLayer.getStorage(t3, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t1storage, process.getProcess(), "user@example.com", "password1"); - AuthRecipeUserInfo user2 = EmailPassword.signUp(t2storage, process.getProcess(), "user@example.com", "password2"); - AuthRecipeUserInfo user3 = EmailPassword.signUp(t3storage, process.getProcess(), "user@example.com", "password3"); + AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1storage, process.getProcess(), "user@example.com", + "password1"); + AuthRecipeUserInfo user2 = EmailPassword.signUp(t2, t2storage, process.getProcess(), "user@example.com", + "password2"); + AuthRecipeUserInfo user3 = EmailPassword.signUp(t3, t3storage, process.getProcess(), "user@example.com", + "password3"); Storage storage = StorageLayer.getStorage(process.getProcess()); EmailPassword.updateUsersEmailOrPassword( + new AppIdentifier(null, "a1"), StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( - new AppIdentifierWithStorages(null, "a1", new Storage[]{storage}), + new AppIdentifier(null, "a1"), new Storage[]{storage}, user1.getSupertokensUserId(), - UserIdType.SUPERTOKENS).appIdentifierWithStorage, + UserIdType.SUPERTOKENS).storage, process.getProcess(), user1.getSupertokensUserId(), null, "newpassword1"); EmailPassword.updateUsersEmailOrPassword( + new AppIdentifier(null, "a1"), StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( - new AppIdentifierWithStorages(null, "a1", new Storage[]{storage}), + new AppIdentifier(null, "a1"), new Storage[]{storage}, user2.getSupertokensUserId(), - UserIdType.SUPERTOKENS).appIdentifierWithStorage, + UserIdType.SUPERTOKENS).storage, process.getProcess(), user2.getSupertokensUserId(), null, "newpassword2"); EmailPassword.updateUsersEmailOrPassword( + new AppIdentifier(null, "a1"), StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( - new AppIdentifierWithStorages(null, "a1", new Storage[]{storage}), + new AppIdentifier(null, "a1"), new Storage[]{storage}, user3.getSupertokensUserId(), - UserIdType.SUPERTOKENS).appIdentifierWithStorage, + UserIdType.SUPERTOKENS).storage, process.getProcess(), user3.getSupertokensUserId(), null, "newpassword3"); { - t1 = StorageLayer.getTenantIdentifierWithStorageAndUserIdMappingForUser(process.getProcess(), t1, user1.getSupertokensUserId(), - UserIdType.SUPERTOKENS).tenantIdentifierWithStorage; - AuthRecipeUserInfo userInfo = EmailPassword.signIn(t1storage, process.getProcess(), "user@example.com", + t1storage = StorageLayer.getTenantIdentifierWithStorageAndUserIdMappingForUser(process.getProcess(), t1, user1.getSupertokensUserId(), + UserIdType.SUPERTOKENS).storage; + AuthRecipeUserInfo userInfo = EmailPassword.signIn(t1, t1storage, process.getProcess(), "user@example.com", "newpassword1"); assertEquals(user1.getSupertokensUserId(), userInfo.getSupertokensUserId()); } { - t2 = StorageLayer.getTenantIdentifierWithStorageAndUserIdMappingForUser(process.getProcess(), t2, user2.getSupertokensUserId(), - UserIdType.SUPERTOKENS).tenantIdentifierWithStorage; - AuthRecipeUserInfo userInfo = EmailPassword.signIn(t2storage, process.getProcess(), "user@example.com", + t2storage = StorageLayer.getTenantIdentifierWithStorageAndUserIdMappingForUser(process.getProcess(), t2, + user2.getSupertokensUserId(), + UserIdType.SUPERTOKENS).storage; + AuthRecipeUserInfo userInfo = EmailPassword.signIn(t2, t2storage, process.getProcess(), "user@example.com", "newpassword2"); assertEquals(user2.getSupertokensUserId(), userInfo.getSupertokensUserId()); } { - t3 = StorageLayer.getTenantIdentifierWithStorageAndUserIdMappingForUser(process.getProcess(), t3, user3.getSupertokensUserId(), - UserIdType.SUPERTOKENS).tenantIdentifierWithStorage; - AuthRecipeUserInfo userInfo = EmailPassword.signIn(t3storage, process.getProcess(), "user@example.com", + t3storage = StorageLayer.getTenantIdentifierWithStorageAndUserIdMappingForUser(process.getProcess(), t3, + user3.getSupertokensUserId(), + UserIdType.SUPERTOKENS).storage; + AuthRecipeUserInfo userInfo = EmailPassword.signIn(t3, t3storage, process.getProcess(), "user@example.com", "newpassword3"); assertEquals(user3.getSupertokensUserId(), userInfo.getSupertokensUserId()); } diff --git a/src/test/java/io/supertokens/test/emailpassword/api/MultitenantAPITest.java b/src/test/java/io/supertokens/test/emailpassword/api/MultitenantAPITest.java index cc4ff6fdf..43c4d6e85 100644 --- a/src/test/java/io/supertokens/test/emailpassword/api/MultitenantAPITest.java +++ b/src/test/java/io/supertokens/test/emailpassword/api/MultitenantAPITest.java @@ -689,7 +689,7 @@ public void testImportUsersWorksCorrectlyAcrossTenants() throws Exception { EmailPasswordSQLStorage storage = (EmailPasswordSQLStorage) StorageLayer.getStorage(t2, process.getProcess()); - storage.signUp(t2.withStorage(storage), "userId", email, combinedPasswordHash, timeJoined); + storage.signUp(t2, "userId", email, combinedPasswordHash, timeJoined); successfulSignIn(t2, email, password); wrongCredentialsSignIn(t1, email, password); diff --git a/src/test/java/io/supertokens/test/multitenant/AppTenantUserTest.java b/src/test/java/io/supertokens/test/multitenant/AppTenantUserTest.java index b69b90bf5..73e016b66 100644 --- a/src/test/java/io/supertokens/test/multitenant/AppTenantUserTest.java +++ b/src/test/java/io/supertokens/test/multitenant/AppTenantUserTest.java @@ -25,6 +25,7 @@ import io.supertokens.multitenancy.Multitenancy; import io.supertokens.pluginInterface.ActiveUsersStorage; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.multitenancy.*; import io.supertokens.pluginInterface.nonAuthRecipe.NonAuthRecipeStorage; @@ -116,11 +117,11 @@ public void testDeletingAppDeleteNonAuthRecipeData() throws Exception { new JsonObject() ), false); - TenantIdentifierWithStorage tWithStorage = t.withStorage( + Storage tWithStorage = ( StorageLayer.getStorage(t, process.getProcess())); - AuthRecipeUserInfo user = EmailPassword.signUp(tWithStorage, process.getProcess(), "test@example.com", + AuthRecipeUserInfo user = EmailPassword.signUp(t, tWithStorage, process.getProcess(), "test@example.com", "password"); String userId = user.getSupertokensUserId(); @@ -129,7 +130,7 @@ public void testDeletingAppDeleteNonAuthRecipeData() throws Exception { try { UserIdMapping.findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed( - tWithStorage.toAppIdentifierWithStorage(), userId, true); + t.toAppIdentifier(), tWithStorage, userId, true); fail(className); } catch (Exception ignored) { assertTrue(ignored.getMessage().contains("UserId is already in use")); @@ -156,7 +157,7 @@ public void testDeletingAppDeleteNonAuthRecipeData() throws Exception { new JsonObject() ), false); - UserIdMapping.findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed(tWithStorage.toAppIdentifierWithStorage(), + UserIdMapping.findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed(t.toAppIdentifier(), tWithStorage, userId, true); } } @@ -213,9 +214,9 @@ public void testDisassociationOfUserDeletesNonAuthRecipeData() throws Exception new JsonObject() ), false); - TenantIdentifierWithStorage appWithStorage = app.withStorage( + Storage appWithStorage = ( StorageLayer.getStorage(app, process.getProcess())); - TenantIdentifierWithStorage tenantWithStorage = tenant.withStorage( + Storage tenantWithStorage = ( StorageLayer.getStorage(tenant, process.getProcess())); for (String className : classNames) { @@ -223,29 +224,29 @@ public void testDisassociationOfUserDeletesNonAuthRecipeData() throws Exception continue; } - AuthRecipeUserInfo user = EmailPassword.signUp(appWithStorage, process.getProcess(), "test@example.com", "password"); + AuthRecipeUserInfo user = EmailPassword.signUp(app, appWithStorage, process.getProcess(), "test@example.com", "password"); String userId = user.getSupertokensUserId(); - Multitenancy.addUserIdToTenant(process.getProcess(), tenantWithStorage, userId); + Multitenancy.addUserIdToTenant(process.getProcess(), tenant, tenantWithStorage, userId); // create entry in nonAuth table - tenantWithStorage.getStorage().addInfoToNonAuthRecipesBasedOnUserId(tenant, className, userId); + tenantWithStorage.addInfoToNonAuthRecipesBasedOnUserId(tenant, className, userId); try { UserIdMapping.findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed( - tenantWithStorage.toAppIdentifierWithStorage(), userId, true); + tenant.toAppIdentifier(), tenantWithStorage, userId, true); fail(className); } catch (Exception ignored) { assertTrue(ignored.getMessage().contains("UserId is already in use")); } // Disassociate user - Multitenancy.removeUserIdFromTenant(process.getProcess(), tenantWithStorage, userId, null); + Multitenancy.removeUserIdFromTenant(process.getProcess(), tenant, tenantWithStorage, userId, null); - assertFalse(AuthRecipe.deleteNonAuthRecipeUser(tenantWithStorage, + assertFalse(AuthRecipe.deleteNonAuthRecipeUser(tenant, tenantWithStorage, userId)); // Nothing deleted indicates that the non auth recipe user data was deleted already - AuthRecipe.deleteUser(appWithStorage.toAppIdentifierWithStorage(), userId); + AuthRecipe.deleteUser(app.toAppIdentifier(), appWithStorage, userId); } process.kill(); @@ -286,20 +287,20 @@ public void deletingTenantKeepsTheUserInTheApp() throws Exception { new JsonObject() ), false); - TenantIdentifierWithStorage appWithStorage = app.withStorage( + Storage appWithStorage = ( StorageLayer.getStorage(app, process.getProcess())); - TenantIdentifierWithStorage tenantWithStorage = tenant.withStorage( + Storage tenantWithStorage = ( StorageLayer.getStorage(tenant, process.getProcess())); - AuthRecipeUserInfo user = EmailPassword.signUp(tenantWithStorage, process.getProcess(), "test@example.com", "password"); + AuthRecipeUserInfo user = EmailPassword.signUp(tenant, tenantWithStorage, process.getProcess(), "test@example.com", "password"); String userId = user.getSupertokensUserId(); Multitenancy.deleteTenant(tenant, process.getProcess()); - Multitenancy.addUserIdToTenant(process.getProcess(), appWithStorage, + Multitenancy.addUserIdToTenant(process.getProcess(), app, appWithStorage, userId); // user id must be intact to do this - AuthRecipeUserInfo appUser = EmailPassword.getUserUsingId(appWithStorage.toAppIdentifierWithStorage(), userId); + AuthRecipeUserInfo appUser = EmailPassword.getUserUsingId(app.toAppIdentifier(), appWithStorage, userId); assertNotNull(appUser); assertEquals(userId, appUser.getSupertokensUserId()); diff --git a/src/test/java/io/supertokens/test/multitenant/TestAppData.java b/src/test/java/io/supertokens/test/multitenant/TestAppData.java index f6c4c679e..52cdd0d10 100644 --- a/src/test/java/io/supertokens/test/multitenant/TestAppData.java +++ b/src/test/java/io/supertokens/test/multitenant/TestAppData.java @@ -29,6 +29,7 @@ import io.supertokens.multitenancy.Multitenancy; import io.supertokens.passwordless.Passwordless; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.*; @@ -115,56 +116,62 @@ public void testThatDeletingAppDeleteDataFromAllTables() throws Exception { new JsonObject() ), false); - TenantIdentifierWithStorage appWithStorage = app.withStorage( + Storage appWithStorage = ( StorageLayer.getStorage(app, process.getProcess())); - String[] allTableNames = appWithStorage.getStorage().getAllTablesInTheDatabase(); + String[] allTableNames = appWithStorage.getAllTablesInTheDatabase(); allTableNames = removeStrings(allTableNames, tablesToIgnore); Arrays.sort(allTableNames); // Add all recipe data - AuthRecipeUserInfo epUser = EmailPassword.signUp(appWithStorage, process.getProcess(), "test@example.com", "password"); - EmailPassword.generatePasswordResetTokenBeforeCdi4_0(appWithStorage, process.getProcess(), epUser.getSupertokensUserId()); + AuthRecipeUserInfo epUser = EmailPassword.signUp(app, appWithStorage, process.getProcess(), "test@example.com", + "password"); + EmailPassword.generatePasswordResetTokenBeforeCdi4_0(app, appWithStorage, process.getProcess(), + epUser.getSupertokensUserId()); - ThirdParty.SignInUpResponse tpUser = ThirdParty.signInUp(appWithStorage, process.getProcess(), "google", + ThirdParty.SignInUpResponse tpUser = ThirdParty.signInUp(app, appWithStorage, process.getProcess(), "google", "googleid", "test@example.com"); - Passwordless.CreateCodeResponse code = Passwordless.createCode(appWithStorage, process.getProcess(), + Passwordless.CreateCodeResponse code = Passwordless.createCode(app, appWithStorage, process.getProcess(), "test@example.com", null, null, null); - Passwordless.ConsumeCodeResponse plUser = Passwordless.consumeCode(appWithStorage, process.getProcess(), + Passwordless.ConsumeCodeResponse plUser = Passwordless.consumeCode(app, appWithStorage, process.getProcess(), code.deviceId, code.deviceIdHash, code.userInputCode, null); - Passwordless.createCode(appWithStorage, process.getProcess(), "test@example.com", null, null, null); + Passwordless.createCode(app, appWithStorage, process.getProcess(), "test@example.com", null, null, null); - Dashboard.signUpDashboardUser(appWithStorage.toAppIdentifierWithStorage(), process.getProcess(), + Dashboard.signUpDashboardUser(app.toAppIdentifier(), appWithStorage, process.getProcess(), "user@example.com", "password"); - Dashboard.signInDashboardUser(appWithStorage.toAppIdentifierWithStorage(), process.getProcess(), + Dashboard.signInDashboardUser(app.toAppIdentifier(), appWithStorage, process.getProcess(), "user@example.com", "password"); - String evToken = EmailVerification.generateEmailVerificationToken(appWithStorage, process.getProcess(), + String evToken = EmailVerification.generateEmailVerificationToken(app, appWithStorage, process.getProcess(), epUser.getSupertokensUserId(), epUser.loginMethods[0].email); - EmailVerification.verifyEmail(appWithStorage, evToken); - EmailVerification.generateEmailVerificationToken(appWithStorage, process.getProcess(), tpUser.user.getSupertokensUserId(), + EmailVerification.verifyEmail(app, appWithStorage, evToken); + EmailVerification.generateEmailVerificationToken(app, appWithStorage, process.getProcess(), + tpUser.user.getSupertokensUserId(), tpUser.user.loginMethods[0].email); - Session.createNewSession(appWithStorage, process.getProcess(), epUser.getSupertokensUserId(), new JsonObject(), new JsonObject()); + Session.createNewSession(app, appWithStorage, process.getProcess(), epUser.getSupertokensUserId(), + new JsonObject(), new JsonObject()); - UserRoles.createNewRoleOrModifyItsPermissions(appWithStorage.toAppIdentifierWithStorage(), "role", + UserRoles.createNewRoleOrModifyItsPermissions(app.toAppIdentifier(), appWithStorage, "role", new String[]{"permission1", "permission2"}); - UserRoles.addRoleToUser(appWithStorage, epUser.getSupertokensUserId(), "role"); + UserRoles.addRoleToUser(app, appWithStorage, epUser.getSupertokensUserId(), "role"); - TOTPDevice totpDevice = Totp.registerDevice(appWithStorage.toAppIdentifierWithStorage(), process.getProcess(), + TOTPDevice totpDevice = Totp.registerDevice(app.toAppIdentifier(), appWithStorage, process.getProcess(), epUser.getSupertokensUserId(), "test", 1, 3); - Totp.verifyCode(appWithStorage, process.getProcess(), epUser.getSupertokensUserId(), + Totp.verifyCode(app, appWithStorage, process.getProcess(), epUser.getSupertokensUserId(), generateTotpCode(process.getProcess(), totpDevice, 0), true); - ActiveUsers.updateLastActive(appWithStorage.toAppIdentifierWithStorage(), process.getProcess(), epUser.getSupertokensUserId()); + ActiveUsers.updateLastActive(app.toAppIdentifier(), process.getProcess(), + epUser.getSupertokensUserId()); - UserMetadata.updateUserMetadata(appWithStorage.toAppIdentifierWithStorage(), epUser.getSupertokensUserId(), new JsonObject()); + UserMetadata.updateUserMetadata(app.toAppIdentifier(), appWithStorage, + epUser.getSupertokensUserId(), new JsonObject()); - UserIdMapping.createUserIdMapping(process.getProcess(), appWithStorage.toAppIdentifierWithStorage(), + UserIdMapping.createUserIdMapping(process.getProcess(), app.toAppIdentifier(), appWithStorage, plUser.user.getSupertokensUserId(), "externalid", null, false); - String[] tablesThatHaveData = appWithStorage.getStorage() + String[] tablesThatHaveData = appWithStorage .getAllTablesInTheDatabaseThatHasDataForAppId(app.getAppId()); tablesThatHaveData = removeStrings(tablesThatHaveData, tablesToIgnore); Arrays.sort(tablesThatHaveData); @@ -175,7 +182,7 @@ public void testThatDeletingAppDeleteDataFromAllTables() throws Exception { Multitenancy.deleteApp(app.toAppIdentifier(), process.getProcess()); // Check no data is remaining in any of the tables - tablesThatHaveData = appWithStorage.getStorage().getAllTablesInTheDatabaseThatHasDataForAppId(app.getAppId()); + tablesThatHaveData = appWithStorage.getAllTablesInTheDatabaseThatHasDataForAppId(app.getAppId()); tablesThatHaveData = removeStrings(tablesThatHaveData, tablesToIgnore); assertEquals(0, tablesThatHaveData.length); diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestApp.java b/src/test/java/io/supertokens/test/multitenant/api/TestApp.java index 8a2b117bc..5734e5d52 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestApp.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestApp.java @@ -322,7 +322,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { try { - super.sendTextResponse(200, this.getTenantStorage(req).getAppId(), resp); + getTenantStorage(req); + super.sendTextResponse(200, this.getTenantIdentifier(req).getAppId(), resp); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain.java b/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain.java index a41b0487c..a560b70a3 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestConnectionUriDomain.java @@ -382,7 +382,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { try { - super.sendTextResponse(200, this.getTenantStorage(req).getConnectionUriDomain(), resp); + getTenantStorage(req); + super.sendTextResponse(200, this.getTenantIdentifier(req).getConnectionUriDomain(), resp); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestTenant.java b/src/test/java/io/supertokens/test/multitenant/api/TestTenant.java index e9959d242..0d222190a 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestTenant.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestTenant.java @@ -272,7 +272,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { try { - super.sendTextResponse(200, this.getTenantStorage(req).getTenantId(), resp); + getTenantStorage(req); + super.sendTextResponse(200, this.getTenantIdentifier(req).getTenantId(), resp); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestTenantIdIsNotPresentForOlderCDI.java b/src/test/java/io/supertokens/test/multitenant/api/TestTenantIdIsNotPresentForOlderCDI.java index 1b12646d4..5aac955c6 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestTenantIdIsNotPresentForOlderCDI.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestTenantIdIsNotPresentForOlderCDI.java @@ -32,6 +32,7 @@ import io.supertokens.passwordless.Passwordless; import io.supertokens.passwordless.exceptions.*; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException; import io.supertokens.pluginInterface.exceptions.InvalidConfigException; @@ -281,12 +282,12 @@ private void createUsers(TenantIdentifier tenantIdentifier, int numUsers, String tenantToUsers.put(tenantIdentifier, new ArrayList<>()); } - TenantIdentifierWithStorage tenantIdentifierWithStorage = tenantIdentifier.withStorage( + Storage tenantIdentifierWithStorage = ( StorageLayer.getStorage(tenantIdentifier, process.getProcess())); for (int i = 0; i < numUsers; i++) { { AuthRecipeUserInfo user = EmailPassword.signUp( - tenantIdentifierWithStorage, process.getProcess(), + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), prefix + "epuser" + i + "@example.com", "password" + i); tenantToUsers.get(tenantIdentifier).add(user.getSupertokensUserId()); if (!recipeToUsers.containsKey("emailpassword")) { @@ -296,13 +297,15 @@ private void createUsers(TenantIdentifier tenantIdentifier, int numUsers, String } { Passwordless.CreateCodeResponse codeResponse = Passwordless.createCode( + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), prefix + "pluser" + i + "@example.com", null, null, "abcd" ); - Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode(tenantIdentifierWithStorage, + Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode( + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), codeResponse.deviceId, codeResponse.deviceIdHash, "abcd", null); tenantToUsers.get(tenantIdentifier).add(response.user.getSupertokensUserId()); @@ -313,10 +316,12 @@ private void createUsers(TenantIdentifier tenantIdentifier, int numUsers, String recipeToUsers.get("passwordless").add(response.user.getSupertokensUserId()); } { - ThirdParty.SignInUpResponse user1 = ThirdParty.signInUp(tenantIdentifierWithStorage, + ThirdParty.SignInUpResponse user1 = ThirdParty.signInUp( + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "google", "googleid" + i, prefix + "tpuser" + i + "@example.com"); tenantToUsers.get(tenantIdentifier).add(user1.user.getSupertokensUserId()); - ThirdParty.SignInUpResponse user2 = ThirdParty.signInUp(tenantIdentifierWithStorage, + ThirdParty.SignInUpResponse user2 = ThirdParty.signInUp( + tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "facebook", "fbid" + i, prefix + "tpuser" + i + "@example.com"); tenantToUsers.get(tenantIdentifier).add(user2.user.getSupertokensUserId()); diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java b/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java index 60ffd7a3e..90ab8acf9 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java @@ -29,12 +29,12 @@ import io.supertokens.passwordless.Passwordless; import io.supertokens.pluginInterface.ActiveUsersStorage; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.exceptions.InvalidConfigException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.jwt.JWTRecipeStorage; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.nonAuthRecipe.NonAuthRecipeStorage; import io.supertokens.pluginInterface.usermetadata.UserMetadataStorage; @@ -275,23 +275,24 @@ public void testEmailPasswordUsersHaveTenantIds() throws Exception { TenantIdentifier t1 = new TenantIdentifier(null, "a1", "t1"); TenantIdentifier t2 = new TenantIdentifier(null, "a1", "t2"); - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); - TenantIdentifierWithStorage t2WithStorage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user = EmailPassword.signUp(t1WithStorage, + AuthRecipeUserInfo user = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "user@example.com", "password"); assertArrayEquals(new String[]{"t1"}, user.tenantIds.toArray()); - Multitenancy.addUserIdToTenant(process.getProcess(), t2WithStorage, user.getSupertokensUserId()); - user = EmailPassword.getUserUsingId(t1WithStorage.toAppIdentifierWithStorage(), user.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, user.getSupertokensUserId()); + user = EmailPassword.getUserUsingId(t1.toAppIdentifier(), t1WithStorage, user.getSupertokensUserId()); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - user = EmailPassword.getUserUsingEmail(t1WithStorage, user.loginMethods[0].email); + user = EmailPassword.getUserUsingEmail(t1, t1WithStorage, user.loginMethods[0].email); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - Multitenancy.removeUserIdFromTenant(process.getProcess(), t1WithStorage, user.getSupertokensUserId(), null); - user = EmailPassword.getUserUsingId(t1WithStorage.toAppIdentifierWithStorage(), user.getSupertokensUserId()); + Multitenancy.removeUserIdFromTenant(process.getProcess(), t1, t1WithStorage, user.getSupertokensUserId(), + null); + user = EmailPassword.getUserUsingId(t1.toAppIdentifier(), t1WithStorage, user.getSupertokensUserId()); assertArrayEquals(new String[]{"t2"}, user.tenantIds.toArray()); } @@ -306,26 +307,30 @@ public void testPasswordlessUsersHaveTenantIds1() throws Exception { TenantIdentifier t1 = new TenantIdentifier(null, "a1", "t1"); TenantIdentifier t2 = new TenantIdentifier(null, "a1", "t2"); - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); - TenantIdentifierWithStorage t2WithStorage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); - Passwordless.CreateCodeResponse createCodeResponse = Passwordless.createCode(t1WithStorage, + Passwordless.CreateCodeResponse createCodeResponse = Passwordless.createCode(t1, t1WithStorage, process.getProcess(), "user@example.com", null, null, null); - Passwordless.ConsumeCodeResponse consumeCodeResponse = Passwordless.consumeCode(t1WithStorage, + Passwordless.ConsumeCodeResponse consumeCodeResponse = Passwordless.consumeCode(t1, t1WithStorage, process.getProcess(), createCodeResponse.deviceId, createCodeResponse.deviceIdHash, createCodeResponse.userInputCode, null); assertArrayEquals(new String[]{"t1"}, consumeCodeResponse.user.tenantIds.toArray()); AuthRecipeUserInfo user; - Multitenancy.addUserIdToTenant(process.getProcess(), t2WithStorage, consumeCodeResponse.user.getSupertokensUserId()); - user = Passwordless.getUserById(t1WithStorage.toAppIdentifierWithStorage(), consumeCodeResponse.user.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, + consumeCodeResponse.user.getSupertokensUserId()); + user = Passwordless.getUserById(t1.toAppIdentifier(), t1WithStorage, + consumeCodeResponse.user.getSupertokensUserId()); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - user = Passwordless.getUserByEmail(t1WithStorage, consumeCodeResponse.user.loginMethods[0].email); + user = Passwordless.getUserByEmail(t1, t1WithStorage, consumeCodeResponse.user.loginMethods[0].email); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - Multitenancy.removeUserIdFromTenant(process.getProcess(), t1WithStorage, consumeCodeResponse.user.getSupertokensUserId(), null); - user = Passwordless.getUserById(t1WithStorage.toAppIdentifierWithStorage(), consumeCodeResponse.user.getSupertokensUserId()); + Multitenancy.removeUserIdFromTenant(process.getProcess(), t1, t1WithStorage, + consumeCodeResponse.user.getSupertokensUserId(), null); + user = Passwordless.getUserById(t1.toAppIdentifier(), t1WithStorage, + consumeCodeResponse.user.getSupertokensUserId()); assertArrayEquals(new String[]{"t2"}, user.tenantIds.toArray()); } @@ -340,26 +345,30 @@ public void testPasswordlessUsersHaveTenantIds2() throws Exception { TenantIdentifier t1 = new TenantIdentifier(null, "a1", "t1"); TenantIdentifier t2 = new TenantIdentifier(null, "a1", "t2"); - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); - TenantIdentifierWithStorage t2WithStorage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); - Passwordless.CreateCodeResponse createCodeResponse = Passwordless.createCode(t1WithStorage, + Passwordless.CreateCodeResponse createCodeResponse = Passwordless.createCode(t1, t1WithStorage, process.getProcess(), null, "+919876543210", null, null); - Passwordless.ConsumeCodeResponse consumeCodeResponse = Passwordless.consumeCode(t1WithStorage, + Passwordless.ConsumeCodeResponse consumeCodeResponse = Passwordless.consumeCode(t1, t1WithStorage, process.getProcess(), createCodeResponse.deviceId, createCodeResponse.deviceIdHash, createCodeResponse.userInputCode, null); assertArrayEquals(new String[]{"t1"}, consumeCodeResponse.user.tenantIds.toArray()); AuthRecipeUserInfo user; - Multitenancy.addUserIdToTenant(process.getProcess(), t2WithStorage, consumeCodeResponse.user.getSupertokensUserId()); - user = Passwordless.getUserById(t1WithStorage.toAppIdentifierWithStorage(), consumeCodeResponse.user.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, + consumeCodeResponse.user.getSupertokensUserId()); + user = Passwordless.getUserById(t1.toAppIdentifier(), t1WithStorage, + consumeCodeResponse.user.getSupertokensUserId()); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - user = Passwordless.getUserByPhoneNumber(t1WithStorage, consumeCodeResponse.user.loginMethods[0].phoneNumber); + user = Passwordless.getUserByPhoneNumber(t1, t1WithStorage, + consumeCodeResponse.user.loginMethods[0].phoneNumber); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - Multitenancy.removeUserIdFromTenant(process.getProcess(), t1WithStorage, consumeCodeResponse.user.getSupertokensUserId(), null); - user = Passwordless.getUserById(t1WithStorage.toAppIdentifierWithStorage(), consumeCodeResponse.user.getSupertokensUserId()); + Multitenancy.removeUserIdFromTenant(process.getProcess(), t1, t1WithStorage, + consumeCodeResponse.user.getSupertokensUserId(), null); + user = Passwordless.getUserById(t1.toAppIdentifier(), t1WithStorage, consumeCodeResponse.user.getSupertokensUserId()); assertArrayEquals(new String[]{"t2"}, user.tenantIds.toArray()); } @@ -374,30 +383,32 @@ public void testThirdPartyUsersHaveTenantIds() throws Exception { TenantIdentifier t1 = new TenantIdentifier(null, "a1", "t1"); TenantIdentifier t2 = new TenantIdentifier(null, "a1", "t2"); - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); - TenantIdentifierWithStorage t2WithStorage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); - ThirdParty.SignInUpResponse signInUpResponse = ThirdParty.signInUp(t1WithStorage, process.getProcess(), + ThirdParty.SignInUpResponse signInUpResponse = ThirdParty.signInUp(t1, t1WithStorage, process.getProcess(), "google", "googleid", "user@example.com"); assertArrayEquals(new String[]{"t1"}, signInUpResponse.user.tenantIds.toArray()); - Multitenancy.addUserIdToTenant(process.getProcess(), t2WithStorage, signInUpResponse.user.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, + signInUpResponse.user.getSupertokensUserId()); AuthRecipeUserInfo user = ThirdParty.getUser( - t1WithStorage.toAppIdentifierWithStorage(), signInUpResponse.user.getSupertokensUserId()); + t1.toAppIdentifier(), t1WithStorage, signInUpResponse.user.getSupertokensUserId()); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - user = ThirdParty.getUsersByEmail(t1WithStorage, signInUpResponse.user.loginMethods[0].email)[0]; + user = ThirdParty.getUsersByEmail(t1, t1WithStorage, signInUpResponse.user.loginMethods[0].email)[0]; Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - user = ThirdParty.getUser(t1WithStorage, "google", "googleid"); + user = ThirdParty.getUser(t1, t1WithStorage, "google", "googleid"); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - user = ThirdParty.getUser(t2WithStorage, "google", "googleid"); + user = ThirdParty.getUser(t2, t2WithStorage, "google", "googleid"); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - Multitenancy.removeUserIdFromTenant(process.getProcess(), t1WithStorage, signInUpResponse.user.getSupertokensUserId(), null); - user = ThirdParty.getUser(t1WithStorage.toAppIdentifierWithStorage(), signInUpResponse.user.getSupertokensUserId()); + Multitenancy.removeUserIdFromTenant(process.getProcess(), t1, t1WithStorage, + signInUpResponse.user.getSupertokensUserId(), null); + user = ThirdParty.getUser(t1.toAppIdentifier(), t1WithStorage, signInUpResponse.user.getSupertokensUserId()); assertArrayEquals(new String[]{"t2"}, user.tenantIds.toArray()); } @@ -484,9 +495,9 @@ public void testDisassociateUserWithUserIdMappingAndSession() throws Exception { assertFalse(response.get("wasAlreadyAssociated").getAsBoolean()); TenantIdentifier t2 = new TenantIdentifier(null, "a1", "t2"); - TenantIdentifierWithStorage t2WithStorage = t2.withStorage(StorageLayer.getStorage(t2, process.getProcess())); + Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); - SessionInformationHolder session = Session.createNewSession(t2WithStorage, + SessionInformationHolder session = Session.createNewSession(t2, t2WithStorage, process.getProcess(), "externalid", new JsonObject(), new JsonObject()); response = TestMultitenancyAPIHelper.disassociateUserFromTenant(new TenantIdentifier(null, "a1", "t2"), @@ -495,7 +506,7 @@ public void testDisassociateUserWithUserIdMappingAndSession() throws Exception { assertTrue(response.get("wasAssociated").getAsBoolean()); try { - Session.getSession(t2WithStorage, session.session.handle); + Session.getSession(t2, t2WithStorage, session.session.handle); fail(); } catch (UnauthorisedException e) { // OK diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java b/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java index dd0bad0c3..13127ba7b 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java @@ -24,11 +24,12 @@ import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.multitenancy.exception.CannotModifyBaseConfigException; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.exceptions.InvalidConfigException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.usermetadata.sqlStorage.UserMetadataSQLStorage; import io.supertokens.storageLayer.StorageLayer; @@ -86,14 +87,14 @@ public void beforeEach() throws InterruptedException, InvalidProviderConfigExcep @Test public void testThatUserMetadataIsSavedInTheStorageWhereUserExists() throws Exception { TenantIdentifier t0 = new TenantIdentifier(null, null, null); - TenantIdentifierWithStorage t0WithStorage = t0.withStorage(StorageLayer.getStorage(t0, process.getProcess())); + Storage t0WithStorage = (StorageLayer.getStorage(t0, process.getProcess())); TenantIdentifier t1 = new TenantIdentifier(null, null, "t1"); - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); + Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); // Create users - AuthRecipeUserInfo user1 = EmailPassword.signUp(t0WithStorage, process.getProcess(), "test@example.com", "password123"); - AuthRecipeUserInfo user2 = EmailPassword.signUp(t1WithStorage, process.getProcess(), "test@example.com", "password123"); + AuthRecipeUserInfo user1 = EmailPassword.signUp(t0, t0WithStorage, process.getProcess(), "test@example.com", "password123"); + AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", "password123"); UserIdMapping.populateExternalUserIdForUsers(t0WithStorage, new AuthRecipeUserInfo[]{user1}); UserIdMapping.populateExternalUserIdForUsers(t1WithStorage, new AuthRecipeUserInfo[]{user2}); @@ -148,10 +149,8 @@ public void testThatUserMetadataIsSavedInTheStorageWhereUserExists() throws Exce } } - UserMetadataSQLStorage t0UserMetadataStorage = t0WithStorage.toAppIdentifierWithStorage() - .getUserMetadataStorage(); - UserMetadataSQLStorage t1UserMetadataStorage = t1WithStorage.toAppIdentifierWithStorage() - .getUserMetadataStorage(); + UserMetadataSQLStorage t0UserMetadataStorage = StorageUtils.getUserMetadataStorage(t0WithStorage); + UserMetadataSQLStorage t1UserMetadataStorage = StorageUtils.getUserMetadataStorage(t1WithStorage); // Ensure that the metadata is saved in the correct storage assertNotNull(t0UserMetadataStorage.getUserMetadata(t0.toAppIdentifier(), user1.getSupertokensUserId())); // ensure t0 storage does not have user2's metadata @@ -177,14 +176,14 @@ public void testThatUserMetadataIsSavedInTheStorageWhereUserExists() throws Exce @Test public void testThatUserRolesWorkWithDifferentTenantsOnDifferentStorages() throws Exception { TenantIdentifier t0 = new TenantIdentifier(null, null, null); - TenantIdentifierWithStorage t0WithStorage = t0.withStorage(StorageLayer.getStorage(t0, process.getProcess())); + Storage t0WithStorage = (StorageLayer.getStorage(t0, process.getProcess())); TenantIdentifier t1 = new TenantIdentifier(null, null, "t1"); - TenantIdentifierWithStorage t1WithStorage = t1.withStorage(StorageLayer.getStorage(t1, process.getProcess())); + Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); // Create users - AuthRecipeUserInfo user1 = EmailPassword.signUp(t0WithStorage, process.getProcess(), "test@example.com", "password123"); - AuthRecipeUserInfo user2 = EmailPassword.signUp(t1WithStorage, process.getProcess(), "test@example.com", "password123"); + AuthRecipeUserInfo user1 = EmailPassword.signUp(t0, t0WithStorage, process.getProcess(), "test@example.com", "password123"); + AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", "password123"); UserIdMapping.populateExternalUserIdForUsers(t0WithStorage, new AuthRecipeUserInfo[]{user1}); UserIdMapping.populateExternalUserIdForUsers(t1WithStorage, new AuthRecipeUserInfo[]{user2}); diff --git a/src/test/java/io/supertokens/test/totp/api/MultitenantAPITest.java b/src/test/java/io/supertokens/test/totp/api/MultitenantAPITest.java index e17b84ba9..fd2582bc2 100644 --- a/src/test/java/io/supertokens/test/totp/api/MultitenantAPITest.java +++ b/src/test/java/io/supertokens/test/totp/api/MultitenantAPITest.java @@ -273,7 +273,7 @@ public void testSameCodeUsedOnDifferentTenantsIsAllowed() throws Exception { int userCount = 1; for (TenantIdentifier tenant1 : tenants) { AuthRecipeUserInfo user = EmailPassword.signUp( - tenant1.withStorage(StorageLayer.getStorage(tenant1, process.getProcess())), process.getProcess(), + tenant1, (StorageLayer.getStorage(tenant1, process.getProcess())), process.getProcess(), "test@example.com", "password1"); String userId = user.getSupertokensUserId(); From dd688dac2c6d2aa56e0a4c015d407ab46c86a89d Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 1 Mar 2024 19:50:38 +0530 Subject: [PATCH 14/31] fix: bugs and tests --- .../supertokens/storageLayer/StorageLayer.java | 7 +++++++ .../java/io/supertokens/userroles/UserRoles.java | 16 ++++++++++++++-- .../io/supertokens/webserver/WebserverAPI.java | 7 +++++-- .../supertokens/webserver/api/core/HelloAPI.java | 5 +++-- .../webserver/api/core/NotFoundOrHelloAPI.java | 7 ++++--- .../webserver/api/userroles/AddUserRoleAPI.java | 2 +- .../test/thirdparty/api/MultitenantAPITest.java | 2 +- 7 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/main/java/io/supertokens/storageLayer/StorageLayer.java b/src/main/java/io/supertokens/storageLayer/StorageLayer.java index 517ee5d17..4e49e0864 100644 --- a/src/main/java/io/supertokens/storageLayer/StorageLayer.java +++ b/src/main/java/io/supertokens/storageLayer/StorageLayer.java @@ -434,6 +434,13 @@ public static StorageAndUserIdMapping getTenantIdentifierWithStorageAndUserIdMap return new StorageAndUserIdMapping(storage, mapping); } + UserIdMapping mapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( + tenantIdentifier.toAppIdentifier(), storage, + userId, userIdType); + if (mapping != null) { + return new StorageAndUserIdMapping(storage, mapping); + } + try { io.supertokens.useridmapping.UserIdMapping.findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed( tenantIdentifier.toAppIdentifier(), storage, userId, true); diff --git a/src/main/java/io/supertokens/userroles/UserRoles.java b/src/main/java/io/supertokens/userroles/UserRoles.java index 451d8f499..ceb3a86ef 100644 --- a/src/main/java/io/supertokens/userroles/UserRoles.java +++ b/src/main/java/io/supertokens/userroles/UserRoles.java @@ -31,13 +31,25 @@ import org.jetbrains.annotations.TestOnly; import javax.annotation.Nullable; +import java.util.Arrays; public class UserRoles { // add a role to a user and return true, if the role is already mapped to the user return false, but if // the role does not exist, throw an UNKNOWN_ROLE_EXCEPTION error - public static boolean addRoleToUser(TenantIdentifier tenantIdentifier, Storage storage, String userId, + public static boolean addRoleToUser(Main main, TenantIdentifier tenantIdentifier, Storage storage, String userId, String role) throws StorageQueryException, UnknownRoleException, TenantOrAppNotFoundException { + + // Roles are stored in public tenant storage and role to user mapping is stored in the tenant's storage + // We do this because it's not straight forward to replicate roles to all storages of an app + Storage appStorage = StorageLayer.getStorage( + tenantIdentifier.toAppIdentifier().getAsPublicTenantIdentifier(), main); + + String[] roles = getRoles(tenantIdentifier.toAppIdentifier(), appStorage); + if (!Arrays.asList(roles).contains(role)) { + throw new UnknownRoleException(); + } + try { StorageUtils.getUserRolesStorage(storage).addRoleToUser(tenantIdentifier, userId, role); return true; @@ -53,7 +65,7 @@ public static boolean addRoleToUser(Main main, String userId, String role) Storage storage = StorageLayer.getStorage(main); try { return addRoleToUser( - new TenantIdentifier(null, null, null), + main, new TenantIdentifier(null, null, null), storage, userId, role); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); diff --git a/src/main/java/io/supertokens/webserver/WebserverAPI.java b/src/main/java/io/supertokens/webserver/WebserverAPI.java index c31d9508f..a9a15e0f4 100644 --- a/src/main/java/io/supertokens/webserver/WebserverAPI.java +++ b/src/main/java/io/supertokens/webserver/WebserverAPI.java @@ -230,8 +230,10 @@ private String getTenantId(HttpServletRequest req) { if (!apiPath.startsWith("/")) { apiPath = "/" + apiPath; } - if (apiPath.equals("/") && (path.equals("") || path.equals("/"))) { - return null; + if (apiPath.equals("/")) { + if ((path.equals("") || path.equals("/"))) { + return null; + } } else { if (path.matches("^/appid-[a-z0-9-]*/[a-z0-9-]+" + apiPath + "/?$")) { String tenantId = path.split("/")[2].toLowerCase(); @@ -251,6 +253,7 @@ private String getTenantId(HttpServletRequest req) { return null; } } + return null; } private String getAppId(HttpServletRequest req) { diff --git a/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java b/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java index a16587fd9..62f4f5851 100644 --- a/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java @@ -22,6 +22,7 @@ import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; +import io.supertokens.storageLayer.StorageLayer; import io.supertokens.utils.RateLimiter; import io.supertokens.webserver.WebserverAPI; import jakarta.servlet.ServletException; @@ -89,8 +90,8 @@ private void handleRequest(HttpServletRequest req, HttpServletResponse resp) thr return; } - Storage[] storages = enforcePublicTenantAndGetAllStoragesForApp(req); AppIdentifier appIdentifier = getAppIdentifier(req); + Storage[] storages = StorageLayer.getStoragesForApp(main, appIdentifier); for (Storage storage : storages) { // even if the public tenant does not exist, the following function will return a null @@ -98,7 +99,7 @@ private void handleRequest(HttpServletRequest req, HttpServletResponse resp) thr storage.getKeyValue(appIdentifier.getAsPublicTenantIdentifier(), "Test"); } super.sendTextResponse(200, "Hello", resp); - } catch (StorageQueryException | BadPermissionException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException e) { // we send 500 status code throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java b/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java index 5517c79b5..0a9e5b77b 100644 --- a/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java @@ -23,6 +23,7 @@ import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; +import io.supertokens.storageLayer.StorageLayer; import io.supertokens.utils.RateLimiter; import io.supertokens.webserver.WebserverAPI; import jakarta.servlet.ServletException; @@ -73,11 +74,11 @@ protected void handleRequest(HttpServletRequest req, HttpServletResponse resp) t ServletException { // getServletPath returns the path without the base path. AppIdentifier appIdentifier = getAppIdentifier(req); - Storage[] storages = null; + Storage[] storages; try { - enforcePublicTenantAndGetAllStoragesForApp(req); // check if app exists and enforce public tenant - } catch (TenantOrAppNotFoundException | BadPermissionException e) { + storages = StorageLayer.getStoragesForApp(main, appIdentifier); + } catch (TenantOrAppNotFoundException e) { // we send 500 status code throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java index 7d2b7f2b7..cbfe89873 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/AddUserRoleAPI.java @@ -66,7 +66,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO Storage storage = getTenantStorage(req); boolean didUserAlreadyHaveRole = !UserRoles.addRoleToUser( - tenantIdentifier, storage, userId, role); + main, tenantIdentifier, storage, userId, role); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); response.addProperty("didUserAlreadyHaveRole", didUserAlreadyHaveRole); diff --git a/src/test/java/io/supertokens/test/thirdparty/api/MultitenantAPITest.java b/src/test/java/io/supertokens/test/thirdparty/api/MultitenantAPITest.java index 068ffb27a..b638f860d 100644 --- a/src/test/java/io/supertokens/test/thirdparty/api/MultitenantAPITest.java +++ b/src/test/java/io/supertokens/test/thirdparty/api/MultitenantAPITest.java @@ -249,7 +249,7 @@ public void testGetUserUsingIdReturnsUserFromTheRightTenantWhileQueryingFromAnyT JsonObject user2 = signInUp(t2, "google", "google-user-id", "user@gmail.com"); JsonObject user3 = signInUp(t3, "google", "google-user-id", "user@gmail.com"); - for (TenantIdentifier tenant : new TenantIdentifier[]{t1, t2, t3}) { + for (TenantIdentifier tenant : new TenantIdentifier[]{t1}) { // Only public tenant can get user by id assertEquals(user1, getUserUsingId(tenant, user1.get("id").getAsString())); assertEquals(user2, getUserUsingId(tenant, user2.get("id").getAsString())); assertEquals(user3, getUserUsingId(tenant, user3.get("id").getAsString())); From c5fc6a36035c86c43066747eeb6c2652963d55d8 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 1 Mar 2024 20:37:36 +0530 Subject: [PATCH 15/31] fix: bugs and tests --- .../java/io/supertokens/session/Session.java | 2 +- .../io/supertokens/test/HelloAPITest.java | 41 ++---------- .../test/accountlinking/MultitenantTest.java | 2 +- .../MultitenantEmailPasswordTest.java | 16 ++--- .../emailpassword/api/MultitenantAPITest.java | 62 ++++++++----------- .../api/MultitenantAPITest.java | 5 +- .../test/multitenant/TestAppData.java | 2 +- .../passwordless/api/MultitenantAPITest.java | 42 +++++-------- .../userIdMapping/api/MultitenantAPITest.java | 31 +++++----- 9 files changed, 78 insertions(+), 125 deletions(-) diff --git a/src/main/java/io/supertokens/session/Session.java b/src/main/java/io/supertokens/session/Session.java index 66aea184a..c1969bd46 100644 --- a/src/main/java/io/supertokens/session/Session.java +++ b/src/main/java/io/supertokens/session/Session.java @@ -759,7 +759,7 @@ public static String[] revokeSessionUsingSessionHandles(Main main, continue; } - String[] sessionHandlesRevokedForTenant = revokeSessionUsingSessionHandles(tenantIdentifier, storage, + String[] sessionHandlesRevokedForTenant = revokeSessionUsingSessionHandles(tenantIdentifier, tenantStorage, sessionHandlesForTenant); revokedSessionHandles.addAll(Arrays.asList(sessionHandlesRevokedForTenant)); } diff --git a/src/test/java/io/supertokens/test/HelloAPITest.java b/src/test/java/io/supertokens/test/HelloAPITest.java index c337208e6..61049ff3e 100644 --- a/src/test/java/io/supertokens/test/HelloAPITest.java +++ b/src/test/java/io/supertokens/test/HelloAPITest.java @@ -144,6 +144,7 @@ public void testHelloAPIWithBasePath3() throws Exception { "http://localhost:3567/hello/hello/", // baseUrl + (hello tenant) + / : works because the hello api doesn't check if that tenant exists "http://localhost:3567/hello/appid-hello/hello", // baseUrl + app + /hello "http://localhost:3567/hello/appid-hello/hello/", // baseUrl + app + /hello + "http://localhost:3567/hello/appid-hello/test/hello", // baseUrl + app + tenant + /hello }; for (String helloUrl: HELLO_ROUTES) { @@ -159,11 +160,11 @@ public void testHelloAPIWithBasePath3() throws Exception { "http://localhost:3567/hello/appid-hello", // baseUrl + app + / "http://localhost:3567/hello/appid-hello/", // baseUrl + app + / "http://localhost:3567/hello/appid-hello/test", // baseUrl + app + tenant + / + "http://localhost:3567/hello/appid-hello/test/", // baseUrl + app + tenant + / }; // Not found for (String notFoundUrl : NOT_FOUND_ROUTES) { - System.out.println(notFoundUrl); try { String res = HttpRequestForTesting.sendGETRequest(process.getProcess(), "", notFoundUrl, null, 1000, 1000, @@ -174,23 +175,6 @@ public void testHelloAPIWithBasePath3() throws Exception { } } - String[] BAD_PERMISSION_ROUTES = new String[]{ - "http://localhost:3567/hello/appid-hello/test/hello", // baseUrl + app + tenant + /hello - "http://localhost:3567/hello/appid-hello/test/", // baseUrl + app + tenant + / - }; - - // Bad permission - for (String badPermUrl : BAD_PERMISSION_ROUTES) { - try { - String res = HttpRequestForTesting.sendGETRequest(process.getProcess(), "", - badPermUrl, null, 1000, 1000, - null, Utils.getCdiVersionStringLatestForTests(), ""); - fail(); - } catch (HttpResponseException e) { - assertEquals(403, e.statusCode); - } - } - process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); } @@ -243,6 +227,7 @@ public void testWithBasePathThatHelloAPIDoesNotRequireAPIKeys() throws Exception "http://localhost:3567/hello/hello/", // baseUrl + (hello tenant) + / : works because the hello api doesn't check if that tenant exists "http://localhost:3567/hello/appid-hello/hello", // baseUrl + app + /hello "http://localhost:3567/hello/appid-hello/hello/", // baseUrl + app + /hello + "http://localhost:3567/hello/appid-hello/test/hello", // baseUrl + app + tenant + /hello }; for (String helloUrl: HELLO_ROUTES) { @@ -260,6 +245,7 @@ public void testWithBasePathThatHelloAPIDoesNotRequireAPIKeys() throws Exception "http://localhost:3567/hello/appid-hello", // baseUrl + app + / "http://localhost:3567/hello/appid-hello/", // baseUrl + app + / "http://localhost:3567/hello/appid-hello/test", // baseUrl + app + tenant + / + "http://localhost:3567/hello/appid-hello/test/", // baseUrl + app + tenant + / }; // Not found @@ -274,23 +260,6 @@ public void testWithBasePathThatHelloAPIDoesNotRequireAPIKeys() throws Exception } } - String[] BAD_PERMISSION_ROUTES = new String[]{ - "http://localhost:3567/hello/appid-hello/test/hello", // baseUrl + app + tenant + /hello - "http://localhost:3567/hello/appid-hello/test/", // baseUrl + app + tenant + / - }; - - // Bad permission - for (String badPermUrl : BAD_PERMISSION_ROUTES) { - try { - String res = HttpRequestForTesting.sendGETRequest(process.getProcess(), "", - badPermUrl, null, 1000, 1000, - null, Utils.getCdiVersionStringLatestForTests(), ""); - fail(); - } catch (HttpResponseException e) { - assertEquals(403, e.statusCode); - } - } - process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); } @@ -342,6 +311,7 @@ public void testThatHelloAPIDoesNotRequireAPIKeys() throws Exception { "http://localhost:3567/hello/", // (hello tenant) + / : works because the hello api doesn't check if that tenant exists "http://localhost:3567/appid-hello/hello", // app + /hello "http://localhost:3567/appid-hello/hello/", // app + /hello + "http://localhost:3567/appid-hello/test/hello", // app + tenant + /hello }; for (String helloUrl: HELLO_ROUTES) { @@ -358,6 +328,7 @@ public void testThatHelloAPIDoesNotRequireAPIKeys() throws Exception { "http://localhost:3567/appid-hello", // app + / "http://localhost:3567/appid-hello/", // app + / "http://localhost:3567/appid-hello/test", // app + tenant + / + "http://localhost:3567/appid-hello/test/", // app + tenant + / }; // Not found diff --git a/src/test/java/io/supertokens/test/accountlinking/MultitenantTest.java b/src/test/java/io/supertokens/test/accountlinking/MultitenantTest.java index c804492c7..638068b7f 100644 --- a/src/test/java/io/supertokens/test/accountlinking/MultitenantTest.java +++ b/src/test/java/io/supertokens/test/accountlinking/MultitenantTest.java @@ -341,7 +341,7 @@ public void testTenantDeletionWithAccountLinkingWithUserRoles() throws Exception user1.getSupertokensUserId()); UserRoles.createNewRoleOrModifyItsPermissions(t2.toAppIdentifier(), t2WithStorage, "admin", new String[]{"p1"}); - UserRoles.addRoleToUser(t2, t2WithStorage, user1.getSupertokensUserId(), "admin"); + UserRoles.addRoleToUser(process.getProcess(), t2, t2WithStorage, user1.getSupertokensUserId(), "admin"); Multitenancy.deleteTenant(t2, process.getProcess()); diff --git a/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java b/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java index 455feda14..a85876c1a 100644 --- a/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java +++ b/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java @@ -270,13 +270,13 @@ public void testGetUserUsingIdReturnsCorrectUser() AuthRecipeUserInfo user3 = EmailPassword.signUp(t3, t3storage, process.getProcess(), "user3@example.com", "password3"); - Storage storage = StorageLayer.getStorage(process.getProcess()); + Storage[] storages = StorageLayer.getStoragesForApp(process.getProcess(), new AppIdentifier(null, "a1")); { AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingId( new AppIdentifier(null, "a1"), StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( - new AppIdentifier(null, "a1"), new Storage[]{storage}, + new AppIdentifier(null, "a1"), storages, user1.getSupertokensUserId(), UserIdType.SUPERTOKENS).storage, user1.getSupertokensUserId()); assertEquals(user1, userInfo); @@ -286,7 +286,7 @@ public void testGetUserUsingIdReturnsCorrectUser() AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingId( new AppIdentifier(null, "a1"), StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( - new AppIdentifier(null, "a1"), new Storage[]{storage}, + new AppIdentifier(null, "a1"), storages, user2.getSupertokensUserId(), UserIdType.SUPERTOKENS).storage, user2.getSupertokensUserId()); assertEquals(user2, userInfo); @@ -296,7 +296,7 @@ public void testGetUserUsingIdReturnsCorrectUser() AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingId( new AppIdentifier(null, "a1"), StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( - new AppIdentifier(null, "a1"), new Storage[]{storage}, + new AppIdentifier(null, "a1"), storages, user3.getSupertokensUserId(), UserIdType.SUPERTOKENS).storage, user3.getSupertokensUserId()); assertEquals(user3, userInfo); @@ -393,26 +393,26 @@ public void testUpdatePasswordWorksCorrectlyAcrossAllTenants() AuthRecipeUserInfo user3 = EmailPassword.signUp(t3, t3storage, process.getProcess(), "user@example.com", "password3"); - Storage storage = StorageLayer.getStorage(process.getProcess()); + Storage[] storages = StorageLayer.getStoragesForApp(process.getProcess(), new AppIdentifier(null, "a1")); EmailPassword.updateUsersEmailOrPassword( new AppIdentifier(null, "a1"), StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( - new AppIdentifier(null, "a1"), new Storage[]{storage}, + new AppIdentifier(null, "a1"), storages, user1.getSupertokensUserId(), UserIdType.SUPERTOKENS).storage, process.getProcess(), user1.getSupertokensUserId(), null, "newpassword1"); EmailPassword.updateUsersEmailOrPassword( new AppIdentifier(null, "a1"), StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( - new AppIdentifier(null, "a1"), new Storage[]{storage}, + new AppIdentifier(null, "a1"), storages, user2.getSupertokensUserId(), UserIdType.SUPERTOKENS).storage, process.getProcess(), user2.getSupertokensUserId(), null, "newpassword2"); EmailPassword.updateUsersEmailOrPassword( new AppIdentifier(null, "a1"), StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( - new AppIdentifier(null, "a1"), new Storage[]{storage}, + new AppIdentifier(null, "a1"), storages, user3.getSupertokensUserId(), UserIdType.SUPERTOKENS).storage, process.getProcess(), user3.getSupertokensUserId(), null, "newpassword3"); diff --git a/src/test/java/io/supertokens/test/emailpassword/api/MultitenantAPITest.java b/src/test/java/io/supertokens/test/emailpassword/api/MultitenantAPITest.java index 43c4d6e85..8cb5d5ffe 100644 --- a/src/test/java/io/supertokens/test/emailpassword/api/MultitenantAPITest.java +++ b/src/test/java/io/supertokens/test/emailpassword/api/MultitenantAPITest.java @@ -386,9 +386,7 @@ public void testGetUserUsingIdReturnsUserFromTheRightTenantWhileQueryingFromAnyT JsonObject user3 = signUp(t3, "user@example.com", "password3"); for (JsonObject user : new JsonObject[]{user1, user2, user3}) { - for (TenantIdentifier t : new TenantIdentifier[]{t1, t2, t3}) { - assertEquals(user, getUserUsingId(t, user.getAsJsonPrimitive("id").getAsString())); - } + assertEquals(user, getUserUsingId(t1, user.getAsJsonPrimitive("id").getAsString())); } } @@ -428,16 +426,14 @@ public void testUpdatePasswordWorksCorrectlyAcrossTenants() throws Exception { JsonObject user = users[i]; TenantIdentifier userTenant = tenants[i]; - for (TenantIdentifier tenant : tenants) { - String newPassword = generateRandomString(16); - updatePassword(tenant, user.getAsJsonPrimitive("id").getAsString(), newPassword); + String newPassword = generateRandomString(16); + updatePassword(t1, user.getAsJsonPrimitive("id").getAsString(), newPassword); - for (TenantIdentifier loginTenant : tenants) { - if (loginTenant.equals(userTenant)) { - assertEquals(user, successfulSignIn(loginTenant, "user@example.com", newPassword)); - } else { - wrongCredentialsSignIn(loginTenant, "user@example.com", newPassword); - } + for (TenantIdentifier loginTenant : tenants) { + if (loginTenant.equals(userTenant)) { + assertEquals(user, successfulSignIn(loginTenant, "user@example.com", newPassword)); + } else { + wrongCredentialsSignIn(loginTenant, "user@example.com", newPassword); } } } @@ -462,18 +458,16 @@ public void testUpdateEmailWorksCorrectlyAcrossTenants() throws Exception { JsonObject user = users[i]; TenantIdentifier userTenant = tenants[i]; - for (TenantIdentifier tenant : tenants) { - String newEmail = (generateRandomString(16) + "@example.com").toLowerCase(); - updateEmail(tenant, user.getAsJsonPrimitive("id").getAsString(), newEmail); - user.remove("email"); - user.addProperty("email", newEmail); + String newEmail = (generateRandomString(16) + "@example.com").toLowerCase(); + updateEmail(t1, user.getAsJsonPrimitive("id").getAsString(), newEmail); + user.remove("email"); + user.addProperty("email", newEmail); - for (TenantIdentifier loginTenant : tenants) { - if (loginTenant.equals(userTenant)) { - assertEquals(user, successfulSignIn(loginTenant, newEmail, "password")); - } else { - wrongCredentialsSignIn(loginTenant, newEmail, "password"); - } + for (TenantIdentifier loginTenant : tenants) { + if (loginTenant.equals(userTenant)) { + assertEquals(user, successfulSignIn(loginTenant, newEmail, "password")); + } else { + wrongCredentialsSignIn(loginTenant, newEmail, "password"); } } } @@ -498,20 +492,18 @@ public void testUpdateEmailAndPasswordWorksCorrectlyAcrossTenants() throws Excep JsonObject user = users[i]; TenantIdentifier userTenant = tenants[i]; - for (TenantIdentifier tenant : tenants) { - String newPassword = generateRandomString(16); - String newEmail = (generateRandomString(16) + "@example.com").toLowerCase(); - updateEmailAndPassword(tenant, user.getAsJsonPrimitive("id").getAsString(), newEmail, newPassword); + String newPassword = generateRandomString(16); + String newEmail = (generateRandomString(16) + "@example.com").toLowerCase(); + updateEmailAndPassword(t1, user.getAsJsonPrimitive("id").getAsString(), newEmail, newPassword); - user.remove("email"); - user.addProperty("email", newEmail); + user.remove("email"); + user.addProperty("email", newEmail); - for (TenantIdentifier loginTenant : tenants) { - if (loginTenant.equals(userTenant)) { - assertEquals(user, successfulSignIn(loginTenant, newEmail, newPassword)); - } else { - wrongCredentialsSignIn(loginTenant, newEmail, newPassword); - } + for (TenantIdentifier loginTenant : tenants) { + if (loginTenant.equals(userTenant)) { + assertEquals(user, successfulSignIn(loginTenant, newEmail, newPassword)); + } else { + wrongCredentialsSignIn(loginTenant, newEmail, newPassword); } } } diff --git a/src/test/java/io/supertokens/test/emailverification/api/MultitenantAPITest.java b/src/test/java/io/supertokens/test/emailverification/api/MultitenantAPITest.java index 2fc093038..f917bcd9f 100644 --- a/src/test/java/io/supertokens/test/emailverification/api/MultitenantAPITest.java +++ b/src/test/java/io/supertokens/test/emailverification/api/MultitenantAPITest.java @@ -214,8 +214,6 @@ public void testSameEmailAcrossDifferentUserPoolNeedsToBeVerifiedSeparately() th verifyEmail(t1, "userid", "test@example.com"); assertTrue(isEmailVerified(t1, "userid", "test@example.com")); - assertFalse(isEmailVerified(t2, "userid", "test@example.com")); - assertFalse(isEmailVerified(t3, "userid", "test@example.com")); } @Test @@ -225,7 +223,6 @@ public void testSameEmailAcrossDifferentTenantButSameUserPoolDoesNotNeedVerifica } verifyEmail(t2, "userid", "test@example.com"); - assertTrue(isEmailVerified(t2, "userid", "test@example.com")); - assertTrue(isEmailVerified(t3, "userid", "test@example.com")); + assertTrue(isEmailVerified(t1, "userid", "test@example.com")); } } diff --git a/src/test/java/io/supertokens/test/multitenant/TestAppData.java b/src/test/java/io/supertokens/test/multitenant/TestAppData.java index 52cdd0d10..5a30a3dea 100644 --- a/src/test/java/io/supertokens/test/multitenant/TestAppData.java +++ b/src/test/java/io/supertokens/test/multitenant/TestAppData.java @@ -155,7 +155,7 @@ public void testThatDeletingAppDeleteDataFromAllTables() throws Exception { UserRoles.createNewRoleOrModifyItsPermissions(app.toAppIdentifier(), appWithStorage, "role", new String[]{"permission1", "permission2"}); - UserRoles.addRoleToUser(app, appWithStorage, epUser.getSupertokensUserId(), "role"); + UserRoles.addRoleToUser(process.getProcess(), app, appWithStorage, epUser.getSupertokensUserId(), "role"); TOTPDevice totpDevice = Totp.registerDevice(app.toAppIdentifier(), appWithStorage, process.getProcess(), epUser.getSupertokensUserId(), "test", 1, 3); diff --git a/src/test/java/io/supertokens/test/passwordless/api/MultitenantAPITest.java b/src/test/java/io/supertokens/test/passwordless/api/MultitenantAPITest.java index 7b13a4990..913366fd4 100644 --- a/src/test/java/io/supertokens/test/passwordless/api/MultitenantAPITest.java +++ b/src/test/java/io/supertokens/test/passwordless/api/MultitenantAPITest.java @@ -472,11 +472,9 @@ public void testGetUserUsingIdReturnsUserFromTheRightTenantWhileQueryingFromAnyT JsonObject user2 = signInUpEmailUsingLinkCode(t2, "user1@example.com"); JsonObject user3 = signInUpEmailUsingLinkCode(t3, "user1@example.com"); - for (TenantIdentifier tenant : new TenantIdentifier[]{t1, t2, t3}) { - assertEquals(user1, getUserUsingId(tenant, user1.get("id").getAsString())); - assertEquals(user2, getUserUsingId(tenant, user2.get("id").getAsString())); - assertEquals(user3, getUserUsingId(tenant, user3.get("id").getAsString())); - } + assertEquals(user1, getUserUsingId(t1, user1.get("id").getAsString())); + assertEquals(user2, getUserUsingId(t1, user2.get("id").getAsString())); + assertEquals(user3, getUserUsingId(t1, user3.get("id").getAsString())); } { @@ -484,11 +482,9 @@ public void testGetUserUsingIdReturnsUserFromTheRightTenantWhileQueryingFromAnyT JsonObject user2 = signInUpNumberUsingUserInputCode(t2, "+442071838750"); JsonObject user3 = signInUpNumberUsingUserInputCode(t3, "+442071838750"); - for (TenantIdentifier tenant : new TenantIdentifier[]{t1, t2, t3}) { - assertEquals(user1, getUserUsingId(tenant, user1.get("id").getAsString())); - assertEquals(user2, getUserUsingId(tenant, user2.get("id").getAsString())); - assertEquals(user3, getUserUsingId(tenant, user3.get("id").getAsString())); - } + assertEquals(user1, getUserUsingId(t1, user1.get("id").getAsString())); + assertEquals(user2, getUserUsingId(t1, user2.get("id").getAsString())); + assertEquals(user3, getUserUsingId(t1, user3.get("id").getAsString())); } } @@ -539,14 +535,12 @@ public void testUpdateEmail() throws Exception { JsonObject user = users[i]; TenantIdentifier userTenant = tenants[i]; - for (TenantIdentifier tenant : tenants) { - String newEmail = (generateRandomString(16) + "@example.com").toLowerCase(); - updateEmail(tenant, user.getAsJsonPrimitive("id").getAsString(), newEmail); - user.remove("email"); - user.addProperty("email", newEmail); + String newEmail = (generateRandomString(16) + "@example.com").toLowerCase(); + updateEmail(t1, user.getAsJsonPrimitive("id").getAsString(), newEmail); + user.remove("email"); + user.addProperty("email", newEmail); - assertEquals(user, signInUpEmailUsingLinkCode(userTenant, newEmail)); - } + assertEquals(user, signInUpEmailUsingLinkCode(userTenant, newEmail)); } } @@ -567,15 +561,13 @@ public void testUpdateNumber() throws Exception { JsonObject user = users[i]; TenantIdentifier userTenant = tenants[i]; - for (TenantIdentifier tenant : tenants) { - String newPhoneNumber = generateRandomNumber(8); - updatePhoneNumber(tenant, user.getAsJsonPrimitive("id").getAsString(), newPhoneNumber); - user.remove("phoneNumber"); - // We need to normalize the phone number before adding it to the user object, as the update API performs normalization. - user.addProperty("phoneNumber", io.supertokens.utils.Utils.normalizeIfPhoneNumber(newPhoneNumber)); + String newPhoneNumber = generateRandomNumber(8); + updatePhoneNumber(t1, user.getAsJsonPrimitive("id").getAsString(), newPhoneNumber); + user.remove("phoneNumber"); + // We need to normalize the phone number before adding it to the user object, as the update API performs normalization. + user.addProperty("phoneNumber", io.supertokens.utils.Utils.normalizeIfPhoneNumber(newPhoneNumber)); - assertEquals(user, signInUpNumberUsingUserInputCode(userTenant, newPhoneNumber)); - } + assertEquals(user, signInUpNumberUsingUserInputCode(userTenant, newPhoneNumber)); } } } diff --git a/src/test/java/io/supertokens/test/userIdMapping/api/MultitenantAPITest.java b/src/test/java/io/supertokens/test/userIdMapping/api/MultitenantAPITest.java index 1336e1d92..cb33d798e 100644 --- a/src/test/java/io/supertokens/test/userIdMapping/api/MultitenantAPITest.java +++ b/src/test/java/io/supertokens/test/userIdMapping/api/MultitenantAPITest.java @@ -396,29 +396,30 @@ public void testSameExternalIdAcrossUserPoolJustReturnsOneOfThem() throws Except { JsonObject mapping = getUserIdMapping(t1, "euserid", "EXTERNAL"); - assertEquals(user1.get("id").getAsString(), mapping.get("superTokensUserId").getAsString()); + assert mapping.get("superTokensUserId").getAsString().equals(user1.get("id").getAsString()) + || mapping.get("superTokensUserId").getAsString().equals(user2.get("id").getAsString()); } { JsonObject mapping = getUserIdMapping(t1, "euserid", "ANY"); - assertEquals(user1.get("id").getAsString(), mapping.get("superTokensUserId").getAsString()); + assert mapping.get("superTokensUserId").getAsString().equals(user1.get("id").getAsString()) + || mapping.get("superTokensUserId").getAsString().equals(user2.get("id").getAsString()); } { - JsonObject mapping = getUserIdMapping(t2, "euserid", "EXTERNAL"); - assertEquals(user2.get("id").getAsString(), mapping.get("superTokensUserId").getAsString()); - } - { - JsonObject mapping = getUserIdMapping(t2, "euserid", "ANY"); - assertEquals(user2.get("id").getAsString(), mapping.get("superTokensUserId").getAsString()); - } - - { - JsonObject mapping = getUserIdMapping(t3, "euserid", "EXTERNAL"); - assertEquals(user2.get("id").getAsString(), mapping.get("superTokensUserId").getAsString()); + try { + JsonObject mapping = getUserIdMapping(t2, "euserid", "EXTERNAL"); + fail(); + } catch (HttpResponseException e) { + assertEquals(403, e.statusCode); + } } { - JsonObject mapping = getUserIdMapping(t3, "euserid", "ANY"); - assertEquals(user2.get("id").getAsString(), mapping.get("superTokensUserId").getAsString()); + try { + JsonObject mapping = getUserIdMapping(t2, "euserid", "ANY"); + fail(); + } catch (HttpResponseException e) { + assertEquals(403, e.statusCode); + } } } From 5f00b5e783f41e7d3df5fd9a580c536667e1033e Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 1 Mar 2024 20:54:57 +0530 Subject: [PATCH 16/31] fix: func rename --- .../supertokens/storageLayer/StorageLayer.java | 6 +++--- .../useridmapping/UserIdMapping.java | 6 ++---- .../io/supertokens/webserver/WebserverAPI.java | 4 ++-- .../MultitenantEmailPasswordTest.java | 18 +++++++++--------- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/main/java/io/supertokens/storageLayer/StorageLayer.java b/src/main/java/io/supertokens/storageLayer/StorageLayer.java index 4e49e0864..1de61142a 100644 --- a/src/main/java/io/supertokens/storageLayer/StorageLayer.java +++ b/src/main/java/io/supertokens/storageLayer/StorageLayer.java @@ -405,7 +405,7 @@ public static Storage[] getStoragesForApp(Main main, AppIdentifier appIdentifier return storages; } - public static StorageAndUserIdMapping getTenantIdentifierWithStorageAndUserIdMappingForUser( + public static StorageAndUserIdMapping findStorageAndUserIdMappingForUser( Main main, TenantIdentifier tenantIdentifier, String userId, UserIdType userIdType) throws StorageQueryException, TenantOrAppNotFoundException, UnknownUserIdException { Storage storage = getStorage(tenantIdentifier, main); @@ -457,9 +457,9 @@ public static StorageAndUserIdMapping getTenantIdentifierWithStorageAndUserIdMap throw new UnknownUserIdException(); } - public static StorageAndUserIdMapping getAppIdentifierWithStorageAndUserIdMappingForUser( + public static StorageAndUserIdMapping findStorageAndUserIdMappingForUser( AppIdentifier appIdentifier, Storage[] storages, String userId, - UserIdType userIdType) throws StorageQueryException, TenantOrAppNotFoundException, UnknownUserIdException { + UserIdType userIdType) throws StorageQueryException, UnknownUserIdException { if (userIdType == UserIdType.SUPERTOKENS) { for (Storage storage : storages) { diff --git a/src/main/java/io/supertokens/useridmapping/UserIdMapping.java b/src/main/java/io/supertokens/useridmapping/UserIdMapping.java index 554517681..274e08efc 100644 --- a/src/main/java/io/supertokens/useridmapping/UserIdMapping.java +++ b/src/main/java/io/supertokens/useridmapping/UserIdMapping.java @@ -20,7 +20,6 @@ import io.supertokens.StorageAndUserIdMapping; import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.StorageUtils; -import io.supertokens.pluginInterface.authRecipe.AuthRecipeStorage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.authRecipe.LoginMethod; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; @@ -29,7 +28,6 @@ import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.jwt.JWTRecipeStorage; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.session.SessionStorage; import io.supertokens.pluginInterface.sqlStorage.TransactionConnection; @@ -86,7 +84,7 @@ public static void createUserIdMapping(AppIdentifier appIdentifier, Storage[] st // race condition is fixed. try { // with external id StorageAndUserIdMapping mappingAndStorage = - StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + StorageLayer.findStorageAndUserIdMappingForUser( appIdentifier, storages, externalUserId, UserIdType.EXTERNAL); if (mappingAndStorage.userIdMapping != null) { @@ -101,7 +99,7 @@ public static void createUserIdMapping(AppIdentifier appIdentifier, Storage[] st StorageAndUserIdMapping mappingAndStorage; try { - mappingAndStorage = StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + mappingAndStorage = StorageLayer.findStorageAndUserIdMappingForUser( appIdentifier, storages, superTokensUserId, UserIdType.SUPERTOKENS); } catch (UnknownUserIdException e) { throw new UnknownSuperTokensUserIdException(); diff --git a/src/main/java/io/supertokens/webserver/WebserverAPI.java b/src/main/java/io/supertokens/webserver/WebserverAPI.java index a9a15e0f4..60f311efc 100644 --- a/src/main/java/io/supertokens/webserver/WebserverAPI.java +++ b/src/main/java/io/supertokens/webserver/WebserverAPI.java @@ -341,7 +341,7 @@ protected StorageAndUserIdMapping getStorageAndUserIdMappingForTenantSpecificApi throws StorageQueryException, TenantOrAppNotFoundException, UnknownUserIdException, ServletException { TenantIdentifier tenantIdentifier = new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), this.getTenantId(req)); - return StorageLayer.getTenantIdentifierWithStorageAndUserIdMappingForUser(main, tenantIdentifier, userId, + return StorageLayer.findStorageAndUserIdMappingForUser(main, tenantIdentifier, userId, userIdType); } @@ -353,7 +353,7 @@ protected StorageAndUserIdMapping getStorageAndUserIdMappingForAppSpecificApi( // while searching for the user across all storages for the app AppIdentifier appIdentifier = getAppIdentifier(req); Storage[] storages = enforcePublicTenantAndGetAllStoragesForApp(req); - return StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + return StorageLayer.findStorageAndUserIdMappingForUser( appIdentifier, storages, userId, userIdType); } diff --git a/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java b/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java index a85876c1a..9ed499fee 100644 --- a/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java +++ b/src/test/java/io/supertokens/test/emailpassword/MultitenantEmailPasswordTest.java @@ -275,7 +275,7 @@ public void testGetUserUsingIdReturnsCorrectUser() { AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingId( new AppIdentifier(null, "a1"), - StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + StorageLayer.findStorageAndUserIdMappingForUser( new AppIdentifier(null, "a1"), storages, user1.getSupertokensUserId(), UserIdType.SUPERTOKENS).storage, user1.getSupertokensUserId()); @@ -285,7 +285,7 @@ public void testGetUserUsingIdReturnsCorrectUser() { AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingId( new AppIdentifier(null, "a1"), - StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + StorageLayer.findStorageAndUserIdMappingForUser( new AppIdentifier(null, "a1"), storages, user2.getSupertokensUserId(), UserIdType.SUPERTOKENS).storage, user2.getSupertokensUserId()); @@ -295,7 +295,7 @@ public void testGetUserUsingIdReturnsCorrectUser() { AuthRecipeUserInfo userInfo = EmailPassword.getUserUsingId( new AppIdentifier(null, "a1"), - StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + StorageLayer.findStorageAndUserIdMappingForUser( new AppIdentifier(null, "a1"), storages, user3.getSupertokensUserId(), UserIdType.SUPERTOKENS).storage, user3.getSupertokensUserId()); @@ -397,28 +397,28 @@ public void testUpdatePasswordWorksCorrectlyAcrossAllTenants() EmailPassword.updateUsersEmailOrPassword( new AppIdentifier(null, "a1"), - StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + StorageLayer.findStorageAndUserIdMappingForUser( new AppIdentifier(null, "a1"), storages, user1.getSupertokensUserId(), UserIdType.SUPERTOKENS).storage, process.getProcess(), user1.getSupertokensUserId(), null, "newpassword1"); EmailPassword.updateUsersEmailOrPassword( new AppIdentifier(null, "a1"), - StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + StorageLayer.findStorageAndUserIdMappingForUser( new AppIdentifier(null, "a1"), storages, user2.getSupertokensUserId(), UserIdType.SUPERTOKENS).storage, process.getProcess(), user2.getSupertokensUserId(), null, "newpassword2"); EmailPassword.updateUsersEmailOrPassword( new AppIdentifier(null, "a1"), - StorageLayer.getAppIdentifierWithStorageAndUserIdMappingForUser( + StorageLayer.findStorageAndUserIdMappingForUser( new AppIdentifier(null, "a1"), storages, user3.getSupertokensUserId(), UserIdType.SUPERTOKENS).storage, process.getProcess(), user3.getSupertokensUserId(), null, "newpassword3"); { - t1storage = StorageLayer.getTenantIdentifierWithStorageAndUserIdMappingForUser(process.getProcess(), t1, user1.getSupertokensUserId(), + t1storage = StorageLayer.findStorageAndUserIdMappingForUser(process.getProcess(), t1, user1.getSupertokensUserId(), UserIdType.SUPERTOKENS).storage; AuthRecipeUserInfo userInfo = EmailPassword.signIn(t1, t1storage, process.getProcess(), "user@example.com", "newpassword1"); @@ -426,7 +426,7 @@ public void testUpdatePasswordWorksCorrectlyAcrossAllTenants() } { - t2storage = StorageLayer.getTenantIdentifierWithStorageAndUserIdMappingForUser(process.getProcess(), t2, + t2storage = StorageLayer.findStorageAndUserIdMappingForUser(process.getProcess(), t2, user2.getSupertokensUserId(), UserIdType.SUPERTOKENS).storage; AuthRecipeUserInfo userInfo = EmailPassword.signIn(t2, t2storage, process.getProcess(), "user@example.com", @@ -435,7 +435,7 @@ public void testUpdatePasswordWorksCorrectlyAcrossAllTenants() } { - t3storage = StorageLayer.getTenantIdentifierWithStorageAndUserIdMappingForUser(process.getProcess(), t3, + t3storage = StorageLayer.findStorageAndUserIdMappingForUser(process.getProcess(), t3, user3.getSupertokensUserId(), UserIdType.SUPERTOKENS).storage; AuthRecipeUserInfo userInfo = EmailPassword.signIn(t3, t3storage, process.getProcess(), "user@example.com", From 311b9b054b79e9220becb4811ed866e95bc30eaf Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Mon, 4 Mar 2024 11:19:24 +0530 Subject: [PATCH 17/31] fix: PR comments --- src/main/java/io/supertokens/ActiveUsers.java | 20 +-- .../io/supertokens/authRecipe/AuthRecipe.java | 6 +- .../java/io/supertokens/inmemorydb/Start.java | 9 +- .../inmemorydb/queries/UserRolesQueries.java | 2 - .../io/supertokens/userroles/UserRoles.java | 24 +-- .../supertokens/webserver/WebserverAPI.java | 8 +- .../CanCreatePrimaryUserAPI.java | 2 +- .../accountlinking/CanLinkAccountsAPI.java | 4 +- .../accountlinking/CreatePrimaryUserAPI.java | 2 +- .../api/accountlinking/LinkAccountsAPI.java | 4 +- .../api/accountlinking/UnlinkAccountAPI.java | 2 +- .../api/core/ActiveUsersCountAPI.java | 5 +- .../webserver/api/core/ConfigAPI.java | 11 +- .../webserver/api/core/DeleteUserAPI.java | 2 +- .../webserver/api/core/GetUserByIdAPI.java | 2 +- .../webserver/api/core/HelloAPI.java | 8 +- .../webserver/api/emailpassword/UserAPI.java | 4 +- .../emailverification/UnverifyEmailAPI.java | 2 +- .../api/emailverification/VerifyEmailAPI.java | 2 +- .../api/multitenancy/ListTenantsAPI.java | 5 +- .../webserver/api/passwordless/UserAPI.java | 4 +- .../api/session/RefreshSessionAPI.java | 4 +- .../api/session/SessionRemoveAPI.java | 77 +++++++-- .../webserver/api/thirdparty/UserAPI.java | 2 +- .../api/totp/CreateOrUpdateTotpDeviceAPI.java | 13 +- .../webserver/api/totp/GetTotpDevicesAPI.java | 6 +- .../api/totp/RemoveTotpDeviceAPI.java | 5 +- .../webserver/api/totp/VerifyTotpAPI.java | 4 - .../api/totp/VerifyTotpDeviceAPI.java | 4 - .../useridmapping/RemoveUserIdMappingAPI.java | 2 +- .../UpdateExternalUserIdInfoAPI.java | 2 +- .../api/useridmapping/UserIdMappingAPI.java | 14 +- .../usermetadata/RemoveUserMetadataAPI.java | 2 +- .../api/usermetadata/UserMetadataAPI.java | 4 +- .../api/userroles/GetUsersForRoleAPI.java | 2 +- .../api/userroles/RemoveRoleAPI.java | 4 +- .../api/userroles/RemoveUserRoleAPI.java | 2 +- .../io/supertokens/test/FeatureFlagTest.java | 18 +-- .../accountlinking/CreatePrimaryUserTest.java | 10 +- .../GetUserByAccountInfoTest.java | 104 ++++++------- .../test/accountlinking/LinkAccountsTest.java | 10 +- .../test/accountlinking/MultitenantTest.java | 146 +++++++++--------- .../test/accountlinking/SessionTests.java | 66 ++++---- .../test/authRecipe/MultitenantAPITest.java | 28 ++-- .../test/authRecipe/UserPaginationTest.java | 12 +- .../dashboard/apis/MultitenantAPITest.java | 4 +- .../test/emailpassword/EmailPasswordTest.java | 10 +- .../test/multitenant/AppTenantUserTest.java | 36 ++--- .../test/multitenant/TestAppData.java | 44 +++--- .../multitenant/api/TestPermissionChecks.java | 6 +- .../TestTenantIdIsNotPresentForOlderCDI.java | 12 +- .../api/TestTenantUserAssociation.java | 78 +++++----- .../api/TestWithNonAuthRecipes.java | 28 ++-- .../test/totp/api/TotpUserIdMappingTest.java | 4 +- .../test/userRoles/UserRolesStorageTest.java | 5 +- 55 files changed, 449 insertions(+), 447 deletions(-) diff --git a/src/main/java/io/supertokens/ActiveUsers.java b/src/main/java/io/supertokens/ActiveUsers.java index 78d9885a4..7ee3c5534 100644 --- a/src/main/java/io/supertokens/ActiveUsers.java +++ b/src/main/java/io/supertokens/ActiveUsers.java @@ -31,29 +31,15 @@ public static void updateLastActive(Main main, String userId) { } } - public static int countUsersActiveSince(AppIdentifier appIdentifier, Storage storage, long time) + public static int countUsersActiveSince(Main main, AppIdentifier appIdentifier, long time) throws StorageQueryException, TenantOrAppNotFoundException { + Storage storage = StorageLayer.getStorage(appIdentifier.getAsPublicTenantIdentifier(), main); return StorageUtils.getActiveUsersStorage(storage).countUsersActiveSince(appIdentifier, time); } @TestOnly public static int countUsersActiveSince(Main main, long time) throws StorageQueryException, TenantOrAppNotFoundException { - return countUsersActiveSince(new AppIdentifier(null, null), - StorageLayer.getStorage(main), time); - } - - public static void removeActiveUser(AppIdentifier appIdentifier, Storage storage, String userId) - throws StorageQueryException { - try { - ((AuthRecipeSQLStorage) StorageUtils.getActiveUsersStorage(storage)).startTransaction(con -> { - StorageUtils.getActiveUsersStorage(storage).deleteUserActive_Transaction(con, appIdentifier, userId); - ((AuthRecipeSQLStorage) StorageUtils.getActiveUsersStorage(storage)).commitTransaction(con); - return null; - }); - - } catch (StorageTransactionLogicException e) { - throw new StorageQueryException(e.actualException); - } + return countUsersActiveSince(main, new AppIdentifier(null, null), time); } } diff --git a/src/main/java/io/supertokens/authRecipe/AuthRecipe.java b/src/main/java/io/supertokens/authRecipe/AuthRecipe.java index 6d355209f..e480f45f2 100644 --- a/src/main/java/io/supertokens/authRecipe/AuthRecipe.java +++ b/src/main/java/io/supertokens/authRecipe/AuthRecipe.java @@ -252,7 +252,7 @@ private static CanLinkAccountsResult canLinkAccountsHelper(TransactionConnection TenantIdentifier tenantIdentifier = new TenantIdentifier( appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), tenantId); - // we do not bother with getting the tenantIdentifierWithStorage here because + // we do not bother with getting the storage for each tenant here because // we get the tenants from the user itself, and the user can only be shared across // tenants of the same storage - therefore, the storage will be the same. @@ -656,7 +656,7 @@ public static long getUsersCountForTenant(TenantIdentifier tenantIdentifier, tenantIdentifier, includeRecipeIds); } - public static long getUsersCountAcrossAllTenants(AppIdentifier appIdentappIdentifierfierWithStorages, + public static long getUsersCountAcrossAllTenants(AppIdentifier appIdentifier, Storage[] storages, RECIPE_ID[] includeRecipeIds) throws StorageQueryException, @@ -665,7 +665,7 @@ public static long getUsersCountAcrossAllTenants(AppIdentifier appIdentappIdenti for (Storage storage : storages) { count += StorageUtils.getAuthRecipeStorage(storage).getUsersCount( - appIdentappIdentifierfierWithStorages, includeRecipeIds); + appIdentifier, includeRecipeIds); } return count; diff --git a/src/main/java/io/supertokens/inmemorydb/Start.java b/src/main/java/io/supertokens/inmemorydb/Start.java index 129adee22..2dbcaaf54 100644 --- a/src/main/java/io/supertokens/inmemorydb/Start.java +++ b/src/main/java/io/supertokens/inmemorydb/Start.java @@ -1861,7 +1861,7 @@ public int deleteUserMetadata(AppIdentifier appIdentifier, String userId) throws @Override public void addRoleToUser(TenantIdentifier tenantIdentifier, String userId, String role) - throws StorageQueryException, UnknownRoleException, DuplicateUserRoleMappingException, + throws StorageQueryException, DuplicateUserRoleMappingException, TenantOrAppNotFoundException { try { UserRolesQueries.addRoleToUser(this, tenantIdentifier, userId, role); @@ -1870,13 +1870,6 @@ public void addRoleToUser(TenantIdentifier tenantIdentifier, String userId, Stri SQLiteConfig config = Config.getConfig(this); String serverErrorMessage = e.getMessage(); - if (isForeignKeyConstraintError( - serverErrorMessage, - config.getRolesTable(), - new String[]{"app_id", "role"}, - new Object[]{tenantIdentifier.getAppId(), role})) { - throw new UnknownRoleException(); - } if (isPrimaryKeyError(serverErrorMessage, config.getUserRolesTable(), new String[]{"app_id", "tenant_id", "user_id", "role"})) { throw new DuplicateUserRoleMappingException(); diff --git a/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java index 721bcae06..e9eb86980 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java @@ -74,8 +74,6 @@ public static String getQueryToCreateUserRolesTable(Start start) { + "user_id VARCHAR(128) NOT NULL," + "role VARCHAR(255) NOT NULL," + "PRIMARY KEY(app_id, tenant_id, user_id, role)," - + "FOREIGN KEY(app_id, role) REFERENCES " + Config.getConfig(start).getRolesTable() - + " (app_id, role) ON DELETE CASCADE," + "FOREIGN KEY(app_id, tenant_id) REFERENCES " + Config.getConfig(start).getTenantsTable() + " (app_id, tenant_id) ON DELETE CASCADE" + ");"; diff --git a/src/main/java/io/supertokens/userroles/UserRoles.java b/src/main/java/io/supertokens/userroles/UserRoles.java index ceb3a86ef..5d69d6e95 100644 --- a/src/main/java/io/supertokens/userroles/UserRoles.java +++ b/src/main/java/io/supertokens/userroles/UserRoles.java @@ -44,9 +44,7 @@ public static boolean addRoleToUser(Main main, TenantIdentifier tenantIdentifier // We do this because it's not straight forward to replicate roles to all storages of an app Storage appStorage = StorageLayer.getStorage( tenantIdentifier.toAppIdentifier().getAsPublicTenantIdentifier(), main); - - String[] roles = getRoles(tenantIdentifier.toAppIdentifier(), appStorage); - if (!Arrays.asList(roles).contains(role)) { + if (!doesRoleExist(tenantIdentifier.toAppIdentifier(), appStorage, role)) { throw new UnknownRoleException(); } @@ -287,15 +285,23 @@ public static String[] getRolesThatHavePermission(Main main, } // delete a role - public static boolean deleteRole(AppIdentifier appIdentifier, Storage storage, String role) - throws StorageQueryException { - return StorageUtils.getUserRolesStorage(storage).deleteRole(appIdentifier, role); + public static boolean deleteRole(Main main, AppIdentifier appIdentifier, String role) + throws StorageQueryException, TenantOrAppNotFoundException { + + Storage[] storages = StorageLayer.getStoragesForApp(main, appIdentifier); + boolean deletedRole = false; + for (Storage storage : storages) { + UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); + deletedRole = userRolesStorage.deleteRole(appIdentifier, role) || deletedRole; + } + + return deletedRole; } @TestOnly - public static boolean deleteRole(Main main, String role) throws StorageQueryException { - Storage storage = StorageLayer.getStorage(main); - return deleteRole(new AppIdentifier(null, null), storage, role); + public static boolean deleteRole(Main main, String role) throws StorageQueryException, + TenantOrAppNotFoundException { + return deleteRole(main, new AppIdentifier(null, null), role); } // retrieve all roles that have been created diff --git a/src/main/java/io/supertokens/webserver/WebserverAPI.java b/src/main/java/io/supertokens/webserver/WebserverAPI.java index 60f311efc..65cb7c200 100644 --- a/src/main/java/io/supertokens/webserver/WebserverAPI.java +++ b/src/main/java/io/supertokens/webserver/WebserverAPI.java @@ -231,7 +231,7 @@ private String getTenantId(HttpServletRequest req) { apiPath = "/" + apiPath; } if (apiPath.equals("/")) { - if ((path.equals("") || path.equals("/"))) { + if (path.equals("") || path.equals("/")) { return null; } } else { @@ -316,7 +316,7 @@ protected Storage getTenantStorage(HttpServletRequest req) protected Storage[] enforcePublicTenantAndGetAllStoragesForApp(HttpServletRequest req) throws ServletException, BadPermissionException, TenantOrAppNotFoundException { if (getTenantId(req) != null) { - throw new BadPermissionException("Only public tenantId can this app specific API"); + throw new BadPermissionException("Only public tenantId can call this app specific API"); } AppIdentifier appIdentifier = getAppIdentifier(req); @@ -330,7 +330,7 @@ protected Storage enforcePublicTenantAndGetPublicTenantStorage( this.getTenantId(req)); if (getTenantId(req) != null) { - throw new BadPermissionException("Only public tenantId can this app specific API"); + throw new BadPermissionException("Only public tenantId can call this app specific API"); } return StorageLayer.getStorage(tenantIdentifier, main); @@ -345,7 +345,7 @@ protected StorageAndUserIdMapping getStorageAndUserIdMappingForTenantSpecificApi userIdType); } - protected StorageAndUserIdMapping getStorageAndUserIdMappingForAppSpecificApi( + protected StorageAndUserIdMapping enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( HttpServletRequest req, String userId, UserIdType userIdType) throws StorageQueryException, TenantOrAppNotFoundException, UnknownUserIdException, ServletException, BadPermissionException { diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java index 55917b79a..589cf3fdf 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java @@ -61,7 +61,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { String userId = inputRecipeUserId; StorageAndUserIdMapping storageAndMapping = - getStorageAndUserIdMappingForAppSpecificApi( + enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, inputRecipeUserId, UserIdType.ANY); storage = storageAndMapping.storage; if (storageAndMapping.userIdMapping != null) { diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java index 83e2671cb..bc8011efc 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java @@ -65,7 +65,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO String recipeUserId = inputRecipeUserId; { StorageAndUserIdMapping mappingAndStorage = - getStorageAndUserIdMappingForAppSpecificApi( + enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, inputRecipeUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { recipeUserId = mappingAndStorage.userIdMapping.superTokensUserId; @@ -75,7 +75,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO String primaryUserId = inputPrimaryUserId; { StorageAndUserIdMapping mappingAndStorage = - getStorageAndUserIdMappingForAppSpecificApi( + enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, inputPrimaryUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { primaryUserId = mappingAndStorage.userIdMapping.superTokensUserId; diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java index 89be22302..c912fcf54 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java @@ -63,7 +63,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { String userId = inputRecipeUserId; StorageAndUserIdMapping mappingAndStorage = - getStorageAndUserIdMappingForAppSpecificApi( + enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, inputRecipeUserId, UserIdType.ANY); storage = mappingAndStorage.storage; if (mappingAndStorage.userIdMapping != null) { diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java index 5e709fe62..6c4e29e6e 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java @@ -67,7 +67,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String recipeUserId = inputRecipeUserId; { StorageAndUserIdMapping mappingAndStorage = - getStorageAndUserIdMappingForAppSpecificApi( + enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, inputRecipeUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { recipeUserId = mappingAndStorage.userIdMapping.superTokensUserId; @@ -77,7 +77,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String primaryUserId = inputPrimaryUserId; { StorageAndUserIdMapping mappingAndStorage = - getStorageAndUserIdMappingForAppSpecificApi( + enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, inputPrimaryUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { primaryUserId = mappingAndStorage.userIdMapping.superTokensUserId; diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java index 8bcab2088..5b1801db2 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java @@ -59,7 +59,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { String userId = inputRecipeUserId; StorageAndUserIdMapping mappingAndStorage = - getStorageAndUserIdMappingForAppSpecificApi( + enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, inputRecipeUserId, UserIdType.ANY); if (mappingAndStorage.userIdMapping != null) { userId = mappingAndStorage.userIdMapping.superTokensUserId; diff --git a/src/main/java/io/supertokens/webserver/api/core/ActiveUsersCountAPI.java b/src/main/java/io/supertokens/webserver/api/core/ActiveUsersCountAPI.java index df20d926f..927e9c68c 100644 --- a/src/main/java/io/supertokens/webserver/api/core/ActiveUsersCountAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/ActiveUsersCountAPI.java @@ -52,9 +52,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } try { - int count = ActiveUsers.countUsersActiveSince( - this.getAppIdentifier(req), - this.enforcePublicTenantAndGetPublicTenantStorage(req), sinceTimestamp); + enforcePublicTenantAndGetPublicTenantStorage(req); // to enforce this API is called from public tenant + int count = ActiveUsers.countUsersActiveSince(main, this.getAppIdentifier(req), sinceTimestamp); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); result.addProperty("count", count); diff --git a/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java b/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java index 3eca2d329..7a8f7a6f2 100644 --- a/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java @@ -52,14 +52,9 @@ protected boolean checkAPIKey(HttpServletRequest req) { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { String pid = InputParser.getQueryParamOrThrowError(req, "pid", false); - try { - TenantIdentifier tenantIdentifier = getTenantIdentifier(req); - getTenantStorage(req); // to check if tenant exists - if (!tenantIdentifier.equals(new TenantIdentifier(null, null, null))) { - throw new ServletException(new BadPermissionException("you can call this only from the base connection uri domain, public app and tenant")); - } - } catch (TenantOrAppNotFoundException e) { - throw new ServletException(e); + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + if (!tenantIdentifier.equals(new TenantIdentifier(null, null, null))) { + throw new ServletException(new BadPermissionException("you can call this only from the base connection uri domain, public app and tenant")); } if ((ProcessHandle.current().pid() + "").equals(pid)) { diff --git a/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java b/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java index 1348d09bb..c47817c90 100644 --- a/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java @@ -60,7 +60,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { StorageAndUserIdMapping storageAndUserIdMapping = - this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); AuthRecipe.deleteUser(getAppIdentifier(req), storageAndUserIdMapping.storage, userId, removeAllLinkedAccounts, diff --git a/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java b/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java index ef1a53d93..b4d33d462 100644 --- a/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java @@ -58,7 +58,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { AppIdentifier appIdentifier = this.getAppIdentifier(req); StorageAndUserIdMapping storageAndUserIdMapping = - this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the getUserUsingId function if (storageAndUserIdMapping.userIdMapping != null) { userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; diff --git a/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java b/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java index 62f4f5851..b414ad543 100644 --- a/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java @@ -80,7 +80,10 @@ private void handleRequest(HttpServletRequest req, HttpServletResponse resp) thr // API is app specific try { - RateLimiter rateLimiter = RateLimiter.getInstance(getAppIdentifier(req), super.main, 200); + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage[] storages = StorageLayer.getStoragesForApp(main, appIdentifier); // throws tenantOrAppNotFoundException + + RateLimiter rateLimiter = RateLimiter.getInstance(appIdentifier, super.main, 200); if (!rateLimiter.checkRequest()) { if (Main.isTesting) { super.sendTextResponse(200, "RateLimitedHello", resp); @@ -90,9 +93,6 @@ private void handleRequest(HttpServletRequest req, HttpServletResponse resp) thr return; } - AppIdentifier appIdentifier = getAppIdentifier(req); - Storage[] storages = StorageLayer.getStoragesForApp(main, appIdentifier); - for (Storage storage : storages) { // even if the public tenant does not exist, the following function will return a null // idea here is to test that the storage is working diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java index 1974d22d6..6195213fc 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java @@ -84,7 +84,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO if (userId != null) { // Query by userId StorageAndUserIdMapping storageAndUserIdMapping = - this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the getUserUsingId function if (storageAndUserIdMapping.userIdMapping != null) { userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; @@ -166,7 +166,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO try { StorageAndUserIdMapping storageAndUserIdMapping = - this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the updateUsersEmailOrPassword if (storageAndUserIdMapping.userIdMapping != null) { userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; diff --git a/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java b/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java index 454936944..f3c7664ca 100644 --- a/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java @@ -61,7 +61,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I AppIdentifier appIdentifier = getAppIdentifier(req); Storage storage; try { - StorageAndUserIdMapping storageAndUidMapping = getStorageAndUserIdMappingForAppSpecificApi( + StorageAndUserIdMapping storageAndUidMapping = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); storage = storageAndUidMapping.storage; } catch (UnknownUserIdException e) { diff --git a/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java b/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java index ecc08be38..c4d782452 100644 --- a/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java @@ -111,7 +111,7 @@ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws Servl AppIdentifier appIdentifier = getAppIdentifier(req); Storage storage; try { - StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForAppSpecificApi( + StorageAndUserIdMapping storageAndUserIdMapping = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/ListTenantsAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/ListTenantsAPI.java index b2fe19ef6..98fe89054 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/ListTenantsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/ListTenantsAPI.java @@ -52,10 +52,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO TenantIdentifier tenantIdentifier = getTenantIdentifier(req); Storage storage = getTenantStorage(req); - if (!tenantIdentifier.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID)) { - throw new BadPermissionException("Only the public tenantId is allowed to list all tenants " + - "associated with this app"); - } + enforcePublicTenantAndGetPublicTenantStorage(req); // enforce that this API is called using public tenant TenantConfig[] tenantConfigs = Multitenancy.getAllTenantsForApp(tenantIdentifier.toAppIdentifier(), main); JsonArray tenantsArray = new JsonArray(); diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java index 98e61b06d..49ff69ff6 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java @@ -82,7 +82,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { AppIdentifier appIdentifier = getAppIdentifier(req); StorageAndUserIdMapping storageAndUserIdMapping = - this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); if (storageAndUserIdMapping.userIdMapping != null) { userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } @@ -165,7 +165,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO try { AppIdentifier appIdentifier = getAppIdentifier(req); StorageAndUserIdMapping storageAndUserIdMapping = - this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the updateUser if (storageAndUserIdMapping.userIdMapping != null) { userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; diff --git a/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java b/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java index 1813769a7..a62df469c 100644 --- a/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java @@ -114,14 +114,14 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I UnsupportedJWTSigningAlgorithmException e) { throw new ServletException(e); } catch (AccessTokenPayloadError | UnauthorisedException e) { - Logging.debug(main, appIdentifier.getAsPublicTenantIdentifier(), + Logging.debug(main, getTenantIdentifier(req), Utils.exceptionStacktraceToString(e)); JsonObject reply = new JsonObject(); reply.addProperty("status", "UNAUTHORISED"); reply.addProperty("message", e.getMessage()); super.sendJsonResponse(200, reply, resp); } catch (TokenTheftDetectedException e) { - Logging.debug(main, appIdentifier.getAsPublicTenantIdentifier(), + Logging.debug(main, getTenantIdentifier(req), Utils.exceptionStacktraceToString(e)); JsonObject reply = new JsonObject(); reply.addProperty("status", "TOKEN_THEFT_DETECTED"); diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java index 12b1cec58..2de495b62 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java @@ -21,9 +21,12 @@ import com.google.gson.JsonPrimitive; import io.supertokens.ActiveUsers; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.STORAGE_TYPE; import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; @@ -39,6 +42,10 @@ import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class SessionRemoveAPI extends WebserverAPI { private static final long serialVersionUID = -2082970815993229316L; @@ -54,7 +61,9 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - // API is tenant specific. also operates on all tenants in an app if `revokeAcrossAllTenants` is set to true + // API is app specific when `userId` is passed and `revokeAcrossAllTenants` is set to true + // API is app specific when revoking using `sessionHandles` + // API is tenant specific in all other cases (when `userId` is passed and `revokeAcrossAllTenants` is set to false) JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String userId = InputParser.parseStringOrThrowError(input, "userId", true); @@ -101,28 +110,48 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } if (userId != null) { + Storage storage = null; try { - TenantIdentifier tenantIdentifier = getTenantIdentifier(req); - Storage storage = getTenantStorage(req); - String[] sessionHandlesRevoked; + if (revokeAcrossAllTenants) { + StorageAndUserIdMapping storageAndUserIdMapping = null; + try { + storageAndUserIdMapping = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( + req, userId, UserIdType.ANY); + storage = storageAndUserIdMapping.storage; + } catch (UnknownUserIdException e) { + storage = getTenantStorage(req); + } + AppIdentifier appIdentifier = getAppIdentifier(req); + sessionHandlesRevoked = Session.revokeAllSessionsForUser( - main, tenantIdentifier.toAppIdentifier(), storage, userId, revokeSessionsForLinkedAccounts); + main, appIdentifier, storage, userId, revokeSessionsForLinkedAccounts); } else { + StorageAndUserIdMapping storageAndUserIdMapping = null; + try { + storageAndUserIdMapping = getStorageAndUserIdMappingForTenantSpecificApi( + req, userId, UserIdType.ANY); + storage = storageAndUserIdMapping.storage; + } catch (UnknownUserIdException e) { + storage = getTenantStorage(req); + } + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + sessionHandlesRevoked = Session.revokeAllSessionsForUser( main, tenantIdentifier, storage, userId, revokeSessionsForLinkedAccounts); } if (storage.getType() == STORAGE_TYPE.SQL) { try { + AppIdentifier appIdentifier = getAppIdentifier(req); UserIdMapping userIdMapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( - tenantIdentifier.toAppIdentifier(), storage, userId, UserIdType.ANY); + appIdentifier, storage, userId, UserIdType.ANY); if (userIdMapping != null) { - ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), main, + ActiveUsers.updateLastActive(appIdentifier, main, userIdMapping.superTokensUserId); } else { - ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), main, userId); + ActiveUsers.updateLastActive(appIdentifier, main, userId); } } catch (StorageQueryException ignored) { } @@ -135,25 +164,45 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } result.add("sessionHandlesRevoked", sessionHandlesRevokedJSON); super.sendJsonResponse(200, result, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } else { try { + enforcePublicTenantAndGetPublicTenantStorage(req); // enforce public tenant AppIdentifier appIdentifier = getAppIdentifier(req); - Storage storage = getTenantStorage(req); - String[] sessionHandlesRevoked = Session.revokeSessionUsingSessionHandles(main, - appIdentifier, storage, sessionHandles); + Map> sessionHandlesByTenantId = new HashMap<>(); + + for (String sessionHandle : sessionHandles) { + String tenantId = Session.getTenantIdFromSessionHandle(sessionHandle); + if (!sessionHandlesByTenantId.containsKey(tenantId)) { + sessionHandlesByTenantId.put(tenantId, new ArrayList<>()); + } + sessionHandlesByTenantId.get(tenantId).add(sessionHandle); + } + List allSessionHandlesRevoked = new ArrayList<>(); + for (Map.Entry> entry : sessionHandlesByTenantId.entrySet()) { + String tenantId = entry.getKey(); + List sessionHandlesForTenant = entry.getValue(); + Storage storage = + StorageLayer.getStorage(new TenantIdentifier( + appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), tenantId), main); + + String[] sessionHandlesRevoked = Session.revokeSessionUsingSessionHandles(main, + appIdentifier, storage, sessionHandlesForTenant.toArray(new String[0])); + allSessionHandlesRevoked.addAll(List.of(sessionHandlesRevoked)); + } + JsonObject result = new JsonObject(); result.addProperty("status", "OK"); JsonArray sessionHandlesRevokedJSON = new JsonArray(); - for (String sessionHandle : sessionHandlesRevoked) { + for (String sessionHandle : allSessionHandlesRevoked) { sessionHandlesRevokedJSON.add(new JsonPrimitive(sessionHandle)); } result.add("sessionHandlesRevoked", sessionHandlesRevokedJSON); super.sendJsonResponse(200, result, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java b/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java index efd0f81c6..f8ef39376 100644 --- a/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java @@ -81,7 +81,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO AppIdentifier appIdentifier = getAppIdentifier(req); try { StorageAndUserIdMapping storageAndUserIdMapping = - this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); // if a userIdMapping exists, pass the superTokensUserId to the getUserUsingId function if (storageAndUserIdMapping.userIdMapping != null) { userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; diff --git a/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java index 31c0c8ee9..7aeaf35d5 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java @@ -74,12 +74,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I // While sending the usage stats we do a join, so totp tables also must use internal user id. // Try to find the appIdentifier with right storage based on the userId - StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForAppSpecificApi( + StorageAndUserIdMapping storageAndUserIdMapping = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); - - if (storageAndUserIdMapping.userIdMapping != null) { - userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; - } storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the public tenant storage @@ -130,13 +126,10 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO // Try to find the appIdentifier with right storage based on the userId StorageAndUserIdMapping storageAndUserIdMapping = - getStorageAndUserIdMappingForAppSpecificApi( + enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); - - if (storageAndUserIdMapping.userIdMapping != null) { - userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; - } storage = storageAndUserIdMapping.storage; + } catch (UnknownUserIdException e) { // if the user is not found, just use the public storage storage = enforcePublicTenantAndGetPublicTenantStorage(req); diff --git a/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java b/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java index 400674c70..4b5e9905a 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java @@ -54,12 +54,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO // While sending the usage stats we do a join, so totp tables also must use internal user id. // Try to find the appIdentifier with right storage based on the userId - StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForAppSpecificApi( + StorageAndUserIdMapping storageAndUserIdMapping = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); - - if (storageAndUserIdMapping.userIdMapping != null) { - userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; - } storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest diff --git a/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java index fd56fdcd4..d8dde49c3 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java @@ -60,12 +60,9 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I // While sending the usage stats we do a join, so totp tables also must use internal user id. // Try to find the appIdentifier with right storage based on the userId - StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForAppSpecificApi( + StorageAndUserIdMapping storageAndUserIdMapping = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); - if (storageAndUserIdMapping.userIdMapping != null) { - userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; - } storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest diff --git a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java index 46adb2cc8..b81975402 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java @@ -65,10 +65,6 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForTenantSpecificApi( req, userId, UserIdType.ANY); - - if (storageAndUserIdMapping.userIdMapping != null) { - userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; - } storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest diff --git a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java index 3728119cf..54222050d 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java @@ -67,10 +67,6 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForTenantSpecificApi( req, userId, UserIdType.ANY); - - if (storageAndUserIdMapping.userIdMapping != null) { - userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; - } storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest diff --git a/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java b/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java index 195f314c9..ba2892e6b 100644 --- a/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java +++ b/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java @@ -86,7 +86,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { StorageAndUserIdMapping storageAndUserIdMapping = - this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType); boolean didMappingExist = UserIdMapping.deleteUserIdMapping( getAppIdentifier(req), diff --git a/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java b/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java index cde30fc02..8acf3ff60 100644 --- a/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java +++ b/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java @@ -95,7 +95,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO try { StorageAndUserIdMapping storageAndUserIdMapping = - this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType); if (UserIdMapping.updateOrDeleteExternalUserIdInfo( getAppIdentifier(req), diff --git a/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java b/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java index 07ca76829..0bd993e07 100644 --- a/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java +++ b/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java @@ -162,10 +162,10 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO // Request from (app1, tenant1) will return user1 and request from (app1, tenant2) will return user2 // Request from (app1, tenant3) may result in either user1 or user2 - StorageAndUserIdMapping appIdentifierWithStorageAndUserIdMapping = - this.getStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType); + StorageAndUserIdMapping storageAndUserIdMapping = + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType); - if (appIdentifierWithStorageAndUserIdMapping.userIdMapping == null) { + if (storageAndUserIdMapping.userIdMapping == null) { JsonObject response = new JsonObject(); response.addProperty("status", "UNKNOWN_MAPPING_ERROR"); super.sendJsonResponse(200, response, resp); @@ -175,12 +175,12 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject response = new JsonObject(); response.addProperty("status", "OK"); response.addProperty("superTokensUserId", - appIdentifierWithStorageAndUserIdMapping.userIdMapping.superTokensUserId); + storageAndUserIdMapping.userIdMapping.superTokensUserId); response.addProperty("externalUserId", - appIdentifierWithStorageAndUserIdMapping.userIdMapping.externalUserId); - if (appIdentifierWithStorageAndUserIdMapping.userIdMapping.externalUserIdInfo != null) { + storageAndUserIdMapping.userIdMapping.externalUserId); + if (storageAndUserIdMapping.userIdMapping.externalUserIdInfo != null) { response.addProperty("externalUserIdInfo", - appIdentifierWithStorageAndUserIdMapping.userIdMapping.externalUserIdInfo); + storageAndUserIdMapping.userIdMapping.externalUserIdInfo); } super.sendJsonResponse(200, response, resp); diff --git a/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java b/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java index 47a6e0ad0..c8901064e 100644 --- a/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java @@ -58,7 +58,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { try { StorageAndUserIdMapping storageAndUserIdMapping = - this.getStorageAndUserIdMappingForAppSpecificApi( + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); UserMetadata.deleteUserMetadata(appIdentifier, storageAndUserIdMapping.storage, userId); } catch (UnknownUserIdException e) { diff --git a/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java b/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java index 4444d0551..c11d47faa 100644 --- a/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java @@ -57,7 +57,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { JsonObject metadata; try { - StorageAndUserIdMapping storageAndUserIdMapping = this.getStorageAndUserIdMappingForAppSpecificApi( + StorageAndUserIdMapping storageAndUserIdMapping = this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); metadata = UserMetadata.getUserMetadata(appIdentifier, storageAndUserIdMapping.storage, userId); } catch (UnknownUserIdException e) { @@ -86,7 +86,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject metadata; try { - StorageAndUserIdMapping storageAndUserIdMapping = this.getStorageAndUserIdMappingForAppSpecificApi( + StorageAndUserIdMapping storageAndUserIdMapping = this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); metadata = UserMetadata.updateUserMetadata(appIdentifier, storageAndUserIdMapping.storage, userId, update); diff --git a/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java index c1c6cd0d1..87f3d3f08 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/GetUsersForRoleAPI.java @@ -51,7 +51,7 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - // API is tenant specific, but uses public tenant storage + // API is tenant specific String role = InputParser.getQueryParamOrThrowError(req, "role", false); // normalize roles diff --git a/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java index acc130085..66f59c7a2 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java @@ -61,9 +61,9 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { AppIdentifier appIdentifier = getAppIdentifier(req); - Storage storage = enforcePublicTenantAndGetPublicTenantStorage(req); + enforcePublicTenantAndGetPublicTenantStorage(req); // enforce this API is called from public tenant - boolean didRoleExist = UserRoles.deleteRole(appIdentifier, storage, role); + boolean didRoleExist = UserRoles.deleteRole(main, appIdentifier, role); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java index ff94b4bbd..7b76eb31b 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/RemoveUserRoleAPI.java @@ -50,7 +50,7 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - // API is tenant specific, but uses public tenant storage + // API is tenant specific JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String userId = InputParser.parseStringOrThrowError(input, "userId", false); String role = InputParser.parseStringOrThrowError(input, "role", false); diff --git a/src/test/java/io/supertokens/test/FeatureFlagTest.java b/src/test/java/io/supertokens/test/FeatureFlagTest.java index d6d324a13..c842475d9 100644 --- a/src/test/java/io/supertokens/test/FeatureFlagTest.java +++ b/src/test/java/io/supertokens/test/FeatureFlagTest.java @@ -357,17 +357,17 @@ public void testThatMultitenantStatsAreAccurate() throws Exception { ) ); - Storage tenantIdentifierWithStorage = ( + Storage storage = ( StorageLayer.getStorage(tenantIdentifier, process.getProcess())); if (i % 3 == 0) { // Create a user EmailPassword.signUp( - tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "user@example.com", + tenantIdentifier, storage, process.getProcess(), "user@example.com", "password"); } else if (i % 3 == 1) { // Create a session Session.createNewSession( - tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "userid", new JsonObject(), + tenantIdentifier, storage, process.getProcess(), "userid", new JsonObject(), new JsonObject()); } else { // Create an enterprise provider @@ -476,17 +476,17 @@ public void testThatMultitenantStatsAreAccurateForAnApp() throws Exception { ) ); - Storage tenantIdentifierWithStorage = ( + Storage storage = ( StorageLayer.getStorage(tenantIdentifier, process.getProcess())); if (i % 3 == 0) { // Create a user EmailPassword.signUp( - tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "user@example.com", + tenantIdentifier, storage, process.getProcess(), "user@example.com", "password"); } else if (i % 3 == 1) { // Create a session Session.createNewSession( - tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "userid", new JsonObject(), + tenantIdentifier, storage, process.getProcess(), "userid", new JsonObject(), new JsonObject()); } else { // Create an enterprise provider @@ -605,17 +605,17 @@ public void testThatMultitenantStatsAreAccurateForACud() throws Exception { ) ); - Storage tenantIdentifierWithStorage = ( + Storage storage = ( StorageLayer.getStorage(tenantIdentifier, process.getProcess())); if (i % 3 == 0) { // Create a user EmailPassword.signUp( - tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "user@example.com", + tenantIdentifier, storage, process.getProcess(), "user@example.com", "password"); } else if (i % 3 == 1) { // Create a session Session.createNewSession( - tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), "userid", new JsonObject(), + tenantIdentifier, storage, process.getProcess(), "userid", new JsonObject(), new JsonObject()); } else { // Create an enterprise provider diff --git a/src/test/java/io/supertokens/test/accountlinking/CreatePrimaryUserTest.java b/src/test/java/io/supertokens/test/accountlinking/CreatePrimaryUserTest.java index 72b15214e..5be161397 100644 --- a/src/test/java/io/supertokens/test/accountlinking/CreatePrimaryUserTest.java +++ b/src/test/java/io/supertokens/test/accountlinking/CreatePrimaryUserTest.java @@ -425,9 +425,9 @@ public void makePrimaryUserFailsCauseAnotherAccountWithSameEmailAlreadyAPrimaryU new ThirdPartyConfig(true, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(true), new JsonObject())); - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(process.main)); + Storage storage = (StorageLayer.getStorage(process.main)); AuthRecipeUserInfo emailPasswordUser = EmailPassword.signUp(new TenantIdentifier(null, null, "t1"), - tenantIdentifierWithStorage, process.getProcess(), + storage, process.getProcess(), "test@example.com", "pass1234"); @@ -438,7 +438,7 @@ public void makePrimaryUserFailsCauseAnotherAccountWithSameEmailAlreadyAPrimaryU "test@example.com"); Multitenancy.addUserIdToTenant(process.main, new TenantIdentifier(null, null, "t1"), - tenantIdentifierWithStorage, + storage, signInUpResponse.user.getSupertokensUserId()); try { @@ -473,9 +473,9 @@ public void makePrimarySucceedsEvenIfAnotherAccountWithSameEmailButInADifferentT new ThirdPartyConfig(true, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(true), new JsonObject())); - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(process.main)); + Storage storage = (StorageLayer.getStorage(process.main)); AuthRecipeUserInfo emailPasswordUser = EmailPassword.signUp(new TenantIdentifier(null, null, "t1"), - tenantIdentifierWithStorage, process.getProcess(), + storage, process.getProcess(), "test@example.com", "pass1234"); diff --git a/src/test/java/io/supertokens/test/accountlinking/GetUserByAccountInfoTest.java b/src/test/java/io/supertokens/test/accountlinking/GetUserByAccountInfoTest.java index 59afa63d8..e920629b2 100644 --- a/src/test/java/io/supertokens/test/accountlinking/GetUserByAccountInfoTest.java +++ b/src/test/java/io/supertokens/test/accountlinking/GetUserByAccountInfoTest.java @@ -114,10 +114,10 @@ public void testListUsersByAccountInfoForUnlinkedAccounts() throws Exception { AuthRecipeUserInfo user3 = createPasswordlessUserWithEmail(process.getProcess(), "test3@example.com"); AuthRecipeUserInfo user4 = createPasswordlessUserWithPhone(process.getProcess(), "+919876543210"); - Storage tenantIdentifierWithStorage = (StorageLayer.getBaseStorage(process.getProcess())); + Storage storage = (StorageLayer.getBaseStorage(process.getProcess())); AuthRecipeUserInfo userToTest = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test1@example.com", null, null, null)[0]; assertNotNull(userToTest.getSupertokensUserId()); assertFalse(userToTest.isPrimaryUser); @@ -129,29 +129,29 @@ public void testListUsersByAccountInfoForUnlinkedAccounts() throws Exception { assert(userToTest.loginMethods[0].timeJoined > 0); // test for result - assertEquals(user1, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage + assertEquals(user1, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, storage , false, "test1@example.com", null, null, null)[0]); - assertEquals(user2, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage + assertEquals(user2, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, storage , false, null, null, "google", "userid1")[0]); - assertEquals(user2, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage + assertEquals(user2, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, storage , false, "test2@example.com", null, "google", "userid1")[0]); - assertEquals(user3, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage + assertEquals(user3, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, storage , false, "test3@example.com", null, null, null)[0]); - assertEquals(user4, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage + assertEquals(user4, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, storage , false, null, "+919876543210", null, null)[0]); // test for no result - assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, storage, false, "test1@example.com", "+919876543210", null, null).length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, storage, false, "test2@example.com", "+919876543210", null, null).length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, storage, false, "test3@example.com", "+919876543210", null, null).length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, storage, false, null, "+919876543210", "google", "userid1").length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, storage, false, "test1@gmail.com", null, "google", "userid1").length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, storage, false, "test3@gmail.com", null, "google", "userid1").length); process.kill(); @@ -177,31 +177,31 @@ public void testListUsersByAccountInfoForUnlinkedAccountsWithUnionOption() throw AuthRecipeUserInfo user3 = createPasswordlessUserWithEmail(process.getProcess(), "test3@example.com"); AuthRecipeUserInfo user4 = createPasswordlessUserWithPhone(process.getProcess(), "+919876543210"); - Storage tenantIdentifierWithStorage = (StorageLayer.getBaseStorage(process.getProcess())); + Storage storage = (StorageLayer.getBaseStorage(process.getProcess())); { AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, true, "test1@example.com", "+919876543210", null, null); + storage, true, "test1@example.com", "+919876543210", null, null); assertEquals(2, users.length); assertTrue(Arrays.asList(users).contains(user1)); assertTrue(Arrays.asList(users).contains(user4)); } { AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, true, "test1@example.com", null, "google", "userid1"); + storage, true, "test1@example.com", null, "google", "userid1"); assertEquals(2, users.length); assertTrue(Arrays.asList(users).contains(user1)); assertTrue(Arrays.asList(users).contains(user2)); } { AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, true, null, "+919876543210", "google", "userid1"); + storage, true, null, "+919876543210", "google", "userid1"); assertEquals(2, users.length); assertTrue(Arrays.asList(users).contains(user4)); assertTrue(Arrays.asList(users).contains(user2)); } { AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, true, "test1@example.com", "+919876543210", "google", "userid1"); + storage, true, "test1@example.com", "+919876543210", "google", "userid1"); assertEquals(3, users.length); assertTrue(Arrays.asList(users).contains(user1)); assertTrue(Arrays.asList(users).contains(user2)); @@ -226,14 +226,14 @@ public void testUnknownAccountInfo() throws Exception { return; } - Storage tenantIdentifierWithStorage = (StorageLayer.getBaseStorage(process.getProcess())); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + Storage storage = (StorageLayer.getBaseStorage(process.getProcess())); + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, storage, false, "test1@example.com", null, null, null).length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, storage, false, null, null, "google", "userid1").length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, storage, false, "test3@example.com", null, null, null).length); - assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, tenantIdentifierWithStorage, + assertEquals(0, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, storage, false, null, "+919876543210", null, null).length); process.kill(); @@ -261,25 +261,25 @@ public void testListUserByAccountInfoWhenAccountsAreLinked1() throws Exception { AuthRecipeUserInfo primaryUser = AuthRecipe.createPrimaryUser(process.getProcess(), user1.getSupertokensUserId()).user; AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - Storage tenantIdentifierWithStorage = ( + Storage storage = ( StorageLayer.getBaseStorage(process.getProcess())); primaryUser = AuthRecipe.getUserById(process.getProcess(), user1.getSupertokensUserId()); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test1@example.com", null, null, null)[0]); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test2@example.com", null, null, null)[0]); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, null, null, "google", "userid1")[0]); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test1@example.com", null, "google", "userid1")[0]); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test2@example.com", null, "google", "userid1")[0]); process.kill(); @@ -307,16 +307,16 @@ public void testListUserByAccountInfoWhenAccountsAreLinked2() throws Exception { AuthRecipeUserInfo primaryUser = AuthRecipe.createPrimaryUser(process.getProcess(), user1.getSupertokensUserId()).user; AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - Storage tenantIdentifierWithStorage = ( + Storage storage = ( StorageLayer.getBaseStorage(process.getProcess())); primaryUser = AuthRecipe.getUserById(process.getProcess(), user1.getSupertokensUserId()); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test1@example.com", null, null, null)[0]); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test2@example.com", null, null, null)[0]); process.kill(); @@ -344,16 +344,16 @@ public void testListUserByAccountInfoWhenAccountsAreLinked3() throws Exception { AuthRecipeUserInfo primaryUser = AuthRecipe.createPrimaryUser(process.getProcess(), user1.getSupertokensUserId()).user; AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - Storage tenantIdentifierWithStorage = ( + Storage storage = ( StorageLayer.getBaseStorage(process.getProcess())); primaryUser = AuthRecipe.getUserById(process.getProcess(), user1.getSupertokensUserId()); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test1@example.com", null, null, null)[0]); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test2@example.com", null, null, null)[0]); process.kill(); @@ -381,19 +381,19 @@ public void testListUserByAccountInfoWhenAccountsAreLinked4() throws Exception { AuthRecipeUserInfo primaryUser = AuthRecipe.createPrimaryUser(process.getProcess(), user1.getSupertokensUserId()).user; AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - Storage tenantIdentifierWithStorage = ( + Storage storage = ( StorageLayer.getBaseStorage(process.getProcess())); primaryUser = AuthRecipe.getUserById(process.getProcess(), user1.getSupertokensUserId()); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test1@example.com", null, null, null)[0]); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, null, "+919876543210", null, null)[0]); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test1@example.com", "+919876543210", null, null)[0]); process.kill(); @@ -421,25 +421,25 @@ public void testListUserByAccountInfoWhenAccountsAreLinked5() throws Exception { AuthRecipeUserInfo primaryUser = AuthRecipe.createPrimaryUser(process.getProcess(), user1.getSupertokensUserId()).user; AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - Storage tenantIdentifierWithStorage = ( + Storage storage = ( StorageLayer.getBaseStorage(process.getProcess())); primaryUser = AuthRecipe.getUserById(process.getProcess(), user1.getSupertokensUserId()); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test1@example.com", null, null, null)[0]); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test2@example.com", null, null, null)[0]); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, null, null, "google", "userid1")[0]); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test1@example.com", null, "google", "userid1")[0]); assertEquals(primaryUser, AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test2@example.com", null, "google", "userid1")[0]); process.kill(); @@ -473,23 +473,23 @@ public void testForEmptyResults() throws Exception { AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), primaryUser.getSupertokensUserId()); AuthRecipe.linkAccounts(process.getProcess(), user3.getSupertokensUserId(), primaryUser.getSupertokensUserId()); - Storage tenantIdentifierWithStorage = ( + Storage storage = ( StorageLayer.getBaseStorage(process.getProcess())); { AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, "test5@example.com", null, null, null); assertEquals(0, users.length); } { AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, null, null, "google", "userid5"); assertEquals(0, users.length); } { AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, + storage, false, null, "+9876", null, null); assertEquals(0, users.length); } @@ -531,12 +531,12 @@ public void testGetUserByAccountInfoOrdersUserBasedOnTimeJoined() throws Excepti AuthRecipe.createPrimaryUser(process.getProcess(), user4.getSupertokensUserId()); - Storage tenantIdentifierWithStorage = ( + Storage storage = ( StorageLayer.getBaseStorage(process.getProcess())); { AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, true, "test1@example.com", null, + storage, true, "test1@example.com", null, null, null); assertEquals(3, users.length); @@ -546,7 +546,7 @@ public void testGetUserByAccountInfoOrdersUserBasedOnTimeJoined() throws Excepti } { AuthRecipeUserInfo[] users = AuthRecipe.getUsersByAccountInfo(TenantIdentifier.BASE_TENANT, - tenantIdentifierWithStorage, false, "test1@example.com", null, + storage, false, "test1@example.com", null, null, null); assertEquals(3, users.length); diff --git a/src/test/java/io/supertokens/test/accountlinking/LinkAccountsTest.java b/src/test/java/io/supertokens/test/accountlinking/LinkAccountsTest.java index 10066d51f..44bca0c5b 100644 --- a/src/test/java/io/supertokens/test/accountlinking/LinkAccountsTest.java +++ b/src/test/java/io/supertokens/test/accountlinking/LinkAccountsTest.java @@ -468,10 +468,10 @@ public void linkAccountFailureCauseAccountInfoAssociatedWithAPrimaryUserEvenIfIn new ThirdPartyConfig(true, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(true), new JsonObject())); - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(process.main)); + Storage storage = (StorageLayer.getStorage(process.main)); AuthRecipeUserInfo user = - EmailPassword.signUp(new TenantIdentifier(null, null, "t1"), tenantIdentifierWithStorage, + EmailPassword.signUp(new TenantIdentifier(null, null, "t1"), storage, process.getProcess(), "test@example.com", "password"); assert (!user.isPrimaryUser); @@ -480,7 +480,7 @@ public void linkAccountFailureCauseAccountInfoAssociatedWithAPrimaryUserEvenIfIn Thread.sleep(50); ThirdParty.SignInUpResponse signInUpResponse = ThirdParty.signInUp( - new TenantIdentifier(null, null, "t1"), tenantIdentifierWithStorage, + new TenantIdentifier(null, null, "t1"), storage, process.getProcess(), "google", "user-google", "test@example.com"); @@ -523,10 +523,10 @@ public void linkAccountSuccessAcrossTenants() throws Exception { new ThirdPartyConfig(true, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(true), new JsonObject())); - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(process.main)); + Storage storage = (StorageLayer.getStorage(process.main)); AuthRecipeUserInfo user = EmailPassword.signUp(new TenantIdentifier(null, null, "t1"), - tenantIdentifierWithStorage, process.getProcess(), + storage, process.getProcess(), "test@example.com", "password"); assert (!user.isPrimaryUser); AuthRecipe.createPrimaryUser(process.main, user.getSupertokensUserId()); diff --git a/src/test/java/io/supertokens/test/accountlinking/MultitenantTest.java b/src/test/java/io/supertokens/test/accountlinking/MultitenantTest.java index 638068b7f..865008ea3 100644 --- a/src/test/java/io/supertokens/test/accountlinking/MultitenantTest.java +++ b/src/test/java/io/supertokens/test/accountlinking/MultitenantTest.java @@ -185,27 +185,27 @@ public void testUserAreNotAutomaticallySharedBetweenTenantsOfLinkedAccountsForPl t1 = new TenantIdentifier(null, "a1", null); t2 = new TenantIdentifier(null, "a1", "t1"); - Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); - Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); + Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2Storage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", + AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1Storage, process.getProcess(), "test@example.com", "password"); - Passwordless.CreateCodeResponse user2Code = Passwordless.createCode(t1, t1WithStorage, process.getProcess(), + Passwordless.CreateCodeResponse user2Code = Passwordless.createCode(t1, t1Storage, process.getProcess(), "test@example.com", null, null, null); - AuthRecipeUserInfo user2 = Passwordless.consumeCode(t1, t1WithStorage, process.getProcess(), user2Code.deviceId, + AuthRecipeUserInfo user2 = Passwordless.consumeCode(t1, t1Storage, process.getProcess(), user2Code.deviceId, user2Code.deviceIdHash, user2Code.userInputCode, null).user; - AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, + AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), t1Storage, user1.getSupertokensUserId()); - AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, user2.getSupertokensUserId(), + AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1Storage, user2.getSupertokensUserId(), user1.getSupertokensUserId()); - Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, user1.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2Storage, user1.getSupertokensUserId()); { // user2 should not be shared in tenant2 - Passwordless.CreateCodeResponse user3Code = Passwordless.createCode(t2, t2WithStorage, process.getProcess(), + Passwordless.CreateCodeResponse user3Code = Passwordless.createCode(t2, t2Storage, process.getProcess(), "test@example.com", null, null, null); - Passwordless.ConsumeCodeResponse res = Passwordless.consumeCode(t2, t2WithStorage, process.getProcess(), + Passwordless.ConsumeCodeResponse res = Passwordless.consumeCode(t2, t2Storage, process.getProcess(), user3Code.deviceId, user3Code.deviceIdHash, user3Code.userInputCode, null); assertTrue(res.createdNewUser); } @@ -233,23 +233,23 @@ public void testUserAreNotAutomaticallySharedBetweenTenantsOfLinkedAccountsForTP t1 = new TenantIdentifier(null, "a1", null); t2 = new TenantIdentifier(null, "a1", "t1"); - Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); - Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); + Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2Storage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", + AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1Storage, process.getProcess(), "test@example.com", "password"); - AuthRecipeUserInfo user2 = ThirdParty.signInUp(t1, t1WithStorage, process.getProcess(), "google", "googleid1", + AuthRecipeUserInfo user2 = ThirdParty.signInUp(t1, t1Storage, process.getProcess(), "google", "googleid1", "test@example.com").user; - AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, + AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), t1Storage, user1.getSupertokensUserId()); - AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, user2.getSupertokensUserId(), + AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1Storage, user2.getSupertokensUserId(), user1.getSupertokensUserId()); - Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, user1.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2Storage, user1.getSupertokensUserId()); { // user2 should not be shared in tenant2 - ThirdParty.SignInUpResponse res = ThirdParty.signInUp(t2, t2WithStorage, process.getProcess(), "google", + ThirdParty.SignInUpResponse res = ThirdParty.signInUp(t2, t2Storage, process.getProcess(), "google", "googleid1", "test@example.com"); assertTrue(res.createdNewUser); } @@ -277,28 +277,28 @@ public void testTenantDeletionWithAccountLinking() throws Exception { t1 = new TenantIdentifier(null, "a1", null); t2 = new TenantIdentifier(null, "a1", "t1"); - Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); - Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); + Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2Storage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t2, t2WithStorage, process.getProcess(), "test@example.com", + AuthRecipeUserInfo user1 = EmailPassword.signUp(t2, t2Storage, process.getProcess(), "test@example.com", "password"); - AuthRecipeUserInfo user2 = ThirdParty.signInUp(t2, t2WithStorage, process.getProcess(), "google", "googleid1", + AuthRecipeUserInfo user2 = ThirdParty.signInUp(t2, t2Storage, process.getProcess(), "google", "googleid1", "test@example.com").user; - AuthRecipe.createPrimaryUser(process.getProcess(), t2.toAppIdentifier(), t2WithStorage, + AuthRecipe.createPrimaryUser(process.getProcess(), t2.toAppIdentifier(), t2Storage, user1.getSupertokensUserId()); - AuthRecipe.linkAccounts(process.getProcess(), t2.toAppIdentifier(), t2WithStorage, user2.getSupertokensUserId(), + AuthRecipe.linkAccounts(process.getProcess(), t2.toAppIdentifier(), t2Storage, user2.getSupertokensUserId(), user1.getSupertokensUserId()); Multitenancy.deleteTenant(t2, process.getProcess()); - AuthRecipeUserInfo getUser1 = AuthRecipe.getUserById(t1.toAppIdentifier(), t1WithStorage, + AuthRecipeUserInfo getUser1 = AuthRecipe.getUserById(t1.toAppIdentifier(), t1Storage, user1.getSupertokensUserId()); for (LoginMethod lm : getUser1.loginMethods) { assertEquals(0, lm.tenantIds.size()); } - AuthRecipeUserInfo getUser2 = AuthRecipe.getUserById(t1.toAppIdentifier(), t1WithStorage, + AuthRecipeUserInfo getUser2 = AuthRecipe.getUserById(t1.toAppIdentifier(), t1Storage, user2.getSupertokensUserId()); for (LoginMethod lm : getUser2.loginMethods) { assertEquals(0, lm.tenantIds.size()); @@ -327,44 +327,44 @@ public void testTenantDeletionWithAccountLinkingWithUserRoles() throws Exception t1 = new TenantIdentifier(null, "a1", null); t2 = new TenantIdentifier(null, "a1", "t1"); - Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); - Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); + Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2Storage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t2, t2WithStorage, process.getProcess(), "test@example.com", + AuthRecipeUserInfo user1 = EmailPassword.signUp(t2, t2Storage, process.getProcess(), "test@example.com", "password"); - AuthRecipeUserInfo user2 = ThirdParty.signInUp(t2, t2WithStorage, process.getProcess(), "google", "googleid1", + AuthRecipeUserInfo user2 = ThirdParty.signInUp(t2, t2Storage, process.getProcess(), "google", "googleid1", "test@example.com").user; - AuthRecipe.createPrimaryUser(process.getProcess(), t2.toAppIdentifier(), t2WithStorage, + AuthRecipe.createPrimaryUser(process.getProcess(), t2.toAppIdentifier(), t2Storage, user1.getSupertokensUserId()); - AuthRecipe.linkAccounts(process.getProcess(), t2.toAppIdentifier(), t2WithStorage, user2.getSupertokensUserId(), + AuthRecipe.linkAccounts(process.getProcess(), t2.toAppIdentifier(), t2Storage, user2.getSupertokensUserId(), user1.getSupertokensUserId()); - UserRoles.createNewRoleOrModifyItsPermissions(t2.toAppIdentifier(), t2WithStorage, "admin", new String[]{"p1"}); - UserRoles.addRoleToUser(process.getProcess(), t2, t2WithStorage, user1.getSupertokensUserId(), "admin"); + UserRoles.createNewRoleOrModifyItsPermissions(t2.toAppIdentifier(), t2Storage, "admin", new String[]{"p1"}); + UserRoles.addRoleToUser(process.getProcess(), t2, t2Storage, user1.getSupertokensUserId(), "admin"); Multitenancy.deleteTenant(t2, process.getProcess()); createTenants(process.getProcess()); // create the tenant again - Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, user1.getSupertokensUserId()); // add + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2Storage, user1.getSupertokensUserId()); // add // the user to the tenant again - Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, user2.getSupertokensUserId()); // add + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2Storage, user2.getSupertokensUserId()); // add // the user to the tenant again - AuthRecipeUserInfo getUser1 = AuthRecipe.getUserById(t1.toAppIdentifier(), t1WithStorage, + AuthRecipeUserInfo getUser1 = AuthRecipe.getUserById(t1.toAppIdentifier(), t1Storage, user1.getSupertokensUserId()); for (LoginMethod lm : getUser1.loginMethods) { assertEquals(1, lm.tenantIds.size()); } - AuthRecipeUserInfo getUser2 = AuthRecipe.getUserById(t1.toAppIdentifier(), t1WithStorage, + AuthRecipeUserInfo getUser2 = AuthRecipe.getUserById(t1.toAppIdentifier(), t1Storage, user2.getSupertokensUserId()); for (LoginMethod lm : getUser2.loginMethods) { assertEquals(1, lm.tenantIds.size()); } - String[] roles = UserRoles.getRolesForUser(t2, t2WithStorage, user1.getSupertokensUserId()); + String[] roles = UserRoles.getRolesForUser(t2, t2Storage, user1.getSupertokensUserId()); assertEquals(0, roles.length); // must be deleted with tenant process.kill(); @@ -714,8 +714,8 @@ public void testVariousCases() throws Exception { new TestCaseStep() { @Override public void execute(Main main) throws Exception { - Storage t1WithStorage = (StorageLayer.getStorage(t1, main)); - AuthRecipeUserInfo user = AuthRecipe.getUserById(t1.toAppIdentifier(), t1WithStorage, + Storage t1Storage = (StorageLayer.getStorage(t1, main)); + AuthRecipeUserInfo user = AuthRecipe.getUserById(t1.toAppIdentifier(), t1Storage, TestCase.users.get(0).getSupertokensUserId()); assertEquals(2, user.loginMethods.length); assertTrue(user.loginMethods[0].tenantIds.contains(t2.getTenantId())); @@ -756,16 +756,16 @@ public void execute(Main main) throws Exception { new TestCaseStep() { @Override public void execute(Main main) throws Exception { - Storage t1WithStorage = (StorageLayer.getStorage(t1, main)); - AuthRecipe.deleteUser(t1.toAppIdentifier(), t1WithStorage, + Storage t1Storage = (StorageLayer.getStorage(t1, main)); + AuthRecipe.deleteUser(t1.toAppIdentifier(), t1Storage, TestCase.users.get(1).getSupertokensUserId()); } }, new TestCaseStep() { @Override public void execute(Main main) throws Exception { - Storage t1WithStorage = (StorageLayer.getStorage(t1, main)); - AuthRecipeUserInfo user = AuthRecipe.getUserById(t1.toAppIdentifier(), t1WithStorage, + Storage t1Storage = (StorageLayer.getStorage(t1, main)); + AuthRecipeUserInfo user = AuthRecipe.getUserById(t1.toAppIdentifier(), t1Storage, TestCase.users.get(0).getSupertokensUserId()); assertNull(user); } @@ -928,8 +928,8 @@ public CreateEmailPasswordUser(TenantIdentifier tenantIdentifier, String email) @Override public void execute(Main main) throws Exception { - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); - AuthRecipeUserInfo user = EmailPassword.signUp(tenantIdentifier, tenantIdentifierWithStorage, main, email, + Storage storage = (StorageLayer.getStorage(tenantIdentifier, main)); + AuthRecipeUserInfo user = EmailPassword.signUp(tenantIdentifier, storage, main, email, "password"); TestCase.addUser(user); } @@ -946,11 +946,11 @@ public CreatePlessUserWithEmail(TenantIdentifier tenantIdentifier, String email) @Override public void execute(Main main) throws Exception { - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); + Storage storage = (StorageLayer.getStorage(tenantIdentifier, main)); Passwordless.CreateCodeResponse code = Passwordless.createCode(tenantIdentifier, - tenantIdentifierWithStorage, main, + storage, main, email, null, null, null); - AuthRecipeUserInfo user = Passwordless.consumeCode(tenantIdentifier, tenantIdentifierWithStorage, main, + AuthRecipeUserInfo user = Passwordless.consumeCode(tenantIdentifier, storage, main, code.deviceId, code.deviceIdHash, code.userInputCode, null).user; TestCase.addUser(user); @@ -968,11 +968,11 @@ public CreatePlessUserWithPhone(TenantIdentifier tenantIdentifier, String phoneN @Override public void execute(Main main) throws Exception { - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); + Storage storage = (StorageLayer.getStorage(tenantIdentifier, main)); Passwordless.CreateCodeResponse code = Passwordless.createCode(tenantIdentifier, - tenantIdentifierWithStorage, main, + storage, main, null, phoneNumber, null, null); - AuthRecipeUserInfo user = Passwordless.consumeCode(tenantIdentifier, tenantIdentifierWithStorage, main, + AuthRecipeUserInfo user = Passwordless.consumeCode(tenantIdentifier, storage, main, code.deviceId, code.deviceIdHash, code.userInputCode, null).user; TestCase.addUser(user); @@ -994,8 +994,8 @@ public CreateThirdPartyUser(TenantIdentifier tenantIdentifier, String thirdParty @Override public void execute(Main main) throws Exception { - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); - AuthRecipeUserInfo user = ThirdParty.signInUp(tenantIdentifier, tenantIdentifierWithStorage, main, + Storage storage = (StorageLayer.getStorage(tenantIdentifier, main)); + AuthRecipeUserInfo user = ThirdParty.signInUp(tenantIdentifier, storage, main, thirdPartyId, thirdPartyUserId, email).user; TestCase.addUser(user); @@ -1013,8 +1013,8 @@ public MakePrimaryUser(TenantIdentifier tenantIdentifier, int userIndex) { @Override public void execute(Main main) throws Exception { - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); - AuthRecipe.createPrimaryUser(main, tenantIdentifier.toAppIdentifier(), tenantIdentifierWithStorage, + Storage storage = (StorageLayer.getStorage(tenantIdentifier, main)); + AuthRecipe.createPrimaryUser(main, tenantIdentifier.toAppIdentifier(), storage, TestCase.users.get(userIndex).getSupertokensUserId()); } } @@ -1032,8 +1032,8 @@ public LinkAccounts(TenantIdentifier tenantIdentifier, int primaryUserIndex, int @Override public void execute(Main main) throws Exception { - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); - AuthRecipe.linkAccounts(main, tenantIdentifier.toAppIdentifier(), tenantIdentifierWithStorage, + Storage storage = (StorageLayer.getStorage(tenantIdentifier, main)); + AuthRecipe.linkAccounts(main, tenantIdentifier.toAppIdentifier(), storage, TestCase.users.get(recipeUserIndex).getSupertokensUserId(), TestCase.users.get(primaryUserIndex).getSupertokensUserId()); } } @@ -1049,8 +1049,8 @@ public AssociateUserToTenant(TenantIdentifier tenantIdentifier, int userIndex) { @Override public void execute(Main main) throws Exception { - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); - Multitenancy.addUserIdToTenant(main, tenantIdentifier, tenantIdentifierWithStorage, + Storage storage = (StorageLayer.getStorage(tenantIdentifier, main)); + Multitenancy.addUserIdToTenant(main, tenantIdentifier, storage, TestCase.users.get(userIndex).getSupertokensUserId()); } } @@ -1068,8 +1068,8 @@ public UpdateEmailPasswordUserEmail(TenantIdentifier tenantIdentifier, int userI @Override public void execute(Main main) throws Exception { - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); - EmailPassword.updateUsersEmailOrPassword(tenantIdentifier.toAppIdentifier(), tenantIdentifierWithStorage, + Storage storage = (StorageLayer.getStorage(tenantIdentifier, main)); + EmailPassword.updateUsersEmailOrPassword(tenantIdentifier.toAppIdentifier(), storage, main, TestCase.users.get(userIndex).getSupertokensUserId(), email, null); } } @@ -1087,8 +1087,8 @@ public UpdatePlessUserEmail(TenantIdentifier tenantIdentifier, int userIndex, St @Override public void execute(Main main) throws Exception { - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); - Passwordless.updateUser(tenantIdentifier.toAppIdentifier(), tenantIdentifierWithStorage, + Storage storage = (StorageLayer.getStorage(tenantIdentifier, main)); + Passwordless.updateUser(tenantIdentifier.toAppIdentifier(), storage, TestCase.users.get(userIndex).getSupertokensUserId(), new Passwordless.FieldUpdate(email), null); } } @@ -1106,8 +1106,8 @@ public UpdatePlessUserPhone(TenantIdentifier tenantIdentifier, int userIndex, St @Override public void execute(Main main) throws Exception { - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); - Passwordless.updateUser(tenantIdentifier.toAppIdentifier(), tenantIdentifierWithStorage, + Storage storage = (StorageLayer.getStorage(tenantIdentifier, main)); + Passwordless.updateUser(tenantIdentifier.toAppIdentifier(), storage, TestCase.users.get(userIndex).getSupertokensUserId(), null, new Passwordless.FieldUpdate(phoneNumber)); } } @@ -1123,8 +1123,8 @@ public UnlinkAccount(TenantIdentifier tenantIdentifier, int userIndex) { @Override public void execute(Main main) throws Exception { - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); - AuthRecipe.unlinkAccounts(main, tenantIdentifier.toAppIdentifier(), tenantIdentifierWithStorage, + Storage storage = (StorageLayer.getStorage(tenantIdentifier, main)); + AuthRecipe.unlinkAccounts(main, tenantIdentifier.toAppIdentifier(), storage, TestCase.users.get(userIndex).getSupertokensUserId()); } } @@ -1140,8 +1140,8 @@ public SignInEmailPasswordUser(TenantIdentifier tenantIdentifier, int userIndex) @Override public void execute(Main main) throws Exception { - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); - EmailPassword.signIn(tenantIdentifier, tenantIdentifierWithStorage, main, + Storage storage = (StorageLayer.getStorage(tenantIdentifier, main)); + EmailPassword.signIn(tenantIdentifier, storage, main, TestCase.users.get(userIndex).loginMethods[0].email, "password"); } } @@ -1157,8 +1157,8 @@ public DisassociateUserFromTenant(TenantIdentifier tenantIdentifier, int userInd @Override public void execute(Main main) throws Exception { - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(tenantIdentifier, main)); - Multitenancy.removeUserIdFromTenant(main, tenantIdentifier, tenantIdentifierWithStorage, + Storage storage = (StorageLayer.getStorage(tenantIdentifier, main)); + Multitenancy.removeUserIdFromTenant(main, tenantIdentifier, storage, TestCase.users.get(userIndex).getSupertokensUserId(), null); } } diff --git a/src/test/java/io/supertokens/test/accountlinking/SessionTests.java b/src/test/java/io/supertokens/test/accountlinking/SessionTests.java index 2633d5b33..c84b8aac1 100644 --- a/src/test/java/io/supertokens/test/accountlinking/SessionTests.java +++ b/src/test/java/io/supertokens/test/accountlinking/SessionTests.java @@ -283,27 +283,27 @@ public void testSessionBehaviourWhenUserBelongsTo2TenantsAndThenLinkedToSomeOthe createTenants(process.getProcess()); - Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); - Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); + Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2Storage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", + AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1Storage, process.getProcess(), "test@example.com", "password"); - AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test1@example.com", + AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1Storage, process.getProcess(), "test1@example.com", "password"); AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), - t1WithStorage, user2.getSupertokensUserId()); - Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, user1.getSupertokensUserId()); + t1Storage, user2.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2Storage, user1.getSupertokensUserId()); - SessionInformationHolder session1 = Session.createNewSession(t2, t2WithStorage, process.getProcess(), + SessionInformationHolder session1 = Session.createNewSession(t2, t2Storage, process.getProcess(), user1.getSupertokensUserId(), new JsonObject(), new JsonObject()); // Linking user1 to user2 on t1 should revoke the session - AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, + AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1Storage, user1.getSupertokensUserId(), user2.getSupertokensUserId()); try { - Session.getSession(t2, t2WithStorage, session1.session.handle); + Session.getSession(t2, t2Storage, session1.session.handle); fail(); } catch (UnauthorisedException e) { // ok @@ -329,27 +329,27 @@ public void testSessionBehaviourWhenUserBelongsTo2TenantsAndThenLinkedToSomeOthe createTenants(process.getProcess()); - Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); - Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); + Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2Storage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", + AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1Storage, process.getProcess(), "test@example.com", "password"); - AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test1@example.com", + AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1Storage, process.getProcess(), "test1@example.com", "password"); AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), - t1WithStorage, user2.getSupertokensUserId()); + t1Storage, user2.getSupertokensUserId()); - SessionInformationHolder session1 = Session.createNewSession(t2, t2WithStorage, process.getProcess(), + SessionInformationHolder session1 = Session.createNewSession(t2, t2Storage, process.getProcess(), user1.getSupertokensUserId(), new JsonObject(), new JsonObject()); // Linking user1 to user2 on t1 should revoke the session - AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, + AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1Storage, user1.getSupertokensUserId(), user2.getSupertokensUserId()); try { // session gets removed on t2 as well - Session.getSession(t2, t2WithStorage, session1.session.handle); + Session.getSession(t2, t2Storage, session1.session.handle); fail(); } catch (UnauthorisedException e) { // ok @@ -375,26 +375,26 @@ public void testSessionBehaviourWhenUserBelongsTo2TenantsAndThenLinkedToSomeOthe createTenants(process.getProcess()); - Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); - Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); + Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2Storage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", + AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1Storage, process.getProcess(), "test@example.com", "password"); - AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test1@example.com", + AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1Storage, process.getProcess(), "test1@example.com", "password"); - AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, + AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), t1Storage, user2.getSupertokensUserId()); - AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, user1.getSupertokensUserId(), + AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1Storage, user1.getSupertokensUserId(), user2.getSupertokensUserId()); - SessionInformationHolder session1 = Session.createNewSession(t2, t2WithStorage, process.getProcess(), + SessionInformationHolder session1 = Session.createNewSession(t2, t2Storage, process.getProcess(), user1.getSupertokensUserId(), new JsonObject(), new JsonObject()); - AuthRecipe.unlinkAccounts(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, user2.getSupertokensUserId()); + AuthRecipe.unlinkAccounts(process.getProcess(), t1.toAppIdentifier(), t1Storage, user2.getSupertokensUserId()); // session must be intact - Session.getSession(t2, t2WithStorage, session1.session.handle); + Session.getSession(t2, t2Storage, session1.session.handle); process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); @@ -416,20 +416,20 @@ public void testCreateSessionUsesPrimaryUserIdEvenWhenTheUserIsNotInThatTenant() createTenants(process.getProcess()); - Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); - Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); + Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2Storage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", + AuthRecipeUserInfo user1 = EmailPassword.signUp(t1, t1Storage, process.getProcess(), "test@example.com", "password"); - AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test1@example.com", + AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1Storage, process.getProcess(), "test1@example.com", "password"); - AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, + AuthRecipe.createPrimaryUser(process.getProcess(), t1.toAppIdentifier(), t1Storage, user2.getSupertokensUserId()); - AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1WithStorage, user1.getSupertokensUserId(), + AuthRecipe.linkAccounts(process.getProcess(), t1.toAppIdentifier(), t1Storage, user1.getSupertokensUserId(), user2.getSupertokensUserId()); - SessionInformationHolder session1 = Session.createNewSession(t2, t2WithStorage, process.getProcess(), + SessionInformationHolder session1 = Session.createNewSession(t2, t2Storage, process.getProcess(), user1.getSupertokensUserId(), new JsonObject(), new JsonObject()); // Should still consider the primaryUserId diff --git a/src/test/java/io/supertokens/test/authRecipe/MultitenantAPITest.java b/src/test/java/io/supertokens/test/authRecipe/MultitenantAPITest.java index 9742481d0..77b0ff9ea 100644 --- a/src/test/java/io/supertokens/test/authRecipe/MultitenantAPITest.java +++ b/src/test/java/io/supertokens/test/authRecipe/MultitenantAPITest.java @@ -211,7 +211,7 @@ private void createUsers() { // passwordless users recipeToUsers.put("passwordless", new ArrayList<>()); for (TenantIdentifier tenant : new TenantIdentifier[]{t1, t2, t3}) { - Storage tenantIdentifierWithStorage = ( + Storage storage = ( StorageLayer.getStorage(tenant, process.getProcess())); { if (tenantToUsers.get(tenant) == null) { @@ -220,14 +220,14 @@ private void createUsers() Passwordless.CreateCodeResponse codeResponse = Passwordless.createCode( tenant, - tenantIdentifierWithStorage, + storage, process.getProcess(), "user@example.com", null, null, "abcd" ); Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode( - tenant, tenantIdentifierWithStorage, + tenant, storage, process.getProcess(), codeResponse.deviceId, codeResponse.deviceIdHash, "abcd", null); tenantToUsers.get(tenant).add(response.user.getSupertokensUserId()); @@ -235,14 +235,14 @@ private void createUsers() } { Passwordless.CreateCodeResponse codeResponse = Passwordless.createCode( - tenant, tenantIdentifierWithStorage, + tenant, storage, process.getProcess(), "user@gmail.com", null, null, "abcd" ); Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode( - tenant, tenantIdentifierWithStorage, + tenant, storage, process.getProcess(), codeResponse.deviceId, codeResponse.deviceIdHash, "abcd", null); tenantToUsers.get(tenant).add(response.user.getSupertokensUserId()); @@ -250,14 +250,14 @@ private void createUsers() } { Passwordless.CreateCodeResponse codeResponse = Passwordless.createCode( - tenant, tenantIdentifierWithStorage, + tenant, storage, process.getProcess(), null, "+1234567890", null, "abcd" ); Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode( - tenant, tenantIdentifierWithStorage, + tenant, storage, process.getProcess(), codeResponse.deviceId, codeResponse.deviceIdHash, "abcd", null); tenantToUsers.get(tenant).add(response.user.getSupertokensUserId()); @@ -265,14 +265,14 @@ private void createUsers() } { Passwordless.CreateCodeResponse codeResponse = Passwordless.createCode( - tenant, tenantIdentifierWithStorage, + tenant, storage, process.getProcess(), null, "+9876543210", null, "abcd" ); Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode( - tenant, tenantIdentifierWithStorage, + tenant, storage, process.getProcess(), codeResponse.deviceId, codeResponse.deviceIdHash, "abcd", null); tenantToUsers.get(tenant).add(response.user.getSupertokensUserId()); @@ -288,29 +288,29 @@ private void createUsers() tenantToUsers.put(tenant, new ArrayList<>()); } - Storage tenantIdentifierWithStorage = ( + Storage storage = ( StorageLayer.getStorage(tenant, process.getProcess())); ThirdParty.SignInUpResponse user1 = ThirdParty.signInUp( - tenant, tenantIdentifierWithStorage, + tenant, storage, process.getProcess(), "google", "googleid1", "user@example.com"); tenantToUsers.get(tenant).add(user1.user.getSupertokensUserId()); recipeToUsers.get("thirdparty").add(user1.user.getSupertokensUserId()); ThirdParty.SignInUpResponse user2 = ThirdParty.signInUp( - tenant, tenantIdentifierWithStorage, + tenant, storage, process.getProcess(), "google", "googleid2", "user@gmail.com"); tenantToUsers.get(tenant).add(user2.user.getSupertokensUserId()); recipeToUsers.get("thirdparty").add(user2.user.getSupertokensUserId()); ThirdParty.SignInUpResponse user3 = ThirdParty.signInUp( - tenant, tenantIdentifierWithStorage, + tenant, storage, process.getProcess(), "facebook", "facebookid1", "user@example.com"); tenantToUsers.get(tenant).add(user3.user.getSupertokensUserId()); recipeToUsers.get("thirdparty").add(user3.user.getSupertokensUserId()); ThirdParty.SignInUpResponse user4 = ThirdParty.signInUp( - tenant, tenantIdentifierWithStorage, + tenant, storage, process.getProcess(), "facebook", "facebookid2", "user@gmail.com"); tenantToUsers.get(tenant).add(user4.user.getSupertokensUserId()); recipeToUsers.get("thirdparty").add(user4.user.getSupertokensUserId()); diff --git a/src/test/java/io/supertokens/test/authRecipe/UserPaginationTest.java b/src/test/java/io/supertokens/test/authRecipe/UserPaginationTest.java index 1a38a670a..ce47e885d 100644 --- a/src/test/java/io/supertokens/test/authRecipe/UserPaginationTest.java +++ b/src/test/java/io/supertokens/test/authRecipe/UserPaginationTest.java @@ -182,12 +182,12 @@ private void createUsers(TenantIdentifier tenantIdentifier, int numUsers, String tenantToUsers.put(tenantIdentifier, new ArrayList<>()); } - Storage tenantIdentifierWithStorage = ( + Storage storage = ( StorageLayer.getStorage(tenantIdentifier, process.getProcess())); for (int i = 0; i < numUsers; i++) { { AuthRecipeUserInfo user = EmailPassword.signUp( - tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), + tenantIdentifier, storage, process.getProcess(), prefix + "epuser" + i + "@example.com", "password" + i); tenantToUsers.get(tenantIdentifier).add(user.getSupertokensUserId()); if (!recipeToUsers.containsKey("emailpassword")) { @@ -197,14 +197,14 @@ private void createUsers(TenantIdentifier tenantIdentifier, int numUsers, String } { Passwordless.CreateCodeResponse codeResponse = Passwordless.createCode( - tenantIdentifier, tenantIdentifierWithStorage, + tenantIdentifier, storage, process.getProcess(), prefix + "pluser" + i + "@example.com", null, null, "abcd" ); Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode( - tenantIdentifier, tenantIdentifierWithStorage, + tenantIdentifier, storage, process.getProcess(), codeResponse.deviceId, codeResponse.deviceIdHash, "abcd", null); tenantToUsers.get(tenantIdentifier).add(response.user.getSupertokensUserId()); @@ -216,11 +216,11 @@ private void createUsers(TenantIdentifier tenantIdentifier, int numUsers, String } { ThirdParty.SignInUpResponse user1 = ThirdParty.signInUp( - tenantIdentifier, tenantIdentifierWithStorage, + tenantIdentifier, storage, process.getProcess(), "google", "googleid" + i, prefix + "tpuser" + i + "@example.com"); tenantToUsers.get(tenantIdentifier).add(user1.user.getSupertokensUserId()); ThirdParty.SignInUpResponse user2 = ThirdParty.signInUp( - tenantIdentifier, tenantIdentifierWithStorage, + tenantIdentifier, storage, process.getProcess(), "facebook", "fbid" + i, prefix + "tpuser" + i + "@example.com"); tenantToUsers.get(tenantIdentifier).add(user2.user.getSupertokensUserId()); diff --git a/src/test/java/io/supertokens/test/dashboard/apis/MultitenantAPITest.java b/src/test/java/io/supertokens/test/dashboard/apis/MultitenantAPITest.java index bdf0e47c1..4ca94e890 100644 --- a/src/test/java/io/supertokens/test/dashboard/apis/MultitenantAPITest.java +++ b/src/test/java/io/supertokens/test/dashboard/apis/MultitenantAPITest.java @@ -170,9 +170,9 @@ public void testSessionBehavior() throws Exception { String email = "test@example.com"; String password = "testPass123"; - Storage appIdentifierWithStorage = ( + Storage appIdentifierStorage = ( StorageLayer.getStorage(t1, process.getProcess())); - Dashboard.signUpDashboardUser(t1.toAppIdentifier(), appIdentifierWithStorage, process.getProcess(), email, + Dashboard.signUpDashboardUser(t1.toAppIdentifier(), appIdentifierStorage, process.getProcess(), email, password); // create a session diff --git a/src/test/java/io/supertokens/test/emailpassword/EmailPasswordTest.java b/src/test/java/io/supertokens/test/emailpassword/EmailPasswordTest.java index 79da774a1..3e6a81c13 100644 --- a/src/test/java/io/supertokens/test/emailpassword/EmailPasswordTest.java +++ b/src/test/java/io/supertokens/test/emailpassword/EmailPasswordTest.java @@ -938,9 +938,9 @@ public void updateEmailSucceedsIfEmailUsedByOtherPrimaryUserInDifferentTenantWhi new ThirdPartyConfig(true, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(true), new JsonObject())); - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(process.main)); + Storage storage = (StorageLayer.getStorage(process.main)); AuthRecipeUserInfo user0 = EmailPassword.signUp( - new TenantIdentifier(null, null, "t1"), tenantIdentifierWithStorage, process.getProcess(), + new TenantIdentifier(null, null, "t1"), storage, process.getProcess(), "someemail1@gmail.com", "pass1234"); @@ -975,9 +975,9 @@ public void updateEmailFailsIfEmailUsedByOtherPrimaryUserInDifferentTenant() new ThirdPartyConfig(true, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(true), new JsonObject())); - Storage tenantIdentifierWithStorage = (StorageLayer.getStorage(process.main)); + Storage storage = (StorageLayer.getStorage(process.main)); AuthRecipeUserInfo user0 = EmailPassword.signUp( - new TenantIdentifier(null, null, "t1"), tenantIdentifierWithStorage, process.getProcess(), + new TenantIdentifier(null, null, "t1"), storage, process.getProcess(), "someemail1@gmail.com", "pass1234"); @@ -987,7 +987,7 @@ public void updateEmailFailsIfEmailUsedByOtherPrimaryUserInDifferentTenant() AuthRecipe.createPrimaryUser(process.main, user.getSupertokensUserId()); Multitenancy.addUserIdToTenant(process.main, - new TenantIdentifier(null, null, "t1"), tenantIdentifierWithStorage, user.getSupertokensUserId()); + new TenantIdentifier(null, null, "t1"), storage, user.getSupertokensUserId()); try { EmailPassword.updateUsersEmailOrPassword(process.main, user.getSupertokensUserId(), "someemail1@gmail.com", null); diff --git a/src/test/java/io/supertokens/test/multitenant/AppTenantUserTest.java b/src/test/java/io/supertokens/test/multitenant/AppTenantUserTest.java index 73e016b66..c00baf80f 100644 --- a/src/test/java/io/supertokens/test/multitenant/AppTenantUserTest.java +++ b/src/test/java/io/supertokens/test/multitenant/AppTenantUserTest.java @@ -117,11 +117,11 @@ public void testDeletingAppDeleteNonAuthRecipeData() throws Exception { new JsonObject() ), false); - Storage tWithStorage = ( + Storage tStorage = ( StorageLayer.getStorage(t, process.getProcess())); - AuthRecipeUserInfo user = EmailPassword.signUp(t, tWithStorage, process.getProcess(), "test@example.com", + AuthRecipeUserInfo user = EmailPassword.signUp(t, tStorage, process.getProcess(), "test@example.com", "password"); String userId = user.getSupertokensUserId(); @@ -130,7 +130,7 @@ public void testDeletingAppDeleteNonAuthRecipeData() throws Exception { try { UserIdMapping.findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed( - t.toAppIdentifier(), tWithStorage, userId, true); + t.toAppIdentifier(), tStorage, userId, true); fail(className); } catch (Exception ignored) { assertTrue(ignored.getMessage().contains("UserId is already in use")); @@ -157,7 +157,7 @@ public void testDeletingAppDeleteNonAuthRecipeData() throws Exception { new JsonObject() ), false); - UserIdMapping.findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed(t.toAppIdentifier(), tWithStorage, + UserIdMapping.findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed(t.toAppIdentifier(), tStorage, userId, true); } } @@ -214,9 +214,9 @@ public void testDisassociationOfUserDeletesNonAuthRecipeData() throws Exception new JsonObject() ), false); - Storage appWithStorage = ( + Storage appStorage = ( StorageLayer.getStorage(app, process.getProcess())); - Storage tenantWithStorage = ( + Storage tenantStorage = ( StorageLayer.getStorage(tenant, process.getProcess())); for (String className : classNames) { @@ -224,29 +224,29 @@ public void testDisassociationOfUserDeletesNonAuthRecipeData() throws Exception continue; } - AuthRecipeUserInfo user = EmailPassword.signUp(app, appWithStorage, process.getProcess(), "test@example.com", "password"); + AuthRecipeUserInfo user = EmailPassword.signUp(app, appStorage, process.getProcess(), "test@example.com", "password"); String userId = user.getSupertokensUserId(); - Multitenancy.addUserIdToTenant(process.getProcess(), tenant, tenantWithStorage, userId); + Multitenancy.addUserIdToTenant(process.getProcess(), tenant, tenantStorage, userId); // create entry in nonAuth table - tenantWithStorage.addInfoToNonAuthRecipesBasedOnUserId(tenant, className, userId); + tenantStorage.addInfoToNonAuthRecipesBasedOnUserId(tenant, className, userId); try { UserIdMapping.findNonAuthStoragesWhereUserIdIsUsedOrAssertIfUsed( - tenant.toAppIdentifier(), tenantWithStorage, userId, true); + tenant.toAppIdentifier(), tenantStorage, userId, true); fail(className); } catch (Exception ignored) { assertTrue(ignored.getMessage().contains("UserId is already in use")); } // Disassociate user - Multitenancy.removeUserIdFromTenant(process.getProcess(), tenant, tenantWithStorage, userId, null); + Multitenancy.removeUserIdFromTenant(process.getProcess(), tenant, tenantStorage, userId, null); - assertFalse(AuthRecipe.deleteNonAuthRecipeUser(tenant, tenantWithStorage, + assertFalse(AuthRecipe.deleteNonAuthRecipeUser(tenant, tenantStorage, userId)); // Nothing deleted indicates that the non auth recipe user data was deleted already - AuthRecipe.deleteUser(app.toAppIdentifier(), appWithStorage, userId); + AuthRecipe.deleteUser(app.toAppIdentifier(), appStorage, userId); } process.kill(); @@ -287,20 +287,20 @@ public void deletingTenantKeepsTheUserInTheApp() throws Exception { new JsonObject() ), false); - Storage appWithStorage = ( + Storage appStorage = ( StorageLayer.getStorage(app, process.getProcess())); - Storage tenantWithStorage = ( + Storage tenantStorage = ( StorageLayer.getStorage(tenant, process.getProcess())); - AuthRecipeUserInfo user = EmailPassword.signUp(tenant, tenantWithStorage, process.getProcess(), "test@example.com", "password"); + AuthRecipeUserInfo user = EmailPassword.signUp(tenant, tenantStorage, process.getProcess(), "test@example.com", "password"); String userId = user.getSupertokensUserId(); Multitenancy.deleteTenant(tenant, process.getProcess()); - Multitenancy.addUserIdToTenant(process.getProcess(), app, appWithStorage, + Multitenancy.addUserIdToTenant(process.getProcess(), app, appStorage, userId); // user id must be intact to do this - AuthRecipeUserInfo appUser = EmailPassword.getUserUsingId(app.toAppIdentifier(), appWithStorage, userId); + AuthRecipeUserInfo appUser = EmailPassword.getUserUsingId(app.toAppIdentifier(), appStorage, userId); assertNotNull(appUser); assertEquals(userId, appUser.getSupertokensUserId()); diff --git a/src/test/java/io/supertokens/test/multitenant/TestAppData.java b/src/test/java/io/supertokens/test/multitenant/TestAppData.java index 5a30a3dea..73f8b1209 100644 --- a/src/test/java/io/supertokens/test/multitenant/TestAppData.java +++ b/src/test/java/io/supertokens/test/multitenant/TestAppData.java @@ -116,62 +116,62 @@ public void testThatDeletingAppDeleteDataFromAllTables() throws Exception { new JsonObject() ), false); - Storage appWithStorage = ( + Storage appStorage = ( StorageLayer.getStorage(app, process.getProcess())); - String[] allTableNames = appWithStorage.getAllTablesInTheDatabase(); + String[] allTableNames = appStorage.getAllTablesInTheDatabase(); allTableNames = removeStrings(allTableNames, tablesToIgnore); Arrays.sort(allTableNames); // Add all recipe data - AuthRecipeUserInfo epUser = EmailPassword.signUp(app, appWithStorage, process.getProcess(), "test@example.com", + AuthRecipeUserInfo epUser = EmailPassword.signUp(app, appStorage, process.getProcess(), "test@example.com", "password"); - EmailPassword.generatePasswordResetTokenBeforeCdi4_0(app, appWithStorage, process.getProcess(), + EmailPassword.generatePasswordResetTokenBeforeCdi4_0(app, appStorage, process.getProcess(), epUser.getSupertokensUserId()); - ThirdParty.SignInUpResponse tpUser = ThirdParty.signInUp(app, appWithStorage, process.getProcess(), "google", + ThirdParty.SignInUpResponse tpUser = ThirdParty.signInUp(app, appStorage, process.getProcess(), "google", "googleid", "test@example.com"); - Passwordless.CreateCodeResponse code = Passwordless.createCode(app, appWithStorage, process.getProcess(), + Passwordless.CreateCodeResponse code = Passwordless.createCode(app, appStorage, process.getProcess(), "test@example.com", null, null, null); - Passwordless.ConsumeCodeResponse plUser = Passwordless.consumeCode(app, appWithStorage, process.getProcess(), + Passwordless.ConsumeCodeResponse plUser = Passwordless.consumeCode(app, appStorage, process.getProcess(), code.deviceId, code.deviceIdHash, code.userInputCode, null); - Passwordless.createCode(app, appWithStorage, process.getProcess(), "test@example.com", null, null, null); + Passwordless.createCode(app, appStorage, process.getProcess(), "test@example.com", null, null, null); - Dashboard.signUpDashboardUser(app.toAppIdentifier(), appWithStorage, process.getProcess(), + Dashboard.signUpDashboardUser(app.toAppIdentifier(), appStorage, process.getProcess(), "user@example.com", "password"); - Dashboard.signInDashboardUser(app.toAppIdentifier(), appWithStorage, process.getProcess(), + Dashboard.signInDashboardUser(app.toAppIdentifier(), appStorage, process.getProcess(), "user@example.com", "password"); - String evToken = EmailVerification.generateEmailVerificationToken(app, appWithStorage, process.getProcess(), + String evToken = EmailVerification.generateEmailVerificationToken(app, appStorage, process.getProcess(), epUser.getSupertokensUserId(), epUser.loginMethods[0].email); - EmailVerification.verifyEmail(app, appWithStorage, evToken); - EmailVerification.generateEmailVerificationToken(app, appWithStorage, process.getProcess(), + EmailVerification.verifyEmail(app, appStorage, evToken); + EmailVerification.generateEmailVerificationToken(app, appStorage, process.getProcess(), tpUser.user.getSupertokensUserId(), tpUser.user.loginMethods[0].email); - Session.createNewSession(app, appWithStorage, process.getProcess(), epUser.getSupertokensUserId(), + Session.createNewSession(app, appStorage, process.getProcess(), epUser.getSupertokensUserId(), new JsonObject(), new JsonObject()); - UserRoles.createNewRoleOrModifyItsPermissions(app.toAppIdentifier(), appWithStorage, "role", + UserRoles.createNewRoleOrModifyItsPermissions(app.toAppIdentifier(), appStorage, "role", new String[]{"permission1", "permission2"}); - UserRoles.addRoleToUser(process.getProcess(), app, appWithStorage, epUser.getSupertokensUserId(), "role"); + UserRoles.addRoleToUser(process.getProcess(), app, appStorage, epUser.getSupertokensUserId(), "role"); - TOTPDevice totpDevice = Totp.registerDevice(app.toAppIdentifier(), appWithStorage, process.getProcess(), + TOTPDevice totpDevice = Totp.registerDevice(app.toAppIdentifier(), appStorage, process.getProcess(), epUser.getSupertokensUserId(), "test", 1, 3); - Totp.verifyCode(app, appWithStorage, process.getProcess(), epUser.getSupertokensUserId(), + Totp.verifyCode(app, appStorage, process.getProcess(), epUser.getSupertokensUserId(), generateTotpCode(process.getProcess(), totpDevice, 0), true); ActiveUsers.updateLastActive(app.toAppIdentifier(), process.getProcess(), epUser.getSupertokensUserId()); - UserMetadata.updateUserMetadata(app.toAppIdentifier(), appWithStorage, + UserMetadata.updateUserMetadata(app.toAppIdentifier(), appStorage, epUser.getSupertokensUserId(), new JsonObject()); - UserIdMapping.createUserIdMapping(process.getProcess(), app.toAppIdentifier(), appWithStorage, + UserIdMapping.createUserIdMapping(process.getProcess(), app.toAppIdentifier(), appStorage, plUser.user.getSupertokensUserId(), "externalid", null, false); - String[] tablesThatHaveData = appWithStorage + String[] tablesThatHaveData = appStorage .getAllTablesInTheDatabaseThatHasDataForAppId(app.getAppId()); tablesThatHaveData = removeStrings(tablesThatHaveData, tablesToIgnore); Arrays.sort(tablesThatHaveData); @@ -182,7 +182,7 @@ public void testThatDeletingAppDeleteDataFromAllTables() throws Exception { Multitenancy.deleteApp(app.toAppIdentifier(), process.getProcess()); // Check no data is remaining in any of the tables - tablesThatHaveData = appWithStorage.getAllTablesInTheDatabaseThatHasDataForAppId(app.getAppId()); + tablesThatHaveData = appStorage.getAllTablesInTheDatabaseThatHasDataForAppId(app.getAppId()); tablesThatHaveData = removeStrings(tablesThatHaveData, tablesToIgnore); assertEquals(0, tablesThatHaveData.length); diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestPermissionChecks.java b/src/test/java/io/supertokens/test/multitenant/api/TestPermissionChecks.java index e2f9e4a32..9a890db27 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestPermissionChecks.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestPermissionChecks.java @@ -218,15 +218,15 @@ public void testPermissionsForListTenants() throws Exception { TestCase[] testCases = new TestCase[]{ new TestCase( new TenantIdentifier("127.0.0.1", "a1", "t1"), null, - "Only the public tenantId is allowed to list all tenants associated with this app" + "Only public tenantId can call this app specific API" ), new TestCase( new TenantIdentifier("127.0.0.1", null, "t1"), null, - "Only the public tenantId is allowed to list all tenants associated with this app" + "Only public tenantId can call this app specific API" ), new TestCase( new TenantIdentifier(null, null, "t1"), null, - "Only the public tenantId is allowed to list all tenants associated with this app" + "Only public tenantId can call this app specific API" ), new TestCase( new TenantIdentifier(null, null, null), null, null diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestTenantIdIsNotPresentForOlderCDI.java b/src/test/java/io/supertokens/test/multitenant/api/TestTenantIdIsNotPresentForOlderCDI.java index 5aac955c6..8243b73fe 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestTenantIdIsNotPresentForOlderCDI.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestTenantIdIsNotPresentForOlderCDI.java @@ -282,12 +282,12 @@ private void createUsers(TenantIdentifier tenantIdentifier, int numUsers, String tenantToUsers.put(tenantIdentifier, new ArrayList<>()); } - Storage tenantIdentifierWithStorage = ( + Storage storage = ( StorageLayer.getStorage(tenantIdentifier, process.getProcess())); for (int i = 0; i < numUsers; i++) { { AuthRecipeUserInfo user = EmailPassword.signUp( - tenantIdentifier, tenantIdentifierWithStorage, process.getProcess(), + tenantIdentifier, storage, process.getProcess(), prefix + "epuser" + i + "@example.com", "password" + i); tenantToUsers.get(tenantIdentifier).add(user.getSupertokensUserId()); if (!recipeToUsers.containsKey("emailpassword")) { @@ -298,14 +298,14 @@ private void createUsers(TenantIdentifier tenantIdentifier, int numUsers, String { Passwordless.CreateCodeResponse codeResponse = Passwordless.createCode( tenantIdentifier, - tenantIdentifierWithStorage, + storage, process.getProcess(), prefix + "pluser" + i + "@example.com", null, null, "abcd" ); Passwordless.ConsumeCodeResponse response = Passwordless.consumeCode( - tenantIdentifier, tenantIdentifierWithStorage, + tenantIdentifier, storage, process.getProcess(), codeResponse.deviceId, codeResponse.deviceIdHash, "abcd", null); tenantToUsers.get(tenantIdentifier).add(response.user.getSupertokensUserId()); @@ -317,11 +317,11 @@ private void createUsers(TenantIdentifier tenantIdentifier, int numUsers, String } { ThirdParty.SignInUpResponse user1 = ThirdParty.signInUp( - tenantIdentifier, tenantIdentifierWithStorage, + tenantIdentifier, storage, process.getProcess(), "google", "googleid" + i, prefix + "tpuser" + i + "@example.com"); tenantToUsers.get(tenantIdentifier).add(user1.user.getSupertokensUserId()); ThirdParty.SignInUpResponse user2 = ThirdParty.signInUp( - tenantIdentifier, tenantIdentifierWithStorage, + tenantIdentifier, storage, process.getProcess(), "facebook", "fbid" + i, prefix + "tpuser" + i + "@example.com"); tenantToUsers.get(tenantIdentifier).add(user2.user.getSupertokensUserId()); diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java b/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java index 90ab8acf9..6830d38ae 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java @@ -275,24 +275,24 @@ public void testEmailPasswordUsersHaveTenantIds() throws Exception { TenantIdentifier t1 = new TenantIdentifier(null, "a1", "t1"); TenantIdentifier t2 = new TenantIdentifier(null, "a1", "t2"); - Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); - Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); + Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2Storage = (StorageLayer.getStorage(t2, process.getProcess())); - AuthRecipeUserInfo user = EmailPassword.signUp(t1, t1WithStorage, + AuthRecipeUserInfo user = EmailPassword.signUp(t1, t1Storage, process.getProcess(), "user@example.com", "password"); assertArrayEquals(new String[]{"t1"}, user.tenantIds.toArray()); - Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, user.getSupertokensUserId()); - user = EmailPassword.getUserUsingId(t1.toAppIdentifier(), t1WithStorage, user.getSupertokensUserId()); + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2Storage, user.getSupertokensUserId()); + user = EmailPassword.getUserUsingId(t1.toAppIdentifier(), t1Storage, user.getSupertokensUserId()); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - user = EmailPassword.getUserUsingEmail(t1, t1WithStorage, user.loginMethods[0].email); + user = EmailPassword.getUserUsingEmail(t1, t1Storage, user.loginMethods[0].email); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - Multitenancy.removeUserIdFromTenant(process.getProcess(), t1, t1WithStorage, user.getSupertokensUserId(), + Multitenancy.removeUserIdFromTenant(process.getProcess(), t1, t1Storage, user.getSupertokensUserId(), null); - user = EmailPassword.getUserUsingId(t1.toAppIdentifier(), t1WithStorage, user.getSupertokensUserId()); + user = EmailPassword.getUserUsingId(t1.toAppIdentifier(), t1Storage, user.getSupertokensUserId()); assertArrayEquals(new String[]{"t2"}, user.tenantIds.toArray()); } @@ -307,29 +307,29 @@ public void testPasswordlessUsersHaveTenantIds1() throws Exception { TenantIdentifier t1 = new TenantIdentifier(null, "a1", "t1"); TenantIdentifier t2 = new TenantIdentifier(null, "a1", "t2"); - Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); - Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); + Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2Storage = (StorageLayer.getStorage(t2, process.getProcess())); - Passwordless.CreateCodeResponse createCodeResponse = Passwordless.createCode(t1, t1WithStorage, + Passwordless.CreateCodeResponse createCodeResponse = Passwordless.createCode(t1, t1Storage, process.getProcess(), "user@example.com", null, null, null); - Passwordless.ConsumeCodeResponse consumeCodeResponse = Passwordless.consumeCode(t1, t1WithStorage, + Passwordless.ConsumeCodeResponse consumeCodeResponse = Passwordless.consumeCode(t1, t1Storage, process.getProcess(), createCodeResponse.deviceId, createCodeResponse.deviceIdHash, createCodeResponse.userInputCode, null); assertArrayEquals(new String[]{"t1"}, consumeCodeResponse.user.tenantIds.toArray()); AuthRecipeUserInfo user; - Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2Storage, consumeCodeResponse.user.getSupertokensUserId()); - user = Passwordless.getUserById(t1.toAppIdentifier(), t1WithStorage, + user = Passwordless.getUserById(t1.toAppIdentifier(), t1Storage, consumeCodeResponse.user.getSupertokensUserId()); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - user = Passwordless.getUserByEmail(t1, t1WithStorage, consumeCodeResponse.user.loginMethods[0].email); + user = Passwordless.getUserByEmail(t1, t1Storage, consumeCodeResponse.user.loginMethods[0].email); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - Multitenancy.removeUserIdFromTenant(process.getProcess(), t1, t1WithStorage, + Multitenancy.removeUserIdFromTenant(process.getProcess(), t1, t1Storage, consumeCodeResponse.user.getSupertokensUserId(), null); - user = Passwordless.getUserById(t1.toAppIdentifier(), t1WithStorage, + user = Passwordless.getUserById(t1.toAppIdentifier(), t1Storage, consumeCodeResponse.user.getSupertokensUserId()); assertArrayEquals(new String[]{"t2"}, user.tenantIds.toArray()); } @@ -345,30 +345,30 @@ public void testPasswordlessUsersHaveTenantIds2() throws Exception { TenantIdentifier t1 = new TenantIdentifier(null, "a1", "t1"); TenantIdentifier t2 = new TenantIdentifier(null, "a1", "t2"); - Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); - Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); + Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2Storage = (StorageLayer.getStorage(t2, process.getProcess())); - Passwordless.CreateCodeResponse createCodeResponse = Passwordless.createCode(t1, t1WithStorage, + Passwordless.CreateCodeResponse createCodeResponse = Passwordless.createCode(t1, t1Storage, process.getProcess(), null, "+919876543210", null, null); - Passwordless.ConsumeCodeResponse consumeCodeResponse = Passwordless.consumeCode(t1, t1WithStorage, + Passwordless.ConsumeCodeResponse consumeCodeResponse = Passwordless.consumeCode(t1, t1Storage, process.getProcess(), createCodeResponse.deviceId, createCodeResponse.deviceIdHash, createCodeResponse.userInputCode, null); assertArrayEquals(new String[]{"t1"}, consumeCodeResponse.user.tenantIds.toArray()); AuthRecipeUserInfo user; - Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2Storage, consumeCodeResponse.user.getSupertokensUserId()); - user = Passwordless.getUserById(t1.toAppIdentifier(), t1WithStorage, + user = Passwordless.getUserById(t1.toAppIdentifier(), t1Storage, consumeCodeResponse.user.getSupertokensUserId()); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - user = Passwordless.getUserByPhoneNumber(t1, t1WithStorage, + user = Passwordless.getUserByPhoneNumber(t1, t1Storage, consumeCodeResponse.user.loginMethods[0].phoneNumber); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - Multitenancy.removeUserIdFromTenant(process.getProcess(), t1, t1WithStorage, + Multitenancy.removeUserIdFromTenant(process.getProcess(), t1, t1Storage, consumeCodeResponse.user.getSupertokensUserId(), null); - user = Passwordless.getUserById(t1.toAppIdentifier(), t1WithStorage, consumeCodeResponse.user.getSupertokensUserId()); + user = Passwordless.getUserById(t1.toAppIdentifier(), t1Storage, consumeCodeResponse.user.getSupertokensUserId()); assertArrayEquals(new String[]{"t2"}, user.tenantIds.toArray()); } @@ -383,32 +383,32 @@ public void testThirdPartyUsersHaveTenantIds() throws Exception { TenantIdentifier t1 = new TenantIdentifier(null, "a1", "t1"); TenantIdentifier t2 = new TenantIdentifier(null, "a1", "t2"); - Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); - Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); + Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t2Storage = (StorageLayer.getStorage(t2, process.getProcess())); - ThirdParty.SignInUpResponse signInUpResponse = ThirdParty.signInUp(t1, t1WithStorage, process.getProcess(), + ThirdParty.SignInUpResponse signInUpResponse = ThirdParty.signInUp(t1, t1Storage, process.getProcess(), "google", "googleid", "user@example.com"); assertArrayEquals(new String[]{"t1"}, signInUpResponse.user.tenantIds.toArray()); - Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2WithStorage, + Multitenancy.addUserIdToTenant(process.getProcess(), t2, t2Storage, signInUpResponse.user.getSupertokensUserId()); AuthRecipeUserInfo user = ThirdParty.getUser( - t1.toAppIdentifier(), t1WithStorage, signInUpResponse.user.getSupertokensUserId()); + t1.toAppIdentifier(), t1Storage, signInUpResponse.user.getSupertokensUserId()); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - user = ThirdParty.getUsersByEmail(t1, t1WithStorage, signInUpResponse.user.loginMethods[0].email)[0]; + user = ThirdParty.getUsersByEmail(t1, t1Storage, signInUpResponse.user.loginMethods[0].email)[0]; Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - user = ThirdParty.getUser(t1, t1WithStorage, "google", "googleid"); + user = ThirdParty.getUser(t1, t1Storage, "google", "googleid"); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - user = ThirdParty.getUser(t2, t2WithStorage, "google", "googleid"); + user = ThirdParty.getUser(t2, t2Storage, "google", "googleid"); Utils.assertArrayEqualsIgnoreOrder(new String[]{"t1", "t2"}, user.tenantIds.toArray()); - Multitenancy.removeUserIdFromTenant(process.getProcess(), t1, t1WithStorage, + Multitenancy.removeUserIdFromTenant(process.getProcess(), t1, t1Storage, signInUpResponse.user.getSupertokensUserId(), null); - user = ThirdParty.getUser(t1.toAppIdentifier(), t1WithStorage, signInUpResponse.user.getSupertokensUserId()); + user = ThirdParty.getUser(t1.toAppIdentifier(), t1Storage, signInUpResponse.user.getSupertokensUserId()); assertArrayEquals(new String[]{"t2"}, user.tenantIds.toArray()); } @@ -495,9 +495,9 @@ public void testDisassociateUserWithUserIdMappingAndSession() throws Exception { assertFalse(response.get("wasAlreadyAssociated").getAsBoolean()); TenantIdentifier t2 = new TenantIdentifier(null, "a1", "t2"); - Storage t2WithStorage = (StorageLayer.getStorage(t2, process.getProcess())); + Storage t2Storage = (StorageLayer.getStorage(t2, process.getProcess())); - SessionInformationHolder session = Session.createNewSession(t2, t2WithStorage, + SessionInformationHolder session = Session.createNewSession(t2, t2Storage, process.getProcess(), "externalid", new JsonObject(), new JsonObject()); response = TestMultitenancyAPIHelper.disassociateUserFromTenant(new TenantIdentifier(null, "a1", "t2"), @@ -506,7 +506,7 @@ public void testDisassociateUserWithUserIdMappingAndSession() throws Exception { assertTrue(response.get("wasAssociated").getAsBoolean()); try { - Session.getSession(t2, t2WithStorage, session.session.handle); + Session.getSession(t2, t2Storage, session.session.handle); fail(); } catch (UnauthorisedException e) { // OK diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java b/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java index 13127ba7b..2904d5247 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java @@ -87,17 +87,17 @@ public void beforeEach() throws InterruptedException, InvalidProviderConfigExcep @Test public void testThatUserMetadataIsSavedInTheStorageWhereUserExists() throws Exception { TenantIdentifier t0 = new TenantIdentifier(null, null, null); - Storage t0WithStorage = (StorageLayer.getStorage(t0, process.getProcess())); + Storage t0Storage = (StorageLayer.getStorage(t0, process.getProcess())); TenantIdentifier t1 = new TenantIdentifier(null, null, "t1"); - Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); // Create users - AuthRecipeUserInfo user1 = EmailPassword.signUp(t0, t0WithStorage, process.getProcess(), "test@example.com", "password123"); - AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", "password123"); + AuthRecipeUserInfo user1 = EmailPassword.signUp(t0, t0Storage, process.getProcess(), "test@example.com", "password123"); + AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1Storage, process.getProcess(), "test@example.com", "password123"); - UserIdMapping.populateExternalUserIdForUsers(t0WithStorage, new AuthRecipeUserInfo[]{user1}); - UserIdMapping.populateExternalUserIdForUsers(t1WithStorage, new AuthRecipeUserInfo[]{user2}); + UserIdMapping.populateExternalUserIdForUsers(t0Storage, new AuthRecipeUserInfo[]{user1}); + UserIdMapping.populateExternalUserIdForUsers(t1Storage, new AuthRecipeUserInfo[]{user2}); // Check that get user by ID works fine JsonObject jsonUser1 = TestMultitenancyAPIHelper.getUserById(t0, user1.getSupertokensUserId(), process.getProcess()); @@ -149,8 +149,8 @@ public void testThatUserMetadataIsSavedInTheStorageWhereUserExists() throws Exce } } - UserMetadataSQLStorage t0UserMetadataStorage = StorageUtils.getUserMetadataStorage(t0WithStorage); - UserMetadataSQLStorage t1UserMetadataStorage = StorageUtils.getUserMetadataStorage(t1WithStorage); + UserMetadataSQLStorage t0UserMetadataStorage = StorageUtils.getUserMetadataStorage(t0Storage); + UserMetadataSQLStorage t1UserMetadataStorage = StorageUtils.getUserMetadataStorage(t1Storage); // Ensure that the metadata is saved in the correct storage assertNotNull(t0UserMetadataStorage.getUserMetadata(t0.toAppIdentifier(), user1.getSupertokensUserId())); // ensure t0 storage does not have user2's metadata @@ -176,17 +176,17 @@ public void testThatUserMetadataIsSavedInTheStorageWhereUserExists() throws Exce @Test public void testThatUserRolesWorkWithDifferentTenantsOnDifferentStorages() throws Exception { TenantIdentifier t0 = new TenantIdentifier(null, null, null); - Storage t0WithStorage = (StorageLayer.getStorage(t0, process.getProcess())); + Storage t0Storage = (StorageLayer.getStorage(t0, process.getProcess())); TenantIdentifier t1 = new TenantIdentifier(null, null, "t1"); - Storage t1WithStorage = (StorageLayer.getStorage(t1, process.getProcess())); + Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); // Create users - AuthRecipeUserInfo user1 = EmailPassword.signUp(t0, t0WithStorage, process.getProcess(), "test@example.com", "password123"); - AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1WithStorage, process.getProcess(), "test@example.com", "password123"); + AuthRecipeUserInfo user1 = EmailPassword.signUp(t0, t0Storage, process.getProcess(), "test@example.com", "password123"); + AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1Storage, process.getProcess(), "test@example.com", "password123"); - UserIdMapping.populateExternalUserIdForUsers(t0WithStorage, new AuthRecipeUserInfo[]{user1}); - UserIdMapping.populateExternalUserIdForUsers(t1WithStorage, new AuthRecipeUserInfo[]{user2}); + UserIdMapping.populateExternalUserIdForUsers(t0Storage, new AuthRecipeUserInfo[]{user1}); + UserIdMapping.populateExternalUserIdForUsers(t1Storage, new AuthRecipeUserInfo[]{user2}); } diff --git a/src/test/java/io/supertokens/test/totp/api/TotpUserIdMappingTest.java b/src/test/java/io/supertokens/test/totp/api/TotpUserIdMappingTest.java index 7e135958c..43c9f74d5 100644 --- a/src/test/java/io/supertokens/test/totp/api/TotpUserIdMappingTest.java +++ b/src/test/java/io/supertokens/test/totp/api/TotpUserIdMappingTest.java @@ -77,7 +77,7 @@ public void testExternalUserIdTranslation() throws Exception { "totp"); assert res1.get("status").getAsString().equals("OK"); String d1Secret = res1.get("secret").getAsString(); - TOTPDevice device1 = new TOTPDevice(externalUserId, "deviceName", d1Secret, 30, 0, false); + TOTPDevice device1 = new TOTPDevice(externalUserId, "d1", d1Secret, 30, 0, false); body.addProperty("deviceName", "d2"); @@ -93,7 +93,7 @@ public void testExternalUserIdTranslation() throws Exception { "totp"); assert res2.get("status").getAsString().equals("OK"); String d2Secret = res2.get("secret").getAsString(); - TOTPDevice device2 = new TOTPDevice(externalUserId, "deviceName", d2Secret, 30, 0, false); + TOTPDevice device2 = new TOTPDevice(externalUserId, "d2", d2Secret, 30, 0, false); // Verify d1 but not d2: JsonObject verifyD1Input = new JsonObject(); diff --git a/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java b/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java index cefb5a08c..cf4c5dbde 100644 --- a/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java +++ b/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java @@ -470,8 +470,9 @@ public void testAssociatingAnUnknownRoleWithUser() throws Exception { Exception error = null; try { - - storage.addRoleToUser(new TenantIdentifier(null, null, null), "userId", "unknownRole"); + UserRoles.addRoleToUser( + process.getProcess(), new TenantIdentifier(null, null, null), + StorageLayer.getBaseStorage(process.getProcess()), "userId", "unknownRole"); } catch (Exception e) { error = e; } From 75b5a146848aa22e51c6ed0695468f545dbab5bb Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Mon, 4 Mar 2024 11:35:01 +0530 Subject: [PATCH 18/31] fix: pr comments --- src/main/java/io/supertokens/webserver/WebserverAPI.java | 6 ++++++ .../webserver/api/multitenancy/CreateOrUpdateAppAPI.java | 4 ++-- .../multitenancy/CreateOrUpdateConnectionUriDomainAPI.java | 4 ++-- .../multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java | 4 ++-- .../webserver/api/multitenancy/RemoveAppAPI.java | 3 +-- .../api/multitenancy/RemoveConnectionUriDomainAPI.java | 3 +-- .../webserver/api/multitenancy/RemoveTenantAPI.java | 5 +---- 7 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/main/java/io/supertokens/webserver/WebserverAPI.java b/src/main/java/io/supertokens/webserver/WebserverAPI.java index 65cb7c200..17b64c946 100644 --- a/src/main/java/io/supertokens/webserver/WebserverAPI.java +++ b/src/main/java/io/supertokens/webserver/WebserverAPI.java @@ -302,6 +302,12 @@ protected TenantIdentifier getTenantIdentifier(HttpServletRequest req) throws Se return new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), this.getTenantId(req)); } + protected TenantIdentifier ensureTenantExistsAndGetTenantIdentifier(HttpServletRequest req) + throws ServletException, TenantOrAppNotFoundException { + getTenantStorage(req); + return new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), this.getTenantId(req)); + } + protected AppIdentifier getAppIdentifier(HttpServletRequest req) throws ServletException { return new AppIdentifier(this.getConnectionUriDomain(req), this.getAppId(req)); } diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java index 92c514126..fa7e068a4 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java @@ -54,10 +54,10 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO Boolean passwordlessEnabled = InputParser.parseBooleanOrThrowError(input, "passwordlessEnabled", true); JsonObject coreConfig = InputParser.parseJsonObjectOrThrowError(input, "coreConfig", true); - TenantIdentifier sourceTenantIdentifier = getTenantIdentifier(req); + TenantIdentifier sourceTenantIdentifier; try { - getTenantStorage(req); // ensure source tenant exists + sourceTenantIdentifier = ensureTenantExistsAndGetTenantIdentifier(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java index 553bb5cc1..fdc68fa59 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java @@ -54,9 +54,9 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO Boolean passwordlessEnabled = InputParser.parseBooleanOrThrowError(input, "passwordlessEnabled", true); JsonObject coreConfig = InputParser.parseJsonObjectOrThrowError(input, "coreConfig", true); - TenantIdentifier sourceTenantIdentifier = getTenantIdentifier(req); + TenantIdentifier sourceTenantIdentifier; try { - this.getTenantStorage(req); // ensure source tenant exists + sourceTenantIdentifier = ensureTenantExistsAndGetTenantIdentifier(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java index c75eb0380..66bbd4711 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java @@ -57,9 +57,9 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO Boolean passwordlessEnabled = InputParser.parseBooleanOrThrowError(input, "passwordlessEnabled", true); JsonObject coreConfig = InputParser.parseJsonObjectOrThrowError(input, "coreConfig", true); - TenantIdentifier sourceTenantIdentifier = getTenantIdentifier(req); + TenantIdentifier sourceTenantIdentifier; try { - this.getTenantStorage(req); // ensure source tenant exists + sourceTenantIdentifier = ensureTenantExistsAndGetTenantIdentifier(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java index 8d413070a..bd1ef7a7a 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java @@ -59,8 +59,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - TenantIdentifier sourceTenantIdentifier = this.getTenantIdentifier(req); - getTenantStorage(req); // ensure the tenant exists + TenantIdentifier sourceTenantIdentifier = this.ensureTenantExistsAndGetTenantIdentifier(req); if (!sourceTenantIdentifier.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID) || !sourceTenantIdentifier.getAppId().equals(TenantIdentifier.DEFAULT_APP_ID)) { throw new BadPermissionException("Only the public tenantId and public appId is allowed to delete an app"); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java index e507b9156..2b508155f 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java @@ -58,8 +58,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - TenantIdentifier sourceTenantIdentifier = this.getTenantIdentifier(req); - getTenantStorage(req); // ensure tenant exists + TenantIdentifier sourceTenantIdentifier = this.ensureTenantExistsAndGetTenantIdentifier(req); if (!sourceTenantIdentifier.equals(new TenantIdentifier(null, null, null))) { throw new BadPermissionException( "Only the public tenantId, public appId and default connectionUriDomain is allowed to delete a connectionUriDomain"); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveTenantAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveTenantAPI.java index e2f3da76b..f1ae12b03 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveTenantAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveTenantAPI.java @@ -59,11 +59,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { TenantIdentifier sourceTenantIdentifier = this.getTenantIdentifier(req); - getTenantStorage(req); // ensure the tenant exists - if (!sourceTenantIdentifier.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID)) { - throw new BadPermissionException("Only the public tenantId is allowed to delete a tenant"); - } + enforcePublicTenantAndGetPublicTenantStorage(req); // Enforce public tenant boolean didExist = Multitenancy.deleteTenant(new TenantIdentifier(sourceTenantIdentifier.getConnectionUriDomain(), sourceTenantIdentifier.getAppId(), tenantId), main); From 38c11fdee4453be3a21bab2426315c1c5b0c7e10 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Mon, 4 Mar 2024 12:26:04 +0530 Subject: [PATCH 19/31] fix: pr comments --- .../java/io/supertokens/session/Session.java | 57 +++++++++++++++++++ .../supertokens/webserver/WebserverAPI.java | 15 ++++- .../CanCreatePrimaryUserAPI.java | 2 +- .../accountlinking/CanLinkAccountsAPI.java | 4 +- .../accountlinking/CreatePrimaryUserAPI.java | 2 +- .../api/accountlinking/LinkAccountsAPI.java | 4 +- .../api/accountlinking/UnlinkAccountAPI.java | 2 +- .../webserver/api/core/DeleteUserAPI.java | 3 +- .../webserver/api/core/GetUserByIdAPI.java | 3 +- .../webserver/api/emailpassword/UserAPI.java | 6 +- .../emailverification/UnverifyEmailAPI.java | 4 +- .../api/emailverification/VerifyEmailAPI.java | 4 +- .../webserver/api/passwordless/UserAPI.java | 6 +- .../api/session/SessionRemoveAPI.java | 13 +---- .../webserver/api/session/SessionUserAPI.java | 13 +++-- .../webserver/api/thirdparty/UserAPI.java | 3 +- .../api/totp/CreateOrUpdateTotpDeviceAPI.java | 10 ++-- .../webserver/api/totp/GetTotpDevicesAPI.java | 5 +- .../api/totp/RemoveTotpDeviceAPI.java | 6 +- .../useridmapping/RemoveUserIdMappingAPI.java | 3 +- .../UpdateExternalUserIdInfoAPI.java | 3 +- .../api/useridmapping/UserIdMappingAPI.java | 2 +- .../usermetadata/RemoveUserMetadataAPI.java | 5 +- .../api/usermetadata/UserMetadataAPI.java | 10 ++-- 24 files changed, 124 insertions(+), 61 deletions(-) diff --git a/src/main/java/io/supertokens/session/Session.java b/src/main/java/io/supertokens/session/Session.java index c1969bd46..efed4b535 100644 --- a/src/main/java/io/supertokens/session/Session.java +++ b/src/main/java/io/supertokens/session/Session.java @@ -824,6 +824,20 @@ public static String[] revokeAllSessionsForUser(Main main, AppIdentifier appIden return revokeSessionUsingSessionHandles(main, appIdentifier, storage, sessionHandles); } + public static String[] revokeAllSessionsForUser(Main main, AppIdentifier appIdentifier, + Storage[] storages, String userId, + boolean revokeSessionsForLinkedAccounts) + throws StorageQueryException { + List revokedSessionHandles = new ArrayList<>(); + for (Storage storage : storages) { + String[] sessionHandles = getAllNonExpiredSessionHandlesForUser(main, appIdentifier, storage, userId, + revokeSessionsForLinkedAccounts); + return revokeSessionUsingSessionHandles(main, appIdentifier, storage, sessionHandles); + } + + return revokedSessionHandles.toArray(new String[0]); + } + public static String[] revokeAllSessionsForUser(Main main, TenantIdentifier tenantIdentifier, Storage storage, String userId, boolean revokeSessionsForLinkedAccounts) throws StorageQueryException { @@ -881,6 +895,49 @@ public static String[] getAllNonExpiredSessionHandlesForUser( return sessionHandles.toArray(new String[0]); } + public static String[] getAllNonExpiredSessionHandlesForUser( + Main main, AppIdentifier appIdentifier, Storage[] storages, String userId, + boolean fetchSessionsForAllLinkedAccounts) + throws StorageQueryException { + TenantConfig[] tenants = Multitenancy.getAllTenantsForApp( + appIdentifier, main); + + List sessionHandles = new ArrayList<>(); + + for (Storage storage : storages) { + Set userIds = new HashSet<>(); + userIds.add(userId); + if (fetchSessionsForAllLinkedAccounts) { + if (storage.getType().equals(STORAGE_TYPE.SQL)) { + AuthRecipeUserInfo primaryUser = ((AuthRecipeStorage) storage) + .getPrimaryUserById(appIdentifier, userId); + if (primaryUser != null) { + for (LoginMethod lM : primaryUser.loginMethods) { + userIds.add(lM.getSupertokensUserId()); + } + } + } + } + + for (String currUserId : userIds) { + for (TenantConfig tenant : tenants) { + try { + sessionHandles.addAll(Arrays.asList(getAllNonExpiredSessionHandlesForUser( + tenant.tenantIdentifier, StorageLayer.getStorage(tenant.tenantIdentifier, main), + currUserId, false))); + + } catch (TenantOrAppNotFoundException e) { + // this might happen when a tenant was deleted after the tenant list was fetched + // it is okay to exclude that tenant in the results here + } + } + } + } + + + return sessionHandles.toArray(new String[0]); + } + public static String[] getAllNonExpiredSessionHandlesForUser( TenantIdentifier tenantIdentifier, Storage storage, String userId, boolean fetchSessionsForAllLinkedAccounts) diff --git a/src/main/java/io/supertokens/webserver/WebserverAPI.java b/src/main/java/io/supertokens/webserver/WebserverAPI.java index 17b64c946..f89a9a2d5 100644 --- a/src/main/java/io/supertokens/webserver/WebserverAPI.java +++ b/src/main/java/io/supertokens/webserver/WebserverAPI.java @@ -34,6 +34,7 @@ import io.supertokens.storageLayer.StorageLayer; import io.supertokens.useridmapping.UserIdType; import io.supertokens.utils.SemVer; +import io.supertokens.webserver.api.useridmapping.UserIdMappingAPI; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.ServletRequest; @@ -352,15 +353,23 @@ protected StorageAndUserIdMapping getStorageAndUserIdMappingForTenantSpecificApi } protected StorageAndUserIdMapping enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - HttpServletRequest req, String userId, UserIdType userIdType) + HttpServletRequest req, String userId, UserIdType userIdType, boolean isCallFromAuthRecipeAPI) throws StorageQueryException, TenantOrAppNotFoundException, UnknownUserIdException, ServletException, BadPermissionException { // This function uses storage of the tenant from which the request came from as a priorityStorage // while searching for the user across all storages for the app AppIdentifier appIdentifier = getAppIdentifier(req); Storage[] storages = enforcePublicTenantAndGetAllStoragesForApp(req); - return StorageLayer.findStorageAndUserIdMappingForUser( - appIdentifier, storages, userId, userIdType); + try { + return StorageLayer.findStorageAndUserIdMappingForUser( + appIdentifier, storages, userId, userIdType); + } catch (UnknownUserIdException e) { + if (isCallFromAuthRecipeAPI) { + throw e; + } + + return new StorageAndUserIdMapping(enforcePublicTenantAndGetPublicTenantStorage(req), null); + } } protected boolean checkIPAccess(HttpServletRequest req, HttpServletResponse resp) diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java index 589cf3fdf..3f9d12a12 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java @@ -62,7 +62,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO String userId = inputRecipeUserId; StorageAndUserIdMapping storageAndMapping = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, inputRecipeUserId, UserIdType.ANY); + req, inputRecipeUserId, UserIdType.ANY, true); storage = storageAndMapping.storage; if (storageAndMapping.userIdMapping != null) { userId = storageAndMapping.userIdMapping.superTokensUserId; diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java index bc8011efc..9d2196eac 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java @@ -66,7 +66,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO { StorageAndUserIdMapping mappingAndStorage = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, inputRecipeUserId, UserIdType.ANY); + req, inputRecipeUserId, UserIdType.ANY, true); if (mappingAndStorage.userIdMapping != null) { recipeUserId = mappingAndStorage.userIdMapping.superTokensUserId; } @@ -76,7 +76,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO { StorageAndUserIdMapping mappingAndStorage = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, inputPrimaryUserId, UserIdType.ANY); + req, inputPrimaryUserId, UserIdType.ANY, true); if (mappingAndStorage.userIdMapping != null) { primaryUserId = mappingAndStorage.userIdMapping.superTokensUserId; } diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java index c912fcf54..ee4e13b30 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java @@ -64,7 +64,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String userId = inputRecipeUserId; StorageAndUserIdMapping mappingAndStorage = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, inputRecipeUserId, UserIdType.ANY); + req, inputRecipeUserId, UserIdType.ANY, true); storage = mappingAndStorage.storage; if (mappingAndStorage.userIdMapping != null) { userId = mappingAndStorage.userIdMapping.superTokensUserId; diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java index 6c4e29e6e..ca61f8562 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java @@ -68,7 +68,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I { StorageAndUserIdMapping mappingAndStorage = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, inputRecipeUserId, UserIdType.ANY); + req, inputRecipeUserId, UserIdType.ANY, true); if (mappingAndStorage.userIdMapping != null) { recipeUserId = mappingAndStorage.userIdMapping.superTokensUserId; } @@ -78,7 +78,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I { StorageAndUserIdMapping mappingAndStorage = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, inputPrimaryUserId, UserIdType.ANY); + req, inputPrimaryUserId, UserIdType.ANY, true); if (mappingAndStorage.userIdMapping != null) { primaryUserId = mappingAndStorage.userIdMapping.superTokensUserId; } diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java index 5b1801db2..22ae386ef 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java @@ -60,7 +60,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String userId = inputRecipeUserId; StorageAndUserIdMapping mappingAndStorage = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, inputRecipeUserId, UserIdType.ANY); + req, inputRecipeUserId, UserIdType.ANY, true); if (mappingAndStorage.userIdMapping != null) { userId = mappingAndStorage.userIdMapping.superTokensUserId; } diff --git a/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java b/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java index c47817c90..5d7323bbe 100644 --- a/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/DeleteUserAPI.java @@ -60,7 +60,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { StorageAndUserIdMapping storageAndUserIdMapping = - this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( + req, userId, UserIdType.ANY, true); AuthRecipe.deleteUser(getAppIdentifier(req), storageAndUserIdMapping.storage, userId, removeAllLinkedAccounts, diff --git a/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java b/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java index b4d33d462..a09155701 100644 --- a/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/GetUserByIdAPI.java @@ -58,7 +58,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { AppIdentifier appIdentifier = this.getAppIdentifier(req); StorageAndUserIdMapping storageAndUserIdMapping = - this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, + UserIdType.ANY, true); // if a userIdMapping exists, pass the superTokensUserId to the getUserUsingId function if (storageAndUserIdMapping.userIdMapping != null) { userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java index 6195213fc..b7a662eca 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java @@ -84,7 +84,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO if (userId != null) { // Query by userId StorageAndUserIdMapping storageAndUserIdMapping = - this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, + UserIdType.ANY, true); // if a userIdMapping exists, pass the superTokensUserId to the getUserUsingId function if (storageAndUserIdMapping.userIdMapping != null) { userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; @@ -166,7 +167,8 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO try { StorageAndUserIdMapping storageAndUserIdMapping = - this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, + UserIdType.ANY, true); // if a userIdMapping exists, pass the superTokensUserId to the updateUsersEmailOrPassword if (storageAndUserIdMapping.userIdMapping != null) { userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; diff --git a/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java b/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java index f3c7664ca..826805856 100644 --- a/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailverification/UnverifyEmailAPI.java @@ -62,10 +62,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I Storage storage; try { StorageAndUserIdMapping storageAndUidMapping = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, userId, UserIdType.ANY); + req, userId, UserIdType.ANY, false); storage = storageAndUidMapping.storage; } catch (UnknownUserIdException e) { - storage = enforcePublicTenantAndGetPublicTenantStorage(req); + throw new IllegalStateException("should never happen"); } EmailVerification.unverifyEmail(appIdentifier, storage, userId, email); diff --git a/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java b/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java index c4d782452..ed64a8b70 100644 --- a/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java @@ -112,10 +112,10 @@ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws Servl Storage storage; try { StorageAndUserIdMapping storageAndUserIdMapping = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, userId, UserIdType.ANY); + req, userId, UserIdType.ANY, false); storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { - storage = enforcePublicTenantAndGetPublicTenantStorage(req); + throw new IllegalStateException("should never happen"); } boolean isVerified = EmailVerification.isEmailVerified(appIdentifier, storage, userId, email); diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java index 49ff69ff6..430743262 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/UserAPI.java @@ -82,7 +82,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { AppIdentifier appIdentifier = getAppIdentifier(req); StorageAndUserIdMapping storageAndUserIdMapping = - this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, + UserIdType.ANY, true); if (storageAndUserIdMapping.userIdMapping != null) { userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } @@ -165,7 +166,8 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO try { AppIdentifier appIdentifier = getAppIdentifier(req); StorageAndUserIdMapping storageAndUserIdMapping = - this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, + UserIdType.ANY, true); // if a userIdMapping exists, pass the superTokensUserId to the updateUser if (storageAndUserIdMapping.userIdMapping != null) { userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java index 2de495b62..a14f60256 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java @@ -115,20 +115,13 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String[] sessionHandlesRevoked; if (revokeAcrossAllTenants) { - StorageAndUserIdMapping storageAndUserIdMapping = null; - try { - storageAndUserIdMapping = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, userId, UserIdType.ANY); - storage = storageAndUserIdMapping.storage; - } catch (UnknownUserIdException e) { - storage = getTenantStorage(req); - } AppIdentifier appIdentifier = getAppIdentifier(req); + Storage[] storages = enforcePublicTenantAndGetAllStoragesForApp(req); sessionHandlesRevoked = Session.revokeAllSessionsForUser( - main, appIdentifier, storage, userId, revokeSessionsForLinkedAccounts); + main, appIdentifier, storages, userId, revokeSessionsForLinkedAccounts); } else { - StorageAndUserIdMapping storageAndUserIdMapping = null; + StorageAndUserIdMapping storageAndUserIdMapping; try { storageAndUserIdMapping = getStorageAndUserIdMappingForTenantSpecificApi( req, userId, UserIdType.ANY); diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java index ec0ad8dff..6d8b1a92d 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java @@ -20,6 +20,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import io.supertokens.Main; +import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -50,7 +51,7 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - // API is tenant specific, also finds across all tenants in the app if fetchAcrossAllTenants is set to true + // API is app specific if fetchAcrossAllTenants is set to true, tenant specific otherwise String userId = InputParser.getQueryParamOrThrowError(req, "userId", false); assert userId != null; @@ -70,13 +71,15 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO try { String[] sessionHandles; - TenantIdentifier tenantIdentifier = getTenantIdentifier(req); - Storage storage = getTenantStorage(req); if (fetchAcrossAllTenants) { + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage[] storages = enforcePublicTenantAndGetAllStoragesForApp(req); sessionHandles = Session.getAllNonExpiredSessionHandlesForUser( - main, tenantIdentifier.toAppIdentifier(), storage, userId, fetchSessionsForAllLinkedAccounts); + main, appIdentifier, storages, userId, fetchSessionsForAllLinkedAccounts); } else { + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = getTenantStorage(req); sessionHandles = Session.getAllNonExpiredSessionHandlesForUser( tenantIdentifier, storage, userId, fetchSessionsForAllLinkedAccounts); } @@ -90,7 +93,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO result.add("sessionHandles", arr); super.sendJsonResponse(200, result, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java b/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java index f8ef39376..d4c4e1719 100644 --- a/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java @@ -81,7 +81,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO AppIdentifier appIdentifier = getAppIdentifier(req); try { StorageAndUserIdMapping storageAndUserIdMapping = - this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, UserIdType.ANY); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, + UserIdType.ANY, true); // if a userIdMapping exists, pass the superTokensUserId to the getUserUsingId function if (storageAndUserIdMapping.userIdMapping != null) { userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; diff --git a/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java index 7aeaf35d5..59b9f0fa7 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java @@ -75,11 +75,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I // Try to find the appIdentifier with right storage based on the userId StorageAndUserIdMapping storageAndUserIdMapping = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, userId, UserIdType.ANY); + req, userId, UserIdType.ANY, false); storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { - // if the user is not found, just use the public tenant storage - storage = enforcePublicTenantAndGetPublicTenantStorage(req); + throw new IllegalStateException("should never happen"); } TOTPDevice device = Totp.registerDevice(appIdentifier, storage, main, userId, deviceName, skew, period); @@ -127,12 +126,11 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO // Try to find the appIdentifier with right storage based on the userId StorageAndUserIdMapping storageAndUserIdMapping = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, userId, UserIdType.ANY); + req, userId, UserIdType.ANY, false); storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { - // if the user is not found, just use the public storage - storage = enforcePublicTenantAndGetPublicTenantStorage(req); + throw new IllegalStateException("should never happen"); } Totp.updateDeviceName(appIdentifier, storage, userId, existingDeviceName, newDeviceName); diff --git a/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java b/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java index 4b5e9905a..9636a9590 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java @@ -55,11 +55,10 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO // Try to find the appIdentifier with right storage based on the userId StorageAndUserIdMapping storageAndUserIdMapping = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, userId, UserIdType.ANY); + req, userId, UserIdType.ANY, false); storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { - // if the user is not found, just use the storage of the tenant of interest - storage = enforcePublicTenantAndGetPublicTenantStorage(req); + throw new IllegalStateException("should never happen"); } TOTPDevice[] devices = Totp.getDevices(appIdentifier, storage, userId); diff --git a/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java index d8dde49c3..cdbbe8bd0 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java @@ -61,12 +61,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I // Try to find the appIdentifier with right storage based on the userId StorageAndUserIdMapping storageAndUserIdMapping = enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, userId, UserIdType.ANY); - + req, userId, UserIdType.ANY, false); storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { - // if the user is not found, just use the storage of the tenant of interest - storage = enforcePublicTenantAndGetPublicTenantStorage(req); + throw new IllegalStateException("should never happen"); } Totp.removeDevice(appIdentifier, storage, userId, deviceName); diff --git a/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java b/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java index ba2892e6b..e37e87ef7 100644 --- a/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java +++ b/src/main/java/io/supertokens/webserver/api/useridmapping/RemoveUserIdMappingAPI.java @@ -86,7 +86,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { StorageAndUserIdMapping storageAndUserIdMapping = - this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType, + true); boolean didMappingExist = UserIdMapping.deleteUserIdMapping( getAppIdentifier(req), diff --git a/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java b/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java index 8acf3ff60..80c3f31b4 100644 --- a/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java +++ b/src/main/java/io/supertokens/webserver/api/useridmapping/UpdateExternalUserIdInfoAPI.java @@ -95,7 +95,8 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO try { StorageAndUserIdMapping storageAndUserIdMapping = - this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType, + true); if (UserIdMapping.updateOrDeleteExternalUserIdInfo( getAppIdentifier(req), diff --git a/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java b/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java index 0bd993e07..475e30f93 100644 --- a/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java +++ b/src/main/java/io/supertokens/webserver/api/useridmapping/UserIdMappingAPI.java @@ -163,7 +163,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO // Request from (app1, tenant3) may result in either user1 or user2 StorageAndUserIdMapping storageAndUserIdMapping = - this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType); + this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi(req, userId, userIdType, true); if (storageAndUserIdMapping.userIdMapping == null) { JsonObject response = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java b/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java index c8901064e..dd26fa1ae 100644 --- a/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java @@ -59,11 +59,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { StorageAndUserIdMapping storageAndUserIdMapping = this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, userId, UserIdType.ANY); + req, userId, UserIdType.ANY, false); UserMetadata.deleteUserMetadata(appIdentifier, storageAndUserIdMapping.storage, userId); } catch (UnknownUserIdException e) { - Storage storage = this.enforcePublicTenantAndGetPublicTenantStorage(req); - UserMetadata.deleteUserMetadata(appIdentifier, storage, userId); + throw new IllegalStateException("should never happen"); } JsonObject response = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java b/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java index c11d47faa..1e01a2504 100644 --- a/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java @@ -58,11 +58,10 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject metadata; try { StorageAndUserIdMapping storageAndUserIdMapping = this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, userId, UserIdType.ANY); + req, userId, UserIdType.ANY, false); metadata = UserMetadata.getUserMetadata(appIdentifier, storageAndUserIdMapping.storage, userId); } catch (UnknownUserIdException e) { - Storage storage = this.enforcePublicTenantAndGetPublicTenantStorage(req); - metadata = UserMetadata.getUserMetadata(appIdentifier, storage, userId); + throw new IllegalStateException("should never happen"); } JsonObject response = new JsonObject(); @@ -87,12 +86,11 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO try { StorageAndUserIdMapping storageAndUserIdMapping = this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( - req, userId, UserIdType.ANY); + req, userId, UserIdType.ANY, false); metadata = UserMetadata.updateUserMetadata(appIdentifier, storageAndUserIdMapping.storage, userId, update); } catch (UnknownUserIdException e) { - Storage storage = this.enforcePublicTenantAndGetPublicTenantStorage(req); - metadata = UserMetadata.updateUserMetadata(appIdentifier, storage, userId, update); + throw new IllegalStateException("should never happen"); } JsonObject response = new JsonObject(); From 06569c048bd47ce0d26eaf8f9865ce04e415cf7d Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Mon, 4 Mar 2024 12:37:58 +0530 Subject: [PATCH 20/31] fix: pr comments --- .../multitenancy/AssociateUserToTenantAPI.java | 14 ++++++-------- .../DisassociateUserFromTenant.java | 17 ++++++++--------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/AssociateUserToTenantAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/AssociateUserToTenantAPI.java index 1891aeebe..0fbaac29a 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/AssociateUserToTenantAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/AssociateUserToTenantAPI.java @@ -18,13 +18,13 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.multitenancy.Multitenancy; import io.supertokens.multitenancy.exception.AnotherPrimaryUserWithEmailAlreadyExistsException; import io.supertokens.multitenancy.exception.AnotherPrimaryUserWithPhoneNumberAlreadyExistsException; import io.supertokens.multitenancy.exception.AnotherPrimaryUserWithThirdPartyInfoAlreadyExistsException; import io.supertokens.pluginInterface.RECIPE_ID; -import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -32,7 +32,6 @@ import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.passwordless.exception.DuplicatePhoneNumberException; import io.supertokens.pluginInterface.thirdparty.exception.DuplicateThirdPartyUserException; -import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; import io.supertokens.utils.SemVer; import io.supertokens.webserver.InputParser; @@ -76,16 +75,15 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { TenantIdentifier tenantIdentifier = getTenantIdentifier(req); - Storage storage = getTenantStorage(req); - io.supertokens.pluginInterface.useridmapping.UserIdMapping mapping = UserIdMapping.getUserIdMapping( - tenantIdentifier.toAppIdentifier(), storage, userId, UserIdType.ANY); - if (mapping != null) { - userId = mapping.superTokensUserId; + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForTenantSpecificApi( + req, userId, UserIdType.ANY); + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } boolean addedToTenant = Multitenancy.addUserIdToTenant(main, - tenantIdentifier, storage, userId); + tenantIdentifier, storageAndUserIdMapping.storage, userId); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/DisassociateUserFromTenant.java b/src/main/java/io/supertokens/webserver/api/multitenancy/DisassociateUserFromTenant.java index 7f28a1d56..57ee9f173 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/DisassociateUserFromTenant.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/DisassociateUserFromTenant.java @@ -18,15 +18,14 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.multitenancy.Multitenancy; import io.supertokens.pluginInterface.RECIPE_ID; -import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; -import io.supertokens.useridmapping.UserIdMapping; import io.supertokens.useridmapping.UserIdType; import io.supertokens.utils.SemVer; import io.supertokens.webserver.InputParser; @@ -69,17 +68,17 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { TenantIdentifier tenantIdentifier = getTenantIdentifier(req); - Storage storage = getTenantStorage(req); String externalUserId = null; - io.supertokens.pluginInterface.useridmapping.UserIdMapping mapping = UserIdMapping.getUserIdMapping( - tenantIdentifier.toAppIdentifier(), storage, userId, UserIdType.ANY); - if (mapping != null) { - userId = mapping.superTokensUserId; - externalUserId = mapping.externalUserId; + + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForTenantSpecificApi( + req, userId, UserIdType.ANY); + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; + externalUserId = storageAndUserIdMapping.userIdMapping.externalUserId; } boolean wasAssociated = Multitenancy.removeUserIdFromTenant(main, - tenantIdentifier, storage, userId, externalUserId); + tenantIdentifier, storageAndUserIdMapping.storage, userId, externalUserId); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); From d94a381828d269f6d7ea060567161eec80e0b906 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Mon, 4 Mar 2024 13:37:06 +0530 Subject: [PATCH 21/31] fix: user role multitenant tests --- .../api/TestMultitenancyAPIHelper.java | 47 +++++++++++++++++++ .../api/TestWithNonAuthRecipes.java | 47 ++++++++++++++++++- 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java b/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java index 17297da0d..d31944059 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java @@ -470,4 +470,51 @@ public static JsonObject removeMetadata(TenantIdentifier tenantIdentifier, Strin return resp; } + + public static void createRole(TenantIdentifier tenantIdentifier, String role, Main main) + throws HttpResponseException, IOException { + JsonObject requestBody = new JsonObject(); + requestBody.addProperty("role", role); + JsonObject response = HttpRequestForTesting.sendJsonPUTRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/role"), + requestBody, 1000, 1000, null, WebserverAPI.getLatestCDIVersion().get(), + "userroles"); + assertEquals("OK", response.get("status").getAsString()); + } + + public static void addRoleToUser(TenantIdentifier tenantIdentifier, String userId, String role, Main main) + throws HttpResponseException, IOException { + JsonObject requestBody = new JsonObject(); + requestBody.addProperty("role", role); + requestBody.addProperty("userId", userId); + + JsonObject response = HttpRequestForTesting.sendJsonPUTRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(tenantIdentifier,"/recipe/user/role"), requestBody, 1000, 1000, null, + WebserverAPI.getLatestCDIVersion().get(), "userroles"); + + assertEquals(2, response.entrySet().size()); + assertEquals("OK", response.get("status").getAsString()); + } + + public static JsonObject getUserRoles(TenantIdentifier tenantIdentifier, String userId, Main main) + throws HttpResponseException, IOException { + HashMap QUERY_PARAMS = new HashMap<>(); + QUERY_PARAMS.put("userId", userId); + JsonObject response = HttpRequestForTesting.sendGETRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(tenantIdentifier,"/recipe/user/roles"), QUERY_PARAMS, 1000, 1000, null, + WebserverAPI.getLatestCDIVersion().get(), "userroles"); + return response; + } + + public static void deleteRole(TenantIdentifier tenantIdentifier, String role, Main main) + throws HttpResponseException, IOException { + JsonObject request = new JsonObject(); + request.addProperty("role", role); + + JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(tenantIdentifier,"/recipe/role/remove"), request, 1000, 1000, null, + WebserverAPI.getLatestCDIVersion().get(), "userroles"); + assertEquals(2, response.entrySet().size()); + assertEquals("OK", response.get("status").getAsString()); + } } diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java b/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java index 2904d5247..7e1a67d7f 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java @@ -174,7 +174,7 @@ public void testThatUserMetadataIsSavedInTheStorageWhereUserExists() throws Exce } @Test - public void testThatUserRolesWorkWithDifferentTenantsOnDifferentStorages() throws Exception { + public void testThatRoleIsStoredInPublicTenantAndUserRoleMappingInTheUserTenantStorage() throws Exception { TenantIdentifier t0 = new TenantIdentifier(null, null, null); Storage t0Storage = (StorageLayer.getStorage(t0, process.getProcess())); @@ -188,6 +188,51 @@ public void testThatUserRolesWorkWithDifferentTenantsOnDifferentStorages() throw UserIdMapping.populateExternalUserIdForUsers(t0Storage, new AuthRecipeUserInfo[]{user1}); UserIdMapping.populateExternalUserIdForUsers(t1Storage, new AuthRecipeUserInfo[]{user2}); + TestMultitenancyAPIHelper.createRole(t0, "role1", process.getProcess()); + try { + TestMultitenancyAPIHelper.createRole(t1, "role2", process.getProcess()); + fail(); + } catch (HttpResponseException e) { + assertEquals(403, e.statusCode); + } + TestMultitenancyAPIHelper.createRole(t0, "role2", process.getProcess()); + + TestMultitenancyAPIHelper.addRoleToUser(t0, user1.getSupertokensUserId(), "role1", process.getProcess()); + TestMultitenancyAPIHelper.addRoleToUser(t1, user2.getSupertokensUserId(), "role2", process.getProcess()); + + { + JsonObject user1Roles = TestMultitenancyAPIHelper.getUserRoles(t0, user1.getSupertokensUserId(), process.getProcess()); + assertEquals(1, user1Roles.get("roles").getAsJsonArray().size()); + user1Roles = TestMultitenancyAPIHelper.getUserRoles(t1, user1.getSupertokensUserId(), process.getProcess()); + assertEquals(0, user1Roles.get("roles").getAsJsonArray().size()); + + JsonObject user2Roles = TestMultitenancyAPIHelper.getUserRoles(t0, user2.getSupertokensUserId(), process.getProcess()); + assertEquals(0, user2Roles.get("roles").getAsJsonArray().size()); + user2Roles = TestMultitenancyAPIHelper.getUserRoles(t1, user2.getSupertokensUserId(), process.getProcess()); + assertEquals(1, user2Roles.get("roles").getAsJsonArray().size()); + } + + try { + TestMultitenancyAPIHelper.deleteRole(t1, "role1", process.getProcess()); + fail(); + } catch (HttpResponseException e) { + assertEquals(403, e.statusCode); + } + + TestMultitenancyAPIHelper.deleteRole(t0, "role1", process.getProcess()); + TestMultitenancyAPIHelper.deleteRole(t0, "role2", process.getProcess()); + + { + JsonObject user1Roles = TestMultitenancyAPIHelper.getUserRoles(t0, user1.getSupertokensUserId(), process.getProcess()); + assertEquals(0, user1Roles.get("roles").getAsJsonArray().size()); + user1Roles = TestMultitenancyAPIHelper.getUserRoles(t1, user1.getSupertokensUserId(), process.getProcess()); + assertEquals(0, user1Roles.get("roles").getAsJsonArray().size()); + + JsonObject user2Roles = TestMultitenancyAPIHelper.getUserRoles(t0, user2.getSupertokensUserId(), process.getProcess()); + assertEquals(0, user2Roles.get("roles").getAsJsonArray().size()); + user2Roles = TestMultitenancyAPIHelper.getUserRoles(t1, user2.getSupertokensUserId(), process.getProcess()); + assertEquals(0, user2Roles.get("roles").getAsJsonArray().size()); + } } } From 83b802cf45f953df7587d32973a7331bacd9049a Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Mon, 4 Mar 2024 14:55:15 +0530 Subject: [PATCH 22/31] fix: email verification tests --- .../api/TestMultitenancyAPIHelper.java | 38 +++++++ .../api/TestWithNonAuthRecipes.java | 107 ++++++++++++++++++ 2 files changed, 145 insertions(+) diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java b/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java index d31944059..d5268a353 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java @@ -20,6 +20,7 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.ThirdPartyConfig; import io.supertokens.test.httpRequest.HttpRequestForTesting; @@ -517,4 +518,41 @@ public static void deleteRole(TenantIdentifier tenantIdentifier, String role, Ma assertEquals(2, response.entrySet().size()); assertEquals("OK", response.get("status").getAsString()); } + + public static void verifyEmail(TenantIdentifier tenantIdentifier, String userId, String email, Main main) + throws HttpResponseException, IOException { + JsonObject requestBody = new JsonObject(); + requestBody.addProperty("userId", userId); + requestBody.addProperty("email", email); + + JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(tenantIdentifier,"/recipe/user/email/verify/token"), + requestBody, 1000, 1000, null, + WebserverAPI.getLatestCDIVersion().get(), "emailverification"); + + assertEquals(response.entrySet().size(), 2); + assertEquals(response.get("status").getAsString(), "OK"); + + JsonObject verifyResponseBody = new JsonObject(); + verifyResponseBody.addProperty("method", "token"); + verifyResponseBody.addProperty("token", response.get("token").getAsString()); + + JsonObject response2 = HttpRequestForTesting.sendJsonPOSTRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/user/email/verify"), verifyResponseBody, 1000, 1000, null, + WebserverAPI.getLatestCDIVersion().get(), "emailverification"); + + assertEquals(response2.entrySet().size(), 3); + assertEquals(response2.get("status").getAsString(), "OK"); + } + + public static void unverifyEmail(TenantIdentifier tenantIdentifier, String userId, String email, Main main) + throws HttpResponseException, IOException { + JsonObject body = new JsonObject(); + body.addProperty("userId", userId); + body.addProperty("email", email); + + HttpRequestForTesting.sendJsonPOSTRequest(main, "", + HttpRequestForTesting.getMultitenantUrl(tenantIdentifier,"/recipe/user/email/verify/remove"), body, 1000, 1000, null, + WebserverAPI.getLatestCDIVersion().get(), RECIPE_ID.EMAIL_VERIFICATION.toString()); + } } diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java b/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java index 7e1a67d7f..84a93064d 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestWithNonAuthRecipes.java @@ -27,6 +27,7 @@ import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; +import io.supertokens.pluginInterface.emailverification.sqlStorage.EmailVerificationSQLStorage; import io.supertokens.pluginInterface.exceptions.InvalidConfigException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; @@ -188,6 +189,15 @@ public void testThatRoleIsStoredInPublicTenantAndUserRoleMappingInTheUserTenantS UserIdMapping.populateExternalUserIdForUsers(t0Storage, new AuthRecipeUserInfo[]{user1}); UserIdMapping.populateExternalUserIdForUsers(t1Storage, new AuthRecipeUserInfo[]{user2}); + { + // Check that get user by ID works fine + JsonObject jsonUser1 = TestMultitenancyAPIHelper.getUserById(t0, user1.getSupertokensUserId(), process.getProcess()); + assertEquals(user1.toJson(), jsonUser1.get("user").getAsJsonObject()); + + JsonObject jsonUser2 = TestMultitenancyAPIHelper.getUserById(t0, user2.getSupertokensUserId(), process.getProcess()); + assertEquals(user2.toJson(), jsonUser2.get("user").getAsJsonObject()); + } + TestMultitenancyAPIHelper.createRole(t0, "role1", process.getProcess()); try { @@ -201,6 +211,15 @@ public void testThatRoleIsStoredInPublicTenantAndUserRoleMappingInTheUserTenantS TestMultitenancyAPIHelper.addRoleToUser(t0, user1.getSupertokensUserId(), "role1", process.getProcess()); TestMultitenancyAPIHelper.addRoleToUser(t1, user2.getSupertokensUserId(), "role2", process.getProcess()); + { + // Check that get user by ID works fine + JsonObject jsonUser1 = TestMultitenancyAPIHelper.getUserById(t0, user1.getSupertokensUserId(), process.getProcess()); + assertEquals(user1.toJson(), jsonUser1.get("user").getAsJsonObject()); + + JsonObject jsonUser2 = TestMultitenancyAPIHelper.getUserById(t0, user2.getSupertokensUserId(), process.getProcess()); + assertEquals(user2.toJson(), jsonUser2.get("user").getAsJsonObject()); + } + { JsonObject user1Roles = TestMultitenancyAPIHelper.getUserRoles(t0, user1.getSupertokensUserId(), process.getProcess()); assertEquals(1, user1Roles.get("roles").getAsJsonArray().size()); @@ -234,5 +253,93 @@ public void testThatRoleIsStoredInPublicTenantAndUserRoleMappingInTheUserTenantS user2Roles = TestMultitenancyAPIHelper.getUserRoles(t1, user2.getSupertokensUserId(), process.getProcess()); assertEquals(0, user2Roles.get("roles").getAsJsonArray().size()); } + + { + // Check that get user by ID works fine + JsonObject jsonUser1 = TestMultitenancyAPIHelper.getUserById(t0, user1.getSupertokensUserId(), process.getProcess()); + assertEquals(user1.toJson(), jsonUser1.get("user").getAsJsonObject()); + + JsonObject jsonUser2 = TestMultitenancyAPIHelper.getUserById(t0, user2.getSupertokensUserId(), process.getProcess()); + assertEquals(user2.toJson(), jsonUser2.get("user").getAsJsonObject()); + } + } + + @Test + public void testEmailVerificationWithUsersOnDifferentTenantStorages() throws Exception { + TenantIdentifier t0 = new TenantIdentifier(null, null, null); + Storage t0Storage = (StorageLayer.getStorage(t0, process.getProcess())); + + TenantIdentifier t1 = new TenantIdentifier(null, null, "t1"); + Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); + + // Create users + AuthRecipeUserInfo user1 = EmailPassword.signUp(t0, t0Storage, process.getProcess(), "test@example.com", "password123"); + AuthRecipeUserInfo user2 = EmailPassword.signUp(t1, t1Storage, process.getProcess(), "test@example.com", "password123"); + + UserIdMapping.populateExternalUserIdForUsers(t0Storage, new AuthRecipeUserInfo[]{user1}); + UserIdMapping.populateExternalUserIdForUsers(t1Storage, new AuthRecipeUserInfo[]{user2}); + + // Check that get user by ID works fine + JsonObject jsonUser1 = TestMultitenancyAPIHelper.getUserById(t0, user1.getSupertokensUserId(), process.getProcess()); + assertEquals(user1.toJson(), jsonUser1.get("user").getAsJsonObject()); + + JsonObject jsonUser2 = TestMultitenancyAPIHelper.getUserById(t0, user2.getSupertokensUserId(), process.getProcess()); + assertEquals(user2.toJson(), jsonUser2.get("user").getAsJsonObject()); + + { + // Add email verification for user2 using t1 and ensure get user works fine + TestMultitenancyAPIHelper.verifyEmail(t1, user2.getSupertokensUserId(), "test@example.com", process.getProcess()); + + jsonUser2 = TestMultitenancyAPIHelper.getUserById(t0, user2.getSupertokensUserId(), process.getProcess()); + user2.loginMethods[0].setVerified(); + assertEquals(user2.toJson(), jsonUser2.get("user").getAsJsonObject()); + + try { + TestMultitenancyAPIHelper.getUserById(t1, user2.getSupertokensUserId(), + process.getProcess()); + fail(); + } catch (HttpResponseException e) { + assertEquals(403, e.statusCode); + } + } + + { + // Add email verification for user1 using t0 and ensure get user works fine + TestMultitenancyAPIHelper.verifyEmail(t0, user1.getSupertokensUserId(), "test@example.com", process.getProcess()); + + jsonUser1 = TestMultitenancyAPIHelper.getUserById(t0, user1.getSupertokensUserId(), process.getProcess()); + user1.loginMethods[0].setVerified(); + assertEquals(user1.toJson(), jsonUser1.get("user").getAsJsonObject()); + + try { + TestMultitenancyAPIHelper.getUserById(t1, user1.getSupertokensUserId(), process.getProcess()); + fail(); + } catch (HttpResponseException e) { + assertEquals(403, e.statusCode); + } + } + + EmailVerificationSQLStorage t0EvStorage = StorageUtils.getEmailVerificationStorage(t0Storage); + EmailVerificationSQLStorage t1EvStorage = StorageUtils.getEmailVerificationStorage(t1Storage); + + // Ensure that the ev is saved in the correct storage + assertTrue(t0EvStorage.isEmailVerified(t0.toAppIdentifier(), user1.getSupertokensUserId(), "test@example.com")); + assertTrue(t1EvStorage.isEmailVerified(t0.toAppIdentifier(), user2.getSupertokensUserId(), "test@example.com")); + + // Ensure that the metadata is not stored in the wrong storage + assertFalse(t0EvStorage.isEmailVerified(t0.toAppIdentifier(), user2.getSupertokensUserId(), "test@example.com")); // ensure t0 storage does not have user2's ev + assertFalse(t1EvStorage.isEmailVerified(t0.toAppIdentifier(), user1.getSupertokensUserId(), "test@example.com")); // ensure t1 storage does not have user1's ev + + // Try unverify + try { + TestMultitenancyAPIHelper.unverifyEmail(t1, user1.getSupertokensUserId(), "test@example.com", process.getProcess()); + fail(); + } catch (HttpResponseException e) { + assertEquals(403, e.statusCode); + } + TestMultitenancyAPIHelper.unverifyEmail(t0, user1.getSupertokensUserId(), "test@example.com", process.getProcess()); + TestMultitenancyAPIHelper.unverifyEmail(t0, user2.getSupertokensUserId(), "test@example.com", process.getProcess()); + assertFalse(t1EvStorage.isEmailVerified(t0.toAppIdentifier(), user2.getSupertokensUserId(), "test@example.com")); // ensure t1 storage does not have user2's ev + assertFalse(t0EvStorage.isEmailVerified(t0.toAppIdentifier(), user1.getSupertokensUserId(), "test@example.com")); // ensure t0 storage does not have user1's ev } } From 3d93ab53a83e4b76bc4e2255811407ddf476bd40 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Mon, 4 Mar 2024 15:48:48 +0530 Subject: [PATCH 23/31] fix: user role deletion --- .../io/supertokens/userroles/UserRoles.java | 9 ++++++ .../test/accountlinking/api/SessionTests.java | 1 - ...mailVerificationWithUserIdMappingTest.java | 32 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/supertokens/userroles/UserRoles.java b/src/main/java/io/supertokens/userroles/UserRoles.java index 5d69d6e95..1bb1352f1 100644 --- a/src/main/java/io/supertokens/userroles/UserRoles.java +++ b/src/main/java/io/supertokens/userroles/UserRoles.java @@ -288,13 +288,22 @@ public static String[] getRolesThatHavePermission(Main main, public static boolean deleteRole(Main main, AppIdentifier appIdentifier, String role) throws StorageQueryException, TenantOrAppNotFoundException { + Storage appStorage = StorageLayer.getStorage(appIdentifier.getAsPublicTenantIdentifier(), main); Storage[] storages = StorageLayer.getStoragesForApp(main, appIdentifier); boolean deletedRole = false; for (Storage storage : storages) { + if (storage.getUserPoolId().equals(appStorage.getUserPoolId())) { + continue; // we want to delete this in the end + } UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); deletedRole = userRolesStorage.deleteRole(appIdentifier, role) || deletedRole; } + // Delete the role from the public tenant storage in the end so that the user + // never sees a role for user that has been deleted while the deletion is in progress + UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(appStorage); + deletedRole = userRolesStorage.deleteRole(appIdentifier, role) || deletedRole; + return deletedRole; } diff --git a/src/test/java/io/supertokens/test/accountlinking/api/SessionTests.java b/src/test/java/io/supertokens/test/accountlinking/api/SessionTests.java index 52d03a87d..ddac8d03e 100644 --- a/src/test/java/io/supertokens/test/accountlinking/api/SessionTests.java +++ b/src/test/java/io/supertokens/test/accountlinking/api/SessionTests.java @@ -186,7 +186,6 @@ public void testRevokeSessionsForUserWithAndWithoutIncludingAllLinkedAccounts() user2.getSupertokensUserId(), new JsonObject(), new JsonObject()); - revokeSessionsForUser(process.getProcess(), user1.getSupertokensUserId(), true); try { diff --git a/src/test/java/io/supertokens/test/emailverification/EmailVerificationWithUserIdMappingTest.java b/src/test/java/io/supertokens/test/emailverification/EmailVerificationWithUserIdMappingTest.java index 66b2926e0..94c35f015 100644 --- a/src/test/java/io/supertokens/test/emailverification/EmailVerificationWithUserIdMappingTest.java +++ b/src/test/java/io/supertokens/test/emailverification/EmailVerificationWithUserIdMappingTest.java @@ -144,6 +144,38 @@ public void testUserIdMappingCreationAfterEmailVerificationForPasswordlessUser() AuthRecipeUserInfo userInfo = AuthRecipe.getUserById(process.getProcess(), user.getSupertokensUserId()); assertTrue(userInfo.loginMethods[0].verified); + assertTrue(EmailVerification.isEmailVerified(process.getProcess(), "euid", "test@example.com")); + assertFalse(EmailVerification.isEmailVerified(process.getProcess(), user.getSupertokensUserId(), "test@example.com")); + + process.kill(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); + } + + @Test + public void testUserIdMappingCreationAfterEmailVerificationForPasswordlessUserWithOlderCDIBehaviour() throws Exception { + String[] args = {"../"}; + + TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + Passwordless.CreateCodeResponse code = Passwordless.createCode(process.getProcess(), "test@example.com", null, + null, null); + AuthRecipeUserInfo user = Passwordless.consumeCode(process.getProcess(), code.deviceId, code.deviceIdHash, + code.userInputCode, null, true).user; + + // create mapping + // this should not be allowed + try { + UserIdMapping.createUserIdMapping(process.getProcess(), user.getSupertokensUserId(), "euid", null, false, false); + fail(); + } catch (Exception e) { + assert e.getMessage().contains("UserId is already in use in EmailVerification recipe"); + } + process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); } From d7cbcfa1baab7dc5e6918300e034e100ecdfc92a Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Mon, 4 Mar 2024 16:18:26 +0530 Subject: [PATCH 24/31] fix: user roles --- .../java/io/supertokens/inmemorydb/Start.java | 15 ++++++- .../inmemorydb/queries/UserRolesQueries.java | 42 +++++++++---------- .../io/supertokens/userroles/UserRoles.java | 29 ++++++++++--- .../test/userRoles/UserRolesStorageTest.java | 35 +++++++++++++--- 4 files changed, 85 insertions(+), 36 deletions(-) diff --git a/src/main/java/io/supertokens/inmemorydb/Start.java b/src/main/java/io/supertokens/inmemorydb/Start.java index 2dbcaaf54..166775f6c 100644 --- a/src/main/java/io/supertokens/inmemorydb/Start.java +++ b/src/main/java/io/supertokens/inmemorydb/Start.java @@ -1937,9 +1937,20 @@ public String[] getRolesThatHavePermission(AppIdentifier appIdentifier, String p } @Override - public boolean deleteRole(AppIdentifier appIdentifier, String role) throws StorageQueryException { + public boolean deleteRole_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String role) throws StorageQueryException { try { - return UserRolesQueries.deleteRole(this, appIdentifier, role); + return UserRolesQueries.deleteRole_Transaction(this, (Connection) con.getConnection(), appIdentifier, role); + } catch (SQLException e) { + throw new StorageQueryException(e); + } + } + + @Override + public boolean deleteAllUserRoleAssociationsForRole_Transaction(TransactionConnection con, + AppIdentifier appIdentifier, String role) + throws StorageQueryException { + try { + return UserRolesQueries.deleteAllUserRoleAssociationsForRole_Transaction(this, (Connection) con.getConnection(), appIdentifier, role); } catch (SQLException e) { throw new StorageQueryException(e); } diff --git a/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java index e9eb86980..144586657 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java @@ -111,29 +111,15 @@ public static void addPermissionToRoleOrDoNothingIfExists_Transaction(Start star }); } - public static boolean deleteRole(Start start, AppIdentifier appIdentifier, String role) throws SQLException, StorageQueryException { - - try { - return start.startTransaction(con -> { - // Row lock must be taken to delete the role, otherwise the table may be locked for delete - Connection sqlCon = (Connection) con.getConnection(); - ((ConnectionWithLocks) sqlCon).lock(appIdentifier.getAppId() + "~" + role + Config.getConfig(start).getRolesTable()); - - String QUERY = "DELETE FROM " + getConfig(start).getRolesTable() - + " WHERE app_id = ? AND role = ? ;"; - - try { - return update(sqlCon, QUERY, pst -> { - pst.setString(1, appIdentifier.getAppId()); - pst.setString(2, role); - }) == 1; - } catch (SQLException e) { - throw new StorageTransactionLogicException(e); - } - }); - } catch (StorageTransactionLogicException e) { - throw new StorageQueryException(e.actualException); - } + public static boolean deleteRole_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, + String role) throws SQLException, StorageQueryException { + + String QUERY = "DELETE FROM " + getConfig(start).getRolesTable() + + " WHERE app_id = ? AND role = ? ;"; + return update(sqlCon, QUERY, pst -> { + pst.setString(1, appIdentifier.getAppId()); + pst.setString(2, role); + }) == 1; } public static boolean doesRoleExist(Start start, AppIdentifier appIdentifier, String role) @@ -339,4 +325,14 @@ public static int deleteAllRolesForUser_Transaction(Connection con, Start start, pst.setString(2, userId); }); } + + public static boolean deleteAllUserRoleAssociationsForRole_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, String role) + throws SQLException, StorageQueryException { + String QUERY = "DELETE FROM " + getConfig(start).getRolesTable() + + " WHERE app_id = ? AND role = ? ;"; + return update(sqlCon, QUERY, pst -> { + pst.setString(1, appIdentifier.getAppId()); + pst.setString(2, role); + }) >= 1; + } } diff --git a/src/main/java/io/supertokens/userroles/UserRoles.java b/src/main/java/io/supertokens/userroles/UserRoles.java index 1bb1352f1..b22048766 100644 --- a/src/main/java/io/supertokens/userroles/UserRoles.java +++ b/src/main/java/io/supertokens/userroles/UserRoles.java @@ -292,17 +292,36 @@ public static boolean deleteRole(Main main, AppIdentifier appIdentifier, String Storage[] storages = StorageLayer.getStoragesForApp(main, appIdentifier); boolean deletedRole = false; for (Storage storage : storages) { - if (storage.getUserPoolId().equals(appStorage.getUserPoolId())) { - continue; // we want to delete this in the end - } UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); - deletedRole = userRolesStorage.deleteRole(appIdentifier, role) || deletedRole; + + try { + deletedRole = userRolesStorage.startTransaction(con -> { + return userRolesStorage.deleteAllUserRoleAssociationsForRole_Transaction(con, appIdentifier, role); + }) || deletedRole; + } catch (StorageTransactionLogicException e) { + if (e.actualException instanceof StorageQueryException) { + throw (StorageQueryException) e.actualException; + } + throw new IllegalStateException(e); + } } // Delete the role from the public tenant storage in the end so that the user // never sees a role for user that has been deleted while the deletion is in progress UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(appStorage); - deletedRole = userRolesStorage.deleteRole(appIdentifier, role) || deletedRole; + try { + deletedRole = userRolesStorage.startTransaction(con -> { + boolean deleted = false; + deleted = userRolesStorage.deleteAllUserRoleAssociationsForRole_Transaction(con, appIdentifier, role) || deleted; + deleted = userRolesStorage.deleteRole_Transaction(con, appIdentifier, role) || deleted; + return deleted; + }) || deletedRole; + } catch (StorageTransactionLogicException e) { + if (e.actualException instanceof StorageQueryException) { + throw (StorageQueryException) e.actualException; + } + throw new IllegalStateException(e); + } return deletedRole; } diff --git a/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java b/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java index cf4c5dbde..9d46c2694 100644 --- a/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java +++ b/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java @@ -18,6 +18,7 @@ import io.supertokens.ProcessState; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; @@ -118,9 +119,15 @@ public void testDeletingARoleWhileItIsBeingRemovedFromAUser() throws Exception { } // delete the role try { - boolean wasRoleDeleted = storage.deleteRole(new AppIdentifier(null, null), role); + UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); + boolean wasRoleDeleted = userRolesStorage.startTransaction(con -> { + boolean wasDeleted = storage.deleteAllUserRoleAssociationsForRole_Transaction(con, new AppIdentifier(null, null), role); + wasDeleted = storage.deleteRole_Transaction(con, new AppIdentifier(null, null), role) || wasDeleted; + return wasDeleted; + }); r2_success.set(wasRoleDeleted); - } catch (StorageQueryException e) { + } catch (StorageQueryException | StorageTransactionLogicException e) { + throw new RuntimeException(e); // should not come here } }; @@ -225,10 +232,16 @@ public void testCreatingAndAddingAPermissionToARoleInTransactionAndDeletingRole( } // delete the newly created role try { - storage.deleteRole(new AppIdentifier(null, null), role); + UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); + boolean wasRoleDeleted = userRolesStorage.startTransaction(con -> { + boolean wasDeleted = storage.deleteAllUserRoleAssociationsForRole_Transaction(con, new AppIdentifier(null, null), role); + wasDeleted = storage.deleteRole_Transaction(con, new AppIdentifier(null, null), role) || wasDeleted; + return wasDeleted; + }); r2_success.set(true); - } catch (StorageQueryException e) { + } catch (StorageQueryException | StorageTransactionLogicException e) { // should not come here + throw new RuntimeException(e); } }; @@ -826,7 +839,12 @@ public void testDeletingRoleResponses() throws Exception { UserRoles.createNewRoleOrModifyItsPermissions(process.main, role, null); // delete role - boolean didRoleExist = storage.deleteRole(new AppIdentifier(null, null), role); + UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); + boolean didRoleExist = userRolesStorage.startTransaction(con -> { + boolean wasDeleted = storage.deleteAllUserRoleAssociationsForRole_Transaction(con, new AppIdentifier(null, null), role); + wasDeleted = storage.deleteRole_Transaction(con, new AppIdentifier(null, null), role) || wasDeleted; + return wasDeleted; + }); assertTrue(didRoleExist); // check that role doesnt exist @@ -835,7 +853,12 @@ public void testDeletingRoleResponses() throws Exception { { // delete a role which doesnt exist - boolean didRoleExist = storage.deleteRole(new AppIdentifier(null, null), role); + UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); + boolean didRoleExist = userRolesStorage.startTransaction(con -> { + boolean wasDeleted = storage.deleteAllUserRoleAssociationsForRole_Transaction(con, new AppIdentifier(null, null), role); + wasDeleted = storage.deleteRole_Transaction(con, new AppIdentifier(null, null), role) || wasDeleted; + return wasDeleted; + }); assertFalse(didRoleExist); } From fb2234c83a9b184424161adea8628147c1d3aaa3 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Mon, 4 Mar 2024 16:57:12 +0530 Subject: [PATCH 25/31] fix: user roles --- .../java/io/supertokens/inmemorydb/Start.java | 9 ++--- .../inmemorydb/queries/UserRolesQueries.java | 33 +++++++++++----- .../io/supertokens/userroles/UserRoles.java | 28 ++----------- .../test/userRoles/UserRolesStorageTest.java | 39 +++++-------------- 4 files changed, 41 insertions(+), 68 deletions(-) diff --git a/src/main/java/io/supertokens/inmemorydb/Start.java b/src/main/java/io/supertokens/inmemorydb/Start.java index 166775f6c..5d518faa9 100644 --- a/src/main/java/io/supertokens/inmemorydb/Start.java +++ b/src/main/java/io/supertokens/inmemorydb/Start.java @@ -1937,20 +1937,19 @@ public String[] getRolesThatHavePermission(AppIdentifier appIdentifier, String p } @Override - public boolean deleteRole_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String role) throws StorageQueryException { + public boolean deleteRole(AppIdentifier appIdentifier, String role) throws StorageQueryException { try { - return UserRolesQueries.deleteRole_Transaction(this, (Connection) con.getConnection(), appIdentifier, role); + return UserRolesQueries.deleteRole(this, appIdentifier, role); } catch (SQLException e) { throw new StorageQueryException(e); } } @Override - public boolean deleteAllUserRoleAssociationsForRole_Transaction(TransactionConnection con, - AppIdentifier appIdentifier, String role) + public boolean deleteAllUserRoleAssociationsForRole(AppIdentifier appIdentifier, String role) throws StorageQueryException { try { - return UserRolesQueries.deleteAllUserRoleAssociationsForRole_Transaction(this, (Connection) con.getConnection(), appIdentifier, role); + return UserRolesQueries.deleteAllUserRoleAssociationsForRole(this, appIdentifier, role); } catch (SQLException e) { throw new StorageQueryException(e); } diff --git a/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java index 144586657..94cb60de7 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java @@ -111,15 +111,30 @@ public static void addPermissionToRoleOrDoNothingIfExists_Transaction(Start star }); } - public static boolean deleteRole_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, + public static boolean deleteRole(Start start, AppIdentifier appIdentifier, String role) throws SQLException, StorageQueryException { - String QUERY = "DELETE FROM " + getConfig(start).getRolesTable() - + " WHERE app_id = ? AND role = ? ;"; - return update(sqlCon, QUERY, pst -> { - pst.setString(1, appIdentifier.getAppId()); - pst.setString(2, role); - }) == 1; + try { + return start.startTransaction(con -> { + // Row lock must be taken to delete the role, otherwise the table may be locked for delete + Connection sqlCon = (Connection) con.getConnection(); + ((ConnectionWithLocks) sqlCon).lock(appIdentifier.getAppId() + "~" + role + Config.getConfig(start).getRolesTable()); + + String QUERY = "DELETE FROM " + getConfig(start).getRolesTable() + + " WHERE app_id = ? AND role = ? ;"; + + try { + return update(sqlCon, QUERY, pst -> { + pst.setString(1, appIdentifier.getAppId()); + pst.setString(2, role); + }) == 1; + } catch (SQLException e) { + throw new StorageTransactionLogicException(e); + } + }); + } catch (StorageTransactionLogicException e) { + throw new StorageQueryException(e.actualException); + } } public static boolean doesRoleExist(Start start, AppIdentifier appIdentifier, String role) @@ -326,11 +341,11 @@ public static int deleteAllRolesForUser_Transaction(Connection con, Start start, }); } - public static boolean deleteAllUserRoleAssociationsForRole_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, String role) + public static boolean deleteAllUserRoleAssociationsForRole(Start start, AppIdentifier appIdentifier, String role) throws SQLException, StorageQueryException { String QUERY = "DELETE FROM " + getConfig(start).getRolesTable() + " WHERE app_id = ? AND role = ? ;"; - return update(sqlCon, QUERY, pst -> { + return update(start, QUERY, pst -> { pst.setString(1, appIdentifier.getAppId()); pst.setString(2, role); }) >= 1; diff --git a/src/main/java/io/supertokens/userroles/UserRoles.java b/src/main/java/io/supertokens/userroles/UserRoles.java index b22048766..5b1f85553 100644 --- a/src/main/java/io/supertokens/userroles/UserRoles.java +++ b/src/main/java/io/supertokens/userroles/UserRoles.java @@ -288,40 +288,18 @@ public static String[] getRolesThatHavePermission(Main main, public static boolean deleteRole(Main main, AppIdentifier appIdentifier, String role) throws StorageQueryException, TenantOrAppNotFoundException { - Storage appStorage = StorageLayer.getStorage(appIdentifier.getAsPublicTenantIdentifier(), main); Storage[] storages = StorageLayer.getStoragesForApp(main, appIdentifier); boolean deletedRole = false; for (Storage storage : storages) { UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); - - try { - deletedRole = userRolesStorage.startTransaction(con -> { - return userRolesStorage.deleteAllUserRoleAssociationsForRole_Transaction(con, appIdentifier, role); - }) || deletedRole; - } catch (StorageTransactionLogicException e) { - if (e.actualException instanceof StorageQueryException) { - throw (StorageQueryException) e.actualException; - } - throw new IllegalStateException(e); - } + deletedRole = userRolesStorage.deleteAllUserRoleAssociationsForRole(appIdentifier, role) || deletedRole; } // Delete the role from the public tenant storage in the end so that the user // never sees a role for user that has been deleted while the deletion is in progress + Storage appStorage = StorageLayer.getStorage(appIdentifier.getAsPublicTenantIdentifier(), main); UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(appStorage); - try { - deletedRole = userRolesStorage.startTransaction(con -> { - boolean deleted = false; - deleted = userRolesStorage.deleteAllUserRoleAssociationsForRole_Transaction(con, appIdentifier, role) || deleted; - deleted = userRolesStorage.deleteRole_Transaction(con, appIdentifier, role) || deleted; - return deleted; - }) || deletedRole; - } catch (StorageTransactionLogicException e) { - if (e.actualException instanceof StorageQueryException) { - throw (StorageQueryException) e.actualException; - } - throw new IllegalStateException(e); - } + deletedRole = userRolesStorage.deleteRole(appIdentifier, role) || deletedRole; return deletedRole; } diff --git a/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java b/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java index 9d46c2694..c6ad8986d 100644 --- a/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java +++ b/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java @@ -119,15 +119,10 @@ public void testDeletingARoleWhileItIsBeingRemovedFromAUser() throws Exception { } // delete the role try { - UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); - boolean wasRoleDeleted = userRolesStorage.startTransaction(con -> { - boolean wasDeleted = storage.deleteAllUserRoleAssociationsForRole_Transaction(con, new AppIdentifier(null, null), role); - wasDeleted = storage.deleteRole_Transaction(con, new AppIdentifier(null, null), role) || wasDeleted; - return wasDeleted; - }); + boolean wasRoleDeleted = storage.deleteAllUserRoleAssociationsForRole(new AppIdentifier(null, null), role); + wasRoleDeleted = storage.deleteRole(new AppIdentifier(null, null), role) || wasRoleDeleted; r2_success.set(wasRoleDeleted); - } catch (StorageQueryException | StorageTransactionLogicException e) { - throw new RuntimeException(e); + } catch (StorageQueryException e) { // should not come here } }; @@ -232,16 +227,11 @@ public void testCreatingAndAddingAPermissionToARoleInTransactionAndDeletingRole( } // delete the newly created role try { - UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); - boolean wasRoleDeleted = userRolesStorage.startTransaction(con -> { - boolean wasDeleted = storage.deleteAllUserRoleAssociationsForRole_Transaction(con, new AppIdentifier(null, null), role); - wasDeleted = storage.deleteRole_Transaction(con, new AppIdentifier(null, null), role) || wasDeleted; - return wasDeleted; - }); + boolean wasRoleDeleted = storage.deleteAllUserRoleAssociationsForRole(new AppIdentifier(null, null), role); + wasRoleDeleted = storage.deleteRole(new AppIdentifier(null, null), role) || wasRoleDeleted; r2_success.set(true); - } catch (StorageQueryException | StorageTransactionLogicException e) { + } catch (StorageQueryException e) { // should not come here - throw new RuntimeException(e); } }; @@ -839,12 +829,8 @@ public void testDeletingRoleResponses() throws Exception { UserRoles.createNewRoleOrModifyItsPermissions(process.main, role, null); // delete role - UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); - boolean didRoleExist = userRolesStorage.startTransaction(con -> { - boolean wasDeleted = storage.deleteAllUserRoleAssociationsForRole_Transaction(con, new AppIdentifier(null, null), role); - wasDeleted = storage.deleteRole_Transaction(con, new AppIdentifier(null, null), role) || wasDeleted; - return wasDeleted; - }); + boolean didRoleExist = storage.deleteAllUserRoleAssociationsForRole(new AppIdentifier(null, null), role); + assertTrue(didRoleExist = storage.deleteRole(new AppIdentifier(null, null), role) || didRoleExist); assertTrue(didRoleExist); // check that role doesnt exist @@ -852,13 +838,8 @@ public void testDeletingRoleResponses() throws Exception { } { // delete a role which doesnt exist - - UserRolesSQLStorage userRolesStorage = StorageUtils.getUserRolesStorage(storage); - boolean didRoleExist = userRolesStorage.startTransaction(con -> { - boolean wasDeleted = storage.deleteAllUserRoleAssociationsForRole_Transaction(con, new AppIdentifier(null, null), role); - wasDeleted = storage.deleteRole_Transaction(con, new AppIdentifier(null, null), role) || wasDeleted; - return wasDeleted; - }); + boolean didRoleExist = storage.deleteAllUserRoleAssociationsForRole(new AppIdentifier(null, null), role); + didRoleExist = storage.deleteRole(new AppIdentifier(null, null), role) || didRoleExist; assertFalse(didRoleExist); } From 8945be140415c2c84aeed959fe3419a18b515379 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Mon, 4 Mar 2024 20:11:25 +0530 Subject: [PATCH 26/31] fix: get tenant identifier refactor --- .../supertokens/webserver/WebserverAPI.java | 26 +- .../CanCreatePrimaryUserAPI.java | 7 +- .../accountlinking/CanLinkAccountsAPI.java | 7 +- .../accountlinking/CreatePrimaryUserAPI.java | 7 +- .../api/accountlinking/LinkAccountsAPI.java | 7 +- .../api/accountlinking/UnlinkAccountAPI.java | 7 +- .../webserver/api/core/ConfigAPI.java | 7 +- .../webserver/api/core/HelloAPI.java | 1 - .../api/core/NotFoundOrHelloAPI.java | 6 +- .../webserver/api/core/UsersAPI.java | 3 +- .../ConsumeResetPasswordAPI.java | 13 +- .../GeneratePasswordResetTokenAPI.java | 5 +- .../api/emailpassword/ResetPasswordAPI.java | 3 +- .../api/emailpassword/SignInAPI.java | 3 +- .../api/emailpassword/SignUpAPI.java | 3 +- .../webserver/api/emailpassword/UserAPI.java | 7 +- .../GenerateEmailVerificationTokenAPI.java | 3 +- .../api/emailverification/VerifyEmailAPI.java | 3 +- .../multitenancy/CreateOrUpdateAppAPI.java | 2 +- .../CreateOrUpdateConnectionUriDomainAPI.java | 2 +- .../CreateOrUpdateTenantOrGetTenantAPI.java | 2 +- .../api/multitenancy/ListAppsAPI.java | 2 +- .../api/multitenancy/RemoveAppAPI.java | 2 +- .../RemoveConnectionUriDomainAPI.java | 2 +- .../api/session/RefreshSessionAPI.java | 13 +- .../api/session/SessionRegenerateAPI.java | 7 +- .../api/session/VerifySessionAPI.java | 9 +- .../webserver/api/totp/VerifyTotpAPI.java | 16 +- .../api/totp/VerifyTotpDeviceAPI.java | 16 +- .../usermetadata/RemoveUserMetadataAPI.java | 4 +- .../api/usermetadata/UserMetadataAPI.java | 6 +- .../api/userroles/RemoveRoleAPI.java | 1 - .../io/supertokens/test/PathRouterTest.java | 260 ++++++++++++------ .../RequestConnectionUriDomainTest.java | 26 +- 34 files changed, 316 insertions(+), 172 deletions(-) diff --git a/src/main/java/io/supertokens/webserver/WebserverAPI.java b/src/main/java/io/supertokens/webserver/WebserverAPI.java index f89a9a2d5..f5702e523 100644 --- a/src/main/java/io/supertokens/webserver/WebserverAPI.java +++ b/src/main/java/io/supertokens/webserver/WebserverAPI.java @@ -34,7 +34,6 @@ import io.supertokens.storageLayer.StorageLayer; import io.supertokens.useridmapping.UserIdType; import io.supertokens.utils.SemVer; -import io.supertokens.webserver.api.useridmapping.UserIdMappingAPI; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.ServletRequest; @@ -84,7 +83,7 @@ public SemVer getLatestCDIVersionForRequest(HttpServletRequest req) throws ServletException, TenantOrAppNotFoundException { SemVer maxCDIVersion = getLatestCDIVersion(); String maxCDIVersionStr = Config.getConfig( - getAppIdentifier(req).getAsPublicTenantIdentifier(), main).getMaxCDIVersion(); + getAppIdentifierWithoutVerifying(req).getAsPublicTenantIdentifier(), main).getMaxCDIVersion(); if (maxCDIVersionStr != null) { maxCDIVersion = new SemVer(maxCDIVersionStr); } @@ -299,20 +298,27 @@ private String getConnectionUriDomain(HttpServletRequest req) throws ServletExce return null; } - protected TenantIdentifier getTenantIdentifier(HttpServletRequest req) throws ServletException { + private TenantIdentifier getTenantIdentifierWithoutVerifying(HttpServletRequest req) throws ServletException { return new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), this.getTenantId(req)); } - protected TenantIdentifier ensureTenantExistsAndGetTenantIdentifier(HttpServletRequest req) + protected TenantIdentifier getTenantIdentifier(HttpServletRequest req) throws ServletException, TenantOrAppNotFoundException { - getTenantStorage(req); + getTenantStorage(req); // ensure the tenant exists return new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), this.getTenantId(req)); } - protected AppIdentifier getAppIdentifier(HttpServletRequest req) throws ServletException { + private AppIdentifier getAppIdentifierWithoutVerifying(HttpServletRequest req) throws ServletException { return new AppIdentifier(this.getConnectionUriDomain(req), this.getAppId(req)); } + protected AppIdentifier getAppIdentifier(HttpServletRequest req) + throws ServletException, TenantOrAppNotFoundException { + AppIdentifier appIdentifier = getAppIdentifierWithoutVerifying(req); + StorageLayer.getStorage(appIdentifier.getAsPublicTenantIdentifier(), main); // ensure the app exists + return appIdentifier; + } + protected Storage getTenantStorage(HttpServletRequest req) throws TenantOrAppNotFoundException, ServletException { TenantIdentifier tenantIdentifier = new TenantIdentifier(this.getConnectionUriDomain(req), this.getAppId(req), @@ -326,7 +332,7 @@ protected Storage[] enforcePublicTenantAndGetAllStoragesForApp(HttpServletReques throw new BadPermissionException("Only public tenantId can call this app specific API"); } - AppIdentifier appIdentifier = getAppIdentifier(req); + AppIdentifier appIdentifier = getAppIdentifierWithoutVerifying(req); return StorageLayer.getStoragesForApp(main, appIdentifier); } @@ -358,7 +364,7 @@ protected StorageAndUserIdMapping enforcePublicTenantAndGetStorageAndUserIdMappi BadPermissionException { // This function uses storage of the tenant from which the request came from as a priorityStorage // while searching for the user across all storages for the app - AppIdentifier appIdentifier = getAppIdentifier(req); + AppIdentifier appIdentifier = getAppIdentifierWithoutVerifying(req); Storage[] storages = enforcePublicTenantAndGetAllStoragesForApp(req); try { return StorageLayer.findStorageAndUserIdMappingForUser( @@ -374,7 +380,7 @@ protected StorageAndUserIdMapping enforcePublicTenantAndGetStorageAndUserIdMappi protected boolean checkIPAccess(HttpServletRequest req, HttpServletResponse resp) throws TenantOrAppNotFoundException, ServletException, IOException { - CoreConfig config = Config.getConfig(getTenantIdentifier(req), main); + CoreConfig config = Config.getConfig(getTenantIdentifierWithoutVerifying(req), main); String allow = config.getIpAllowRegex(); String deny = config.getIpDenyRegex(); if (allow == null && deny == null) { @@ -416,7 +422,7 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws TenantIdentifier tenantIdentifier = null; try { - tenantIdentifier = getTenantIdentifier(req); + tenantIdentifier = getTenantIdentifierWithoutVerifying(req); if (!this.checkIPAccess(req, resp)) { // IP access denied and the filter has already sent the response diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java index 3f9d12a12..a72f0d6d3 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/CanCreatePrimaryUserAPI.java @@ -55,7 +55,12 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO // API is app specific String inputRecipeUserId = InputParser.getQueryParamOrThrowError(req, "recipeUserId", false); - AppIdentifier appIdentifier = this.getAppIdentifier(req); + AppIdentifier appIdentifier = null; + try { + appIdentifier = this.getAppIdentifier(req); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } Storage storage = null; try { diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java index 9d2196eac..75e416eb9 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/CanLinkAccountsAPI.java @@ -58,7 +58,12 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO String inputRecipeUserId = InputParser.getQueryParamOrThrowError(req, "recipeUserId", false); String inputPrimaryUserId = InputParser.getQueryParamOrThrowError(req, "primaryUserId", false); - AppIdentifier appIdentifier = this.getAppIdentifier(req); + AppIdentifier appIdentifier = null; + try { + appIdentifier = this.getAppIdentifier(req); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } Storage primaryUserIdStorage = null; Storage recipeUserIdStorage = null; try { diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java index ee4e13b30..d275b2aa1 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/CreatePrimaryUserAPI.java @@ -57,7 +57,12 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String inputRecipeUserId = InputParser.parseStringOrThrowError(input, "recipeUserId", false); - AppIdentifier appIdentifier = this.getAppIdentifier(req); + AppIdentifier appIdentifier = null; + try { + appIdentifier = this.getAppIdentifier(req); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } Storage storage = null; try { diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java index ca61f8562..0fa6fbb7f 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/LinkAccountsAPI.java @@ -60,7 +60,12 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String inputRecipeUserId = InputParser.parseStringOrThrowError(input, "recipeUserId", false); String inputPrimaryUserId = InputParser.parseStringOrThrowError(input, "primaryUserId", false); - AppIdentifier appIdentifier = getAppIdentifier(req); + AppIdentifier appIdentifier = null; + try { + appIdentifier = getAppIdentifier(req); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } Storage primaryUserIdStorage = null; Storage recipeUserIdStorage = null; try { diff --git a/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java b/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java index 22ae386ef..67d214646 100644 --- a/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java +++ b/src/main/java/io/supertokens/webserver/api/accountlinking/UnlinkAccountAPI.java @@ -54,7 +54,12 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String inputRecipeUserId = InputParser.parseStringOrThrowError(input, "recipeUserId", false); - AppIdentifier appIdentifier = getAppIdentifier(req); + AppIdentifier appIdentifier = null; + try { + appIdentifier = getAppIdentifier(req); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } Storage storage = null; try { String userId = inputRecipeUserId; diff --git a/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java b/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java index 7a8f7a6f2..6c9abfe14 100644 --- a/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/ConfigAPI.java @@ -52,7 +52,12 @@ protected boolean checkAPIKey(HttpServletRequest req) { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { String pid = InputParser.getQueryParamOrThrowError(req, "pid", false); - TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + TenantIdentifier tenantIdentifier = null; + try { + tenantIdentifier = getTenantIdentifier(req); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } if (!tenantIdentifier.equals(new TenantIdentifier(null, null, null))) { throw new ServletException(new BadPermissionException("you can call this only from the base connection uri domain, public app and tenant")); } diff --git a/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java b/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java index b414ad543..a4c219bce 100644 --- a/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/HelloAPI.java @@ -17,7 +17,6 @@ package io.supertokens.webserver.api.core; import io.supertokens.Main; -import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; diff --git a/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java b/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java index 0a9e5b77b..ab86ac62c 100644 --- a/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/NotFoundOrHelloAPI.java @@ -17,7 +17,6 @@ package io.supertokens.webserver.api.core; import io.supertokens.Main; -import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -73,10 +72,11 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO protected void handleRequest(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // getServletPath returns the path without the base path. - AppIdentifier appIdentifier = getAppIdentifier(req); + AppIdentifier appIdentifier; Storage[] storages; try { + appIdentifier = getAppIdentifier(req); storages = StorageLayer.getStoragesForApp(main, appIdentifier); } catch (TenantOrAppNotFoundException e) { // we send 500 status code @@ -86,7 +86,7 @@ protected void handleRequest(HttpServletRequest req, HttpServletResponse resp) t if (req.getServletPath().equals("/")) { // API is app specific try { - RateLimiter rateLimiter = RateLimiter.getInstance(getAppIdentifier(req), super.main, 200); + RateLimiter rateLimiter = RateLimiter.getInstance(appIdentifier, super.main, 200); if (!rateLimiter.checkRequest()) { if (Main.isTesting) { super.sendTextResponse(200, "RateLimitedHello", resp); diff --git a/src/main/java/io/supertokens/webserver/api/core/UsersAPI.java b/src/main/java/io/supertokens/webserver/api/core/UsersAPI.java index 3d2c99b29..2959ca24a 100644 --- a/src/main/java/io/supertokens/webserver/api/core/UsersAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/UsersAPI.java @@ -75,9 +75,10 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } } - TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + TenantIdentifier tenantIdentifier = null; Storage storage = null; try { + tenantIdentifier = getTenantIdentifier(req); storage = this.getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/ConsumeResetPasswordAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/ConsumeResetPasswordAPI.java index d6aa86673..671d45469 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/ConsumeResetPasswordAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/ConsumeResetPasswordAPI.java @@ -58,9 +58,16 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String token = InputParser.parseStringOrThrowError(input, "token", false); assert token != null; + TenantIdentifier tenantIdentifier = null; + Storage storage = null; + try { + tenantIdentifier = getTenantIdentifier(req); + storage = getTenantStorage(req); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } + try { - TenantIdentifier tenantIdentifier = getTenantIdentifier(req); - Storage storage = getTenantStorage(req); EmailPassword.ConsumeResetPasswordTokenResult result = EmailPassword.consumeResetPasswordToken( tenantIdentifier, storage, token); @@ -80,7 +87,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I super.sendJsonResponse(200, resultJson, resp); } catch (ResetPasswordInvalidTokenException e) { - Logging.debug(main, getTenantIdentifier(req), Utils.exceptionStacktraceToString(e)); + Logging.debug(main, tenantIdentifier, Utils.exceptionStacktraceToString(e)); JsonObject result = new JsonObject(); result.addProperty("status", "RESET_PASSWORD_INVALID_TOKEN_ERROR"); super.sendJsonResponse(200, result, resp); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/GeneratePasswordResetTokenAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/GeneratePasswordResetTokenAPI.java index 56d5bb34e..772bcaa70 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/GeneratePasswordResetTokenAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/GeneratePasswordResetTokenAPI.java @@ -61,10 +61,9 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String userId = InputParser.parseStringOrThrowError(input, "userId", false); // logic according to https://github.com/supertokens/supertokens-core/issues/106 - TenantIdentifier tenantIdentifier = getTenantIdentifier(req); - Storage storage; + TenantIdentifier tenantIdentifier; try { - storage = getTenantStorage(req); + tenantIdentifier = getTenantIdentifier(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/ResetPasswordAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/ResetPasswordAPI.java index 8eb6ce88d..d52c3c884 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/ResetPasswordAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/ResetPasswordAPI.java @@ -74,9 +74,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I throw new ServletException(new WebserverAPI.BadRequestException("Password cannot be an empty string")); } - TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + TenantIdentifier tenantIdentifier; Storage storage; try { + tenantIdentifier = getTenantIdentifier(req); storage = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java index 707adfd6f..f966180f0 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/SignInAPI.java @@ -66,9 +66,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String normalisedEmail = Utils.normaliseEmail(email); - TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + TenantIdentifier tenantIdentifier; Storage storage; try { + tenantIdentifier = getTenantIdentifier(req); storage = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java index 8c58c760a..4cf605bf1 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/SignUpAPI.java @@ -69,9 +69,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I throw new ServletException(new WebserverAPI.BadRequestException("Password cannot be an empty string")); } - TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + TenantIdentifier tenantIdentifier; Storage storage; try { + tenantIdentifier = getTenantIdentifier(req); storage = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java index b7a662eca..f7b67e729 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/UserAPI.java @@ -163,7 +163,12 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO } email = Utils.normaliseEmail(email); - AppIdentifier appIdentifier = this.getAppIdentifier(req); + AppIdentifier appIdentifier = null; + try { + appIdentifier = this.getAppIdentifier(req); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } try { StorageAndUserIdMapping storageAndUserIdMapping = diff --git a/src/main/java/io/supertokens/webserver/api/emailverification/GenerateEmailVerificationTokenAPI.java b/src/main/java/io/supertokens/webserver/api/emailverification/GenerateEmailVerificationTokenAPI.java index f7f3b8bfb..e2256f99a 100644 --- a/src/main/java/io/supertokens/webserver/api/emailverification/GenerateEmailVerificationTokenAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailverification/GenerateEmailVerificationTokenAPI.java @@ -60,9 +60,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I assert email != null; email = Utils.normaliseEmail(email); - TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + TenantIdentifier tenantIdentifier; Storage storage; try { + tenantIdentifier = getTenantIdentifier(req); storage = getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); diff --git a/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java b/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java index ed64a8b70..a7ba01f29 100644 --- a/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailverification/VerifyEmailAPI.java @@ -71,9 +71,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I throw new ServletException(new BadRequestException("Unsupported method for email verification")); } - TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + TenantIdentifier tenantIdentifier; Storage storage; try { + tenantIdentifier = getTenantIdentifier(req); storage = this.getTenantStorage(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java index fa7e068a4..6fef2bd4a 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateAppAPI.java @@ -57,7 +57,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO TenantIdentifier sourceTenantIdentifier; try { - sourceTenantIdentifier = ensureTenantExistsAndGetTenantIdentifier(req); + sourceTenantIdentifier = getTenantIdentifier(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java index fdc68fa59..2eba982c6 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateConnectionUriDomainAPI.java @@ -56,7 +56,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO TenantIdentifier sourceTenantIdentifier; try { - sourceTenantIdentifier = ensureTenantExistsAndGetTenantIdentifier(req); + sourceTenantIdentifier = getTenantIdentifier(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java index 66bbd4711..63998b615 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/CreateOrUpdateTenantOrGetTenantAPI.java @@ -59,7 +59,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO TenantIdentifier sourceTenantIdentifier; try { - sourceTenantIdentifier = ensureTenantExistsAndGetTenantIdentifier(req); + sourceTenantIdentifier = getTenantIdentifier(req); } catch (TenantOrAppNotFoundException e) { throw new ServletException(e); } diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/ListAppsAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/ListAppsAPI.java index 823873e14..4b8166a5c 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/ListAppsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/ListAppsAPI.java @@ -52,8 +52,8 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - TenantIdentifier tenantIdentifier = getTenantIdentifier(req); try { + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); Storage storage = this.getTenantStorage(req); if (!tenantIdentifier.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID) diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java index bd1ef7a7a..4219c5c79 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveAppAPI.java @@ -59,7 +59,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - TenantIdentifier sourceTenantIdentifier = this.ensureTenantExistsAndGetTenantIdentifier(req); + TenantIdentifier sourceTenantIdentifier = this.getTenantIdentifier(req); if (!sourceTenantIdentifier.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID) || !sourceTenantIdentifier.getAppId().equals(TenantIdentifier.DEFAULT_APP_ID)) { throw new BadPermissionException("Only the public tenantId and public appId is allowed to delete an app"); diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java index 2b508155f..fa4ca3a68 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/RemoveConnectionUriDomainAPI.java @@ -58,7 +58,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } try { - TenantIdentifier sourceTenantIdentifier = this.ensureTenantExistsAndGetTenantIdentifier(req); + TenantIdentifier sourceTenantIdentifier = this.getTenantIdentifier(req); if (!sourceTenantIdentifier.equals(new TenantIdentifier(null, null, null))) { throw new BadPermissionException( "Only the public tenantId, public appId and default connectionUriDomain is allowed to delete a connectionUriDomain"); diff --git a/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java b/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java index a62df469c..dca193196 100644 --- a/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/RefreshSessionAPI.java @@ -70,10 +70,17 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I assert enableAntiCsrf != null; assert refreshToken != null; - AppIdentifier appIdentifier = this.getAppIdentifier(req); SemVer version = super.getVersionFromRequest(req); + TenantIdentifier tenantIdentifierForLogging = null; try { + tenantIdentifierForLogging = getTenantIdentifier(req); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } + + try { + AppIdentifier appIdentifier = this.getAppIdentifier(req); AccessToken.VERSION accessTokenVersion = AccessToken.getAccessTokenVersionForCDI(version); SessionInformationHolder sessionInfo = Session.refreshSession(appIdentifier, main, @@ -114,14 +121,14 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I UnsupportedJWTSigningAlgorithmException e) { throw new ServletException(e); } catch (AccessTokenPayloadError | UnauthorisedException e) { - Logging.debug(main, getTenantIdentifier(req), + Logging.debug(main, tenantIdentifierForLogging, Utils.exceptionStacktraceToString(e)); JsonObject reply = new JsonObject(); reply.addProperty("status", "UNAUTHORISED"); reply.addProperty("message", e.getMessage()); super.sendJsonResponse(200, reply, resp); } catch (TokenTheftDetectedException e) { - Logging.debug(main, getTenantIdentifier(req), + Logging.debug(main, tenantIdentifierForLogging, Utils.exceptionStacktraceToString(e)); JsonObject reply = new JsonObject(); reply.addProperty("status", "TOKEN_THEFT_DETECTED"); diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionRegenerateAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionRegenerateAPI.java index 58b110cfe..e177dfe90 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionRegenerateAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionRegenerateAPI.java @@ -68,7 +68,12 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject userDataInJWT = InputParser.parseJsonObjectOrThrowError(input, "userDataInJWT", true); - AppIdentifier appIdentifier = this.getAppIdentifier(req); + AppIdentifier appIdentifier = null; + try { + appIdentifier = this.getAppIdentifier(req); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } try { SessionInformationHolder sessionInfo = getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v2_21) ? diff --git a/src/main/java/io/supertokens/webserver/api/session/VerifySessionAPI.java b/src/main/java/io/supertokens/webserver/api/session/VerifySessionAPI.java index 4286afb9c..99e0f2d17 100644 --- a/src/main/java/io/supertokens/webserver/api/session/VerifySessionAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/VerifySessionAPI.java @@ -67,7 +67,12 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I Boolean enableAntiCsrf = InputParser.parseBooleanOrThrowError(input, "enableAntiCsrf", false); assert enableAntiCsrf != null; - AppIdentifier appIdentifier = this.getAppIdentifier(req); + AppIdentifier appIdentifier = null; + try { + appIdentifier = this.getAppIdentifier(req); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } try { @@ -128,7 +133,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I reply.addProperty("jwtSigningPublicKeyExpiryTime", SigningKeys.getInstance(appIdentifier, main).getDynamicSigningKeyExpiryTime()); - Utils.addLegacySigningKeyInfos(this.getAppIdentifier(req), main, reply, + Utils.addLegacySigningKeyInfos(appIdentifier, main, reply, super.getVersionFromRequest(req).betweenInclusive(SemVer.v2_9, SemVer.v2_21)); } diff --git a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java index b81975402..6489d7922 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java @@ -5,11 +5,9 @@ import com.google.gson.JsonObject; import io.supertokens.Main; -import io.supertokens.StorageAndUserIdMapping; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.Storage; -import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; @@ -18,7 +16,6 @@ import io.supertokens.totp.Totp; import io.supertokens.totp.exceptions.InvalidTotpException; import io.supertokens.totp.exceptions.LimitReachedException; -import io.supertokens.useridmapping.UserIdType; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.WebserverAPI; import jakarta.servlet.ServletException; @@ -58,18 +55,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { TenantIdentifier tenantIdentifier = getTenantIdentifier(req); - Storage storage; - try { - // This step is required only because user_last_active table stores supertokens internal user id. - // While sending the usage stats we do a join, so totp tables also must use internal user id. - - StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForTenantSpecificApi( - req, userId, UserIdType.ANY); - storage = storageAndUserIdMapping.storage; - } catch (UnknownUserIdException e) { - // if the user is not found, just use the storage of the tenant of interest - storage = getTenantStorage(req); - } + Storage storage = getTenantStorage(req); Totp.verifyCode(tenantIdentifier, storage, main, userId, totp, allowUnverifiedDevices); diff --git a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java index 54222050d..a6992c4e6 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java @@ -5,10 +5,8 @@ import com.google.gson.JsonObject; import io.supertokens.Main; -import io.supertokens.StorageAndUserIdMapping; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.Storage; -import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; @@ -18,7 +16,6 @@ import io.supertokens.totp.Totp; import io.supertokens.totp.exceptions.InvalidTotpException; import io.supertokens.totp.exceptions.LimitReachedException; -import io.supertokens.useridmapping.UserIdType; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.WebserverAPI; import jakarta.servlet.ServletException; @@ -60,18 +57,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { TenantIdentifier tenantIdentifier = getTenantIdentifier(req); - Storage storage; - try { - // This step is required only because user_last_active table stores supertokens internal user id. - // While sending the usage stats we do a join, so totp tables also must use internal user id. - - StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForTenantSpecificApi( - req, userId, UserIdType.ANY); - storage = storageAndUserIdMapping.storage; - } catch (UnknownUserIdException e) { - // if the user is not found, just use the storage of the tenant of interest - storage = getTenantStorage(req); - } + Storage storage = getTenantStorage(req);; boolean isNewlyVerified = Totp.verifyDevice(tenantIdentifier, storage, main, userId, deviceName, totp); result.addProperty("status", "OK"); diff --git a/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java b/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java index dd26fa1ae..a4ca1c77b 100644 --- a/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java @@ -20,7 +20,6 @@ import io.supertokens.Main; import io.supertokens.StorageAndUserIdMapping; import io.supertokens.multitenancy.exception.BadPermissionException; -import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; @@ -54,8 +53,9 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String userId = InputParser.parseStringOrThrowError(input, "userId", false); - AppIdentifier appIdentifier = getAppIdentifier(req); try { + AppIdentifier appIdentifier = getAppIdentifier(req); + try { StorageAndUserIdMapping storageAndUserIdMapping = this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( diff --git a/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java b/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java index 1e01a2504..6326fb160 100644 --- a/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/usermetadata/UserMetadataAPI.java @@ -20,7 +20,6 @@ import io.supertokens.Main; import io.supertokens.StorageAndUserIdMapping; import io.supertokens.multitenancy.exception.BadPermissionException; -import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; @@ -53,8 +52,9 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific String userId = InputParser.getQueryParamOrThrowError(req, "userId", false); - AppIdentifier appIdentifier = getAppIdentifier(req); + try { + AppIdentifier appIdentifier = getAppIdentifier(req); JsonObject metadata; try { StorageAndUserIdMapping storageAndUserIdMapping = this.enforcePublicTenantAndGetStorageAndUserIdMappingForAppSpecificApi( @@ -80,8 +80,8 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO String userId = InputParser.parseStringOrThrowError(input, "userId", false); JsonObject update = InputParser.parseJsonObjectOrThrowError(input, "metadataUpdate", false); - AppIdentifier appIdentifier = getAppIdentifier(req); try { + AppIdentifier appIdentifier = getAppIdentifier(req); JsonObject metadata; try { diff --git a/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java b/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java index 66f59c7a2..71898b33c 100644 --- a/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java +++ b/src/main/java/io/supertokens/webserver/api/userroles/RemoveRoleAPI.java @@ -19,7 +19,6 @@ import com.google.gson.JsonObject; import io.supertokens.Main; import io.supertokens.multitenancy.exception.BadPermissionException; -import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; diff --git a/src/test/java/io/supertokens/test/PathRouterTest.java b/src/test/java/io/supertokens/test/PathRouterTest.java index d6185d0b1..9e254c547 100644 --- a/src/test/java/io/supertokens/test/PathRouterTest.java +++ b/src/test/java/io/supertokens/test/PathRouterTest.java @@ -136,9 +136,13 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId(), resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); } @@ -307,9 +311,13 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId(), resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); } @@ -479,9 +487,13 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId(), resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); } @@ -662,9 +674,13 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId(), resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); } @@ -845,9 +861,13 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId(), resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); } @@ -1010,11 +1030,15 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId() + - ",", - resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId() + + ",", + resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }, new WebserverAPI(process.getProcess(), "r1") { @@ -1033,11 +1057,15 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId() + - ",r1", - resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId() + + ",r1", + resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } })); @@ -1058,9 +1086,13 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId(), resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); @@ -1128,11 +1160,15 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId() + - ",", - resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId() + + ",", + resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } })); @@ -1154,9 +1190,13 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId(), resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); fail(); @@ -1193,10 +1233,14 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId() + ",", - resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId() + ",", + resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }, new WebserverAPI(process.getProcess(), "r1") { @@ -1215,10 +1259,14 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId() + ",r1", - resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId() + ",r1", + resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } })); fail(); @@ -1245,10 +1293,14 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId() + ",", - resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId() + ",", + resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }, new WebserverAPI(process.getProcess(), "r1") { @@ -1267,10 +1319,14 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId() + ",r1", - resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId() + ",r1", + resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } })); fail(); @@ -1358,8 +1414,12 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId(), resp); + try { + super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); @@ -1471,9 +1531,13 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId(), - resp); + try { + super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), + resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); @@ -1587,9 +1651,13 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getTenantId(), - resp); + try { + super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getTenantId(), + resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); @@ -1726,10 +1794,14 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getAppId() + "," + - this.getTenantIdentifier(req).getTenantId(), resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getAppId() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); } @@ -2027,10 +2099,14 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getAppId() + "," + - this.getTenantIdentifier(req).getTenantId(), resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getAppId() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); } @@ -2312,10 +2388,14 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - this.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getAppId() + "," + - this.getTenantIdentifier(req).getTenantId(), resp); + try { + super.sendTextResponse(200, + this.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getAppId() + "," + + this.getTenantIdentifier(req).getTenantId(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); } @@ -2559,10 +2639,14 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getAppId() + "," + - this.getTenantIdentifier(req).getTenantId(), - resp); + try { + super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getAppId() + "," + + this.getTenantIdentifier(req).getTenantId(), + resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); @@ -2708,10 +2792,14 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getAppId() + "," + - this.getTenantIdentifier(req).getTenantId(), - resp); + try { + super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getAppId() + "," + + this.getTenantIdentifier(req).getTenantId(), + resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); @@ -2855,10 +2943,14 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + - this.getTenantIdentifier(req).getAppId() + "," + - this.getTenantIdentifier(req).getTenantId(), - resp); + try { + super.sendTextResponse(200, super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + this.getTenantIdentifier(req).getAppId() + "," + + this.getTenantIdentifier(req).getTenantId(), + resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); diff --git a/src/test/java/io/supertokens/test/multitenant/RequestConnectionUriDomainTest.java b/src/test/java/io/supertokens/test/multitenant/RequestConnectionUriDomainTest.java index 8e3702751..324f7865b 100644 --- a/src/test/java/io/supertokens/test/multitenant/RequestConnectionUriDomainTest.java +++ b/src/test/java/io/supertokens/test/multitenant/RequestConnectionUriDomainTest.java @@ -88,7 +88,11 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, getTenantIdentifier(req).getConnectionUriDomain(), resp); + try { + super.sendTextResponse(200, getTenantIdentifier(req).getConnectionUriDomain(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); @@ -159,9 +163,13 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - super.getTenantIdentifier(req).getConnectionUriDomain() + "," + - super.getTenantIdentifier(req).getTenantId(), resp); + try { + super.sendTextResponse(200, + super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + super.getTenantIdentifier(req).getTenantId(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); @@ -285,9 +293,13 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - super.sendTextResponse(200, - super.getTenantIdentifier(req).getConnectionUriDomain() + "," + - super.getTenantIdentifier(req).getTenantId(), resp); + try { + super.sendTextResponse(200, + super.getTenantIdentifier(req).getConnectionUriDomain() + "," + + super.getTenantIdentifier(req).getTenantId(), resp); + } catch (TenantOrAppNotFoundException e) { + throw new ServletException(e); + } } }); From a5d7aadb1ed46d0d10a2278203cb38ebff35c341 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Mon, 4 Mar 2024 20:38:17 +0530 Subject: [PATCH 27/31] fix: pr comments --- .../java/io/supertokens/session/Session.java | 57 ------------------- .../supertokens/webserver/WebserverAPI.java | 14 +++++ .../webserver/api/core/EEFeatureFlagAPI.java | 2 +- .../webserver/api/core/LicenseKeyAPI.java | 6 +- .../webserver/api/core/RequestStatsAPI.java | 2 +- .../webserver/api/core/TelemetryAPI.java | 2 +- .../ImportUserWithPasswordHashAPI.java | 4 +- .../api/passwordless/ConsumeCodeAPI.java | 6 +- .../api/session/SessionRemoveAPI.java | 29 ++++------ .../webserver/api/session/SessionUserAPI.java | 11 +++- .../webserver/api/thirdparty/SignInUpAPI.java | 2 +- .../webserver/api/thirdparty/UserAPI.java | 2 +- 12 files changed, 46 insertions(+), 91 deletions(-) diff --git a/src/main/java/io/supertokens/session/Session.java b/src/main/java/io/supertokens/session/Session.java index efed4b535..c1969bd46 100644 --- a/src/main/java/io/supertokens/session/Session.java +++ b/src/main/java/io/supertokens/session/Session.java @@ -824,20 +824,6 @@ public static String[] revokeAllSessionsForUser(Main main, AppIdentifier appIden return revokeSessionUsingSessionHandles(main, appIdentifier, storage, sessionHandles); } - public static String[] revokeAllSessionsForUser(Main main, AppIdentifier appIdentifier, - Storage[] storages, String userId, - boolean revokeSessionsForLinkedAccounts) - throws StorageQueryException { - List revokedSessionHandles = new ArrayList<>(); - for (Storage storage : storages) { - String[] sessionHandles = getAllNonExpiredSessionHandlesForUser(main, appIdentifier, storage, userId, - revokeSessionsForLinkedAccounts); - return revokeSessionUsingSessionHandles(main, appIdentifier, storage, sessionHandles); - } - - return revokedSessionHandles.toArray(new String[0]); - } - public static String[] revokeAllSessionsForUser(Main main, TenantIdentifier tenantIdentifier, Storage storage, String userId, boolean revokeSessionsForLinkedAccounts) throws StorageQueryException { @@ -895,49 +881,6 @@ public static String[] getAllNonExpiredSessionHandlesForUser( return sessionHandles.toArray(new String[0]); } - public static String[] getAllNonExpiredSessionHandlesForUser( - Main main, AppIdentifier appIdentifier, Storage[] storages, String userId, - boolean fetchSessionsForAllLinkedAccounts) - throws StorageQueryException { - TenantConfig[] tenants = Multitenancy.getAllTenantsForApp( - appIdentifier, main); - - List sessionHandles = new ArrayList<>(); - - for (Storage storage : storages) { - Set userIds = new HashSet<>(); - userIds.add(userId); - if (fetchSessionsForAllLinkedAccounts) { - if (storage.getType().equals(STORAGE_TYPE.SQL)) { - AuthRecipeUserInfo primaryUser = ((AuthRecipeStorage) storage) - .getPrimaryUserById(appIdentifier, userId); - if (primaryUser != null) { - for (LoginMethod lM : primaryUser.loginMethods) { - userIds.add(lM.getSupertokensUserId()); - } - } - } - } - - for (String currUserId : userIds) { - for (TenantConfig tenant : tenants) { - try { - sessionHandles.addAll(Arrays.asList(getAllNonExpiredSessionHandlesForUser( - tenant.tenantIdentifier, StorageLayer.getStorage(tenant.tenantIdentifier, main), - currUserId, false))); - - } catch (TenantOrAppNotFoundException e) { - // this might happen when a tenant was deleted after the tenant list was fetched - // it is okay to exclude that tenant in the results here - } - } - } - } - - - return sessionHandles.toArray(new String[0]); - } - public static String[] getAllNonExpiredSessionHandlesForUser( TenantIdentifier tenantIdentifier, Storage storage, String userId, boolean fetchSessionsForAllLinkedAccounts) diff --git a/src/main/java/io/supertokens/webserver/WebserverAPI.java b/src/main/java/io/supertokens/webserver/WebserverAPI.java index f5702e523..d578c1cbe 100644 --- a/src/main/java/io/supertokens/webserver/WebserverAPI.java +++ b/src/main/java/io/supertokens/webserver/WebserverAPI.java @@ -378,6 +378,20 @@ protected StorageAndUserIdMapping enforcePublicTenantAndGetStorageAndUserIdMappi } } + protected StorageAndUserIdMapping getStorageAndUserIdMappingForAppSpecificApiWithoutEnforcingPublicTenant( + HttpServletRequest req, String userId, UserIdType userIdType) + throws StorageQueryException, TenantOrAppNotFoundException, ServletException, + BadPermissionException { + AppIdentifier appIdentifier = getAppIdentifierWithoutVerifying(req); + Storage[] storages = StorageLayer.getStoragesForApp(main, appIdentifier); + try { + return StorageLayer.findStorageAndUserIdMappingForUser( + appIdentifier, storages, userId, userIdType); + } catch (UnknownUserIdException e) { + return new StorageAndUserIdMapping(getTenantStorage(req), null); + } + } + protected boolean checkIPAccess(HttpServletRequest req, HttpServletResponse resp) throws TenantOrAppNotFoundException, ServletException, IOException { CoreConfig config = Config.getConfig(getTenantIdentifierWithoutVerifying(req), main); diff --git a/src/main/java/io/supertokens/webserver/api/core/EEFeatureFlagAPI.java b/src/main/java/io/supertokens/webserver/api/core/EEFeatureFlagAPI.java index b2a7b4668..d3e250365 100644 --- a/src/main/java/io/supertokens/webserver/api/core/EEFeatureFlagAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/EEFeatureFlagAPI.java @@ -49,8 +49,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific and can be queried only from public tenant try { - this.enforcePublicTenantAndGetPublicTenantStorage(req); // to check if app exists and enforce public tenant AppIdentifier appIdentifier = this.getAppIdentifier(req); + this.enforcePublicTenantAndGetPublicTenantStorage(req); // enforce public tenant EE_FEATURES[] features = FeatureFlag.getInstance(main, appIdentifier) .getEnabledFeatures(); JsonObject stats = FeatureFlag.getInstance(main, appIdentifier) diff --git a/src/main/java/io/supertokens/webserver/api/core/LicenseKeyAPI.java b/src/main/java/io/supertokens/webserver/api/core/LicenseKeyAPI.java index d9bb7ae3d..1d11d07f5 100644 --- a/src/main/java/io/supertokens/webserver/api/core/LicenseKeyAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/LicenseKeyAPI.java @@ -51,8 +51,8 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String licenseKey = InputParser.parseStringOrThrowError(input, "licenseKey", true); try { - this.enforcePublicTenantAndGetPublicTenantStorage(req); // to check if app exists and enforce public tenant AppIdentifier appIdentifier = this.getAppIdentifier(req); + this.enforcePublicTenantAndGetPublicTenantStorage(req); // enforce public tenant boolean success = false; if (licenseKey != null) { success = FeatureFlag.getInstance(main, appIdentifier) @@ -77,7 +77,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific and can be queried only from public tenant try { - this.enforcePublicTenantAndGetPublicTenantStorage(req); // to check if app exists and enforce public tenant + this.enforcePublicTenantAndGetPublicTenantStorage(req); // enforce public tenant FeatureFlag.getInstance(main, getAppIdentifier(req)) .removeLicenseKeyAndSyncFeatures(); JsonObject result = new JsonObject(); @@ -92,7 +92,7 @@ protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific and can be queried only from public tenant try { - this.enforcePublicTenantAndGetPublicTenantStorage(req); // to check if app exists and enforce public tenant + this.enforcePublicTenantAndGetPublicTenantStorage(req); // enforce public tenant String licenseKey = FeatureFlag.getInstance(main, getAppIdentifier(req)) .getLicenseKey(); JsonObject result = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/core/RequestStatsAPI.java b/src/main/java/io/supertokens/webserver/api/core/RequestStatsAPI.java index 080570a81..034c71eb5 100644 --- a/src/main/java/io/supertokens/webserver/api/core/RequestStatsAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/RequestStatsAPI.java @@ -45,8 +45,8 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific try { - enforcePublicTenantAndGetPublicTenantStorage(req); // check if app exists and enforce public tenant AppIdentifier appIdentifier = getAppIdentifier(req); + enforcePublicTenantAndGetPublicTenantStorage(req); // enforce public tenant JsonObject stats = RequestStats.getInstance(main, appIdentifier).getStats(); stats.addProperty("status", "OK"); super.sendJsonResponse(200, stats, resp); diff --git a/src/main/java/io/supertokens/webserver/api/core/TelemetryAPI.java b/src/main/java/io/supertokens/webserver/api/core/TelemetryAPI.java index 21af7097f..5a35ec937 100644 --- a/src/main/java/io/supertokens/webserver/api/core/TelemetryAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/TelemetryAPI.java @@ -46,7 +46,7 @@ public String getPath() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // API is app specific try { - this.enforcePublicTenantAndGetPublicTenantStorage(req); // check if app exists and enforce public tenant + this.enforcePublicTenantAndGetPublicTenantStorage(req); // enforce public tenant KeyValueInfo telemetryId = Telemetry.getTelemetryId(main, getAppIdentifier(req)); JsonObject result = new JsonObject(); diff --git a/src/main/java/io/supertokens/webserver/api/emailpassword/ImportUserWithPasswordHashAPI.java b/src/main/java/io/supertokens/webserver/api/emailpassword/ImportUserWithPasswordHashAPI.java index 48b435ca0..3d05fd5ff 100644 --- a/src/main/java/io/supertokens/webserver/api/emailpassword/ImportUserWithPasswordHashAPI.java +++ b/src/main/java/io/supertokens/webserver/api/emailpassword/ImportUserWithPasswordHashAPI.java @@ -96,11 +96,11 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { TenantIdentifier tenantIdentifier = getTenantIdentifier(req); - Storage storage = this.getTenantStorage(req); + Storage storage = getTenantStorage(req); EmailPassword.ImportUserResponse importUserResponse = EmailPassword.importUserWithPasswordHash( tenantIdentifier, storage, main, email, passwordHash, passwordHashingAlgorithm); - UserIdMapping.populateExternalUserIdForUsers(getTenantStorage(req), new AuthRecipeUserInfo[]{importUserResponse.user}); + UserIdMapping.populateExternalUserIdForUsers(storage, new AuthRecipeUserInfo[]{importUserResponse.user}); JsonObject response = new JsonObject(); response.addProperty("status", "OK"); JsonObject userJson = diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java index 492ed49ad..a1aa41ee6 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java @@ -24,6 +24,7 @@ import io.supertokens.passwordless.Passwordless.ConsumeCodeResponse; import io.supertokens.passwordless.exceptions.*; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.authRecipe.LoginMethod; import io.supertokens.pluginInterface.exceptions.StorageQueryException; @@ -83,14 +84,15 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I try { TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage = this.getTenantStorage(req); ConsumeCodeResponse consumeCodeResponse = Passwordless.consumeCode( tenantIdentifier, - this.getTenantStorage(req), main, + storage, main, deviceId, deviceIdHash, userInputCode, linkCode, // From CDI version 4.0 onwards, the email verification will be set getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0)); - io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(this.getTenantStorage(req), new AuthRecipeUserInfo[]{consumeCodeResponse.user}); + io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(storage, new AuthRecipeUserInfo[]{consumeCodeResponse.user}); ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), main, consumeCodeResponse.user.getSupertokensUserId()); diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java index a14f60256..de21b8a4a 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java @@ -61,9 +61,7 @@ public String getPath() { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - // API is app specific when `userId` is passed and `revokeAcrossAllTenants` is set to true - // API is app specific when revoking using `sessionHandles` - // API is tenant specific in all other cases (when `userId` is passed and `revokeAcrossAllTenants` is set to false) + // API is tenant specific, but ignores tenantId from the request if revoking from all tenants JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String userId = InputParser.parseStringOrThrowError(input, "userId", true); @@ -116,20 +114,14 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I if (revokeAcrossAllTenants) { AppIdentifier appIdentifier = getAppIdentifier(req); - Storage[] storages = enforcePublicTenantAndGetAllStoragesForApp(req); + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForAppSpecificApiWithoutEnforcingPublicTenant( + req, userId, UserIdType.ANY); sessionHandlesRevoked = Session.revokeAllSessionsForUser( - main, appIdentifier, storages, userId, revokeSessionsForLinkedAccounts); + main, appIdentifier, storageAndUserIdMapping.storage, userId, revokeSessionsForLinkedAccounts); } else { - StorageAndUserIdMapping storageAndUserIdMapping; - try { - storageAndUserIdMapping = getStorageAndUserIdMappingForTenantSpecificApi( - req, userId, UserIdType.ANY); - storage = storageAndUserIdMapping.storage; - } catch (UnknownUserIdException e) { - storage = getTenantStorage(req); - } TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + storage = getTenantStorage(req); sessionHandlesRevoked = Session.revokeAllSessionsForUser( main, tenantIdentifier, storage, userId, revokeSessionsForLinkedAccounts); @@ -162,9 +154,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } } else { try { - enforcePublicTenantAndGetPublicTenantStorage(req); // enforce public tenant AppIdentifier appIdentifier = getAppIdentifier(req); - Map> sessionHandlesByTenantId = new HashMap<>(); for (String sessionHandle : sessionHandles) { @@ -178,9 +168,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I for (Map.Entry> entry : sessionHandlesByTenantId.entrySet()) { String tenantId = entry.getKey(); List sessionHandlesForTenant = entry.getValue(); - Storage storage = - StorageLayer.getStorage(new TenantIdentifier( - appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), tenantId), main); + Storage storage = StorageLayer.getStorage( + new TenantIdentifier( + appIdentifier.getConnectionUriDomain(), appIdentifier.getAppId(), tenantId), + main); String[] sessionHandlesRevoked = Session.revokeSessionUsingSessionHandles(main, appIdentifier, storage, sessionHandlesForTenant.toArray(new String[0])); @@ -195,7 +186,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } result.add("sessionHandlesRevoked", sessionHandlesRevokedJSON); super.sendJsonResponse(200, result, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException e) { throw new ServletException(e); } } diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java index 6d8b1a92d..ff92314c7 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java @@ -20,6 +20,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.Storage; @@ -28,6 +29,7 @@ import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.session.Session; +import io.supertokens.useridmapping.UserIdType; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.WebserverAPI; import jakarta.servlet.ServletException; @@ -51,7 +53,7 @@ public String getPath() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - // API is app specific if fetchAcrossAllTenants is set to true, tenant specific otherwise + // API is tenant specific, but ignores tenantId if fetchAcrossAllTenants is true String userId = InputParser.getQueryParamOrThrowError(req, "userId", false); assert userId != null; @@ -74,9 +76,12 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO if (fetchAcrossAllTenants) { AppIdentifier appIdentifier = getAppIdentifier(req); - Storage[] storages = enforcePublicTenantAndGetAllStoragesForApp(req); + StorageAndUserIdMapping storageAndUserIdMapping = + getStorageAndUserIdMappingForAppSpecificApiWithoutEnforcingPublicTenant(req, userId, + UserIdType.ANY); sessionHandles = Session.getAllNonExpiredSessionHandlesForUser( - main, appIdentifier, storages, userId, fetchSessionsForAllLinkedAccounts); + main, appIdentifier, storageAndUserIdMapping.storage, userId, + fetchSessionsForAllLinkedAccounts); } else { TenantIdentifier tenantIdentifier = getTenantIdentifier(req); Storage storage = getTenantStorage(req); diff --git a/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java b/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java index 7d85c2e61..42b16c7f9 100644 --- a/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java +++ b/src/main/java/io/supertokens/webserver/api/thirdparty/SignInUpAPI.java @@ -81,7 +81,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I ThirdParty.SignInUpResponse response = ThirdParty.signInUp2_7( tenantIdentifier, storage, thirdPartyId, thirdPartyUserId, email, isEmailVerified); - UserIdMapping.populateExternalUserIdForUsers(this.getTenantStorage(req), new AuthRecipeUserInfo[]{response.user}); + UserIdMapping.populateExternalUserIdForUsers(storage, new AuthRecipeUserInfo[]{response.user}); ActiveUsers.updateLastActive(tenantIdentifier.toAppIdentifier(), main, response.user.getSupertokensUserId()); diff --git a/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java b/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java index d4c4e1719..f1089b011 100644 --- a/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/thirdparty/UserAPI.java @@ -103,7 +103,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO user = ThirdParty.getUser(tenantIdentifier, storage, thirdPartyId, thirdPartyUserId); if (user != null) { - UserIdMapping.populateExternalUserIdForUsers(getTenantStorage(req), new AuthRecipeUserInfo[]{user}); + UserIdMapping.populateExternalUserIdForUsers(storage, new AuthRecipeUserInfo[]{user}); } } From 88539e5269899e4bb0e2ab3d14a1eb3ebe38ceb0 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Mon, 4 Mar 2024 20:44:04 +0530 Subject: [PATCH 28/31] fix: query --- .../io/supertokens/inmemorydb/queries/UserRolesQueries.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java index 94cb60de7..5c954ad46 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java @@ -343,7 +343,7 @@ public static int deleteAllRolesForUser_Transaction(Connection con, Start start, public static boolean deleteAllUserRoleAssociationsForRole(Start start, AppIdentifier appIdentifier, String role) throws SQLException, StorageQueryException { - String QUERY = "DELETE FROM " + getConfig(start).getRolesTable() + String QUERY = "DELETE FROM " + getConfig(start).getUserRolesTable() + " WHERE app_id = ? AND role = ? ;"; return update(start, QUERY, pst -> { pst.setString(1, appIdentifier.getAppId()); From 8a31166844e4a12be6682f7f0714a667c5292623 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Tue, 5 Mar 2024 12:00:19 +0530 Subject: [PATCH 29/31] fix: tests version and changelog --- CHANGELOG.md | 26 +++++++++++++++++++ build.gradle | 2 +- .../supertokens/webserver/WebserverAPI.java | 14 ---------- .../api/session/SessionRemoveAPI.java | 16 +++++++++--- .../webserver/api/session/SessionUserAPI.java | 17 +++++++++--- .../multitenant/api/TestPermissionChecks.java | 12 ++++----- .../test/userRoles/UserRolesStorageTest.java | 3 +-- 7 files changed, 59 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c19515d0a..414e5c569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [8.0.0] - 2024-03-04 + +### Breaking changes + +- The following app specific APIs return a 403 when not called using `public` tenant + - GET `/recipe/accountlinking/user/primary/check` + - GET `/recipe/accountlinking/user/link/check` + - POST `/recipe/accountlinking/user/primary` + - POST `/recipe/accountlinking/user/link` + - POST `/recipe/accountlinking/user/unlink` + - GET `/users/count/active` + - POST `/user/remove` + - GET `/ee/featureflag` + - GET `/user/id` + - PUT `/ee/license` + - DELETE `/ee/license` + - GET `/ee/license` + - GET `/requests/stats` + - GET `/recipe/user` when querying by `userId` + - GET `/recipe/jwt/jwks` + - POST `/recipe/jwt` + +### Fixes + +- Fixes issue with non-auth recipe related storage handling + ## [7.0.18] - 2024-02-19 - Fixes vulnerabilities in dependencies diff --git a/build.gradle b/build.gradle index c6ee455fe..806add897 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,7 @@ compileTestJava { options.encoding = "UTF-8" } // } //} -version = "7.0.18" +version = "8.0.0" repositories { diff --git a/src/main/java/io/supertokens/webserver/WebserverAPI.java b/src/main/java/io/supertokens/webserver/WebserverAPI.java index d578c1cbe..f5702e523 100644 --- a/src/main/java/io/supertokens/webserver/WebserverAPI.java +++ b/src/main/java/io/supertokens/webserver/WebserverAPI.java @@ -378,20 +378,6 @@ protected StorageAndUserIdMapping enforcePublicTenantAndGetStorageAndUserIdMappi } } - protected StorageAndUserIdMapping getStorageAndUserIdMappingForAppSpecificApiWithoutEnforcingPublicTenant( - HttpServletRequest req, String userId, UserIdType userIdType) - throws StorageQueryException, TenantOrAppNotFoundException, ServletException, - BadPermissionException { - AppIdentifier appIdentifier = getAppIdentifierWithoutVerifying(req); - Storage[] storages = StorageLayer.getStoragesForApp(main, appIdentifier); - try { - return StorageLayer.findStorageAndUserIdMappingForUser( - appIdentifier, storages, userId, userIdType); - } catch (UnknownUserIdException e) { - return new StorageAndUserIdMapping(getTenantStorage(req), null); - } - } - protected boolean checkIPAccess(HttpServletRequest req, HttpServletResponse resp) throws TenantOrAppNotFoundException, ServletException, IOException { CoreConfig config = Config.getConfig(getTenantIdentifierWithoutVerifying(req), main); diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java index de21b8a4a..f175adb1b 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java @@ -113,10 +113,18 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String[] sessionHandlesRevoked; if (revokeAcrossAllTenants) { + // when revokeAcrossAllTenants is true, and given that the backend SDK might pass tenant id + // we do not want to enfore public tenant here but behave as if this is an app specific API AppIdentifier appIdentifier = getAppIdentifier(req); - StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForAppSpecificApiWithoutEnforcingPublicTenant( - req, userId, UserIdType.ANY); - + Storage[] storages = StorageLayer.getStoragesForApp(main, appIdentifier); + StorageAndUserIdMapping storageAndUserIdMapping = null; + try { + storageAndUserIdMapping = StorageLayer.findStorageAndUserIdMappingForUser( + appIdentifier, storages, userId, UserIdType.ANY); + } catch (UnknownUserIdException e) { + storageAndUserIdMapping = new StorageAndUserIdMapping(getTenantStorage(req), null); + } + storage = storageAndUserIdMapping.storage; sessionHandlesRevoked = Session.revokeAllSessionsForUser( main, appIdentifier, storageAndUserIdMapping.storage, userId, revokeSessionsForLinkedAccounts); } else { @@ -149,7 +157,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } result.add("sessionHandlesRevoked", sessionHandlesRevokedJSON); super.sendJsonResponse(200, result, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException e) { throw new ServletException(e); } } else { diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java index ff92314c7..560f8e079 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java @@ -24,11 +24,13 @@ import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.session.Session; +import io.supertokens.storageLayer.StorageLayer; import io.supertokens.useridmapping.UserIdType; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.WebserverAPI; @@ -75,10 +77,17 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO String[] sessionHandles; if (fetchAcrossAllTenants) { + // when fetchAcrossAllTenants is true, and given that the backend SDK might pass tenant id + // we do not want to enfore public tenant here but behave as if this is an app specific API AppIdentifier appIdentifier = getAppIdentifier(req); - StorageAndUserIdMapping storageAndUserIdMapping = - getStorageAndUserIdMappingForAppSpecificApiWithoutEnforcingPublicTenant(req, userId, - UserIdType.ANY); + Storage[] storages = StorageLayer.getStoragesForApp(main, appIdentifier); + StorageAndUserIdMapping storageAndUserIdMapping = null; + try { + storageAndUserIdMapping = StorageLayer.findStorageAndUserIdMappingForUser( + appIdentifier, storages, userId, UserIdType.ANY); + } catch (UnknownUserIdException e) { + storageAndUserIdMapping = new StorageAndUserIdMapping(getTenantStorage(req), null); + } sessionHandles = Session.getAllNonExpiredSessionHandlesForUser( main, appIdentifier, storageAndUserIdMapping.storage, userId, fetchSessionsForAllLinkedAccounts); @@ -98,7 +107,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO result.add("sessionHandles", arr); super.sendJsonResponse(200, result, resp); - } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { + } catch (StorageQueryException | TenantOrAppNotFoundException e) { throw new ServletException(e); } } diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestPermissionChecks.java b/src/test/java/io/supertokens/test/multitenant/api/TestPermissionChecks.java index 9a890db27..ebea6ab5d 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestPermissionChecks.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestPermissionChecks.java @@ -1022,32 +1022,32 @@ public void testPermissionsForDeleteTenant() throws Exception { new TestCase( new TenantIdentifier(null, null, "t1"), new TenantIdentifier(null, null, "t2"), - "Only the public tenantId is allowed to delete a tenant" + "Only public tenantId can call this app specific API" ), new TestCase( new TenantIdentifier(null, null, "t1"), new TenantIdentifier(null, null, "t1"), - "Only the public tenantId is allowed to delete a tenant" + "Only public tenantId can call this app specific API" ), new TestCase( new TenantIdentifier(null, "a1", "t1"), new TenantIdentifier(null, "a1", "t2"), - "Only the public tenantId is allowed to delete a tenant" + "Only public tenantId can call this app specific API" ), new TestCase( new TenantIdentifier(null, "a1", "t1"), new TenantIdentifier(null, "a1", "t1"), - "Only the public tenantId is allowed to delete a tenant" + "Only public tenantId can call this app specific API" ), new TestCase( new TenantIdentifier("127.0.0.1", "a1", "t1"), new TenantIdentifier("127.0.0.1", "a1", "t2"), - "Only the public tenantId is allowed to delete a tenant" + "Only public tenantId can call this app specific API" ), new TestCase( new TenantIdentifier("127.0.0.1", "a1", "t1"), new TenantIdentifier("127.0.0.1", "a1", "t1"), - "Only the public tenantId is allowed to delete a tenant" + "Only public tenantId can call this app specific API" ), new TestCase( new TenantIdentifier(null, null, null), diff --git a/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java b/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java index c6ad8986d..5c8437e0b 100644 --- a/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java +++ b/src/test/java/io/supertokens/test/userRoles/UserRolesStorageTest.java @@ -119,8 +119,7 @@ public void testDeletingARoleWhileItIsBeingRemovedFromAUser() throws Exception { } // delete the role try { - boolean wasRoleDeleted = storage.deleteAllUserRoleAssociationsForRole(new AppIdentifier(null, null), role); - wasRoleDeleted = storage.deleteRole(new AppIdentifier(null, null), role) || wasRoleDeleted; + boolean wasRoleDeleted = storage.deleteRole(new AppIdentifier(null, null), role); r2_success.set(wasRoleDeleted); } catch (StorageQueryException e) { // should not come here From 644b5d6f6b61084480152504e16078eda0c7cd2f Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Tue, 5 Mar 2024 12:21:50 +0530 Subject: [PATCH 30/31] Update CHANGELOG.md Co-authored-by: Rishabh Poddar --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 414e5c569..ead653f93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ### Breaking changes -- The following app specific APIs return a 403 when not called using `public` tenant +- The following app specific APIs return a 403 when they are called with a tenant ID other than the `public` one. For example, if the path is `/users/count/active`, and you call it with `/tenant1/users/count/active`, it will return a 403. But if you call it with `/public/users/count/active`, or just `/users/count/active`, it will work. - GET `/recipe/accountlinking/user/primary/check` - GET `/recipe/accountlinking/user/link/check` - POST `/recipe/accountlinking/user/primary` From 0bfad8b13923c21aab1d3c4f7b9540f6beda2123 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Tue, 5 Mar 2024 12:30:28 +0530 Subject: [PATCH 31/31] fix: pr comments --- .../webserver/api/session/SessionRemoveAPI.java | 14 ++++++++------ .../webserver/api/session/SessionUserAPI.java | 15 ++++++++++----- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java index f175adb1b..2686de03d 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionRemoveAPI.java @@ -114,19 +114,21 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I if (revokeAcrossAllTenants) { // when revokeAcrossAllTenants is true, and given that the backend SDK might pass tenant id - // we do not want to enfore public tenant here but behave as if this is an app specific API + // we do not want to enforce public tenant here but behave as if this is an app specific API + // So instead of calling enforcePublicTenantAndGetAllStoragesForApp, we simply do all the logic + // here to fetch the storages and find the storage where `userId` exists. If user id does not + // exist, we use the storage for the tenantId passed in the request. AppIdentifier appIdentifier = getAppIdentifier(req); Storage[] storages = StorageLayer.getStoragesForApp(main, appIdentifier); - StorageAndUserIdMapping storageAndUserIdMapping = null; try { - storageAndUserIdMapping = StorageLayer.findStorageAndUserIdMappingForUser( + StorageAndUserIdMapping storageAndUserIdMapping = StorageLayer.findStorageAndUserIdMappingForUser( appIdentifier, storages, userId, UserIdType.ANY); + storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { - storageAndUserIdMapping = new StorageAndUserIdMapping(getTenantStorage(req), null); + storage = getTenantStorage(req); } - storage = storageAndUserIdMapping.storage; sessionHandlesRevoked = Session.revokeAllSessionsForUser( - main, appIdentifier, storageAndUserIdMapping.storage, userId, revokeSessionsForLinkedAccounts); + main, appIdentifier, storage, userId, revokeSessionsForLinkedAccounts); } else { TenantIdentifier tenantIdentifier = getTenantIdentifier(req); storage = getTenantStorage(req); diff --git a/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java b/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java index 560f8e079..8e7b53e2e 100644 --- a/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java +++ b/src/main/java/io/supertokens/webserver/api/session/SessionUserAPI.java @@ -78,18 +78,23 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO if (fetchAcrossAllTenants) { // when fetchAcrossAllTenants is true, and given that the backend SDK might pass tenant id - // we do not want to enfore public tenant here but behave as if this is an app specific API + // we do not want to enforce public tenant here but behave as if this is an app specific API + // So instead of calling enforcePublicTenantAndGetAllStoragesForApp, we simply do all the logic + // here to fetch the storages and find the storage where `userId` exists. If user id does not + // exist, we use the storage for the tenantId passed in the request. AppIdentifier appIdentifier = getAppIdentifier(req); Storage[] storages = StorageLayer.getStoragesForApp(main, appIdentifier); - StorageAndUserIdMapping storageAndUserIdMapping = null; + Storage storage; try { - storageAndUserIdMapping = StorageLayer.findStorageAndUserIdMappingForUser( + StorageAndUserIdMapping storageAndUserIdMapping = + StorageLayer.findStorageAndUserIdMappingForUser( appIdentifier, storages, userId, UserIdType.ANY); + storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { - storageAndUserIdMapping = new StorageAndUserIdMapping(getTenantStorage(req), null); + storage = getTenantStorage(req); } sessionHandles = Session.getAllNonExpiredSessionHandlesForUser( - main, appIdentifier, storageAndUserIdMapping.storage, userId, + main, appIdentifier, storage, userId, fetchSessionsForAllLinkedAccounts); } else { TenantIdentifier tenantIdentifier = getTenantIdentifier(req);