Skip to content

Commit 70328ff

Browse files
committed
Merge remote-tracking branch 'origin/7.2' into feat/oauth/allow-list
2 parents 41107c5 + cff42cb commit 70328ff

File tree

7 files changed

+268
-3
lines changed

7 files changed

+268
-3
lines changed

CHANGELOG.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,62 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## [Unreleased]
99

10+
## [7.2.0] - 2024-10-03
11+
12+
- Compatible with plugin interface version 6.3
13+
- Adds support for OAuthStorage
14+
15+
### Migration
16+
17+
```sql
18+
CREATE TABLE IF NOT EXISTS oauth_clients (
19+
app_id VARCHAR(64),
20+
client_id VARCHAR(128) NOT NULL,
21+
is_client_credentials_only BOOLEAN NOT NULL,
22+
PRIMARY KEY (app_id, client_id),
23+
FOREIGN KEY(app_id) REFERENCES apps(app_id) ON DELETE CASCADE
24+
);
25+
26+
CREATE TABLE IF NOT EXISTS oauth_revoke (
27+
app_id VARCHAR(64) DEFAULT 'public',
28+
target_type VARCHAR(16) NOT NULL,
29+
target_value VARCHAR(128) NOT NULL,
30+
timestamp BIGINT NOT NULL,
31+
exp BIGINT NOT NULL,
32+
PRIMARY KEY (app_id, target_type, target_value),
33+
FOREIGN KEY(app_id) REFERENCES apps(app_id) ON DELETE CASCADE
34+
);
35+
36+
CREATE INDEX IF NOT EXISTS oauth_revoke_timestamp_index ON oauth_revoke(timestamp DESC, app_id DESC);
37+
CREATE INDEX IF NOT EXISTS oauth_revoke_exp_index ON oauth_revoke(exp DESC);
38+
39+
CREATE TABLE IF NOT EXISTS oauth_m2m_tokens (
40+
app_id VARCHAR(64) DEFAULT 'public',
41+
client_id VARCHAR(128) NOT NULL,
42+
iat BIGINT NOT NULL,
43+
exp BIGINT NOT NULL,
44+
PRIMARY KEY (app_id, client_id, iat),
45+
FOREIGN KEY(app_id, client_id) REFERENCES oauth_clients(app_id, client_id) ON DELETE CASCADE
46+
);
47+
48+
CREATE INDEX IF NOT EXISTS oauth_m2m_token_iat_index ON oauth_m2m_tokens(iat DESC, app_id DESC);
49+
CREATE INDEX IF NOT EXISTS oauth_m2m_token_exp_index ON oauth_m2m_tokens(exp DESC);
50+
51+
CREATE TABLE IF NOT EXISTS oauth_logout_challenges (
52+
app_id VARCHAR(64) DEFAULT 'public',
53+
challenge VARCHAR(128) NOT NULL,
54+
client_id VARCHAR(128) NOT NULL,
55+
post_logout_redirect_uri VARCHAR(1024),
56+
session_handle VARCHAR(128),
57+
state VARCHAR(128),
58+
time_created BIGINT NOT NULL,
59+
PRIMARY KEY (app_id, challenge),
60+
FOREIGN KEY(app_id, client_id) REFERENCES oauth_clients(app_id, client_id) ON DELETE CASCADE
61+
);
62+
63+
CREATE INDEX IF NOT EXISTS oauth_logout_challenges_time_created_index ON oauth_logout_challenges(time_created DESC);
64+
```
65+
1066
## [7.1.3] - 2024-09-04
1167

1268
- Adds index on `last_active_time` for `user_last_active` table to improve the performance of MAU computation.

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ plugins {
22
id 'java-library'
33
}
44

5-
version = "7.1.3"
5+
version = "7.2.0"
66

77
repositories {
88
mavenCentral()

pluginInterfaceSupported.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"_comment": "contains a list of plugin interfaces branch names that this core supports",
33
"versions": [
4-
"6.2"
4+
"6.3"
55
]
66
}

src/main/java/io/supertokens/storage/postgresql/Start.java

