From 714e4c76f0dc92971aeceba99912f3609792f3af Mon Sep 17 00:00:00 2001 From: tamassoltesz Date: Fri, 15 Nov 2024 16:58:01 +0100 Subject: [PATCH] feat: bulk inserting the bulk migration data --- .../sqlStorage/AuthRecipeSQLStorage.java | 13 +++++++ .../bulkimport/ImportUserBase.java | 34 +++++++++++++++++++ .../EmailPasswordImportUser.java | 30 ++++++++++++++++ .../emailpassword/EmailPasswordStorage.java | 7 ++++ .../EmailVerificationSQLStorage.java | 6 ++++ .../passwordless/PasswordlessImportUser.java | 30 ++++++++++++++++ .../sqlStorage/PasswordlessSQLStorage.java | 5 +++ .../sqlStorage/SQLStorage.java | 3 +- .../thirdparty/ThirdPartyImportUser.java | 33 ++++++++++++++++++ .../sqlStorage/ThirdPartySQLStorage.java | 6 ++++ .../totp/sqlStorage/TOTPSQLStorage.java | 5 +++ .../sqlStorage/UserMetadataSQLStorage.java | 10 ++++++ .../sqlStorage/UserRolesSQLStorage.java | 5 +++ 13 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 src/main/java/io/supertokens/pluginInterface/bulkimport/ImportUserBase.java create mode 100644 src/main/java/io/supertokens/pluginInterface/emailpassword/EmailPasswordImportUser.java create mode 100644 src/main/java/io/supertokens/pluginInterface/passwordless/PasswordlessImportUser.java create mode 100644 src/main/java/io/supertokens/pluginInterface/thirdparty/ThirdPartyImportUser.java diff --git a/src/main/java/io/supertokens/pluginInterface/authRecipe/sqlStorage/AuthRecipeSQLStorage.java b/src/main/java/io/supertokens/pluginInterface/authRecipe/sqlStorage/AuthRecipeSQLStorage.java index 1bcb8efb..f8d30058 100644 --- a/src/main/java/io/supertokens/pluginInterface/authRecipe/sqlStorage/AuthRecipeSQLStorage.java +++ b/src/main/java/io/supertokens/pluginInterface/authRecipe/sqlStorage/AuthRecipeSQLStorage.java @@ -23,12 +23,19 @@ import io.supertokens.pluginInterface.sqlStorage.SQLStorage; import io.supertokens.pluginInterface.sqlStorage.TransactionConnection; +import java.util.List; +import java.util.Map; + public interface AuthRecipeSQLStorage extends AuthRecipeStorage, SQLStorage { AuthRecipeUserInfo getPrimaryUserById_Transaction(AppIdentifier appIdentifier, TransactionConnection con, String userId) throws StorageQueryException; + List getPrimaryUsersByIds_Transaction(AppIdentifier appIdentifier, TransactionConnection con, + List userIds) + throws StorageQueryException; + // lock order: // - emailpassword table // - thirdparty table @@ -52,9 +59,15 @@ AuthRecipeUserInfo[] listPrimaryUsersByThirdPartyInfo_Transaction(AppIdentifier void makePrimaryUser_Transaction(AppIdentifier appIdentifier, TransactionConnection con, String userId) throws StorageQueryException; + void makePrimaryUsers_Transaction(AppIdentifier appIdentifier, TransactionConnection con, List userIds) + throws StorageQueryException; + void linkAccounts_Transaction(AppIdentifier appIdentifier, TransactionConnection con, String recipeUserId, String primaryUserId) throws StorageQueryException; + void linkMultipleAccounts_Transaction(AppIdentifier appIdentifier, TransactionConnection con, + Map recipeUserIdByPrimaryUserId) throws StorageQueryException; + void unlinkAccounts_Transaction(AppIdentifier appIdentifier, TransactionConnection con, String primaryUserId, String recipeUserId) throws StorageQueryException; diff --git a/src/main/java/io/supertokens/pluginInterface/bulkimport/ImportUserBase.java b/src/main/java/io/supertokens/pluginInterface/bulkimport/ImportUserBase.java new file mode 100644 index 00000000..fd97cff2 --- /dev/null +++ b/src/main/java/io/supertokens/pluginInterface/bulkimport/ImportUserBase.java @@ -0,0 +1,34 @@ +/* + * 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.pluginInterface.bulkimport; + +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; + +public class ImportUserBase { + + public String userId; + public String email; + public TenantIdentifier tenantIdentifier; + public long timeJoinedMSSinceEpoch; + + public ImportUserBase(String userId, String email, TenantIdentifier tenantIdentifier, long timeJoinedMSSinceEpoch) { + this.userId = userId; //this will be the supertokens userId. + this.email = email; + this.tenantIdentifier = tenantIdentifier; + this.timeJoinedMSSinceEpoch = timeJoinedMSSinceEpoch; + } +} diff --git a/src/main/java/io/supertokens/pluginInterface/emailpassword/EmailPasswordImportUser.java b/src/main/java/io/supertokens/pluginInterface/emailpassword/EmailPasswordImportUser.java new file mode 100644 index 00000000..00f254df --- /dev/null +++ b/src/main/java/io/supertokens/pluginInterface/emailpassword/EmailPasswordImportUser.java @@ -0,0 +1,30 @@ +/* + * 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.pluginInterface.emailpassword; + +import io.supertokens.pluginInterface.bulkimport.ImportUserBase; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; + +public class EmailPasswordImportUser extends ImportUserBase { + + public String passwordHash; + + public EmailPasswordImportUser(String userId, String email, String passwordHash, TenantIdentifier tenantId, long timeJoinedInMSSinceEpoch) { + super(userId, email, tenantId, timeJoinedInMSSinceEpoch); + this.passwordHash = passwordHash; + } +} diff --git a/src/main/java/io/supertokens/pluginInterface/emailpassword/EmailPasswordStorage.java b/src/main/java/io/supertokens/pluginInterface/emailpassword/EmailPasswordStorage.java index 1d4aee84..2f9a2c0b 100644 --- a/src/main/java/io/supertokens/pluginInterface/emailpassword/EmailPasswordStorage.java +++ b/src/main/java/io/supertokens/pluginInterface/emailpassword/EmailPasswordStorage.java @@ -23,10 +23,13 @@ import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateUserIdException; 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.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; +import java.util.List; + public interface EmailPasswordStorage extends AuthRecipeStorage { // we pass tenantIdentifier here cause this also adds to the userId <-> tenantId mapping @@ -35,6 +38,10 @@ AuthRecipeUserInfo signUp(TenantIdentifier tenantIdentifier, String id, String e throws StorageQueryException, DuplicateUserIdException, DuplicateEmailException, TenantOrAppNotFoundException; + void signUpMultiple(List users) + throws StorageQueryException, DuplicateUserIdException, DuplicateEmailException, + TenantOrAppNotFoundException, StorageTransactionLogicException; + // password reset stuff is app wide cause changing the password for a user affects all the tenants // across which it's shared. void addPasswordResetToken(AppIdentifier appIdentifier, PasswordResetTokenInfo passwordResetTokenInfo) diff --git a/src/main/java/io/supertokens/pluginInterface/emailverification/sqlStorage/EmailVerificationSQLStorage.java b/src/main/java/io/supertokens/pluginInterface/emailverification/sqlStorage/EmailVerificationSQLStorage.java index 877fb902..bde59d29 100644 --- a/src/main/java/io/supertokens/pluginInterface/emailverification/sqlStorage/EmailVerificationSQLStorage.java +++ b/src/main/java/io/supertokens/pluginInterface/emailverification/sqlStorage/EmailVerificationSQLStorage.java @@ -25,6 +25,8 @@ import io.supertokens.pluginInterface.sqlStorage.SQLStorage; import io.supertokens.pluginInterface.sqlStorage.TransactionConnection; +import java.util.Map; + public interface EmailVerificationSQLStorage extends EmailVerificationStorage, SQLStorage { EmailVerificationTokenInfo[] getAllEmailVerificationTokenInfoForUser_Transaction(TenantIdentifier tenantIdentifier, @@ -42,6 +44,10 @@ void updateIsEmailVerified_Transaction(AppIdentifier appIdentifier, TransactionC boolean isEmailVerified) throws StorageQueryException, TenantOrAppNotFoundException; + void updateMultipleIsEmailVerified_Transaction(AppIdentifier appIdentifier, TransactionConnection con, + Map emailToUserId, boolean isEmailVerified) + throws StorageQueryException, TenantOrAppNotFoundException; + void deleteEmailVerificationUserInfo_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId) throws StorageQueryException; diff --git a/src/main/java/io/supertokens/pluginInterface/passwordless/PasswordlessImportUser.java b/src/main/java/io/supertokens/pluginInterface/passwordless/PasswordlessImportUser.java new file mode 100644 index 00000000..4afb2cf9 --- /dev/null +++ b/src/main/java/io/supertokens/pluginInterface/passwordless/PasswordlessImportUser.java @@ -0,0 +1,30 @@ +/* + * 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.pluginInterface.passwordless; + +import io.supertokens.pluginInterface.bulkimport.ImportUserBase; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; + +public class PasswordlessImportUser extends ImportUserBase { + + public String phoneNumber; + + public PasswordlessImportUser(String userId, String phoneNumber, String email, TenantIdentifier tenantIdentifier, long timeJoinedInMSSinceEpoch) { + super(userId, email, tenantIdentifier, timeJoinedInMSSinceEpoch); + this.phoneNumber = phoneNumber; + } +} diff --git a/src/main/java/io/supertokens/pluginInterface/passwordless/sqlStorage/PasswordlessSQLStorage.java b/src/main/java/io/supertokens/pluginInterface/passwordless/sqlStorage/PasswordlessSQLStorage.java index cfd6dbf7..1235366e 100644 --- a/src/main/java/io/supertokens/pluginInterface/passwordless/sqlStorage/PasswordlessSQLStorage.java +++ b/src/main/java/io/supertokens/pluginInterface/passwordless/sqlStorage/PasswordlessSQLStorage.java @@ -23,6 +23,7 @@ import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.passwordless.PasswordlessCode; import io.supertokens.pluginInterface.passwordless.PasswordlessDevice; +import io.supertokens.pluginInterface.passwordless.PasswordlessImportUser; import io.supertokens.pluginInterface.passwordless.PasswordlessStorage; import io.supertokens.pluginInterface.passwordless.exception.DuplicatePhoneNumberException; import io.supertokens.pluginInterface.sqlStorage.SQLStorage; @@ -30,6 +31,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.Collection; public interface PasswordlessSQLStorage extends PasswordlessStorage, SQLStorage { PasswordlessDevice getDevice_Transaction(TenantIdentifier tenantIdentifier, TransactionConnection con, @@ -85,4 +87,7 @@ void updateUserPhoneNumber_Transaction(AppIdentifier appIdentifier, TransactionC void deletePasswordlessUser_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId, boolean deleteUserIdMappingToo) throws StorageQueryException; + + void importPasswordlessUsers_Transaction(TransactionConnection con, Collection users) + throws StorageQueryException; } diff --git a/src/main/java/io/supertokens/pluginInterface/sqlStorage/SQLStorage.java b/src/main/java/io/supertokens/pluginInterface/sqlStorage/SQLStorage.java index 740aa4b2..a5fa1259 100644 --- a/src/main/java/io/supertokens/pluginInterface/sqlStorage/SQLStorage.java +++ b/src/main/java/io/supertokens/pluginInterface/sqlStorage/SQLStorage.java @@ -39,7 +39,8 @@ KeyValueInfo getKeyValue_Transaction(TenantIdentifier tenantIdentifier, Transact throws StorageQueryException; interface TransactionLogic { - T mainLogicAndCommit(TransactionConnection con) throws StorageQueryException, StorageTransactionLogicException; + T mainLogicAndCommit(TransactionConnection con) + throws StorageQueryException, StorageTransactionLogicException, TenantOrAppNotFoundException; } public enum TransactionIsolationLevel { diff --git a/src/main/java/io/supertokens/pluginInterface/thirdparty/ThirdPartyImportUser.java b/src/main/java/io/supertokens/pluginInterface/thirdparty/ThirdPartyImportUser.java new file mode 100644 index 00000000..e66784d7 --- /dev/null +++ b/src/main/java/io/supertokens/pluginInterface/thirdparty/ThirdPartyImportUser.java @@ -0,0 +1,33 @@ +/* + * 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.pluginInterface.thirdparty; + +import io.supertokens.pluginInterface.bulkimport.ImportUserBase; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; + +public class ThirdPartyImportUser extends ImportUserBase { + + public String thirdpartyId; + public String thirdpartyUserId; + + public ThirdPartyImportUser(String email, String userId, String thirdpartyId, String thirdpartyUserId, + TenantIdentifier tenantIdentifier, long timeJoinedInMSSinceEpoch) { + super(userId, email, tenantIdentifier, timeJoinedInMSSinceEpoch); + this.thirdpartyId = thirdpartyId; + this.thirdpartyUserId = thirdpartyUserId; + } +} diff --git a/src/main/java/io/supertokens/pluginInterface/thirdparty/sqlStorage/ThirdPartySQLStorage.java b/src/main/java/io/supertokens/pluginInterface/thirdparty/sqlStorage/ThirdPartySQLStorage.java index ea55a02f..3e022a16 100644 --- a/src/main/java/io/supertokens/pluginInterface/thirdparty/sqlStorage/ThirdPartySQLStorage.java +++ b/src/main/java/io/supertokens/pluginInterface/thirdparty/sqlStorage/ThirdPartySQLStorage.java @@ -20,8 +20,11 @@ import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.sqlStorage.SQLStorage; import io.supertokens.pluginInterface.sqlStorage.TransactionConnection; +import io.supertokens.pluginInterface.thirdparty.ThirdPartyImportUser; import io.supertokens.pluginInterface.thirdparty.ThirdPartyStorage; +import java.util.Collection; + public interface ThirdPartySQLStorage extends ThirdPartyStorage, SQLStorage { void updateUserEmail_Transaction(AppIdentifier appIdentifier, TransactionConnection con, String thirdPartyId, @@ -31,4 +34,7 @@ void updateUserEmail_Transaction(AppIdentifier appIdentifier, TransactionConnect void deleteThirdPartyUser_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId, boolean deleteUserIdMappingToo) throws StorageQueryException; + + void importThirdPartyUsers_Transaction(TransactionConnection con, Collection usersToImport) + throws StorageQueryException; } diff --git a/src/main/java/io/supertokens/pluginInterface/totp/sqlStorage/TOTPSQLStorage.java b/src/main/java/io/supertokens/pluginInterface/totp/sqlStorage/TOTPSQLStorage.java index ab8cb181..cf9750ca 100644 --- a/src/main/java/io/supertokens/pluginInterface/totp/sqlStorage/TOTPSQLStorage.java +++ b/src/main/java/io/supertokens/pluginInterface/totp/sqlStorage/TOTPSQLStorage.java @@ -13,6 +13,8 @@ import io.supertokens.pluginInterface.totp.exception.UnknownTotpUserIdException; import io.supertokens.pluginInterface.totp.exception.UsedCodeAlreadyExistsException; +import java.util.List; + public interface TOTPSQLStorage extends TOTPStorage, SQLStorage { public int deleteDevice_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId, String deviceName) @@ -47,4 +49,7 @@ TOTPDevice getDeviceByName_Transaction(TransactionConnection con, AppIdentifier TOTPDevice createDevice_Transaction(TransactionConnection con, AppIdentifier appIdentifier, TOTPDevice device) throws StorageQueryException, DeviceAlreadyExistsException, TenantOrAppNotFoundException; + + void createDevices_Transaction(TransactionConnection con, AppIdentifier appIdentifier, List devices) + throws StorageQueryException, TenantOrAppNotFoundException; } diff --git a/src/main/java/io/supertokens/pluginInterface/usermetadata/sqlStorage/UserMetadataSQLStorage.java b/src/main/java/io/supertokens/pluginInterface/usermetadata/sqlStorage/UserMetadataSQLStorage.java index dbe5cc74..d391cf3e 100644 --- a/src/main/java/io/supertokens/pluginInterface/usermetadata/sqlStorage/UserMetadataSQLStorage.java +++ b/src/main/java/io/supertokens/pluginInterface/usermetadata/sqlStorage/UserMetadataSQLStorage.java @@ -24,14 +24,24 @@ import io.supertokens.pluginInterface.sqlStorage.TransactionConnection; import io.supertokens.pluginInterface.usermetadata.UserMetadataStorage; +import java.util.List; +import java.util.Map; + public interface UserMetadataSQLStorage extends UserMetadataStorage, SQLStorage { JsonObject getUserMetadata_Transaction(AppIdentifier appIdentifier, TransactionConnection con, String userId) throws StorageQueryException; + Map getMultipleUsersMetadatas_Transaction(AppIdentifier appIdentifier, TransactionConnection + con, List userIds) + throws StorageQueryException; + int setUserMetadata_Transaction(AppIdentifier appIdentifier, TransactionConnection con, String userId, JsonObject metadata) throws StorageQueryException, TenantOrAppNotFoundException; + void setMultipleUsersMetadatas_Transaction(AppIdentifier appIdentifier, TransactionConnection con, Map metadataByUserId) + throws StorageQueryException, TenantOrAppNotFoundException; + int deleteUserMetadata_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId) throws StorageQueryException; } diff --git a/src/main/java/io/supertokens/pluginInterface/userroles/sqlStorage/UserRolesSQLStorage.java b/src/main/java/io/supertokens/pluginInterface/userroles/sqlStorage/UserRolesSQLStorage.java index c395ff31..b3e7931e 100644 --- a/src/main/java/io/supertokens/pluginInterface/userroles/sqlStorage/UserRolesSQLStorage.java +++ b/src/main/java/io/supertokens/pluginInterface/userroles/sqlStorage/UserRolesSQLStorage.java @@ -25,6 +25,8 @@ import io.supertokens.pluginInterface.userroles.UserRolesStorage; import io.supertokens.pluginInterface.userroles.exception.UnknownRoleException; +import java.util.Map; + public interface UserRolesSQLStorage extends UserRolesStorage, SQLStorage { // delete role associated with the input userId from the input roles @@ -56,4 +58,7 @@ boolean doesRoleExist_Transaction(AppIdentifier appIdentifier, TransactionConnec void deleteAllRolesForUser_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId) throws StorageQueryException; + + void addRolesToUsers_Transaction(TransactionConnection connection, Map> rolesToUserByTenants) + throws StorageQueryException; }