Skip to content

Commit

Permalink
fix: review fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
tamassoltesz committed Oct 25, 2024
1 parent a4b1cf0 commit 887234d
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 180 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

package io.supertokens.inmemorydb;

import io.supertokens.pluginInterface.exceptions.StorageQueryException;

import java.sql.PreparedStatement;
import java.sql.SQLException;

Expand All @@ -26,5 +24,5 @@ public interface PreparedStatementValueSetter {
PreparedStatementValueSetter NO_OP_SETTER = pst -> {
};

void setValues(PreparedStatement pst) throws SQLException, StorageQueryException;
void setValues(PreparedStatement pst) throws SQLException;
}
44 changes: 13 additions & 31 deletions src/main/java/io/supertokens/inmemorydb/Start.java
Original file line number Diff line number Diff line change
Expand Up @@ -3196,11 +3196,23 @@ public void deleteOAuthLogoutChallengesBefore(long time) throws StorageQueryExce
public void createOrUpdateOAuthSession(AppIdentifier appIdentifier, String gid, String clientId,
String externalRefreshToken, String internalRefreshToken,
String sessionHandle, List<String> jtis, long exp)
throws StorageQueryException {
throws StorageQueryException, TenantOrAppNotFoundException {
try {
OAuthQueries.createOrUpdateOAuthSession(this, appIdentifier, gid, clientId, externalRefreshToken,
internalRefreshToken, sessionHandle, jtis, exp);
} catch (SQLException e) {
if (e instanceof SQLiteException) {
String errorMessage = e.getMessage();
SQLiteConfig config = Config.getConfig(this);

if (isForeignKeyConstraintError(
errorMessage,
config.getAppsTable(),
new String[]{"app_id"},
new Object[]{appIdentifier.getAppId()})) {
throw new TenantOrAppNotFoundException(appIdentifier);
}
}
throw new StorageQueryException(e);
}
}
Expand All @@ -3215,16 +3227,6 @@ public String getRefreshTokenMapping(AppIdentifier appIdentifier, String externa
}
}

@Override
public void deleteRefreshTokenMapping(AppIdentifier appIdentifier, String externalRefreshToken)
throws StorageQueryException {
try {
OAuthQueries.deleteRefreshTokenMapping(this, appIdentifier, externalRefreshToken);
} catch (SQLException e) {
throw new StorageQueryException(e);
}
}

@Override
public void deleteExpiredOAuthSessions(long exp) throws StorageQueryException {
try {
Expand Down Expand Up @@ -3272,16 +3274,6 @@ public int countTotalNumberOfOAuthM2MTokensAlive(AppIdentifier appIdentifier) th
}
}

@Override
public boolean isOAuthTokenRevokedByClientId(AppIdentifier appIdentifier, String clientId)
throws StorageQueryException {
try {
return !OAuthQueries.isOAuthSessionExistsByClientId(this, appIdentifier, clientId);
} catch (SQLException e) {
throw new StorageQueryException(e);
}
}

