Skip to content

Commit

Permalink
fix: pr comments and refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
sattvikc committed Sep 12, 2024
1 parent 621befb commit 12c09a0
Show file tree
Hide file tree
Showing 18 changed files with 103 additions and 192 deletions.
8 changes: 0 additions & 8 deletions src/main/java/io/supertokens/oauth/OAuth.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,18 @@
import io.supertokens.featureflag.EE_FEATURES;
import io.supertokens.featureflag.FeatureFlag;
import io.supertokens.featureflag.exceptions.FeatureNotEnabledException;
import io.supertokens.jwt.JWTSigningFunctions;
import io.supertokens.jwt.exceptions.UnsupportedJWTSigningAlgorithmException;
import io.supertokens.oauth.exceptions.*;
import io.supertokens.pluginInterface.Storage;
import io.supertokens.pluginInterface.StorageUtils;
import io.supertokens.pluginInterface.exceptions.InvalidConfigException;
import io.supertokens.pluginInterface.exceptions.StorageQueryException;
import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException;
import io.supertokens.pluginInterface.jwt.JWTSigningKeyInfo;
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.accessToken.AccessToken;
import io.supertokens.session.jwt.JWT;
import io.supertokens.session.jwt.JWT.JWTException;
import io.supertokens.signingkeys.JWTSigningKey;
import io.supertokens.signingkeys.SigningKeys;
import io.supertokens.utils.Utils;

import java.io.IOException;
Expand All @@ -55,8 +49,6 @@
import java.util.Map.Entry;

