diff --git a/src/main/java/io/supertokens/inmemorydb/Start.java b/src/main/java/io/supertokens/inmemorydb/Start.java index dcf416dbd..10a35343e 100644 --- a/src/main/java/io/supertokens/inmemorydb/Start.java +++ b/src/main/java/io/supertokens/inmemorydb/Start.java @@ -55,7 +55,6 @@ import io.supertokens.pluginInterface.multitenancy.exceptions.DuplicateThirdPartyIdException; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.multitenancy.sqlStorage.MultitenancySQLStorage; -import io.supertokens.pluginInterface.oauth.exceptions.OAuth2ClientAlreadyExistsForAppException; import io.supertokens.pluginInterface.oauth.sqlStorage.OAuthSQLStorage; import io.supertokens.pluginInterface.passwordless.PasswordlessCode; import io.supertokens.pluginInterface.passwordless.PasswordlessDevice; @@ -3022,18 +3021,10 @@ public boolean doesClientIdExistForApp(AppIdentifier appIdentifier, String clien @Override public void addOrUpdateClientForApp(AppIdentifier appIdentifier, String clientId, boolean isClientCredentialsOnly) - throws StorageQueryException, OAuth2ClientAlreadyExistsForAppException { + throws StorageQueryException { try { OAuthQueries.insertClientIdForAppId(this, clientId, appIdentifier); } catch (SQLException e) { - - SQLiteConfig config = Config.getConfig(this); - String serverErrorMessage = e.getMessage(); - - if (isPrimaryKeyError(serverErrorMessage, config.getOAuthClientTable(), - new String[]{"app_id", "client_id"})) { - throw new OAuth2ClientAlreadyExistsForAppException(); - } throw new StorageQueryException(e); } } diff --git a/src/main/java/io/supertokens/oauth/OAuth.java b/src/main/java/io/supertokens/oauth/OAuth.java index c30ec4e70..636124f98 100644 --- a/src/main/java/io/supertokens/oauth/OAuth.java +++ b/src/main/java/io/supertokens/oauth/OAuth.java @@ -37,7 +37,6 @@ import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.oauth.OAuthStorage; -import io.supertokens.pluginInterface.oauth.exceptions.OAuth2ClientAlreadyExistsForAppException; import io.supertokens.session.jwt.JWT.JWTException; import io.supertokens.utils.Utils; @@ -366,7 +365,7 @@ public static JsonObject transformTokens(Main main, AppIdentifier appIdentifier, return jsonBody; } - public static void addClientId(Main main, AppIdentifier appIdentifier, Storage storage, String clientId, boolean isClientCredentialsOnly) throws StorageQueryException, OAuth2ClientAlreadyExistsForAppException { + public static void addOrUpdateClientId(Main main, AppIdentifier appIdentifier, Storage storage, String clientId, boolean isClientCredentialsOnly) throws StorageQueryException { OAuthStorage oauthStorage = StorageUtils.getOAuthStorage(storage); oauthStorage.addOrUpdateClientForApp(appIdentifier, clientId, isClientCredentialsOnly); } diff --git a/src/main/java/io/supertokens/webserver/api/oauth/CreateUpdateOrGetOAuthClientAPI.java b/src/main/java/io/supertokens/webserver/api/oauth/CreateUpdateOrGetOAuthClientAPI.java index 0fca7b698..7203f0949 100644 --- a/src/main/java/io/supertokens/webserver/api/oauth/CreateUpdateOrGetOAuthClientAPI.java +++ b/src/main/java/io/supertokens/webserver/api/oauth/CreateUpdateOrGetOAuthClientAPI.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; +import java.util.UUID; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -37,7 +38,6 @@ import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; -import io.supertokens.pluginInterface.oauth.exceptions.OAuth2ClientAlreadyExistsForAppException; import io.supertokens.webserver.InputParser; import io.supertokens.webserver.WebserverAPI; import jakarta.servlet.ServletException; @@ -88,6 +88,12 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I input.addProperty("accessTokenStrategy", "jwt"); input.addProperty("skipConsent", true); input.addProperty("subjectType", "public"); + input.addProperty("clientId", "stcl_" + UUID.randomUUID()); + + boolean isClientCredentialsOnly = input.has("grantTypes") && + input.get("grantTypes").isJsonArray() && + input.get("grantTypes").getAsJsonArray().size() == 1 && + input.get("grantTypes").getAsJsonArray().get(0).getAsString().equals("client_credentials"); try { AppIdentifier appIdentifier = getAppIdentifier(req); @@ -110,11 +116,9 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I String clientId = response.jsonResponse.getAsJsonObject().get("clientId").getAsString(); try { - OAuth.addClientId(main, getAppIdentifier(req), enforcePublicTenantAndGetPublicTenantStorage(req), clientId, false); // FIXME + OAuth.addOrUpdateClientId(main, getAppIdentifier(req), enforcePublicTenantAndGetPublicTenantStorage(req), clientId, isClientCredentialsOnly); } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { throw new ServletException(e); - } catch (OAuth2ClientAlreadyExistsForAppException e) { - // ignore } Transformations.applyClientPropsWhiteList(response.jsonResponse.getAsJsonObject()); @@ -130,6 +134,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { JsonObject input = InputParser.parseJsonObjectOrThrowError(req); String clientId = InputParser.parseStringOrThrowError(input, "clientId", false); + boolean isClientCredentialsOnly = input.has("grantTypes") && + input.get("grantTypes").isJsonArray() && + input.get("grantTypes").getAsJsonArray().size() == 1 && + input.get("grantTypes").getAsJsonArray().get(0).getAsString().equals("client_credentials"); // Apply existing client config on top of input try { @@ -171,6 +179,12 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO ); if (response != null) { + try { + OAuth.addOrUpdateClientId(main, getAppIdentifier(req), enforcePublicTenantAndGetPublicTenantStorage(req), clientId, isClientCredentialsOnly); + } catch (StorageQueryException | TenantOrAppNotFoundException | BadPermissionException e) { + throw new ServletException(e); + } + Transformations.applyClientPropsWhiteList(response.jsonResponse.getAsJsonObject()); response.jsonResponse.getAsJsonObject().addProperty("status", "OK"); super.sendJsonResponse(200, response.jsonResponse, resp); diff --git a/src/main/java/io/supertokens/webserver/api/oauth/RevokeOAuthTokenAPI.java b/src/main/java/io/supertokens/webserver/api/oauth/RevokeOAuthTokenAPI.java index cc813e1ff..22fefa96b 100644 --- a/src/main/java/io/supertokens/webserver/api/oauth/RevokeOAuthTokenAPI.java +++ b/src/main/java/io/supertokens/webserver/api/oauth/RevokeOAuthTokenAPI.java @@ -46,12 +46,14 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I if (token.startsWith("st_rt_")) { // revoking refresh token String clientId = InputParser.parseStringOrThrowError(input, "client_id", false); - String clientSecret = InputParser.parseStringOrThrowError(input, "client_secret", false); + String clientSecret = InputParser.parseStringOrThrowError(input, "client_secret", true); Map formFields = new HashMap<>(); formFields.put("token", token); formFields.put("client_id", clientId); - formFields.put("client_secret", clientSecret); + if (clientSecret != null) { + formFields.put("client_secret", clientSecret); + } HttpRequestForOry.Response response = OAuthProxyHelper.proxyFormPOST( main, req, resp, diff --git a/src/test/java/io/supertokens/test/oauth/api/OAuthAuthAPITest.java b/src/test/java/io/supertokens/test/oauth/api/OAuthAuthAPITest.java index bdc2e5ee1..bc27456e3 100644 --- a/src/test/java/io/supertokens/test/oauth/api/OAuthAuthAPITest.java +++ b/src/test/java/io/supertokens/test/oauth/api/OAuthAuthAPITest.java @@ -27,7 +27,6 @@ import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.oauth.OAuthAuthResponse; -import io.supertokens.pluginInterface.oauth.exceptions.OAuth2ClientAlreadyExistsForAppException; import io.supertokens.pluginInterface.oauth.sqlStorage.OAuthSQLStorage; import io.supertokens.storageLayer.StorageLayer; import io.supertokens.test.TestingProcessManager; diff --git a/src/test/java/io/supertokens/test/oauth/api/OAuthClientsAPITest.java b/src/test/java/io/supertokens/test/oauth/api/OAuthClientsAPITest.java index c667ce72d..8b1169853 100644 --- a/src/test/java/io/supertokens/test/oauth/api/OAuthClientsAPITest.java +++ b/src/test/java/io/supertokens/test/oauth/api/OAuthClientsAPITest.java @@ -24,7 +24,6 @@ import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.oauth.exceptions.OAuth2ClientAlreadyExistsForAppException; import io.supertokens.pluginInterface.oauth.sqlStorage.OAuthSQLStorage; import io.supertokens.storageLayer.StorageLayer; import io.supertokens.test.TestingProcessManager;