@Override
public boolean isOAuthTokenRevokedByGID(AppIdentifier appIdentifier, String gid) throws StorageQueryException {
try {
Expand All @@ -3300,14 +3292,4 @@ public boolean isOAuthTokenRevokedByJTI(AppIdentifier appIdentifier, String gid,
throw new StorageQueryException(e);
}
}

@Override
public boolean isOAuthTokenRevokedBySessionHandle(AppIdentifier appIdentifier, String sessionHandle)
throws StorageQueryException {
try {
return !OAuthQueries.isOAuthSessionExistsBySessionHandle(this, appIdentifier, sessionHandle);
} catch (SQLException e) {
throw new StorageQueryException(e);
}
}
}
121 changes: 23 additions & 98 deletions src/main/java/io/supertokens/inmemorydb/queries/OAuthQueries.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static io.supertokens.inmemorydb.QueryExecutorTemplate.execute;
import static io.supertokens.inmemorydb.QueryExecutorTemplate.update;
Expand Down Expand Up @@ -151,7 +153,7 @@ public static void createOrUpdateOAuthSession(Start start, AppIdentifier appIden
String QUERY = "INSERT INTO " + Config.getConfig(start).getOAuthSessionsTable() +
" (gid, client_id, app_id, external_refresh_token, internal_refresh_token, session_handle, jti, exp) VALUES (?, ?, ?, ?, ?, ?, ?, ?) " +
"ON CONFLICT (gid) DO UPDATE SET external_refresh_token = ?, internal_refresh_token = ?, " +
"session_handle = ? , jti = ?, exp = ?";
"session_handle = ? , jti = CONCAT(jti, ',' , ?), exp = ?";
update(start, QUERY, pst -> {
String jtiDbValue = jtis == null ? null : String.join(",", jtis);

Expand All @@ -164,20 +166,11 @@ public static void createOrUpdateOAuthSession(Start start, AppIdentifier appIden
pst.setString(7, jtiDbValue);
pst.setLong(8, exp);

List<String> alreadySavedJTIs = getOAuthJTIsByGID(start, appIdentifier, gid);
if(alreadySavedJTIs != null) {
if(jtiDbValue != null) {
jtiDbValue += ",";
}
jtiDbValue += String.join(",", alreadySavedJTIs);
}

pst.setString(9, externalRefreshToken);
pst.setString(10, internalRefreshToken);
pst.setString(11, sessionHandle);
pst.setString(12, jtiDbValue);
pst.setLong(13, exp);

});
}

Expand Down Expand Up @@ -233,7 +226,7 @@ public static boolean deleteOAuthClient(Start start, String clientId, AppIdentif
public static boolean deleteOAuthSessionByGID(Start start, AppIdentifier appIdentifier, String gid)
throws SQLException, StorageQueryException {
String DELETE = "DELETE FROM " + Config.getConfig(start).getOAuthSessionsTable()
+ " WHERE gid = ? and app_id = ?";
+ " WHERE gid = ? and app_id = ?;";
int numberOfRows = update(start, DELETE, pst -> {
pst.setString(1, gid);
pst.setString(2, appIdentifier.getAppId());
Expand All @@ -244,7 +237,7 @@ public static boolean deleteOAuthSessionByGID(Start start, AppIdentifier appIden
public static boolean deleteOAuthSessionByClientId(Start start, AppIdentifier appIdentifier, String clientId)
throws SQLException, StorageQueryException {
String DELETE = "DELETE FROM " + Config.getConfig(start).getOAuthSessionsTable()
+ " WHERE app_id = ? and client_id = ?";
+ " WHERE app_id = ? and client_id = ?;";
int numberOfRows = update(start, DELETE, pst -> {
pst.setString(1, appIdentifier.getAppId());
pst.setString(2, clientId);
Expand All @@ -266,14 +259,15 @@ public static boolean deleteOAuthSessionBySessionHandle(Start start, AppIdentifi
public static boolean deleteJTIFromOAuthSession(Start start, AppIdentifier appIdentifier, String gid, String jti)
throws SQLException, StorageQueryException {
//jti is a comma separated list. When deleting a jti, just have to delete from the list
List<String> savedJTIs = getOAuthJTIsByGID(start, appIdentifier, gid);
List<String> toSaveJTIs = new ArrayList<>(savedJTIs);
boolean deletionHappened = false;
if (toSaveJTIs != null && toSaveJTIs.contains(jti)){
toSaveJTIs.remove(jti);
deletionHappened = updateOAuthJTIsByGID(start, appIdentifier, gid, toSaveJTIs) > 0;
}
return deletionHappened;
String DELETE = "UPDATE " + Config.getConfig(start).getOAuthSessionsTable()
+ " SET jti = REPLACE(jti, ?, '')" // deletion means replacing the jti with empty char
+ " WHERE app_id = ? and gid = ?";
int numberOfRows = update(start, DELETE, pst -> {
pst.setString(1, jti);
pst.setString(2, appIdentifier.getAppId());
pst.setString(3, gid);
});
return numberOfRows > 0;
}

public static int countTotalNumberOfClients(Start start, AppIdentifier appIdentifier,
Expand Down Expand Up @@ -415,45 +409,6 @@ public static String getRefreshTokenMapping(Start start, AppIdentifier appIdenti
});
}

public static void deleteRefreshTokenMapping(Start start, AppIdentifier appIdentifier,
String externalRefreshToken) throws SQLException, StorageQueryException {
String QUERY = "UPDATE " + Config.getConfig(start).getOAuthSessionsTable() +
" SET external_refresh_token = ?, internal_refresh_token = ?" +
" WHERE app_id = ? AND external_refresh_token = ?";
update(start, QUERY, pst -> {
pst.setString(1, null);
pst.setString(2, null);
pst.setString(3, appIdentifier.getAppId());
pst.setString(4, externalRefreshToken);
});
}

public static List<String> getOAuthJTIsByGID(Start start, AppIdentifier appIdentifier, String gid)
throws SQLException, StorageQueryException {
String SELECT = "SELECT jti FROM " + Config.getConfig(start).getOAuthSessionsTable() +
" WHERE app_id = ? AND gid = ?";
return execute(start, SELECT, pst -> {
pst.setString(1, appIdentifier.getAppId());
pst.setString(2, gid);
}, result -> {
if (result.next()) {
return List.of(result.getString("jti").split(","));
}
return null;
});
}

public static int updateOAuthJTIsByGID(Start start, AppIdentifier appIdentifier, String gid, List<String> jtis)
throws SQLException, StorageQueryException {
String UPDATE = "UPDATE " + Config.getConfig(start).getOAuthSessionsTable() +
" SET jti = ? WHERE app_id = ? AND gid = ?";
return update(start, UPDATE, pst -> {
pst.setString(1, String.join(",", jtis));
pst.setString(2, appIdentifier.getAppId());
pst.setString(3, gid);
});
}

public static void deleteExpiredOAuthSessions(Start start, long exp) throws SQLException, StorageQueryException {
// delete expired M2M tokens
String QUERY = "DELETE FROM " + Config.getConfig(start).getOAuthSessionsTable() +
Expand All @@ -468,68 +423,38 @@ public static void deleteExpiredOAuthM2MTokens(Start start, long exp) throws SQL
// delete expired M2M tokens
String QUERY = "DELETE FROM " + Config.getConfig(start).getOAuthM2MTokensTable() +
" WHERE exp < ?";

update(start, QUERY, pst -> {
pst.setLong(1, exp);
});
}

public static boolean isOAuthSessionExistsByGID(Start start, AppIdentifier appIdentifier, String gid)
public static boolean isOAuthSessionExistsByJTI(Start start, AppIdentifier appIdentifier, String gid, String jti)
throws SQLException, StorageQueryException {
String SELECT = "SELECT count(*) FROM " + Config.getConfig(start).getOAuthSessionsTable()
+ " WHERE app_id = ? and gid = ?";
String SELECT = "SELECT jti FROM " + Config.getConfig(start).getOAuthSessionsTable()
+ " WHERE app_id = ? and gid = ?;";
return execute(start, SELECT, pst -> {
pst.setString(1, appIdentifier.getAppId());
pst.setString(2, gid);
}, result -> {
if(result.next()){
return result.getInt(1) > 0;
List<String> jtis = Arrays.stream(result.getString(1).split(",")).filter(s -> !s.isEmpty()).collect(
Collectors.toList());
return jtis.contains(jti);
}
return false;
});
}

public static boolean isOAuthSessionExistsByClientId(Start start, AppIdentifier appIdentifier, String clientId)
public static boolean isOAuthSessionExistsByGID(Start start, AppIdentifier appIdentifier, String gid)
throws SQLException, StorageQueryException {
String SELECT = "SELECT count(*) FROM " + Config.getConfig(start).getOAuthSessionsTable()
+ " WHERE app_id = ? and client_id = ?";
return execute(start, SELECT, pst -> {
pst.setString(1, appIdentifier.getAppId());
pst.setString(2, clientId);
}, result -> {
if(result.next()){
return result.getInt(1) > 0;
}
return false;
});
}

public static boolean isOAuthSessionExistsBySessionHandle(Start start, AppIdentifier appIdentifier, String sessionHandle)
throws SQLException, StorageQueryException {
String SELECT = "SELECT count(*) FROM " + Config.getConfig(start).getOAuthSessionsTable()
+ " WHERE app_id = ? and session_handle = ?";
return execute(start, SELECT, pst -> {
pst.setString(1, appIdentifier.getAppId());
pst.setString(2, sessionHandle);
}, result -> {
if(result.next()){
return result.getInt(1) > 0;
}
return false;
});
}

public static boolean isOAuthSessionExistsByJTI(Start start, AppIdentifier appIdentifier, String gid, String jti)
throws SQLException, StorageQueryException {
String SELECT = "SELECT jti FROM " + Config.getConfig(start).getOAuthSessionsTable()
+ " WHERE app_id = ? and gid = ?";
+ " WHERE app_id = ? and gid = ?;";
return execute(start, SELECT, pst -> {
pst.setString(1, appIdentifier.getAppId());
pst.setString(2, gid);
}, result -> {
if(result.next()){
List<String> jtis = List.of(result.getString(1).split(","));
return jtis.contains(jti);
return result.getInt(1) > 0;
}
return false;
});
Expand Down
39 changes: 11 additions & 28 deletions src/main/java/io/supertokens/oauth/OAuth.java
Original file line number Diff line number Diff line change
Expand Up @@ -496,23 +496,14 @@ public static void verifyAndUpdateIntrospectRefreshTokenPayload(Main main, AppId
}

private static boolean isTokenRevokedBasedOnPayload(OAuthStorage oauthStorage, AppIdentifier appIdentifier, JsonObject payload) throws StorageQueryException {
long issuedAt = payload.get("iat").getAsLong();
boolean revoked = false;

revoked = oauthStorage.isOAuthTokenRevokedByClientId(appIdentifier, payload.get("client_id").getAsString());

boolean revoked = true;
if (payload.has("jti") && payload.has("gid")) {
revoked = revoked || oauthStorage.isOAuthTokenRevokedByJTI(appIdentifier, payload.get("gid").getAsString(), payload.get("jti").getAsString());
}

if (payload.has("gid")) {
revoked = revoked || oauthStorage.isOAuthTokenRevokedByGID(appIdentifier, payload.get("gid").getAsString());
}

if (payload.has("sessionHandle")) {
revoked = revoked || oauthStorage.isOAuthTokenRevokedBySessionHandle(appIdentifier, payload.get("sessionHandle").getAsString());
//access token
revoked = oauthStorage.isOAuthTokenRevokedByJTI(appIdentifier, payload.get("gid").getAsString(), payload.get("jti").getAsString());
} else {
// refresh token
revoked = oauthStorage.isOAuthTokenRevokedByGID(appIdentifier, payload.get("gid").getAsString());
}

return revoked;
}

Expand Down Expand Up @@ -551,7 +542,7 @@ public static void revokeTokensForClientId(Main main, AppIdentifier appIdentifie
oauthStorage.revokeOAuthTokenByClientId(appIdentifier, clientId);
}

public static void revokeRefreshToken(Main main, AppIdentifier appIdentifier, Storage storage, String gid, long exp)
public static void revokeRefreshToken(Main main, AppIdentifier appIdentifier, Storage storage, String gid)
throws StorageQueryException, NoSuchAlgorithmException, TenantOrAppNotFoundException {
OAuthStorage oauthStorage = StorageUtils.getOAuthStorage(storage);
oauthStorage.revokeOAuthTokenByGID(appIdentifier, gid);
Expand All @@ -562,9 +553,6 @@ public static void revokeAccessToken(Main main, AppIdentifier appIdentifier,
try {
OAuthStorage oauthStorage = StorageUtils.getOAuthStorage(storage);
JsonObject payload = OAuthToken.getPayloadFromJWTToken(appIdentifier, main, token);

long exp = payload.get("exp").getAsLong();

if (payload.has("stt") && payload.get("stt").getAsInt() == OAuthToken.TokenType.ACCESS_TOKEN.getValue()) {
String jti = payload.get("jti").getAsString();
String gid = payload.get("gid").getAsString();
Expand Down Expand Up @@ -669,17 +657,12 @@ public static String getInternalRefreshToken(Main main, AppIdentifier appIdentif
return internalRefreshToken;
}

public static void createOrUpdateRefreshTokenMapping(Main main, AppIdentifier appIdentifier, Storage storage,
String clientId, String gid, String externalRefreshToken, String internalRefreshToken,
String sessionHandle, List<String> jtis, long exp) throws StorageQueryException {
public static void createOrUpdateOauthSession(Main main, AppIdentifier appIdentifier, Storage storage,
String clientId, String gid, String externalRefreshToken, String internalRefreshToken,
String sessionHandle, List<String> jtis, long exp)
throws StorageQueryException, TenantOrAppNotFoundException {
OAuthStorage oauthStorage = StorageUtils.getOAuthStorage(storage);
oauthStorage.createOrUpdateOAuthSession(appIdentifier, gid, clientId, externalRefreshToken, internalRefreshToken,
sessionHandle, jtis, exp);
}

public static void deleteRefreshTokenMappingIfExists(Main main, AppIdentifier appIdentifier, Storage storage,
String externalRefreshToken) throws StorageQueryException {
OAuthStorage oauthStorage = StorageUtils.getOAuthStorage(storage);
oauthStorage.deleteRefreshTokenMapping(appIdentifier, externalRefreshToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
updateLastActive(appIdentifier, sessionHandle);
}

OAuth.createOrUpdateRefreshTokenMapping(main, appIdentifier, storage, clientId, gid, null, null, sessionHandle, List.of(jti), exp);
OAuth.createOrUpdateOauthSession(main, appIdentifier, storage, clientId, gid, null, null, sessionHandle, List.of(jti), exp);
}
}
}
Expand Down
Loading

0 comments on commit 887234d

Please sign in to comment.