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

feat: hydra integration for auth, token and few more endpoints #1032

Merged
merged 40 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
8438685
fix: auth and token api
sattvikc Aug 20, 2024
48cfb7a
fix: cookie and code transformations
sattvikc Aug 21, 2024
fa44c0c
fix: token re-signing
sattvikc Aug 23, 2024
cb79064
fix: token endpoint
sattvikc Aug 26, 2024
393146b
fix: license check and jwks caching
sattvikc Aug 26, 2024
824cbbd
fix: exceptions
sattvikc Aug 27, 2024
cf408d4
fix: refactor
sattvikc Aug 27, 2024
802bbd3
fix: refactor
sattvikc Aug 28, 2024
7839b69
fix: refactor and client crud APIs
sattvikc Aug 29, 2024
8eb8dc2
fix: token type enum
sattvikc Sep 3, 2024
b9b2d68
fix: process ext only on access token
sattvikc Sep 3, 2024
04e7c76
fix: refactor
sattvikc Sep 4, 2024
874ac8c
fix: bugs and refactor
sattvikc Sep 5, 2024
2721620
fix: oauth clients list api
sattvikc Sep 5, 2024
6f03959
fix: consent get accept and reject
sattvikc Sep 5, 2024
41836b3
fix: login request
sattvikc Sep 6, 2024
3a10264
fix: query param transformation
sattvikc Sep 6, 2024
1eddb69
fix: logout request
sattvikc Sep 9, 2024
84fda3f
fix: refactor
sattvikc Sep 9, 2024
7f413c6
fix: remove error debug and hint
sattvikc Sep 9, 2024
c620cdf
fix: introspect api
sattvikc Sep 10, 2024
3e94443
fix: pr comments
sattvikc Sep 11, 2024
b79ddfa
fix: pr comments
sattvikc Sep 11, 2024
ca95c13
fix: pr comment
sattvikc Sep 11, 2024
621befb
fix: pr comment
sattvikc Sep 11, 2024
12c09a0
fix: pr comments and refactor
sattvikc Sep 12, 2024
b6ab81b
fix: pr comments
sattvikc Sep 12, 2024
d87769a
fix: pr comments
sattvikc Sep 12, 2024
085e5c1
fix: revert original http request
sattvikc Sep 12, 2024
bdcdc29
fix: pr comment refactor
sattvikc Sep 12, 2024
d8a1b87
fix: pr comment
sattvikc Sep 16, 2024
360b266
fix: pr comment
sattvikc Sep 16, 2024
f3c022f
fix: pr comment
sattvikc Sep 18, 2024
095a27f
fix: pr comments
sattvikc Sep 18, 2024
da96bc4
fix: owner and pagination
sattvikc Sep 18, 2024
160dce5
fix: pr comment
sattvikc Sep 18, 2024
bd0a918
fix: client id check
sattvikc Sep 18, 2024
b791bf4
fix: ext related
sattvikc Sep 18, 2024
c568f5c
fix: pr comment
sattvikc Sep 19, 2024
bd86375
fix: revoke APIs (#1041)
sattvikc Sep 25, 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
2 changes: 1 addition & 1 deletion config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ core_config_version: 0
# service.
# oauth_provider_admin_service_url:

# (OPTIONAL | Default: http://localhost:3000) string value. If specified, the core uses this URL replace the default
# (OPTIONAL | Default: null) string value. If specified, the core uses this URL replace the default
# consent and login URLs to {apiDomain}.
# oauth_provider_consent_login_base_url:

Expand Down
11 changes: 5 additions & 6 deletions devConfig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -154,17 +154,16 @@ disable_telemetry: true

# (OPTIONAL | Default: null) string value. If specified, the core uses this URL to connect to the OAuth provider
# public service.
# oauth_provider_public_service_url:
oauth_provider_public_service_url: http://localhost:4444

# (OPTIONAL | Default: null) string value. If specified, the core uses this URL to connect to the OAuth provider admin
# service.
# oauth_provider_admin_service_url:
oauth_provider_admin_service_url: http://localhost:4445


# (OPTIONAL | Default: http://localhost:3000) string value. If specified, the core uses this URL replace the default
# (OPTIONAL | Default: null) string value. If specified, the core uses this URL replace the default
# consent and login URLs to {apiDomain}.
# oauth_provider_consent_login_base_url:
oauth_provider_consent_login_base_url: http://localhost:4001/auth

# (OPTIONAL | Default: oauth_provider_public_service_url) If specified, the core uses this URL to parse responses from the oauth provider when
# the oauth provider's internal address differs from the known public provider address.
# oauth_provider_url_configured_in_hydra:
# oauth_provider_url_configured_in_hydra:
28 changes: 28 additions & 0 deletions ee/src/main/java/io/supertokens/ee/EEFeatureFlag.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import io.supertokens.pluginInterface.KeyValueInfo;
import io.supertokens.pluginInterface.STORAGE_TYPE;
import io.supertokens.pluginInterface.Storage;
import io.supertokens.pluginInterface.StorageUtils;
import io.supertokens.pluginInterface.authRecipe.AuthRecipeStorage;
import io.supertokens.pluginInterface.dashboard.sqlStorage.DashboardSQLStorage;
import io.supertokens.pluginInterface.exceptions.StorageQueryException;
Expand All @@ -32,6 +33,7 @@
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
import io.supertokens.pluginInterface.multitenancy.ThirdPartyConfig;
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
import io.supertokens.pluginInterface.oauth.OAuthStorage;
import io.supertokens.pluginInterface.session.sqlStorage.SessionSQLStorage;
import io.supertokens.storageLayer.StorageLayer;
import io.supertokens.utils.Utils;
Expand Down Expand Up @@ -338,6 +340,28 @@ private JsonObject getAccountLinkingStats() throws StorageQueryException, Tenant
return result;
}

