Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [6.0.4] - 2023-07-13
- Fixes tenant prefix in stack trace log
- `supertokens_default_cdi_version` config renamed to `supertokens_max_cdi_version`
- Fixes `/apiversion` GET to return versions until `supertokens_max_cdi_version` if set
- Fixes `/recipe/multitenancy/tenant` GET to return `TENANT_NOT_FOUND_ERROR` with 200 status when tenant was not found

## [6.0.3] - 2023-07-11

Expand Down
2 changes: 1 addition & 1 deletion config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,4 @@ core_config_version: 0
# (DIFFERENT_ACROSS_APPS | OPTIONAL | Default: null). This is used when the core needs to assume a specific CDI version
# when CDI version is not specified in the request. When set to null, the core will assume the latest version of the
# CDI.
# supertokens_default_cdi_version:
# supertokens_max_cdi_version:
2 changes: 1 addition & 1 deletion devConfig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,4 @@ disable_telemetry: true
# (DIFFERENT_ACROSS_APPS | OPTIONAL | Default: null). This is used when the core needs to assume a specific CDI version
# when CDI version is not specified in the request. When set to null, the core will assume the latest version of the
# CDI.
# supertokens_default_cdi_version:
# supertokens_max_cdi_version:
15 changes: 7 additions & 8 deletions src/main/java/io/supertokens/config/CoreConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ public class CoreConfig {

@NotConflictingInApp
@JsonProperty
private String supertokens_default_cdi_version = null;
private String supertokens_max_cdi_version = null;

@IgnoreForAnnotationCheck
private Set<LOG_LEVEL> allowedLogLevels = null;
Expand Down Expand Up @@ -564,15 +564,15 @@ void normalizeAndValidate(Main main) throws InvalidConfigException {
}
}

if (supertokens_default_cdi_version != null) {
if (supertokens_max_cdi_version != null) {
try {
SemVer version = new SemVer(supertokens_default_cdi_version);
SemVer version = new SemVer(supertokens_max_cdi_version);

if (!WebserverAPI.supportedVersions.contains(version)) {
throw new InvalidConfigException("supertokens_default_cdi_version is not a supported version");
throw new InvalidConfigException("supertokens_max_cdi_version is not a supported version");
}
} catch (IllegalArgumentException e) {
throw new InvalidConfigException("supertokens_default_cdi_version is not a valid semantic version");
throw new InvalidConfigException("supertokens_max_cdi_version is not a valid semantic version");
}
}

Expand Down Expand Up @@ -722,8 +722,7 @@ void assertThatConfigFromSameAppIdAreNotConflicting(CoreConfig other) throws Inv
}
}

public String getDefaultCDIVersion() {
return this.supertokens_default_cdi_version;
public String getMaxCDIVersion() {
return this.supertokens_max_cdi_version;
}
}

4 changes: 4 additions & 0 deletions src/main/java/io/supertokens/utils/SemVer.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ public boolean greaterThanOrEqualTo(SemVer min) {
return min.compareTo(this) <= 0;
}

public boolean greaterThan(SemVer min) {
return min.compareTo(this) < 0;
}

