Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Feat/bulk import api 4 #965

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
300592f
feat: Add an api to add bulk import users
anku255 Feb 14, 2024
bb7d84e
fix: PR changes
anku255 Feb 15, 2024
32625d4
fix: PR changes
anku255 Feb 20, 2024
d5f0c67
fix: PR changes
anku255 Feb 20, 2024
d7ba8d1
fix: PR changes
anku255 Feb 22, 2024
1a178db
feat: Add delete bulk import users api
anku255 Feb 23, 2024
4b34b89
fix: PR changes
anku255 Feb 23, 2024
ee82e2d
fix: PR changes
anku255 Feb 26, 2024
290dd92
Merge branch 'feat/bulk-import-api' into feat/bulk-import-api-1
anku255 Feb 27, 2024
3982196
fix: PR changes
anku255 Feb 27, 2024
8c597f2
Merge branch 'feat/bulk-import-api-2' of https://github.com/supertoke…
anku255 Feb 27, 2024
0210602
Merge branch 'feat/bulk-import-api-1' into feat/bulk-import-api-2
anku255 Feb 27, 2024
c02ad54
fix: PR changes
anku255 Feb 27, 2024
7d25645
fix: PR changes
anku255 Feb 27, 2024
3bb6adf
fix: PR changes
anku255 Feb 28, 2024
9285632
fix: PR changes
anku255 Feb 28, 2024
f09cf72
fix: PR changes
anku255 Feb 28, 2024
9967d6d
fix: PR changes
anku255 Feb 28, 2024
0574bfe
fix: PR changes
anku255 Feb 28, 2024
de4e614
Merge branch 'feat/bulk-import-api-1' into feat/bulk-import-api-2
anku255 Feb 28, 2024
9b2a659
fix: PR changes
anku255 Feb 28, 2024
ab7d2bf
fix: Make period and skew optional
anku255 Feb 28, 2024
bee759c
Merge remote-tracking branch 'origin/feat/bulk-import-api-1' into fea…
anku255 Feb 28, 2024
61c9225
fix: Rename deletedUserIds to deletedIds
anku255 Feb 28, 2024
4a3a63d
merge latest (#947)
sattvikc Mar 7, 2024
3f46b5d
fix: add check code API and update delete code API (#948)
sattvikc Mar 11, 2024
bb7dfd8
Merge remote-tracking branch 'origin/feat/mfa' into feat/bulk-import-…
anku255 Mar 11, 2024
233ce9e
fix: build
anku255 Mar 11, 2024
ba4e11b
feat: Add ProcessBulkImportUsers cron job
anku255 Mar 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ highlighting the necessary changes)
latest branch (`git branch --all`) whose `X.Y` is greater than the latest released tag.
- If no such branch exists, then create one from the latest released branch.
- [ ] If added a foreign key constraint on `app_id_to_user_id` table, make sure to delete from this table when deleting the user as well if `deleteUserIdMappingToo` is false.
- [ ] If added a new recipe, then make sure to update the bulk import API to include the new recipe.
## Remaining TODOs for this PR

- [ ] Item1
Expand Down
28 changes: 27 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ 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] - 2023-11-29
## [9.0.0] - 2024-03-04

### Added

Expand Down Expand Up @@ -35,6 +35,32 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

- TODO - copy once postgres / mysql changelog is done

## [8.0.0] - 2024-03-04

### Breaking changes