public class OAuth {
private static final String HYDRA_JWKS_PATH = "/.well-known/jwks.json";

private static void checkForOauthFeature(AppIdentifier appIdentifier, Main main)
throws StorageQueryException, TenantOrAppNotFoundException, FeatureNotEnabledException {
EE_FEATURES[] features = FeatureFlag.getInstance(main, appIdentifier).getEnabledFeatures();
Expand Down
1 change: 0 additions & 1 deletion src/main/java/io/supertokens/oauth/OAuthToken.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ public static JsonObject getPayloadFromJWTToken(AppIdentifier appIdentifier,

public static String reSignToken(AppIdentifier appIdentifier, Main main, String token, String iss, JsonObject payloadUpdate, TokenType tokenType, boolean useDynamicSigningKey, int retryCount) throws IOException, JWTException, InvalidKeyException, NoSuchAlgorithmException, StorageQueryException, StorageTransactionLogicException, UnsupportedJWTSigningAlgorithmException, TenantOrAppNotFoundException, InvalidKeySpecException,
JWTCreationException {
// Load the JWKS from the specified URL
JsonObject payload = JWT.getPayloadWithoutVerifying(token).payload;

// move keys in ext to root
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
package io.supertokens.webserver.api.oauth;

import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

Expand Down Expand Up @@ -65,8 +63,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO
"/admin/clients/" + clientId, // proxyPath
true, // proxyToAdmin
true, // camelToSnakeCaseConversion
() -> OAuthProxyHelper.defaultGetQueryParamsFromRequest(req),
() -> new HashMap<>(), // getHeadersForProxy
OAuthProxyHelper.defaultGetQueryParamsFromRequest(req),
new HashMap<>(), // getHeadersForProxy
(statusCode, headers, rawBody, jsonBody) -> { // handleResponse
this.sendJsonResponse(200, jsonBody, resp);
}
Expand All @@ -93,12 +91,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
"/admin/clients", // proxyPath
true, // proxyToAdmin
true, // camelToSnakeCaseConversion
() -> { // getJsonBody
return input;
},
() -> { // getHeadersForProxy
return new HashMap<>();
},
input, // jsonBody
new HashMap<>(), // headers
(statusCode, headers, rawBody, jsonBody) -> { // handleResponse
String clientId = jsonBody.getAsJsonObject().get("clientId").getAsString();

Expand All @@ -122,6 +116,31 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO
JsonObject input = InputParser.parseJsonObjectOrThrowError(req);
String clientId = InputParser.parseStringOrThrowError(input, "clientId", false);

// Apply existing client config on top of input
try {
Map<String, String> queryParams = new HashMap<>();
queryParams.put("client_id", clientId);
HttpRequest.Response response = OAuth.handleOAuthProxyGET(
main,
getAppIdentifier(req),
enforcePublicTenantAndGetPublicTenantStorage(req),
"/admin/clients/" + clientId,
true, queryParams, null);

JsonObject existingConfig = response.jsonResponse.getAsJsonObject();
existingConfig = OAuth.convertSnakeCaseToCamelCaseRecursively(existingConfig).getAsJsonObject();
for (Map.Entry<String, JsonElement> entry : existingConfig.entrySet()) {
String key = entry.getKey();
if (!input.has(key)) {
input.add(key, entry.getValue());
}
}
} catch (StorageQueryException | TenantOrAppNotFoundException | FeatureNotEnabledException | InvalidConfigException | BadPermissionException e) {
throw new ServletException(e);
} catch (OAuthClientNotFoundException | OAuthAPIException e) {
// ignore since the PUT API will throw one of this error later on
}

try {
OAuthProxyHelper.proxyJsonPUT(
main, req, resp,
Expand All @@ -130,39 +149,9 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO
"/admin/clients/" + clientId,
true, // proxyToAdmin
true, // camelToSnakeCaseConversion
() -> { // getJsonBody
return new HashMap<>();
},
() -> { // getHeadersForProxy
try {
Map<String, String> queryParams = new HashMap<>();
queryParams.put("client_id", clientId);
HttpRequest.Response response = OAuth.handleOAuthProxyGET(
main,
getAppIdentifier(req),
enforcePublicTenantAndGetPublicTenantStorage(req),
"/admin/clients/" + clientId,
true, queryParams, null);

JsonObject existingConfig = response.jsonResponse.getAsJsonObject();
existingConfig = OAuth.convertSnakeCaseToCamelCaseRecursively(existingConfig).getAsJsonObject();
for (Map.Entry<String, JsonElement> entry : existingConfig.entrySet()) {
String key = entry.getKey();
if (!input.has(key)) {
input.add(key, entry.getValue());
}
}
} catch (StorageQueryException | TenantOrAppNotFoundException | FeatureNotEnabledException | InvalidConfigException | BadPermissionException e) {
throw new ServletException(e);
} catch (OAuthClientNotFoundException | OAuthAPIException e) {
// ignore since the PUT API will throw one of this error later on
}

return input;
},
() -> { // getHeadersForProxy
return new HashMap<>();
},
new HashMap<>(), // queryParams
input, // jsonBody
new HashMap<>(), // headers
(statusCode, headers, rawBody, jsonBody) -> { // handleResponse
this.sendJsonResponse(200, jsonBody, resp);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package io.supertokens.webserver.api.oauth;

import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import com.google.gson.JsonObject;

Expand Down Expand Up @@ -41,9 +38,9 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO
"/admin/oauth2/auth/requests/consent/accept", // proxyPath
true, // proxyToAdmin
true, // camelToSnakeCaseConversion
() -> OAuthProxyHelper.defaultGetQueryParamsFromRequest(req),
() -> input, // getJsonBody
HashMap::new, // getHeadersForProxy
OAuthProxyHelper.defaultGetQueryParamsFromRequest(req),
input, // jsonBody
new HashMap<>(), // headers
(statusCode, headers, rawBody, jsonBody) -> { // handleResponse
JsonObject response = jsonBody.getAsJsonObject();
response.addProperty("status", "OK");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package io.supertokens.webserver.api.oauth;

import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import com.google.gson.JsonObject;

Expand Down Expand Up @@ -41,9 +38,9 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO
"/admin/oauth2/auth/requests/login/accept",
true,
true,
() -> OAuthProxyHelper.defaultGetQueryParamsFromRequest(req),
() -> input,
HashMap::new,
OAuthProxyHelper.defaultGetQueryParamsFromRequest(req),
input, // jsonBody
new HashMap<>(), // headers
(statusCode, headers, rawBody, jsonBody) -> {
JsonObject response = jsonBody.getAsJsonObject();
response.addProperty("status", "OK");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package io.supertokens.webserver.api.oauth;

import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import com.google.gson.JsonObject;

Expand Down Expand Up @@ -41,9 +38,9 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO
"/admin/oauth2/auth/requests/logout/accept",
true,
true,
() -> OAuthProxyHelper.defaultGetQueryParamsFromRequest(req),
() -> input,
HashMap::new,
OAuthProxyHelper.defaultGetQueryParamsFromRequest(req),
input,
new HashMap<>(),
(statusCode, headers, rawBody, jsonBody) -> {
JsonObject response = jsonBody.getAsJsonObject();
response.addProperty("status", "OK");
Expand Down
36 changes: 17 additions & 19 deletions src/main/java/io/supertokens/webserver/api/oauth/OAuthAuthAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
JsonObject params = InputParser.parseJsonObjectOrThrowError(input, "params", false);
String cookies = InputParser.parseStringOrThrowError(input, "cookies", true);

Map<String, String> queryParams = params.entrySet().stream().collect(Collectors.toMap(
Map.Entry::getKey,
e -> e.getValue().getAsString()
));

Map<String, String> headers = new HashMap<>();

if (cookies != null) {
headers.put("Cookie", cookies);
}

try {
OAuthProxyHelper.proxyGET(
main, req, resp,
Expand All @@ -60,28 +71,15 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
"/oauth2/auth", // proxyPath
false, // proxyToAdmin
false, // camelToSnakeCaseConversion
() -> { // getQueryParamsForProxy
return params.entrySet().stream().collect(Collectors.toMap(
Map.Entry::getKey,
e -> e.getValue().getAsString()
));
},
() -> { // getHeadersForProxy
Map<String, String> headers = new HashMap<>();

if (cookies != null) {
headers.put("Cookie", cookies);
}

return headers;
},
(statusCode, headers, rawBody, jsonBody) -> { // handleResponse
if (headers == null || !headers.containsKey("Location")) {
queryParams,
headers,
(statusCode, responseHeaders, rawBody, jsonBody) -> { // handleResponse
if (headers == null || !responseHeaders.containsKey("Location")) {
throw new IllegalStateException("Invalid response from hydra");
}

String redirectTo = headers.get("Location").get(0);
List<String> responseCookies = headers.get("Set-Cookie");
String redirectTo = responseHeaders.get("Location").get(0);
List<String> responseCookies = responseHeaders.get("Set-Cookie");

JsonObject response = new JsonObject();
response.addProperty("redirectTo", redirectTo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO
"/admin/clients", // proxyPath
true, // proxyToAdmin
true, // camelToSnakeCaseConversion
HashMap::new, // getQueryParamsForProxy
HashMap::new, // getHeadersForProxy
new HashMap<>(), // queryParams
new HashMap<>(), // headers
(statusCode, headers, rawBody, jsonBody) -> { // handleResponse
JsonObject response = new JsonObject();
response.addProperty("status", "OK");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package io.supertokens.webserver.api.oauth;

import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import com.google.gson.JsonObject;

Expand Down Expand Up @@ -38,8 +35,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO
"/admin/oauth2/auth/requests/consent", // proxyPath
true, // proxyToAdmin
true, // camelToSnakeCaseConversion
() -> OAuthProxyHelper.defaultGetQueryParamsFromRequest(req),
HashMap::new, // getHeadersForProxy
OAuthProxyHelper.defaultGetQueryParamsFromRequest(req),
new HashMap<>(), // headers
(statusCode, headers, rawBody, jsonBody) -> { // handleResponse
JsonObject response = jsonBody.getAsJsonObject();
response.addProperty("status", "OK");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package io.supertokens.webserver.api.oauth;

import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import com.google.gson.JsonObject;

Expand Down Expand Up @@ -38,8 +35,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO
"/admin/oauth2/auth/requests/login", // proxyPath
true, // proxyToAdmin
true, // camelToSnakeCaseConversion
() -> OAuthProxyHelper.defaultGetQueryParamsFromRequest(req),
HashMap::new, // getHeadersForProxy
OAuthProxyHelper.defaultGetQueryParamsFromRequest(req),
new HashMap<>(), // headers
(statusCode, headers, rawBody, jsonBody) -> { // handleResponse
JsonObject response = jsonBody.getAsJsonObject();
response.addProperty("status", "OK");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package io.supertokens.webserver.api.oauth;

import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import com.google.gson.JsonObject;

Expand Down Expand Up @@ -38,8 +35,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO
"/admin/oauth2/auth/requests/logout", // proxyPath
true, // proxyToAdmin
true, // camelToSnakeCaseConversion
() -> OAuthProxyHelper.defaultGetQueryParamsFromRequest(req),
HashMap::new, // getHeadersForProxy
OAuthProxyHelper.defaultGetQueryParamsFromRequest(req),
new HashMap<>(), // headers
(statusCode, headers, rawBody, jsonBody) -> { // handleResponse
JsonObject response = jsonBody.getAsJsonObject();
response.addProperty("status", "OK");
Expand Down
Loading

0 comments on commit 12c09a0

Please sign in to comment.