public boolean lesserThan(SemVer max) {
return this.compareTo(max) < 0;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/io/supertokens/webserver/Webserver.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import io.supertokens.webserver.api.multitenancy.*;
import io.supertokens.webserver.api.multitenancy.CreateOrUpdateAppAPI;
import io.supertokens.webserver.api.multitenancy.CreateOrUpdateConnectionUriDomainAPI;
import io.supertokens.webserver.api.multitenancy.CreateOrUpdateTenantAPI;
import io.supertokens.webserver.api.multitenancy.CreateOrUpdateTenantOrGetTenantAPI;
import io.supertokens.webserver.api.multitenancy.RemoveTenantAPI;
import io.supertokens.webserver.api.multitenancy.thirdparty.CreateOrUpdateThirdPartyConfigAPI;
import io.supertokens.webserver.api.multitenancy.thirdparty.RemoveThirdPartyConfigAPI;
Expand Down Expand Up @@ -240,7 +240,7 @@ private void setupRoutes() {
addAPI(new RemoveAppAPI(main));
addAPI(new ListAppsAPI(main));

addAPI(new CreateOrUpdateTenantAPI(main));
addAPI(new CreateOrUpdateTenantOrGetTenantAPI(main));
addAPI(new RemoveTenantAPI(main));
addAPI(new ListTenantsAPI(main));

Expand Down
44 changes: 33 additions & 11 deletions src/main/java/io/supertokens/webserver/WebserverAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@ public abstract class WebserverAPI extends HttpServlet {
public static SemVer getLatestCDIVersion() {
return SemVer.v3_0;
}

public SemVer getLatestCDIVersionForRequest(HttpServletRequest req)
throws ServletException, TenantOrAppNotFoundException {
SemVer maxCDIVersion = getLatestCDIVersion();
String maxCDIVersionStr = Config.getConfig(
getAppIdentifierWithStorage(req).getAsPublicTenantIdentifier(), main).getMaxCDIVersion();
if (maxCDIVersionStr != null) {
maxCDIVersion = new SemVer(maxCDIVersionStr);
}
return maxCDIVersion;
}

public WebserverAPI(Main main, String rid) {
super();
Expand Down Expand Up @@ -446,6 +457,8 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws
sendTextResponse(400,
"AppId or tenantId not found => " + ((TenantOrAppNotFoundException) rootCause).getMessage(),
resp);
} else if (rootCause instanceof UnsupportedCDIVersionException) {
sendTextResponse(400, "Unsupported CDI version", resp);
} else if (rootCause instanceof BadPermissionException) {
sendTextResponse(403, rootCause.getMessage(), resp);
} else {
Expand All @@ -463,23 +476,24 @@ protected String getRIDFromRequest(HttpServletRequest req) {
}

protected SemVer getVersionFromRequest(HttpServletRequest req) throws ServletException {
String version = req.getHeader("cdi-version");
try {
SemVer maxCDIVersion = getLatestCDIVersionForRequest(req);
String version = req.getHeader("cdi-version");

if (version != null) {
return new SemVer(version);
}
if (version != null) {
SemVer versionFromRequest = new SemVer(version);

try {
String defaultCDIVersion = Config.getConfig(
getAppIdentifierWithStorage(req).getAsPublicTenantIdentifier(), main).getDefaultCDIVersion();
if (defaultCDIVersion != null) {
return new SemVer(defaultCDIVersion);
if (versionFromRequest.greaterThan(maxCDIVersion)) {
throw new ServletException(new UnsupportedCDIVersionException());
}

return versionFromRequest;
}

return maxCDIVersion;
} catch (TenantOrAppNotFoundException e) {
throw new ServletException(e);
}

return getLatestCDIVersion();
}

public static class BadRequestException extends Exception {
Expand All @@ -498,4 +512,12 @@ public APIKeyUnauthorisedException() {
super();
}
}

protected static class UnsupportedCDIVersionException extends Exception {
private static final long serialVersionUID = 6058119137747009809L;

public UnsupportedCDIVersionException() {
super();
}
}
}
22 changes: 17 additions & 5 deletions src/main/java/io/supertokens/webserver/api/core/ApiVersionAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import io.supertokens.Main;
import io.supertokens.config.Config;
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
import io.supertokens.utils.SemVer;
import io.supertokens.webserver.WebserverAPI;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
Expand All @@ -45,13 +48,22 @@ protected boolean versionNeeded(HttpServletRequest req) {
}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
JsonObject result = new JsonObject();
JsonArray versions = new JsonArray();
for (SemVer s : WebserverAPI.supportedVersions) {
versions.add(new JsonPrimitive(s.get()));

try {
SemVer maxCDIVersion = getLatestCDIVersionForRequest(req);

for (SemVer s : WebserverAPI.supportedVersions) {
if (s.lesserThan(maxCDIVersion) || s.equals(maxCDIVersion)) {
versions.add(new JsonPrimitive(s.get()));
}
}
result.add("versions", versions);
super.sendJsonResponse(200, result, resp);
} catch (TenantOrAppNotFoundException e) {
throw new ServletException(e);
}
result.add("versions", versions);
super.sendJsonResponse(200, result, resp);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@

import java.io.IOException;

public class CreateOrUpdateTenantAPI extends BaseCreateOrUpdate {
public class CreateOrUpdateTenantOrGetTenantAPI extends BaseCreateOrUpdate {

private static final long serialVersionUID = -4641988458637882374L;

public CreateOrUpdateTenantAPI(Main main) {
public CreateOrUpdateTenantOrGetTenantAPI(Main main) {
super(main);
}

Expand All @@ -51,6 +51,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO
if (tenantId != null) {
tenantId = Utils.normalizeAndValidateTenantId(tenantId);
}

Boolean emailPasswordEnabled = InputParser.parseBooleanOrThrowError(input, "emailPasswordEnabled", true);
Boolean thirdPartyEnabled = InputParser.parseBooleanOrThrowError(input, "thirdPartyEnabled", true);
Boolean passwordlessEnabled = InputParser.parseBooleanOrThrowError(input, "passwordlessEnabled", true);
Expand Down Expand Up @@ -84,7 +85,10 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO

super.sendJsonResponse(200, result, resp);
} catch (TenantOrAppNotFoundException e) {
throw new ServletException(e);
JsonObject result = new JsonObject();
result.addProperty("status", "TENANT_NOT_FOUND_ERROR");

super.sendJsonResponse(200, result, resp);
}
}
}
Loading