Lines changed: 190 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ public class Start
132132
private ResourceDistributor resourceDistributor = new ResourceDistributor();
133133
private String processId;
134134
private HikariLoggingAppender appender;
135-
private static final String APP_ID_KEY_NAME = "app_id";
136135
private static final String ACCESS_TOKEN_SIGNING_KEY_NAME = "access_token_signing_key";
137136
private static final String REFRESH_TOKEN_KEY_NAME = "refresh_token_key";
138137
public static boolean isTesting = false;
@@ -875,6 +874,8 @@ public void addInfoToNonAuthRecipesBasedOnUserId(TenantIdentifier tenantIdentifi
875874
}
876875
} else if (className.equals(JWTRecipeStorage.class.getName())) {
877876
/* Since JWT recipe tables do not store userId we do not add any data to them */
877+
} else if (className.equals(OAuthStorage.class.getName())) {
878+
/* Since OAuth recipe tables do not store userId we do not add any data to them */
878879
} else if (className.equals(ActiveUsersStorage.class.getName())) {
879880
try {
880881
ActiveUsersQueries.updateUserLastActive(this, tenantIdentifier.toAppIdentifier(), userId);
@@ -3100,6 +3101,194 @@ public int countUsersThatHaveMoreThanOneLoginMethodOrTOTPEnabledAndActiveSince(A
31003101
}
31013102
}
31023103

3104+
@Override
3105+
public boolean doesOAuthClientIdExist(AppIdentifier appIdentifier, String clientId)
3106+
throws StorageQueryException {
3107+
try {
3108+
return OAuthQueries.doesOAuthClientIdExist(this, clientId, appIdentifier);
3109+
} catch (SQLException e) {
3110+
throw new StorageQueryException(e);
3111+
}
3112+
}
3113+
3114+
@Override
3115+
public void addOrUpdateOauthClient(AppIdentifier appIdentifier, String clientId, boolean isClientCredentialsOnly)
3116+
throws StorageQueryException, TenantOrAppNotFoundException {
3117+
try {
3118+
OAuthQueries.addOrUpdateOauthClient(this, appIdentifier, clientId, isClientCredentialsOnly);
3119+
} catch (SQLException e) {
3120+
PostgreSQLConfig config = Config.getConfig(this);
3121+
if (e instanceof PSQLException) {
3122+
ServerErrorMessage serverMessage = ((PSQLException) e).getServerErrorMessage();
3123+
3124+
if (isForeignKeyConstraintError(serverMessage, config.getOAuthClientsTable(), "app_id")) {
3125+
throw new TenantOrAppNotFoundException(appIdentifier);
3126+
}
3127+
}
3128+
throw new StorageQueryException(e);
3129+
}
3130+
}
3131+
3132+
@Override
3133+
public boolean deleteOAuthClient(AppIdentifier appIdentifier, String clientId) throws StorageQueryException {
3134+
try {
3135+
return OAuthQueries.deleteOAuthClient(this, clientId, appIdentifier);
3136+
} catch (SQLException e) {
3137+
throw new StorageQueryException(e);
3138+
}
3139+
}
3140+
3141+
@Override
3142+
public List<String> listOAuthClients(AppIdentifier appIdentifier) throws StorageQueryException {
3143+
try {
3144+
return OAuthQueries.listOAuthClients(this, appIdentifier);
3145+
} catch (SQLException e) {
3146+
throw new StorageQueryException(e);
3147+
}
3148+
}
3149+
3150+
@Override
3151+
public void revokeOAuthTokensBasedOnTargetFields(AppIdentifier appIdentifier, OAuthRevokeTargetType targetType, String targetValue, long exp)
3152+
throws StorageQueryException, TenantOrAppNotFoundException {
3153+
try {
3154+
OAuthQueries.revokeOAuthTokensBasedOnTargetFields(this, appIdentifier, targetType, targetValue, exp);
3155+
} catch (SQLException e) {
3156+
PostgreSQLConfig config = Config.getConfig(this);
3157+
if (e instanceof PSQLException) {
3158+
ServerErrorMessage serverMessage = ((PSQLException) e).getServerErrorMessage();
3159+
3160+
if (isForeignKeyConstraintError(serverMessage, config.getOAuthRevokeTable(), "app_id")) {
3161+
throw new TenantOrAppNotFoundException(appIdentifier);
3162+
}
3163+
}
3164+
throw new StorageQueryException(e);
3165+
}
3166+
3167+
}
3168+
3169+
@Override
3170+
public boolean isOAuthTokenRevokedBasedOnTargetFields(AppIdentifier appIdentifier, OAuthRevokeTargetType[] targetTypes, String[] targetValues, long issuedAt)
3171+
throws StorageQueryException {
3172+
try {
3173+
return OAuthQueries.isOAuthTokenRevokedBasedOnTargetFields(this, appIdentifier, targetTypes, targetValues, issuedAt);
3174+
} catch (SQLException e) {
3175+
throw new StorageQueryException(e);
3176+
}
3177+
}
3178+
3179+
@Override
3180+
public void addOAuthM2MTokenForStats(AppIdentifier appIdentifier, String clientId, long iat, long exp)
3181+
throws StorageQueryException, OAuthClientNotFoundException {
3182+
try {
3183+
OAuthQueries.addOAuthM2MTokenForStats(this, appIdentifier, clientId, iat, exp);
3184+
} catch (SQLException e) {
3185+
PostgreSQLConfig config = Config.getConfig(this);
3186+
if (e instanceof PSQLException) {
3187+
ServerErrorMessage serverMessage = ((PSQLException) e).getServerErrorMessage();
3188+
3189+
if (isForeignKeyConstraintError(serverMessage, config.getOAuthM2MTokensTable(), "client_id")) {
3190+
throw new OAuthClientNotFoundException();
3191+
}
3192+
}
3193+
throw new StorageQueryException(e);
3194+
}
3195+
}
3196+
3197+
@Override
3198+
public void cleanUpExpiredAndRevokedOAuthTokensList() throws StorageQueryException {
3199+
try {
3200+
OAuthQueries.cleanUpExpiredAndRevokedOAuthTokensList(this);
3201+
} catch (SQLException e) {
3202+
throw new StorageQueryException(e);
3203+
}
3204+
}
3205+
3206+
@Override
3207+
public void addOAuthLogoutChallenge(AppIdentifier appIdentifier, String challenge, String clientId,
3208+
String postLogoutRedirectionUri, String sessionHandle, String state, long timeCreated)
3209+
throws StorageQueryException, DuplicateOAuthLogoutChallengeException, OAuthClientNotFoundException {
3210+
try {
3211+
OAuthQueries.addOAuthLogoutChallenge(this, appIdentifier, challenge, clientId, postLogoutRedirectionUri, sessionHandle, state, timeCreated);
3212+
} catch (SQLException e) {
3213+
PostgreSQLConfig config = Config.getConfig(this);
3214+
if (e instanceof PSQLException) {
3215+
ServerErrorMessage serverMessage = ((PSQLException) e).getServerErrorMessage();
3216+
3217+
if (isPrimaryKeyError(serverMessage, config.getOAuthLogoutChallengesTable())) {
3218+
throw new DuplicateOAuthLogoutChallengeException();
3219+
} else if (isForeignKeyConstraintError(serverMessage, config.getOAuthLogoutChallengesTable(), "client_id")) {
3220+
throw new OAuthClientNotFoundException();
3221+
}
3222+
}
3223+
throw new StorageQueryException(e);
3224+
}
3225+
}
3226+
3227+
@Override
3228+
public OAuthLogoutChallenge getOAuthLogoutChallenge(AppIdentifier appIdentifier, String challenge) throws StorageQueryException {
3229+
try {
3230+
return OAuthQueries.getOAuthLogoutChallenge(this, appIdentifier, challenge);
3231+
} catch (SQLException e) {
3232+
throw new StorageQueryException(e);
3233+
}
3234+
}
3235+
3236+
@Override
3237+
public void deleteOAuthLogoutChallenge(AppIdentifier appIdentifier, String challenge) throws StorageQueryException {
3238+
try {
3239+
OAuthQueries.deleteOAuthLogoutChallenge(this, appIdentifier, challenge);
3240+
} catch (SQLException e) {
3241+
throw new StorageQueryException(e);
3242+
}
3243+
}
3244+
3245+
@Override
3246+
public void deleteOAuthLogoutChallengesBefore(long time) throws StorageQueryException {
3247+
try {
3248+
OAuthQueries.deleteOAuthLogoutChallengesBefore(this, time);
3249+
} catch (SQLException e) {
3250+
throw new StorageQueryException(e);
3251+
}
3252+
}
3253+
3254+
@Override
3255+
public int countTotalNumberOfOAuthClients(AppIdentifier appIdentifier) throws StorageQueryException {
3256+
try {
3257+
return OAuthQueries.countTotalNumberOfClients(this, appIdentifier, false);
3258+
} catch (SQLException e) {
3259+
throw new StorageQueryException(e);
3260+
}
3261+
}
3262+
3263+
@Override
3264+
public int countTotalNumberOfClientCredentialsOnlyOAuthClients(AppIdentifier appIdentifier)
3265+
throws StorageQueryException {
3266+
try {
3267+
return OAuthQueries.countTotalNumberOfClients(this, appIdentifier, true);
3268+
} catch (SQLException e) {
3269+
throw new StorageQueryException(e);
3270+
}
3271+
}
3272+
3273+
@Override
3274+
public int countTotalNumberOfOAuthM2MTokensCreatedSince(AppIdentifier appIdentifier, long since)
3275+
throws StorageQueryException {
3276+
try {
3277+
return OAuthQueries.countTotalNumberOfOAuthM2MTokensCreatedSince(this, appIdentifier, since);
3278+
} catch (SQLException e) {
3279+
throw new StorageQueryException(e);
3280+
}
3281+
}
3282+
3283+
@Override
3284+
public int countTotalNumberOfOAuthM2MTokensAlive(AppIdentifier appIdentifier) throws StorageQueryException {
3285+
try {
3286+
return OAuthQueries.countTotalNumberOfOAuthM2MTokensAlive(this, appIdentifier);
3287+
} catch (SQLException e) {
3288+
throw new StorageQueryException(e);
3289+
}
3290+
}
3291+
31033292
@TestOnly
31043293
public int getDbActivityCount(String dbname) throws SQLException, StorageQueryException {
31053294
String QUERY = "SELECT COUNT(*) as c FROM pg_stat_activity WHERE datname = ?;";

src/main/java/io/supertokens/storage/postgresql/config/PostgreSQLConfig.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,22 @@ public String getDashboardSessionsTable() {
434434
return addSchemaAndPrefixToTableName("dashboard_user_sessions");
435435
}
436436

437+
public String getOAuthClientsTable() {
438+
return addSchemaAndPrefixToTableName("oauth_clients");
439+
}
440+
441+
public String getOAuthRevokeTable() {
442+
return addSchemaAndPrefixToTableName("oauth_revoke");
443+
}
444+
445+
public String getOAuthM2MTokensTable() {
446+
return addSchemaAndPrefixToTableName("oauth_m2m_tokens");
447+
}
448+
449+
public String getOAuthLogoutChallengesTable() {
450+
return addSchemaAndPrefixToTableName("oauth_logout_challenges");
451+
}
452+
437453
public String getTotpUsersTable() {
438454
return addSchemaAndPrefixToTableName("totp_users");
439455
}

src/main/java/io/supertokens/storage/postgresql/queries/GeneralQueries.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,10 @@ public static void deleteAllTables(Start start) throws SQLException, StorageQuer
655655
+ getConfig(start).getUserRolesTable() + ","
656656
+ getConfig(start).getDashboardUsersTable() + ","
657657
+ getConfig(start).getDashboardSessionsTable() + ","
658+
+ getConfig(start).getOAuthClientsTable() + ","
659+
+ getConfig(start).getOAuthRevokeTable() + ","
660+
+ getConfig(start).getOAuthM2MTokensTable() + ","
661+
+ getConfig(start).getOAuthLogoutChallengesTable() + ","
658662
+ getConfig(start).getTotpUsedCodesTable() + ","
659663
+ getConfig(start).getTotpUserDevicesTable() + ","
660664
+ getConfig(start).getTotpUsersTable() + ","

0 commit comments

Comments
 (0)