private JsonObject getOAuthStats() throws StorageQueryException, TenantOrAppNotFoundException {
JsonObject result = new JsonObject();

OAuthStorage oAuthStorage = StorageUtils.getOAuthStorage(StorageLayer.getStorage(
this.appIdentifier.getAsPublicTenantIdentifier(), main));

result.addProperty("totalNumberOfClients", oAuthStorage.countTotalNumberOfClientsForApp(appIdentifier));
result.addProperty("numberOfClientCredentialsOnlyClients", oAuthStorage.countTotalNumberOfClientCredentialsOnlyClientsForApp(appIdentifier));
result.addProperty("numberOfM2MTokensAlive", oAuthStorage.countTotalNumberOfM2MTokensAlive(appIdentifier));

long now = System.currentTimeMillis();
JsonArray tokensCreatedArray = new JsonArray();
for (int i = 1; i <= 31; i++) {
long timestamp = now - (i * 24 * 60 * 60 * 1000L);
int numberOfTokensCreated = oAuthStorage.countTotalNumberOfM2MTokensCreatedSince(this.appIdentifier, timestamp);
tokensCreatedArray.add(new JsonPrimitive(numberOfTokensCreated));
}
result.add("numberOfM2MTokensCreated", tokensCreatedArray);

return result;
}

private JsonArray getMAUs() throws StorageQueryException, TenantOrAppNotFoundException {
JsonArray mauArr = new JsonArray();
long now = System.currentTimeMillis();
Expand Down Expand Up @@ -395,6 +419,10 @@ public JsonObject getPaidFeatureStats() throws StorageQueryException, TenantOrAp
if (feature == EE_FEATURES.SECURITY) {
usageStats.add(EE_FEATURES.SECURITY.toString(), new JsonObject());
}

if (feature == EE_FEATURES.OAUTH) {
usageStats.add(EE_FEATURES.OAUTH.toString(), getOAuthStats());
}
}