- 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`
- 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
Expand Down
Binary file modified cli/jar/cli.jar
Binary file not shown.
Binary file modified downloader/jar/downloader.jar
Binary file not shown.
Binary file modified ee/jar/ee.jar
Binary file not shown.
3 changes: 1 addition & 2 deletions ee/src/main/java/io/supertokens/ee/EEFeatureFlag.java
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,7 @@ private JsonObject getMultiTenancyStats()
return stats;
}

private JsonObject getAccountLinkingStats() throws StorageQueryException {
// TODO: Active users are present only on public tenant and MFA users may be present on different storages
private JsonObject getAccountLinkingStats() throws StorageQueryException, TenantOrAppNotFoundException {
JsonObject result = new JsonObject();
Storage[] storages = StorageLayer.getStoragesForApp(main, this.appIdentifier);
boolean usesAccountLinking = false;
Expand Down
Binary file removed jar/core-7.0.18.jar
Binary file not shown.
Binary file added jar/core-8.0.0.jar
Binary file not shown.
35 changes: 12 additions & 23 deletions src/main/java/io/supertokens/ActiveUsers.java
Original file line number Diff line number Diff line change
@@ -1,56 +1,45 @@
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, Main main, String userId)
throws TenantOrAppNotFoundException {
Storage storage = StorageLayer.getStorage(appIdentifier.getAsPublicTenantIdentifier(), main);
try {
appIdentifierWithStorage.getActiveUsersStorage().updateLastActive(appIdentifierWithStorage, userId);
StorageUtils.getActiveUsersStorage(storage).updateLastActive(appIdentifier, userId);
} catch (StorageQueryException ignored) {
}
}

@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),
main, userId);
} catch (TenantOrAppNotFoundException e) {
throw new IllegalStateException(e);
}
}

public static int countUsersActiveSince(AppIdentifierWithStorage appIdentifierWithStorage, Main main, long time)
public static int countUsersActiveSince(Main main, AppIdentifier appIdentifier, long time)
throws StorageQueryException, TenantOrAppNotFoundException {
return appIdentifierWithStorage.getActiveUsersStorage().countUsersActiveSince(appIdentifierWithStorage, time);
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 AppIdentifierWithStorage(null, null, StorageLayer.getStorage(main)), main,
time);
}

public static void removeActiveUser(AppIdentifierWithStorage appIdentifierWithStorage, String userId)
throws StorageQueryException {
try {
((AuthRecipeSQLStorage) appIdentifierWithStorage.getActiveUsersStorage()).startTransaction(con -> {
appIdentifierWithStorage.getActiveUsersStorage().deleteUserActive_Transaction(con, appIdentifierWithStorage, userId);
((AuthRecipeSQLStorage) appIdentifierWithStorage.getActiveUsersStorage()).commitTransaction(con);
return null;
});

} catch (StorageTransactionLogicException e) {
throw new StorageQueryException(e.actualException);
}
return countUsersActiveSince(main, new AppIdentifier(null, null), time);
}
}
4 changes: 4 additions & 0 deletions src/main/java/io/supertokens/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import io.supertokens.config.Config;
import io.supertokens.config.CoreConfig;
import io.supertokens.cronjobs.Cronjobs;
import io.supertokens.cronjobs.bulkimport.ProcessBulkImportUsers;
import io.supertokens.cronjobs.deleteExpiredAccessTokenSigningKeys.DeleteExpiredAccessTokenSigningKeys;
import io.supertokens.cronjobs.deleteExpiredDashboardSessions.DeleteExpiredDashboardSessions;
import io.supertokens.cronjobs.deleteExpiredEmailVerificationTokens.DeleteExpiredEmailVerificationTokens;
Expand Down Expand Up @@ -254,6 +255,9 @@ private void init() throws IOException, StorageQueryException {
// starts DeleteExpiredAccessTokenSigningKeys cronjob if the access token signing keys can change
Cronjobs.addCronjob(this, DeleteExpiredAccessTokenSigningKeys.init(this, uniqueUserPoolIdsTenants));

// starts ProcessBulkImportUsers cronjob to process bulk import users
Cronjobs.addCronjob(this, ProcessBulkImportUsers.init(this, uniqueUserPoolIdsTenants));

// this is to ensure tenantInfos are in sync for the new cron job as well
MultitenancyHelper.getInstance(this).refreshCronjobs();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

This file was deleted.

Loading
Loading