usageStats.add("maus", getMAUs());
Expand Down
3 changes: 3 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.cleanupOAuthRevokeList.CleanupOAuthRevokeList;
import io.supertokens.cronjobs.deleteExpiredAccessTokenSigningKeys.DeleteExpiredAccessTokenSigningKeys;
import io.supertokens.cronjobs.deleteExpiredDashboardSessions.DeleteExpiredDashboardSessions;
import io.supertokens.cronjobs.deleteExpiredEmailVerificationTokens.DeleteExpiredEmailVerificationTokens;
Expand Down Expand Up @@ -256,6 +257,8 @@ private void init() throws IOException, StorageQueryException {
// starts DeleteExpiredAccessTokenSigningKeys cronjob if the access token signing keys can change
Cronjobs.addCronjob(this, DeleteExpiredAccessTokenSigningKeys.init(this, uniqueUserPoolIdsTenants));

Cronjobs.addCronjob(this, CleanupOAuthRevokeList.init(this, uniqueUserPoolIdsTenants));

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

Expand Down
1 change: 0 additions & 1 deletion src/main/java/io/supertokens/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import io.supertokens.Main;
Expand Down
8 changes: 3 additions & 5 deletions src/main/java/io/supertokens/config/CoreConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -297,17 +297,15 @@ public class CoreConfig {
@JsonProperty
@HideFromDashboard
@ConfigDescription(
"If specified, the core uses this URL replace the default consent and login URLs to {apiDomain}. Defaults to 'http://localhost:3000'")
private String oauth_provider_consent_login_base_url = "http://localhost:3000";
"If specified, the core uses this URL replace the default consent and login URLs to {apiDomain}. Defaults to 'null'")
private String oauth_provider_consent_login_base_url = null;

@NotConflictingInApp
@JsonProperty
@HideFromDashboard
@ConfigDescription(
"If specified, the core uses this URL to parse responses from the oauth provider when the oauth provider's internal address differs from the known public provider address. Defaults to the oauth_provider_public_service_url")
private String oauth_provider_url_configured_in_hydra;


private String oauth_provider_url_configured_in_hydra = null;

@ConfigYamlOnly
@JsonProperty
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package io.supertokens.cronjobs.cleanupOAuthRevokeList;

import java.util.List;

import io.supertokens.Main;
import io.supertokens.cronjobs.CronTask;
import io.supertokens.cronjobs.CronTaskTest;
import io.supertokens.pluginInterface.Storage;
import io.supertokens.pluginInterface.StorageUtils;
import io.supertokens.pluginInterface.multitenancy.AppIdentifier;
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
import io.supertokens.pluginInterface.oauth.OAuthStorage;
import io.supertokens.storageLayer.StorageLayer;

public class CleanupOAuthRevokeList extends CronTask {

public static final String RESOURCE_KEY = "io.supertokens.cronjobs.cleanupOAuthRevokeList" +
".CleanupOAuthRevokeList";

private CleanupOAuthRevokeList(Main main, List<List<TenantIdentifier>> tenantsInfo) {
super("CleanupOAuthRevokeList", main, tenantsInfo, true);
}

public static CleanupOAuthRevokeList init(Main main, List<List<TenantIdentifier>> tenantsInfo) {
return (CleanupOAuthRevokeList) main.getResourceDistributor()
.setResource(new TenantIdentifier(null, null, null), RESOURCE_KEY,
new CleanupOAuthRevokeList(main, tenantsInfo));
}

@Override
protected void doTaskPerApp(AppIdentifier app) throws Exception {
Storage storage = StorageLayer.getStorage(app.getAsPublicTenantIdentifier(), main);
OAuthStorage oauthStorage = StorageUtils.getOAuthStorage(storage);
oauthStorage.cleanUpExpiredAndRevokedTokens(app);
}

@Override
public int getIntervalTimeSeconds() {
if (Main.isTesting) {
Integer interval = CronTaskTest.getInstance(main).getIntervalInSeconds(RESOURCE_KEY);
if (interval != null) {
return interval;
}
}
// Every 24 hours.
return 24 * 3600;
}

@Override
public int getInitialWaitTimeSeconds() {
if (!Main.isTesting) {
return getIntervalTimeSeconds();
} else {
return 0;
}
}
}
53 changes: 17 additions & 36 deletions src/main/java/io/supertokens/httpRequest/HttpRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,22 @@

package io.supertokens.httpRequest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;

import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import io.supertokens.Main;

import java.io.*;
import java.net.*;
import java.net.http.HttpClient;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import io.supertokens.Main;

public class HttpRequest {

Expand Down Expand Up @@ -126,7 +131,7 @@ public static <T> T sendGETRequest(Main main, String requestID, String url, Map<
public static <T> T sendGETRequestWithResponseHeaders(Main main, String requestID, String url,
Map<String, String> params,
int connectionTimeoutMS, int readTimeoutMS, Integer version,
Map<String, List<String>> responseHeaders, boolean followRedirects)
Map<String, String> responseHeaders)
throws IOException, HttpResponseException {
StringBuilder paramBuilder = new StringBuilder();

Expand All @@ -152,12 +157,12 @@ public static <T> T sendGETRequestWithResponseHeaders(Main main, String requestI
if (version != null) {
con.setRequestProperty("api-version", version + "");
}
con.setInstanceFollowRedirects(followRedirects);

int responseCode = con.getResponseCode();

con.getHeaderFields().forEach((key, value) -> {
if (key != null) {
responseHeaders.put(key, value);
responseHeaders.put(key, value.get(0));
}
});

Expand Down Expand Up @@ -262,35 +267,11 @@ public static <T> T sendJsonPUTRequest(Main main, String requestID, String url,
return sendJsonRequest(main, requestID, url, requestBody, connectionTimeoutMS, readTimeoutMS, version, "PUT");
}

public static <T> T sendJsonPATCHRequest(Main main, String url, JsonElement requestBody)
throws IOException, HttpResponseException, InterruptedException {

HttpClient client = null;

String body = requestBody.toString();
java.net.http.HttpRequest rawRequest = java.net.http.HttpRequest.newBuilder()
.uri(URI.create(url))
.method("PATCH", java.net.http.HttpRequest.BodyPublishers.ofString(body))
.build();
client = HttpClient.newHttpClient();
HttpResponse<String> response = client.send(rawRequest, HttpResponse.BodyHandlers.ofString());

int responseCode = response.statusCode();

if (responseCode < STATUS_CODE_ERROR_THRESHOLD) {
if (!isJsonValid(response.body().toString())) {
return (T) response.body().toString();
}
return (T) (new JsonParser().parse(response.body().toString()));
}
throw new HttpResponseException(responseCode, response.body().toString());
}

public static <T> T sendJsonDELETERequest(Main main, String requestID, String url, JsonElement requestBody,
int connectionTimeoutMS, int readTimeoutMS, Integer version)
throws IOException, HttpResponseException {
return sendJsonRequest(main, requestID, url, requestBody, connectionTimeoutMS, readTimeoutMS, version,
"DELETE");
}

}
}
Loading
Loading