diff --git a/src/main/java/io/permit/sdk/ApiContextLevel.java b/src/main/java/io/permit/sdk/ApiContextLevel.java
new file mode 100644
index 0000000..c95155d
--- /dev/null
+++ b/src/main/java/io/permit/sdk/ApiContextLevel.java
@@ -0,0 +1,18 @@
+package io.permit.sdk;
+
+public enum ApiContextLevel {
+ WAIT_FOR_INIT(0),
+ ORGANIZATION(1),
+ PROJECT(2),
+ ENVIRONMENT(3);
+
+ private final int value;
+
+ ApiContextLevel(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/io/permit/sdk/ApiKeyLevel.java b/src/main/java/io/permit/sdk/ApiKeyLevel.java
index 2e6f047..5a40a85 100644
--- a/src/main/java/io/permit/sdk/ApiKeyLevel.java
+++ b/src/main/java/io/permit/sdk/ApiKeyLevel.java
@@ -1,14 +1,27 @@
package io.permit.sdk;
/**
- * The {@code ApiKeyLevel} enum represents the different levels (or scopes) of API keys in the Permit SDK.
- * These levels determine the scope of permissions granted by the API key: is the API granting permission
+ * The {@code ApiKeyLevel} enum represents the granted access level of an API key used by the Permit SDK.
+ * The access level determine the scope of permissions granted by the API key: is the API granting permission
* to the entire workspace (i.e: organization), to a specific project within the workspace, or to a specific
* project and environment within the workspace.
+ *
+ * NOTE: Access levels are enforced on the backend using the API key (you cannot override this value).
+ * this enum is intended as a read-only representation to help the user understand his access level from code.
*/
public enum ApiKeyLevel {
- WAIT_FOR_INIT,
- ORGANIZATION_LEVEL_API_KEY,
- PROJECT_LEVEL_API_KEY,
- ENVIRONMENT_LEVEL_API_KEY,
+ WAIT_FOR_INIT(0),
+ ORGANIZATION_LEVEL_API_KEY(1),
+ PROJECT_LEVEL_API_KEY(2),
+ ENVIRONMENT_LEVEL_API_KEY(3);
+
+ private final int value;
+
+ ApiKeyLevel(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
}
diff --git a/src/main/java/io/permit/sdk/PermitConfig.java b/src/main/java/io/permit/sdk/PermitConfig.java
index d02c22a..adbd4ed 100644
--- a/src/main/java/io/permit/sdk/PermitConfig.java
+++ b/src/main/java/io/permit/sdk/PermitConfig.java
@@ -26,6 +26,8 @@ public class PermitConfig {
private final String defaultTenant;
private final Boolean useDefaultTenantIfEmpty;
private PermitContext context;
+ public final String version;
+ private final static String defaultVersion = "1.3.1-rc";
private PermitConfig(Builder builder) {
this.token = builder.token;
@@ -41,6 +43,8 @@ private PermitConfig(Builder builder) {
this.defaultTenant = builder.defaultTenant;
this.useDefaultTenantIfEmpty = builder.useDefaultTenantIfEmpty;
this.context = builder.context;
+ String runtimeVersion = Permit.class.getPackage().getImplementationVersion();
+ this.version = (runtimeVersion == null) ? defaultVersion : runtimeVersion;
}
/**
diff --git a/src/main/java/io/permit/sdk/PermitContext.java b/src/main/java/io/permit/sdk/PermitContext.java
index 6fd6162..2a43175 100644
--- a/src/main/java/io/permit/sdk/PermitContext.java
+++ b/src/main/java/io/permit/sdk/PermitContext.java
@@ -1,18 +1,41 @@
package io.permit.sdk;
+import io.permit.sdk.api.PermitContextChangeError;
+
/**
* The {@code PermitContext} class represents the context for Permit API calls.
- *
- * A context can be: the entire workspace, a specific project, or a specific environment.
- * Most API methods require an environment scope (e.g: in order to create a role you
- * need to know in which environment to place it), but some methods can work in higher
- * scopes (for example: creating a project can be done with a workspace-level scope).
+ *
+ * Since the Permit API hierarchy is deeply nested, it is less convenient to specify
+ * the full object hierarchy in every request.
+ *
+ * For example, in order to list roles, the user needs to specify the (id or key) of the:
+ * - the org
+ * - the project
+ * - then environment
+ * in which the roles are located under.
+ *
+ * Instead, the SDK can "remember" the current context and "auto-complete" the details
+ * from that context.
+ *
+ * We then get this kind of experience:
+ *
{@code
+ * permit.api.roles.list();
+ * }
+ *
+ * We can only run this function if the current context already knows the org, project,
+ * and environment that we want to run under, and that is why in this example the api
+ * method assumes we are running under an {@link ApiContextLevel#ENVIRONMENT} context.
*/
public class PermitContext {
- private final ApiKeyLevel apiKeyLevel;
- private final String org;
- private final String project;
- private final String environment;
+ private ApiKeyLevel apiKeyLevel;
+ private String permittedOrganization;
+ private String permittedProject;
+ private String permittedEnviroment;
+
+ private ApiContextLevel contextLevel;
+ private String org;
+ private String project;
+ private String environment;
/**
* Constructs a new instance of the {@code PermitContext} class with the specified builder.
@@ -20,21 +43,74 @@ public class PermitContext {
* @param builder The builder used to construct the PermitContext.
*/
public PermitContext(Builder builder) {
- this.apiKeyLevel = builder.apiKeyLevel;
+ this.saveApiKeyAccessibleScope(builder.org, builder.project, builder.environment);
+ this.contextLevel = builder.contextLevel;
this.org = builder.org;
this.project = builder.project;
this.environment = builder.environment;
}
+ public PermitContext() {
+ // access level
+ this.apiKeyLevel = ApiKeyLevel.WAIT_FOR_INIT;
+ this.permittedOrganization = null;
+ this.permittedProject = null;
+ this.permittedEnviroment = null;
+
+ // known context
+ this.contextLevel = ApiContextLevel.WAIT_FOR_INIT;
+ this.org = null;
+ this.project = null;
+ this.environment = null;
+ }
+
+ private void saveApiKeyAccessibleScope(String org, String project, String environment) {
+ // Do not call this method directly!
+ permittedOrganization = org; // cannot be null
+
+ if (project != null && environment != null) {
+ permittedProject = project;
+ permittedEnviroment = environment;
+ apiKeyLevel = ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY;
+ } else if (project != null) {
+ permittedProject = project;
+ permittedEnviroment = null;
+ apiKeyLevel = ApiKeyLevel.PROJECT_LEVEL_API_KEY;
+ } else {
+ permittedProject = null;
+ permittedEnviroment = null;
+ apiKeyLevel = ApiKeyLevel.ORGANIZATION_LEVEL_API_KEY;
+ }
+ }
+
/**
- * Returns the API key level associated with the Permit context.
+ * Returns the access level of the API key used by the SDK.
*
- * @return The API key level.
+ * @deprecated replaced with {@link PermitContext#getPermittedAccessLevel}
+ * @return The API key access level.
*/
public ApiKeyLevel getApiKeyLevel() {
return apiKeyLevel;
}
+ /**
+ * Returns the access level of the API key used by the SDK.
+ *
+ * @return The API key access level.
+ */
+ public ApiKeyLevel getPermittedAccessLevel() {
+ return apiKeyLevel;
+ }
+
+ /**
+ * Returns the current SDK context level.
+ *
+ * @return the context level.
+ */
+ public ApiContextLevel getContextLevel() {
+ return contextLevel;
+ }
+
/**
* Returns the organization (workspace) associated with the Permit context.
*
@@ -62,11 +138,86 @@ public String getEnvironment() {
return environment;
}
+ /**
+ * Sets the current context of the SDK to a specific organization.
+ *
+ * @param org The organization uuid.
+ * @throws PermitContextChangeError If the SDK context cannot be set due to insufficient API Key permissions.
+ */
+ public void setOrganizationLevelContext(String org) throws PermitContextChangeError {
+ verifyCanAccessOrg(org);
+ this.contextLevel = ApiContextLevel.ORGANIZATION;
+ this.org = org;
+ this.project = null;
+ this.environment = null;
+ }
+
+ /**
+ * Sets the current context of the SDK to a specific project within an organization.
+ *
+ * @param org The organization uuid.
+ * @param project The project uuid.
+ * @throws PermitContextChangeError If the SDK context cannot be set due to insufficient API Key permissions.
+ */
+ public void setProjectLevelContext(String org, String project) throws PermitContextChangeError {
+ verifyCanAccessProject(org, project);
+ this.contextLevel = ApiContextLevel.PROJECT;
+ this.org = org;
+ this.project = project;
+ this.environment = null;
+ }
+
+ /**
+ * Sets the current context of the SDK to a specific environment within an organization and project.
+ *
+ * @param org The organization uuid.
+ * @param project The project uuid.
+ * @param environment The environment uuid.
+ * @throws PermitContextChangeError If the SDK context cannot be set due to insufficient API Key permissions.
+ */
+ public void setEnvironmentLevelContext(String org, String project, String environment) throws PermitContextChangeError {
+ verifyCanAccessEnvironment(org, project, environment);
+ this.contextLevel = ApiContextLevel.ENVIRONMENT;
+ this.org = org;
+ this.project = project;
+ this.environment = environment;
+ }
+
+ private void verifyCanAccessOrg(String org) throws PermitContextChangeError {
+ if (!org.equals(permittedOrganization)) {
+ throw new PermitContextChangeError(
+ "You cannot set an SDK context with org '" + org +
+ "' due to insufficient API Key permissions"
+ );
+ }
+ }
+
+ private void verifyCanAccessProject(String org, String project) throws PermitContextChangeError {
+ verifyCanAccessOrg(org);
+ if (permittedProject != null && !project.equals(permittedProject)) {
+ throw new PermitContextChangeError(
+ "You cannot set an SDK context with project '" + project +
+ "' due to insufficient API Key permissions"
+ );
+ }
+ }
+
+ private void verifyCanAccessEnvironment(String org, String project, String environment) throws PermitContextChangeError {
+ verifyCanAccessProject(org, project);
+ if (permittedEnviroment != null && !environment.equals(permittedEnviroment)) {
+ throw new PermitContextChangeError(
+ "You cannot set an SDK context with environment '" + environment +
+ "' due to insufficient API Key permissions"
+ );
+ }
+ }
+
/**
* The {@code Builder} class provides a builder interface for constructing {@code PermitContext} objects.
*/
public static class Builder {
- private ApiKeyLevel apiKeyLevel;
+
+ private ApiContextLevel contextLevel;
private String org;
private String project;
private String environment;
@@ -78,7 +229,7 @@ public static class Builder {
* context will be stored in the SDK configuration for future API calls.
*/
public Builder() {
- this.apiKeyLevel = ApiKeyLevel.WAIT_FOR_INIT;
+ this.contextLevel = ApiContextLevel.WAIT_FOR_INIT;
this.org = null;
this.project = null;
this.environment = null;
@@ -93,10 +244,10 @@ public Builder() {
* @return The updated {@code Builder} object.
*/
public Builder withOrganization(String org) {
+ this.contextLevel = ApiContextLevel.ORGANIZATION;
this.org = org;
this.project = null;
this.environment = null;
- this.apiKeyLevel = ApiKeyLevel.ORGANIZATION_LEVEL_API_KEY;
return this;
}
@@ -110,10 +261,10 @@ public Builder withOrganization(String org) {
* @return The updated {@code Builder} object.
*/
public Builder withProject(String org, String project) {
+ this.contextLevel = ApiContextLevel.PROJECT;
this.org = org;
this.project = project;
this.environment = null;
- this.apiKeyLevel = ApiKeyLevel.PROJECT_LEVEL_API_KEY;
return this;
}
@@ -127,10 +278,10 @@ public Builder withProject(String org, String project) {
* @return The updated {@code Builder} object.
*/
public Builder withEnvironment(String org, String project, String environment) {
+ this.contextLevel = ApiContextLevel.ENVIRONMENT;
this.org = org;
this.project = project;
this.environment = environment;
- this.apiKeyLevel = ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY;
return this;
}
diff --git a/src/main/java/io/permit/sdk/api/BaseApi.java b/src/main/java/io/permit/sdk/api/BaseApi.java
index 3258305..8f23b62 100644
--- a/src/main/java/io/permit/sdk/api/BaseApi.java
+++ b/src/main/java/io/permit/sdk/api/BaseApi.java
@@ -2,16 +2,14 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
+import io.permit.sdk.ApiContextLevel;
import io.permit.sdk.ApiKeyLevel;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.PermitContext;
import io.permit.sdk.openapi.models.APIKeyScopeRead;
-import io.permit.sdk.openapi.models.RoleCreate;
-import io.permit.sdk.openapi.models.RoleRead;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
@@ -31,6 +29,7 @@ protected BaseApi(OkHttpClient client, PermitConfig config, Logger logger) {
this.headers = new Headers.Builder()
.add("Content-Type", "application/json")
.add("Authorization", String.format("Bearer %s", this.config.getToken()))
+ .add("X-Permit-SDK-Version", String.format("java:%s", this.config.version))
.build();
}
@@ -138,30 +137,39 @@ private void setContextFromApiKey() throws IOException, PermitContextError {
}
}
- protected void ensureContext(ApiKeyLevel callLevel) throws PermitContextError, IOException {
+ protected void ensureAccessLevel(ApiKeyLevel requiredAccessLevel) throws PermitContextError, IOException {
// set context if not already set
- if (this.config.getContext().getApiKeyLevel() == ApiKeyLevel.WAIT_FOR_INIT) {
+ // Should only happen once in the lifetime of the SDK
+ if (config.getContext().getContextLevel() == ApiContextLevel.WAIT_FOR_INIT ||
+ config.getContext().getPermittedAccessLevel() == ApiKeyLevel.WAIT_FOR_INIT) {
setContextFromApiKey();
}
- // verify context matches requested call level
- if (callLevel == ApiKeyLevel.PROJECT_LEVEL_API_KEY && this.config.getContext().getProject() == null) {
- throw new PermitContextError(
- "You're trying to use an SDK method that's specific to a project," +
- "but you haven't set the current project in your client's context yet," +
- "or you are using an organization level API key." +
- "Please set the context to a specific" +
- "project using `permit.set_context()` method."
- );
+ if (requiredAccessLevel != config.getContext().getPermittedAccessLevel()) {
+ if (requiredAccessLevel.getValue() < config.getContext().getPermittedAccessLevel().getValue()) {
+ throw new PermitContextError(
+ "You're trying to use an SDK method that requires an API Key with access level: " +
+ requiredAccessLevel + ", however the SDK is running with an API key with level " +
+ config.getContext().getPermittedAccessLevel() + "."
+ );
+ }
+ }
+ }
+
+
+ protected void ensureContext(ApiContextLevel requiredContext) throws PermitContextError, IOException {
+ // set context if not already set
+ // Should only happen once in the lifetime of the SDK
+ if (config.getContext().getContextLevel() == ApiContextLevel.WAIT_FOR_INIT ||
+ config.getContext().getPermittedAccessLevel() == ApiKeyLevel.WAIT_FOR_INIT) {
+ setContextFromApiKey();
}
- if (callLevel == ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY && this.config.getContext().getEnvironment() == null) {
+ if (config.getContext().getContextLevel().getValue() < requiredContext.getValue()) {
throw new PermitContextError(
- "You're trying to use an SDK method that's specific to an environment," +
- "but you haven't set the current environment in your client's context yet," +
- "or you are using an organization/project level API key." +
- "Please set the context to a specific" +
- "environment using `permit.set_context()` method."
+ "You're trying to use an SDK method that requires an API context of " + requiredContext +
+ ", however the SDK is running in a less specific context level: " +
+ config.getContext().getContextLevel() + "."
);
}
}
diff --git a/src/main/java/io/permit/sdk/api/ConditionSetRulesApi.java b/src/main/java/io/permit/sdk/api/ConditionSetRulesApi.java
index f830525..1287705 100644
--- a/src/main/java/io/permit/sdk/api/ConditionSetRulesApi.java
+++ b/src/main/java/io/permit/sdk/api/ConditionSetRulesApi.java
@@ -1,6 +1,8 @@
package io.permit.sdk.api;
import com.google.gson.Gson;
+
+import io.permit.sdk.ApiContextLevel;
import io.permit.sdk.ApiKeyLevel;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.openapi.models.*;
@@ -57,6 +59,16 @@ interface IConditionSetRulesApi {
*/
ConditionSetRuleRead[] list(String userSetKey, String permissionKey, String resourceSetKey) throws IOException, PermitApiError, PermitContextError;
+ /**
+ * Retrieves all the condition set rules (no filters) with default pagination
+ *
+ * @return An array of {@link ConditionSetRuleRead} objects.
+ * @throws IOException If an I/O error occurs while sending the request.
+ * @throws PermitApiError If the Permit API returns a response with an error status code.
+ * @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
+ */
+ ConditionSetRuleRead[] list() throws IOException, PermitApiError, PermitContextError;
+
/**
* Creates a new condition set rule.
*
@@ -126,7 +138,8 @@ private String getConditionSetRulesUrl(String url) {
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ConditionSetRuleRead[] list(String userSetKey, String permissionKey, String resourceSetKey, int page, int perPage) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getConditionSetRulesUrl("");
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
if (userSetKey != null) {
@@ -188,6 +201,19 @@ public ConditionSetRuleRead[] list(String userSetKey, String permissionKey, Stri
return this.list(userSetKey, permissionKey, resourceSetKey, 1);
}
+ /**
+ * Retrieves all the condition set rules (no filters) with default pagination
+ *
+ * @return An array of {@link ConditionSetRuleRead} objects.
+ * @throws IOException If an I/O error occurs while sending the request.
+ * @throws PermitApiError If the Permit API returns a response with an error status code.
+ * @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
+ */
+ @Override
+ public ConditionSetRuleRead[] list() throws IOException, PermitApiError, PermitContextError {
+ return this.list(null, null, null);
+ }
+
/**
* Creates a new condition set rule.
*
@@ -198,7 +224,8 @@ public ConditionSetRuleRead[] list(String userSetKey, String permissionKey, Stri
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ConditionSetRuleRead create(ConditionSetRuleCreate rule) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getConditionSetRulesUrl("");
RequestBody jsonBody = getJsonRequestBody(rule);
@@ -208,7 +235,8 @@ public ConditionSetRuleRead create(ConditionSetRuleCreate rule) throws IOExcepti
.post(jsonBody)
);
- return this.callApiAndParseJson(request, ConditionSetRuleRead.class);
+ ConditionSetRuleRead[] createdRuleArray = this.callApiAndParseJson(request, ConditionSetRuleRead[].class);
+ return createdRuleArray[0];
}
/**
@@ -220,7 +248,8 @@ public ConditionSetRuleRead create(ConditionSetRuleCreate rule) throws IOExcepti
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public void delete(ConditionSetRuleRemove rule) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getConditionSetRulesUrl("");
RequestBody jsonBody = getJsonRequestBody(rule);
diff --git a/src/main/java/io/permit/sdk/api/ConditionSetsApi.java b/src/main/java/io/permit/sdk/api/ConditionSetsApi.java
index a537c62..1de98ed 100644
--- a/src/main/java/io/permit/sdk/api/ConditionSetsApi.java
+++ b/src/main/java/io/permit/sdk/api/ConditionSetsApi.java
@@ -1,6 +1,7 @@
package io.permit.sdk.api;
import com.google.gson.Gson;
+import io.permit.sdk.ApiContextLevel;
import io.permit.sdk.ApiKeyLevel;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.openapi.models.*;
@@ -66,7 +67,8 @@ private String getConditionSetsUrl(String url) {
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ConditionSetRead[] list(int page, int perPage) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getConditionSetsUrl("");
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
Request request = buildRequest(
@@ -121,7 +123,8 @@ public ConditionSetRead[] list() throws IOException, PermitApiError, PermitConte
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ConditionSetRead get(String conditionSetKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getConditionSetsUrl(String.format("/%s", conditionSetKey));
Request request = buildRequest(
new Request.Builder()
@@ -168,7 +171,8 @@ public ConditionSetRead getById(UUID conditionSetId) throws IOException, PermitA
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ConditionSetRead create(ConditionSetCreate conditionSetData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getConditionSetsUrl("");
RequestBody jsonBody = getJsonRequestBody(conditionSetData);
@@ -192,7 +196,8 @@ public ConditionSetRead create(ConditionSetCreate conditionSetData) throws IOExc
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ConditionSetRead update(String conditionSetKey, ConditionSetUpdate conditionSetData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getConditionSetsUrl(String.format("/%s", conditionSetKey));
RequestBody jsonBody = getJsonRequestBody(conditionSetData);
@@ -214,7 +219,8 @@ public ConditionSetRead update(String conditionSetKey, ConditionSetUpdate condit
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public void delete(String conditionSetKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getConditionSetsUrl(String.format("/%s", conditionSetKey));
Request request = buildRequest(
new Request.Builder()
diff --git a/src/main/java/io/permit/sdk/api/ElementsApi.java b/src/main/java/io/permit/sdk/api/ElementsApi.java
index f233b79..27d1bd6 100644
--- a/src/main/java/io/permit/sdk/api/ElementsApi.java
+++ b/src/main/java/io/permit/sdk/api/ElementsApi.java
@@ -1,6 +1,7 @@
package io.permit.sdk.api;
import com.google.gson.Gson;
+import io.permit.sdk.ApiContextLevel;
import io.permit.sdk.ApiKeyLevel;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.api.models.*;
@@ -34,7 +35,8 @@ public ElementsApi(OkHttpClient client, PermitConfig config) {
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public EmbeddedLoginRequestOutput loginAs(String userKey, String tenantKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = buildUrl("/v2/auth/elements_login_as");
RequestBody jsonBody = getJsonRequestBody(new UserLoginRequestInput(userKey, tenantKey));
diff --git a/src/main/java/io/permit/sdk/api/EnvironmentsApi.java b/src/main/java/io/permit/sdk/api/EnvironmentsApi.java
index d017471..34b383f 100644
--- a/src/main/java/io/permit/sdk/api/EnvironmentsApi.java
+++ b/src/main/java/io/permit/sdk/api/EnvironmentsApi.java
@@ -1,6 +1,7 @@
package io.permit.sdk.api;
import com.google.gson.Gson;
+import io.permit.sdk.ApiContextLevel;
import io.permit.sdk.ApiKeyLevel;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.openapi.models.*;
@@ -69,7 +70,8 @@ private String getEnvironmentsUrl(String projectKey, String url) {
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public EnvironmentRead[] list(String projectKey, int page, int perPage) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.PROJECT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ORGANIZATION);
String url = getEnvironmentsUrl(projectKey, "");
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
Request request = buildRequest(
@@ -127,7 +129,8 @@ public EnvironmentRead[] list(String projectKey) throws IOException, PermitApiEr
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public EnvironmentRead get(String projectKey, String environmentKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.PROJECT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ORGANIZATION);
String url = getEnvironmentsUrl(projectKey, String.format("/%s", environmentKey));
Request request = buildRequest(
new Request.Builder()
@@ -178,7 +181,8 @@ public EnvironmentRead getById(UUID projectId, UUID environmentId) throws IOExce
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public EnvironmentRead create(String projectKey, EnvironmentCreate environmentData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.PROJECT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.PROJECT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ORGANIZATION);
String url = getEnvironmentsUrl(projectKey,"");
RequestBody jsonBody = getJsonRequestBody(environmentData);
@@ -203,7 +207,8 @@ public EnvironmentRead create(String projectKey, EnvironmentCreate environmentDa
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public EnvironmentRead update(String projectKey, String environmentKey, EnvironmentUpdate environmentData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.PROJECT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ORGANIZATION);
String url = getEnvironmentsUrl(projectKey, String.format("/%s", environmentKey));
RequestBody jsonBody = getJsonRequestBody(environmentData);
@@ -233,7 +238,8 @@ public EnvironmentRead update(String projectKey, String environmentKey, Environm
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public EnvironmentRead copy(String projectKey, String environmentKey, EnvironmentCopy copyParams) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.PROJECT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.PROJECT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ORGANIZATION);
String url = getEnvironmentsUrl(projectKey, String.format("/%s/copy", environmentKey));
RequestBody jsonBody = getJsonRequestBody(copyParams);
@@ -256,7 +262,8 @@ public EnvironmentRead copy(String projectKey, String environmentKey, Environmen
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public void delete(String projectKey, String environmentKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.PROJECT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ORGANIZATION);
String url = getEnvironmentsUrl(projectKey, String.format("/%s", environmentKey));
Request request = buildRequest(
new Request.Builder()
diff --git a/src/main/java/io/permit/sdk/api/PermitContextChangeError.java b/src/main/java/io/permit/sdk/api/PermitContextChangeError.java
new file mode 100644
index 0000000..15d1ab1
--- /dev/null
+++ b/src/main/java/io/permit/sdk/api/PermitContextChangeError.java
@@ -0,0 +1,13 @@
+package io.permit.sdk.api;
+
+/**
+ * The {@code PermitContextChangeError} will be thrown when the user is trying to set the
+ * SDK context to an object that the current API Key cannot access (and if allowed,
+ * such API calls will result in a 401 Unauthorized response). Instead, the SDK throws
+ * this exception.
+ */
+public class PermitContextChangeError extends Exception {
+ public PermitContextChangeError(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/io/permit/sdk/api/PermitContextError.java b/src/main/java/io/permit/sdk/api/PermitContextError.java
index 778c34a..7fe9530 100644
--- a/src/main/java/io/permit/sdk/api/PermitContextError.java
+++ b/src/main/java/io/permit/sdk/api/PermitContextError.java
@@ -1,5 +1,12 @@
package io.permit.sdk.api;
+/**
+ * The {@code PermitContextError} class represents an error that occurs when an API method
+ * is called with insufficient context (not knowing in what environment, project or
+ * organization the API call is being made).
+ * Part of the input for each API method is provided implicitly via the SDK context.
+ * If the context is missing some data required for a method - the api call will fail.
+ */
public class PermitContextError extends Exception {
public PermitContextError(String message) {
super(message);
diff --git a/src/main/java/io/permit/sdk/api/ProjectsApi.java b/src/main/java/io/permit/sdk/api/ProjectsApi.java
index b1fe436..1b00c9f 100644
--- a/src/main/java/io/permit/sdk/api/ProjectsApi.java
+++ b/src/main/java/io/permit/sdk/api/ProjectsApi.java
@@ -1,6 +1,7 @@
package io.permit.sdk.api;
import com.google.gson.Gson;
+import io.permit.sdk.ApiContextLevel;
import io.permit.sdk.ApiKeyLevel;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.openapi.models.*;
@@ -66,7 +67,8 @@ private String getProjectsUrl(String url) {
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ProjectRead[] list(int page, int perPage) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ORGANIZATION_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ORGANIZATION);
String url = getProjectsUrl("");
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
Request request = buildRequest(
@@ -121,7 +123,8 @@ public ProjectRead[] list() throws IOException, PermitApiError, PermitContextErr
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ProjectRead get(String projectKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ORGANIZATION_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ORGANIZATION);
String url = getProjectsUrl(String.format("/%s", projectKey));
Request request = buildRequest(
new Request.Builder()
@@ -169,7 +172,8 @@ public ProjectRead getById(UUID projectId) throws IOException, PermitApiError, P
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ProjectRead create(ProjectCreate projectData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ORGANIZATION_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ORGANIZATION_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ORGANIZATION);
String url = getProjectsUrl("");
RequestBody jsonBody = getJsonRequestBody(projectData);
@@ -193,7 +197,8 @@ public ProjectRead create(ProjectCreate projectData) throws IOException, PermitA
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ProjectRead update(String projectKey, ProjectUpdate projectData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ORGANIZATION_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.PROJECT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ORGANIZATION);
String url = getProjectsUrl(String.format("/%s", projectKey));
RequestBody jsonBody = getJsonRequestBody(projectData);
@@ -215,7 +220,8 @@ public ProjectRead update(String projectKey, ProjectUpdate projectData) throws I
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public void delete(String projectKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ORGANIZATION_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.PROJECT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ORGANIZATION);
String url = getProjectsUrl(String.format("/%s", projectKey));
Request request = buildRequest(
new Request.Builder()
diff --git a/src/main/java/io/permit/sdk/api/ResourceActionGroupsApi.java b/src/main/java/io/permit/sdk/api/ResourceActionGroupsApi.java
index 6f615e6..4445947 100644
--- a/src/main/java/io/permit/sdk/api/ResourceActionGroupsApi.java
+++ b/src/main/java/io/permit/sdk/api/ResourceActionGroupsApi.java
@@ -1,6 +1,7 @@
package io.permit.sdk.api;
import com.google.gson.Gson;
+import io.permit.sdk.ApiContextLevel;
import io.permit.sdk.ApiKeyLevel;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.openapi.models.*;
@@ -69,7 +70,8 @@ private String getResourceActionGroupsUrl(String resourceKey, String url) {
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceActionGroupRead[] list(String resourceKey, int page, int perPage) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourceActionGroupsUrl(resourceKey, "");
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
Request request = buildRequest(
@@ -127,7 +129,8 @@ public ResourceActionGroupRead[] list(String resourceKey) throws IOException, Pe
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceActionGroupRead get(String resourceKey, String groupKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourceActionGroupsUrl(resourceKey, String.format("/%s", groupKey));
Request request = buildRequest(
new Request.Builder()
@@ -178,7 +181,8 @@ public ResourceActionGroupRead getById(UUID resourceId, UUID groupId) throws IOE
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceActionGroupRead create(String resourceKey, ResourceActionGroupCreate groupData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourceActionGroupsUrl(resourceKey,"");
RequestBody jsonBody = getJsonRequestBody(groupData);
@@ -201,7 +205,8 @@ public ResourceActionGroupRead create(String resourceKey, ResourceActionGroupCre
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public void delete(String resourceKey, String groupKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourceActionGroupsUrl(resourceKey, String.format("/%s", groupKey));
Request request = buildRequest(
new Request.Builder()
diff --git a/src/main/java/io/permit/sdk/api/ResourceActionsApi.java b/src/main/java/io/permit/sdk/api/ResourceActionsApi.java
index 95f2c53..9202b7b 100644
--- a/src/main/java/io/permit/sdk/api/ResourceActionsApi.java
+++ b/src/main/java/io/permit/sdk/api/ResourceActionsApi.java
@@ -1,6 +1,7 @@
package io.permit.sdk.api;
import com.google.gson.Gson;
+import io.permit.sdk.ApiContextLevel;
import io.permit.sdk.ApiKeyLevel;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.openapi.models.*;
@@ -70,7 +71,8 @@ private String getResourceActionsUrl(String resourceKey, String url) {
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceActionRead[] list(String resourceKey, int page, int perPage) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourceActionsUrl(resourceKey, "");
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
Request request = buildRequest(
@@ -128,7 +130,8 @@ public ResourceActionRead[] list(String resourceKey) throws IOException, PermitA
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceActionRead get(String resourceKey, String actionKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourceActionsUrl(resourceKey, String.format("/%s", actionKey));
Request request = buildRequest(
new Request.Builder()
@@ -179,7 +182,8 @@ public ResourceActionRead getById(UUID resourceId, UUID actionId) throws IOExcep
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceActionRead create(String resourceKey, ResourceActionCreate actionData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourceActionsUrl(resourceKey,"");
RequestBody jsonBody = getJsonRequestBody(actionData);
@@ -204,7 +208,8 @@ public ResourceActionRead create(String resourceKey, ResourceActionCreate action
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceActionRead update(String resourceKey, String actionKey, ResourceActionUpdate actionData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourceActionsUrl(resourceKey, String.format("/%s", actionKey));
RequestBody jsonBody = getJsonRequestBody(actionData);
@@ -227,7 +232,8 @@ public ResourceActionRead update(String resourceKey, String actionKey, ResourceA
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public void delete(String resourceKey, String actionKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourceActionsUrl(resourceKey, String.format("/%s", actionKey));
Request request = buildRequest(
new Request.Builder()
diff --git a/src/main/java/io/permit/sdk/api/ResourceAttributesApi.java b/src/main/java/io/permit/sdk/api/ResourceAttributesApi.java
index 4e67634..6bebdd4 100644
--- a/src/main/java/io/permit/sdk/api/ResourceAttributesApi.java
+++ b/src/main/java/io/permit/sdk/api/ResourceAttributesApi.java
@@ -1,6 +1,7 @@
package io.permit.sdk.api;
import com.google.gson.Gson;
+import io.permit.sdk.ApiContextLevel;
import io.permit.sdk.ApiKeyLevel;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.openapi.models.*;
@@ -74,7 +75,8 @@ private String getResourceAttributesUrl(String resourceKey, String url) {
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceAttributeRead[] list(String resourceKey, int page, int perPage) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourceAttributesUrl(resourceKey, "");
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
Request request = buildRequest(
@@ -132,7 +134,8 @@ public ResourceAttributeRead[] list(String resourceKey) throws IOException, Perm
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceAttributeRead get(String resourceKey, String attributeKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourceAttributesUrl(resourceKey, String.format("/%s", attributeKey));
Request request = buildRequest(
new Request.Builder()
@@ -184,7 +187,8 @@ public ResourceAttributeRead getById(UUID resourceId, UUID attributeId) throws I
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceAttributeRead create(String resourceKey, ResourceAttributeCreate attributeData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourceAttributesUrl(resourceKey,"");
RequestBody jsonBody = getJsonRequestBody(attributeData);
@@ -209,7 +213,8 @@ public ResourceAttributeRead create(String resourceKey, ResourceAttributeCreate
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceAttributeRead update(String resourceKey, String attributeKey, ResourceAttributeUpdate attributeData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourceAttributesUrl(resourceKey, String.format("/%s", attributeKey));
RequestBody jsonBody = getJsonRequestBody(attributeData);
@@ -232,7 +237,8 @@ public ResourceAttributeRead update(String resourceKey, String attributeKey, Res
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public void delete(String resourceKey, String attributeKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourceAttributesUrl(resourceKey, String.format("/%s", attributeKey));
Request request = buildRequest(
new Request.Builder()
diff --git a/src/main/java/io/permit/sdk/api/ResourcesApi.java b/src/main/java/io/permit/sdk/api/ResourcesApi.java
index 0152193..eec3c30 100644
--- a/src/main/java/io/permit/sdk/api/ResourcesApi.java
+++ b/src/main/java/io/permit/sdk/api/ResourcesApi.java
@@ -1,6 +1,7 @@
package io.permit.sdk.api;
import com.google.gson.Gson;
+import io.permit.sdk.ApiContextLevel;
import io.permit.sdk.ApiKeyLevel;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.openapi.models.*;
@@ -68,7 +69,8 @@ private String getResourcesUrl(String url) {
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceRead[] list(int page, int perPage) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourcesUrl("");
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
Request request = buildRequest(
@@ -123,7 +125,8 @@ public ResourceRead[] list() throws IOException, PermitApiError, PermitContextEr
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceRead get(String resourceKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourcesUrl(String.format("/%s", resourceKey));
Request request = buildRequest(
new Request.Builder()
@@ -171,7 +174,8 @@ public ResourceRead getById(UUID resourceId) throws IOException, PermitApiError,
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceRead create(ResourceCreate resourceData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourcesUrl("");
RequestBody jsonBody = getJsonRequestBody(resourceData);
@@ -195,7 +199,8 @@ public ResourceRead create(ResourceCreate resourceData) throws IOException, Perm
* @throws PermitContextError * If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceRead replace(String resourceKey, ResourceReplace resourceData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourcesUrl(String.format("/%s", resourceKey));
RequestBody jsonBody = getJsonRequestBody(resourceData);
@@ -219,7 +224,8 @@ public ResourceRead replace(String resourceKey, ResourceReplace resourceData) th
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public ResourceRead update(String resourceKey, ResourceUpdate resourceData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourcesUrl(String.format("/%s", resourceKey));
RequestBody jsonBody = getJsonRequestBody(resourceData);
@@ -241,7 +247,8 @@ public ResourceRead update(String resourceKey, ResourceUpdate resourceData) thro
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public void delete(String resourceKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getResourcesUrl(String.format("/%s", resourceKey));
Request request = buildRequest(
new Request.Builder()
diff --git a/src/main/java/io/permit/sdk/api/RoleAssignmentsApi.java b/src/main/java/io/permit/sdk/api/RoleAssignmentsApi.java
index 22825f6..8976da5 100644
--- a/src/main/java/io/permit/sdk/api/RoleAssignmentsApi.java
+++ b/src/main/java/io/permit/sdk/api/RoleAssignmentsApi.java
@@ -1,6 +1,7 @@
package io.permit.sdk.api;
import com.google.gson.Gson;
+import io.permit.sdk.ApiContextLevel;
import io.permit.sdk.ApiKeyLevel;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.openapi.models.*;
@@ -66,7 +67,8 @@ private String getRoleAssignmentsUrl(String url) {
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public RoleAssignmentRead[] list(String userKey, String tenantKey, String roleKey, int page, int perPage) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getRoleAssignmentsUrl("");
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
if (userKey != null) {
@@ -139,7 +141,8 @@ public RoleAssignmentRead[] list(String userKey, String tenantKey, String roleKe
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public RoleAssignmentRead assign(RoleAssignmentCreate assignment) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getRoleAssignmentsUrl("");
RequestBody jsonBody = getJsonRequestBody(assignment);
@@ -164,7 +167,8 @@ public RoleAssignmentRead assign(RoleAssignmentCreate assignment) throws IOExcep
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public void unassign(RoleAssignmentRemove unassignment) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getRoleAssignmentsUrl("");
RequestBody jsonBody = getJsonRequestBody(unassignment);
@@ -190,7 +194,8 @@ public void unassign(RoleAssignmentRemove unassignment) throws IOException, Perm
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public BulkRoleAssignmentReport bulkAssign(List assignments) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getRoleAssignmentsUrl("/bulk");
RequestBody jsonBody = getJsonRequestBody(assignments);
@@ -214,7 +219,8 @@ public BulkRoleAssignmentReport bulkAssign(List assignment
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public BulkRoleUnassignmentReport bulkUnassign(List unassignments) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getRoleAssignmentsUrl("/bulk");
RequestBody jsonBody = getJsonRequestBody(unassignments);
diff --git a/src/main/java/io/permit/sdk/api/RolesApi.java b/src/main/java/io/permit/sdk/api/RolesApi.java
index 0b81e68..f840f5e 100644
--- a/src/main/java/io/permit/sdk/api/RolesApi.java
+++ b/src/main/java/io/permit/sdk/api/RolesApi.java
@@ -1,6 +1,7 @@
package io.permit.sdk.api;
import com.google.gson.Gson;
+import io.permit.sdk.ApiContextLevel;
import io.permit.sdk.ApiKeyLevel;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.openapi.models.*;
@@ -68,7 +69,8 @@ private String getRolesUrl(String url) {
* @throws PermitContextError If the configured SDK context {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public RoleRead[] list(int page, int perPage) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getRolesUrl("");
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
Request request = buildRequest(
@@ -123,7 +125,8 @@ public RoleRead[] list() throws IOException, PermitApiError, PermitContextError
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public RoleRead get(String roleKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getRolesUrl(String.format("/%s", roleKey));
Request request = buildRequest(
new Request.Builder()
@@ -171,7 +174,8 @@ public RoleRead getById(UUID roleId) throws IOException, PermitApiError, PermitC
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public RoleRead create(RoleCreate roleData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getRolesUrl("");
RequestBody jsonBody = getJsonRequestBody(roleData);
@@ -195,7 +199,8 @@ public RoleRead create(RoleCreate roleData) throws IOException, PermitApiError,
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public RoleRead update(String roleKey, RoleUpdate roleData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getRolesUrl(String.format("/%s", roleKey));
RequestBody jsonBody = getJsonRequestBody(roleData);
@@ -217,7 +222,8 @@ public RoleRead update(String roleKey, RoleUpdate roleData) throws IOException,
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public void delete(String roleKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getRolesUrl(String.format("/%s", roleKey));
Request request = buildRequest(
new Request.Builder()
@@ -241,7 +247,8 @@ public void delete(String roleKey) throws IOException, PermitApiError, PermitCon
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public RoleRead assignPermissions(String roleKey, ArrayList permissions) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getRolesUrl(String.format("/%s/permissions", roleKey));
RequestBody jsonBody = getJsonRequestBody(new AddRolePermissions(permissions));
@@ -265,7 +272,8 @@ public RoleRead assignPermissions(String roleKey, ArrayList permissions)
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public RoleRead removePermissions(String roleKey, ArrayList permissions) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getRolesUrl(String.format("/%s/permissions", roleKey));
RequestBody jsonBody = getJsonRequestBody(new RemoveRolePermissions(permissions));
diff --git a/src/main/java/io/permit/sdk/api/TenantsApi.java b/src/main/java/io/permit/sdk/api/TenantsApi.java
index 22de999..7f1b5c6 100644
--- a/src/main/java/io/permit/sdk/api/TenantsApi.java
+++ b/src/main/java/io/permit/sdk/api/TenantsApi.java
@@ -1,6 +1,7 @@
package io.permit.sdk.api;
import com.google.gson.Gson;
+import io.permit.sdk.ApiContextLevel;
import io.permit.sdk.ApiKeyLevel;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.api.models.CreateOrUpdateResult;
@@ -69,7 +70,8 @@ private String getTenantsUrl(String url) {
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public TenantRead[] list(int page, int perPage) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getTenantsUrl("");
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
Request request = buildRequest(
@@ -126,7 +128,8 @@ public TenantRead[] list() throws IOException, PermitApiError, PermitContextErro
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public PaginatedResultUserRead listTenantUsers(String tenantKey, int page, int perPage) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getTenantsUrl(String.format("/%s/users", tenantKey));
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
Request request = buildRequest(
@@ -180,7 +183,8 @@ public PaginatedResultUserRead listTenantUsers(String tenantKey) throws IOExcept
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public TenantRead get(String tenantKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getTenantsUrl(String.format("/%s", tenantKey));
Request request = buildRequest(
new Request.Builder()
@@ -227,7 +231,8 @@ public TenantRead getById(UUID tenantId) throws IOException, PermitApiError, Per
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public TenantRead create(TenantCreate tenantData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getTenantsUrl("");
RequestBody jsonBody = getJsonRequestBody(tenantData);
@@ -251,7 +256,8 @@ public TenantRead create(TenantCreate tenantData) throws IOException, PermitApiE
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public TenantRead update(String tenantKey, TenantUpdate tenantData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getTenantsUrl(String.format("/%s", tenantKey));
RequestBody jsonBody = getJsonRequestBody(tenantData);
@@ -273,7 +279,8 @@ public TenantRead update(String tenantKey, TenantUpdate tenantData) throws IOExc
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public void delete(String tenantKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getTenantsUrl(String.format("/%s", tenantKey));
Request request = buildRequest(
new Request.Builder()
diff --git a/src/main/java/io/permit/sdk/api/UsersApi.java b/src/main/java/io/permit/sdk/api/UsersApi.java
index 2a423f0..740a16d 100644
--- a/src/main/java/io/permit/sdk/api/UsersApi.java
+++ b/src/main/java/io/permit/sdk/api/UsersApi.java
@@ -1,6 +1,7 @@
package io.permit.sdk.api;
import com.google.gson.Gson;
+import io.permit.sdk.ApiContextLevel;
import io.permit.sdk.ApiKeyLevel;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.api.models.CreateOrUpdateResult;
@@ -76,7 +77,8 @@ private String getUsersUrl(String url) {
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public PaginatedResultUserRead list(int page, int perPage) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getUsersUrl("");
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
Request request = buildRequest(
@@ -131,7 +133,8 @@ public PaginatedResultUserRead list() throws IOException, PermitApiError, Permit
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public UserRead get(String userKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getUsersUrl(String.format("/%s", userKey));
Request request = buildRequest(
new Request.Builder()
@@ -178,7 +181,8 @@ public UserRead getById(UUID userId) throws IOException, PermitApiError, PermitC
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public UserRead create(UserCreate userData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getUsersUrl("");
RequestBody jsonBody = getJsonRequestBody(userData);
@@ -202,7 +206,8 @@ public UserRead create(UserCreate userData) throws IOException, PermitApiError,
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public UserRead update(String userKey, UserUpdate userData) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getUsersUrl(String.format("/%s", userKey));
RequestBody jsonBody = getJsonRequestBody(userData);
@@ -233,7 +238,8 @@ public CreateOrUpdateResult sync(UserCreate userData) throws IOExcepti
);
}
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getUsersUrl(String.format("/%s", userData.key)); // TODO: fix url to PUT /v2/.../users
RequestBody jsonBody = getJsonRequestBody(userData);
@@ -288,7 +294,8 @@ public CreateOrUpdateResult sync(User user) throws IOException, Permit
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public void delete(String userKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getUsersUrl(String.format("/%s", userKey));
Request request = buildRequest(
new Request.Builder()
@@ -313,7 +320,8 @@ public void delete(String userKey) throws IOException, PermitApiError, PermitCon
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public RoleAssignmentRead assignRole(String userKey, String roleKey, String tenantKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getUsersUrl(String.format("/%s/roles", userKey));
RequestBody jsonBody = getJsonRequestBody(new UserRoleCreate(roleKey, tenantKey));
@@ -337,7 +345,8 @@ public RoleAssignmentRead assignRole(String userKey, String roleKey, String tena
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public void unassignRole(String userKey, String roleKey, String tenantKey) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = getUsersUrl(String.format("/%s/roles", userKey));
RequestBody jsonBody = getJsonRequestBody(new UserRoleRemove(roleKey, tenantKey));
@@ -365,7 +374,8 @@ public void unassignRole(String userKey, String roleKey, String tenantKey) throw
* @throws PermitContextError If the configured {@link io.permit.sdk.PermitContext} does not match the required endpoint context.
*/
public RoleAssignmentRead[] getAssignedRoles(@NotNull String userKey, String tenantKey, int page, int perPage) throws IOException, PermitApiError, PermitContextError {
- ensureContext(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY);
+ ensureContext(ApiContextLevel.ENVIRONMENT);
String url = buildUrl(
String.format(
"/v2/facts/%s/%s/role_assignments",
diff --git a/src/main/java/io/permit/sdk/enforcement/Enforcer.java b/src/main/java/io/permit/sdk/enforcement/Enforcer.java
index 44b1562..87d0324 100644
--- a/src/main/java/io/permit/sdk/enforcement/Enforcer.java
+++ b/src/main/java/io/permit/sdk/enforcement/Enforcer.java
@@ -117,6 +117,7 @@ public boolean check(User user, String action, Resource resource, Context contex
.post(body)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", String.format("Bearer %s", this.config.getToken()))
+ .addHeader("X-Permit-SDK-Version", String.format("java:%s", this.config.version))
.build();
try (Response response = client.newCall(request).execute()) {
diff --git a/src/test/java/io/permit/sdk/RolesApiE2ETest.java b/src/test/java/io/permit/sdk/RolesApiE2ETest.java
deleted file mode 100644
index 5ee295c..0000000
--- a/src/test/java/io/permit/sdk/RolesApiE2ETest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package io.permit.sdk;
-
-import com.google.gson.Gson;
-import com.google.gson.internal.LinkedTreeMap;
-import io.permit.sdk.api.PermitApiError;
-import io.permit.sdk.api.PermitContextError;
-import io.permit.sdk.openapi.models.RoleCreate;
-import io.permit.sdk.openapi.models.RoleRead;
-import io.permit.sdk.openapi.models.RoleUpdate;
-import org.junit.jupiter.api.Test;
-
-import java.io.IOException;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-/**
- * this e2e test should run against a clean permit environment.
- * if the environment contains any objects the test will fail.
- * eventually we want to create an environment programmatically
- * and then extract the api key and start the test.
- */
-public class RolesApiE2ETest extends PermitE2ETestBase {
- @Test
- void testRolesApi() {
- // init the client
- Permit permit = new Permit(this.config);
- Gson gson = new Gson();
-
- // roles lifecycle
- try {
- // list
- RoleRead[] emptyRoles = permit.api.roles.list();
- assertEquals(emptyRoles.length, 0);
-
- // create
- RoleRead admin = permit.api.roles.create(
- new RoleCreate("admin","Admin").withDescription("an admin role")
- );
- assertNotNull(admin);
- assertEquals(admin.key, "admin");
- assertEquals(admin.name, "Admin");
- assertEquals(admin.description, "an admin role");
-
-
- RoleRead viewer = permit.api.roles.create(
- new RoleCreate("viewer","Viewer").withDescription("an viewer role")
- );
- assertNotNull(viewer);
- assertEquals(viewer.key, "viewer");
- assertEquals(viewer.name, "Viewer");
- assertEquals(viewer.description, "an viewer role");
-
- RoleRead[] roles = permit.api.roles.list();
- assertEquals(roles.length, 2);
- assertEquals(roles[0].key, "admin");
- assertEquals(roles[0].name, "Admin");
- assertEquals(roles[1].key, "viewer");
- assertEquals(roles[1].name, "Viewer");
-
- // get
- RoleRead role = permit.api.roles.get("admin");
- assertNotNull(role);
- assertEquals(role.key, "admin");
- assertEquals(role.name, "Admin");
-
- // get 404 no such role
- PermitApiError notFoundError = assertThrows(PermitApiError.class, () -> {
- permit.api.roles.get("editor");
- });
- assertEquals(notFoundError.getMessage(), "Got error status code: 404");
- assertEquals(notFoundError.getResponseCode(), 404);
- LinkedTreeMap error = notFoundError.getErrorObject();
- assertEquals(error.get("error_code"), "NOT_FOUND");
- assertTrue(error.get("message").toString().startsWith("The requested data could not be found"));
-
- // delete
- try {
- permit.api.roles.delete("admin");
- } catch (PermitApiError e) {
- fail("got error: " + e);
- }
-
- roles = permit.api.roles.list();
- assertEquals(roles.length, 1);
- assertEquals(roles[0].key, "viewer");
- assertEquals(roles[0].name, "Viewer");
- assertEquals(roles[0].description, "an viewer role");
-
- // update
- permit.api.roles.update("viewer", new RoleUpdate().withDescription("new description"));
-
- roles = permit.api.roles.list();
- assertEquals(roles.length, 1);
- assertEquals(roles[0].key, "viewer");
- assertEquals(roles[0].name, "Viewer");
- assertEquals(roles[0].description, "new description");
-
- // delete
- try {
- permit.api.roles.delete("viewer");
- } catch (PermitApiError e) {
- fail("got error: " + e);
- }
-
- roles = permit.api.roles.list();
- assertEquals(roles.length, 0);
-
- // we already deleted this
- PermitApiError exception = assertThrows(PermitApiError.class, () -> {
- permit.api.roles.delete("viewer");
- });
- assertEquals(exception.getResponseCode(), 404);
- } catch (IOException | PermitApiError | PermitContextError e) {
- fail("got error: " + e);
- }
- }
-}
diff --git a/src/test/java/io/permit/sdk/PermissionCheckE2ETest.java b/src/test/java/io/permit/sdk/e2e/RbacE2ETest.java
similarity index 95%
rename from src/test/java/io/permit/sdk/PermissionCheckE2ETest.java
rename to src/test/java/io/permit/sdk/e2e/RbacE2ETest.java
index 8f8771e..57c380a 100644
--- a/src/test/java/io/permit/sdk/PermissionCheckE2ETest.java
+++ b/src/test/java/io/permit/sdk/e2e/RbacE2ETest.java
@@ -1,10 +1,9 @@
-package io.permit.sdk;
+package io.permit.sdk.e2e;
-import com.google.gson.Gson;
-import com.google.gson.internal.LinkedTreeMap;
+import io.permit.sdk.PermitE2ETestBase;
import io.permit.sdk.api.PermitApiError;
import io.permit.sdk.api.PermitContextError;
-import io.permit.sdk.api.UsersApi;
+import io.permit.sdk.Permit;
import io.permit.sdk.api.models.CreateOrUpdateResult;
import io.permit.sdk.enforcement.Resource;
import io.permit.sdk.enforcement.User;
@@ -26,8 +25,8 @@
* eventually we want to create an environment programmatically
* and then extract the api key and start the test.
*/
-public class PermissionCheckE2ETest extends PermitE2ETestBase {
- private final Logger logger = LoggerFactory.getLogger(PermissionCheckE2ETest.class);
+public class RbacE2ETest extends PermitE2ETestBase {
+ private final Logger logger = LoggerFactory.getLogger(RbacE2ETest.class);
@Test
void testPermissionCheckRBAC() {
@@ -135,7 +134,7 @@ void testPermissionCheckRBAC() {
.build();
CreateOrUpdateResult result = permit.api.users.sync(userInput);
UserRead user = result.getResult();
- assertTrue(result.wasCreated());
+ // assertTrue(result.wasCreated());
assertEquals(user.key, "auth0|elon");
assertEquals(user.email, "elonmusk@tesla.com");
assertEquals(user.firstName, "Elon");
@@ -153,13 +152,14 @@ void testPermissionCheckRBAC() {
assertEquals(ra.role, viewer.key);
assertEquals(ra.tenant, tenant.key);
- logger.info("sleeping 2 seconds before permit.check() to make sure all writes propagated from cloud to PDP");
- Thread.sleep(2000);
+ logger.info("sleeping 20 seconds before permit.check() to make sure all writes propagated from cloud to PDP");
+ Thread.sleep(20000);
// positive permission check (will be true because elon is a viewer, and a viewer can read a document)
logger.info("testing positive permission check");
HashMap resourceAttrs = new HashMap();
resourceAttrs.put("sdfa", new ArrayList(Arrays.asList("sdf","sdf")));
+
assertTrue(permit.check(
User.fromString("auth0|elon"),
"read",
diff --git a/src/test/java/io/permit/sdk/endpoints/ConditionSetsE2ETest.java b/src/test/java/io/permit/sdk/endpoints/ConditionSetsE2ETest.java
new file mode 100644
index 0000000..fe98541
--- /dev/null
+++ b/src/test/java/io/permit/sdk/endpoints/ConditionSetsE2ETest.java
@@ -0,0 +1,243 @@
+package io.permit.sdk.endpoints;
+
+import com.google.gson.Gson;
+import io.permit.sdk.Permit;
+import io.permit.sdk.PermitE2ETestBase;
+import io.permit.sdk.api.PermitApiError;
+import io.permit.sdk.api.PermitContextError;
+import io.permit.sdk.openapi.models.*;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+
+public class ConditionSetsE2ETest extends PermitE2ETestBase {
+ private static final String DOCUMENT_KEY = "document";
+ private static final String USER_RESOURCE_KEY = "__user";
+
+ private static final String USERSET_KEY = "users_over_thirty";
+
+ private static final String RESOURCESET_KEY = "private_docs";
+ private static ResourceCreate documentData;
+ private static ConditionSetCreate usersetData;
+ private static ConditionSetCreate resourcesetData;
+ private static ConditionSetRuleCreate ruleData;
+
+ private static HashMap getUsersetConditions() {
+ HashMap ageCondition = new HashMap() {{
+ put("greater-than", 30);
+ }};
+
+ HashMap> attributeRef = new HashMap<>();
+ attributeRef.put("user.age", ageCondition);
+
+ List>> andConditions = new ArrayList<>();
+ andConditions.add(attributeRef);
+
+ HashMap conditions = new HashMap<>();
+ conditions.put("allOf", andConditions);
+
+ return conditions;
+ }
+
+ private static HashMap getResourcesetConditions() {
+ HashMap privateCondition = new HashMap() {{
+ put("equals", false);
+ }};
+
+ HashMap> attributeRef = new HashMap<>();
+ attributeRef.put("resource.private", privateCondition);
+
+ List>> andConditions = new ArrayList<>();
+ andConditions.add(attributeRef);
+
+ HashMap conditions = new HashMap<>();
+ conditions.put("allOf", andConditions);
+
+ return conditions;
+ }
+
+ @BeforeAll
+ static void setup() {
+ // resource actions
+ HashMap actions = new HashMap<>();
+ actions.put("create", new ActionBlockEditable());
+ actions.put("read", new ActionBlockEditable().withName("Read").withDescription("Read Action"));
+ actions.put("update", new ActionBlockEditable());
+ actions.put("delete", new ActionBlockEditable());
+ actions.put("sign", new ActionBlockEditable());
+
+ // resource attributes
+ HashMap attributes = new HashMap<>();
+ AttributeBlockEditable privateAttr = new AttributeBlockEditable()
+ .withType(AttributeType.BOOL)
+ .withDescription("whether the document is private");
+ attributes.put("private", privateAttr);
+
+ // create document resource
+ documentData = ((
+ new ResourceCreate("document", "Document", actions)
+ )
+ .withUrn("prn:gdrive:document")
+ .withDescription("google drive document")
+ .withAttributes(attributes)
+ );
+
+ // condition sets data
+ usersetData = ((
+ new ConditionSetCreate(USERSET_KEY, "Users over 30")
+ )
+ .withType(ConditionSetType.USERSET)
+ .withConditions(getUsersetConditions())
+ );
+
+ resourcesetData = ((
+ new ConditionSetCreate(RESOURCESET_KEY, "Private Docs")
+ )
+ .withType(ConditionSetType.RESOURCESET)
+ .withConditions(getResourcesetConditions())
+ );
+
+ ruleData = new ConditionSetRuleCreate(USERSET_KEY, DOCUMENT_KEY + ":sign", RESOURCESET_KEY);
+ }
+
+ void cleanup() {
+ Permit permit = new Permit(this.config);
+ try {
+ try {
+ permit.api.conditionSets.delete(USERSET_KEY);
+ } catch (PermitApiError e) {
+ logger.info("SKIPPING delete of user set: " + USERSET_KEY);
+ }
+ try {
+ permit.api.conditionSets.delete(RESOURCESET_KEY);
+ } catch (PermitApiError e) {
+ logger.info("SKIPPING delete of resource set: " + RESOURCESET_KEY);
+ }
+ try {
+ permit.api.resources.delete(DOCUMENT_KEY);
+ } catch (PermitApiError e) {
+ logger.info("SKIPPING delete of resource: " + DOCUMENT_KEY);
+ }
+ } catch (PermitContextError e) {
+ fail("got error: " + e);
+ } catch (IOException e) {
+ fail("got error: " + e);
+ }
+ }
+
+ @Test
+ void testConditionSetsApi() {
+ // init the client
+ Permit permit = new Permit(this.config);
+ Gson gson = new Gson();
+
+ // roles lifecycle
+ try {
+ logger.info("create document with actions");
+ ResourceRead document = permit.api.resources.create(documentData);
+ assertNotNull(document);
+ assertNotNull(document.id);
+ assertEquals(document.key, documentData.key);
+ assertEquals(document.name, documentData.name);
+ assertEquals(document.description, documentData.description);
+ assertEquals(document.urn, documentData.urn);
+ assertEquals(document.actions.size(), 5);
+ assertEquals(document.attributes.size(), 1);
+ assertTrue(document.actions.containsKey("create"));
+ assertTrue(document.actions.containsKey("read"));
+ assertTrue(document.actions.containsKey("update"));
+ assertTrue(document.actions.containsKey("delete"));
+ assertTrue(document.actions.containsKey("sign"));
+ assertTrue(document.attributes.containsKey("private"));
+
+ logger.info("verify can find new resource in the new list");
+ ResourceRead[] resources = permit.api.resources.list();
+ assertTrue(Arrays.stream(resources).map(r -> r.key).collect(Collectors.toList()).contains(documentData.key));
+
+ logger.info("Create User.age attribute");
+ try {
+ permit.api.resourceAttributes.create(
+ USER_RESOURCE_KEY,
+ new ResourceAttributeCreate("age", AttributeType.NUMBER)
+ );
+ } catch (PermitApiError e) {
+ if (e.getResponseCode() != 409) {
+ fail("got error while creating User.age attribute: " + e);
+ }
+ }
+
+ logger.info("Create condition sets");
+ ConditionSetRead userset = permit.api.conditionSets.create(usersetData);
+ assertNotNull(userset);
+ assertNotNull(userset.id);
+ assertEquals(userset.key, usersetData.key);
+ assertEquals(userset.name, usersetData.name);
+ assertEquals(userset.description, usersetData.description);
+
+ ConditionSetRead resourceset = permit.api.conditionSets.create(resourcesetData.withResourceId(document.id));
+ assertNotNull(resourceset);
+ assertNotNull(resourceset.id);
+ assertEquals(resourceset.key, resourcesetData.key);
+ assertEquals(resourceset.name, resourcesetData.name);
+ assertEquals(resourceset.description, resourcesetData.description);
+
+ logger.info("Getting condition set list");
+ ConditionSetRead[] conditionSets = permit.api.conditionSets.list();
+ assertTrue(Arrays.stream(conditionSets).map(c -> c.key).collect(Collectors.toList()).contains(USERSET_KEY));
+ assertTrue(Arrays.stream(conditionSets).map(c -> c.key).collect(Collectors.toList()).contains(RESOURCESET_KEY));
+
+ logger.info("Create condition set rules");
+ ConditionSetRuleRead rule = permit.api.conditionSetRules.create(ruleData);
+ assertNotNull(rule);
+ assertNotNull(rule.id);
+ assertEquals(rule.userSet, USERSET_KEY);
+ assertEquals(rule.resourceSet, RESOURCESET_KEY);
+ assertEquals(rule.permission, DOCUMENT_KEY + ":sign");
+
+ logger.info("Getting condition set rules list");
+ ConditionSetRuleRead[] rules = permit.api.conditionSetRules.list();
+ assertEquals(rules.length, 1);
+
+ logger.info("Delete objects...");
+ try {
+ permit.api.conditionSetRules.delete(
+ new ConditionSetRuleRemove(
+ rule.userSet,
+ rule.permission,
+ rule.resourceSet
+ )
+ );
+ } catch (PermitApiError e) {
+ fail("got error: " + e);
+ }
+ try {
+ permit.api.conditionSets.delete(USERSET_KEY);
+ } catch (PermitApiError e) {
+ fail("got error: " + e);
+ }
+ try {
+ permit.api.conditionSets.delete(RESOURCESET_KEY);
+ } catch (PermitApiError e) {
+ fail("got error: " + e);
+ }
+ try {
+ permit.api.resources.delete(DOCUMENT_KEY);
+ } catch (PermitApiError e) {
+ fail("got error: " + e);
+ }
+
+ } catch (IOException | PermitApiError | PermitContextError e) {
+ fail("got error: " + e);
+ }
+ finally {
+ cleanup();
+ }
+ }
+}
diff --git a/src/test/java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java b/src/test/java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java
new file mode 100644
index 0000000..71e613b
--- /dev/null
+++ b/src/test/java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java
@@ -0,0 +1,193 @@
+package io.permit.sdk.endpoints;
+
+import com.google.gson.Gson;
+import com.google.gson.internal.LinkedTreeMap;
+import io.permit.sdk.Permit;
+import io.permit.sdk.PermitE2ETestBase;
+import io.permit.sdk.api.PermitApiError;
+import io.permit.sdk.api.PermitContextError;
+import io.permit.sdk.openapi.models.*;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.stream.Collectors;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+
+public class ResourcesApiE2ETest extends PermitE2ETestBase {
+ private static final String DOCUMENT_KEY = "document";
+ private static final String FOLDER_KEY = "folder";
+ private static ResourceCreate documentData;
+ private static ResourceCreate folderData;
+ private static ResourceCreate duplicateData;
+
+ @BeforeAll
+ static void setup() {
+ // resource actions
+ HashMap actions = new HashMap<>();
+ actions.put("create", new ActionBlockEditable());
+ actions.put("read", new ActionBlockEditable().withName("Read").withDescription("Read Action"));
+ actions.put("update", new ActionBlockEditable());
+ actions.put("delete", new ActionBlockEditable());
+
+ // create document resource
+ documentData = ((
+ new ResourceCreate("document", "Document", actions)
+ )
+ .withUrn("prn:gdrive:document")
+ .withDescription("google drive document")
+ );
+
+ // create folder resource
+ folderData = ((
+ new ResourceCreate("folder", "Folder", new HashMap<>())
+ )
+ .withUrn("prn:gdrive:folder")
+ .withDescription("google drive folder")
+ );
+
+ duplicateData = ((
+ new ResourceCreate("document", "Document2", actions)
+ )
+ .withUrn("prn:gdrive:document2")
+ .withDescription("google drive document2")
+ );
+ }
+
+ void cleanup() {
+ Permit permit = new Permit(this.config);
+ try {
+ try {
+ permit.api.resources.delete(DOCUMENT_KEY);
+ } catch (PermitApiError e) {
+ logger.info("SKIPPING delete of resource: " + DOCUMENT_KEY);
+ }
+ try {
+ permit.api.resources.delete(FOLDER_KEY);
+ } catch (PermitApiError e) {
+ logger.info("SKIPPING delete of resource: " + FOLDER_KEY);
+ }
+ } catch (PermitContextError e) {
+ fail("got error: " + e);
+ } catch (IOException e) {
+ fail("got error: " + e);
+ }
+ }
+
+ @Test
+ void testResourcesApi() {
+ // init the client
+ Permit permit = new Permit(this.config);
+ Gson gson = new Gson();
+
+ // roles lifecycle
+ try {
+ logger.info("check original resource length");
+ int originalLength = permit.api.resources.list().length;
+
+ logger.info("create document with actions");
+ ResourceRead document = permit.api.resources.create(documentData);
+ assertNotNull(document);
+ assertNotNull(document.id);
+ assertEquals(document.key, documentData.key);
+ assertEquals(document.name, documentData.name);
+ assertEquals(document.description, documentData.description);
+ assertEquals(document.urn, documentData.urn);
+ assertEquals(document.actions.size(), 4);
+ assertTrue(document.actions.containsKey("create"));
+ assertTrue(document.actions.containsKey("read"));
+ assertTrue(document.actions.containsKey("update"));
+ assertTrue(document.actions.containsKey("delete"));
+
+ logger.info("verify number of items increased by 1");
+ ResourceRead[] resources = permit.api.resources.list();
+ assertEquals(resources.length, originalLength + 1);
+
+ logger.info("verify can find new resource in the new list");
+ assertTrue(Arrays.stream(resources).map(r -> r.key).collect(Collectors.toList()).contains(documentData.key));
+
+ logger.info("get non existing role -> 404");
+ PermitApiError notFoundError = assertThrows(PermitApiError.class, () -> {
+ permit.api.resources.get("group");
+ });
+ assertEquals(notFoundError.getMessage(), "Got error status code: 404");
+ assertEquals(notFoundError.getResponseCode(), 404);
+ LinkedTreeMap error = notFoundError.getErrorObject();
+ assertEquals(error.get("error_code"), "NOT_FOUND");
+ assertTrue(error.get("message").toString().startsWith("The requested data could not be found"));
+
+ logger.info("create existing resource -> 409");
+ PermitApiError duplicateError = assertThrows(PermitApiError.class, () -> {
+ permit.api.resources.create(duplicateData);
+ });
+ assertEquals(duplicateError.getResponseCode(), 409);
+
+ logger.info("create empty resource");
+ ResourceRead folder = permit.api.resources.create(folderData);
+ assertNotNull(folder);
+ assertEquals(folder.key, folderData.key);
+ assertEquals(folder.name, folderData.name);
+ assertEquals(folder.description, folderData.description);
+ assertNotNull(folder.actions);
+ assertEquals(folder.actions.size(), 0);
+
+ logger.info("verify number of items increased by 1");
+ ResourceRead[] resources2 = permit.api.resources.list();
+ assertEquals(resources2.length, originalLength + 2);
+
+ logger.info("Update actions");
+ permit.api.resources.update(
+ folder.key,
+ new ResourceUpdate()
+ .withDescription("wat")
+ .withActions(
+ new HashMap() {{
+ put("pick", new ActionBlockEditable());
+ }}
+ )
+ );
+
+ logger.info("get after update");
+ ResourceRead updatedFolder = permit.api.resources.get(folderData.key);
+ assertNotNull(updatedFolder);
+ assertEquals(updatedFolder.key, folderData.key);
+ assertEquals(updatedFolder.name, folderData.name);
+ assertEquals(updatedFolder.description, "wat");
+ assertNotNull(updatedFolder.actions);
+ assertEquals(updatedFolder.actions.size(), 1);
+ assertTrue(updatedFolder.actions.containsKey("pick"));
+
+ logger.info("Delete objects...");
+ try {
+ permit.api.resources.delete(DOCUMENT_KEY);
+ } catch (PermitApiError e) {
+ fail("got error: " + e);
+ }
+ try {
+ permit.api.resources.delete(FOLDER_KEY);
+ } catch (PermitApiError e) {
+ fail("got error: " + e);
+ }
+
+ logger.info("Verify that again we have the initial number of resources");
+ ResourceRead[] resources3 = permit.api.resources.list();
+ assertEquals(resources3.length, originalLength);
+
+ logger.info("Verify deleted resource cannot be deleted again");
+ PermitApiError exception = assertThrows(PermitApiError.class, () -> {
+ permit.api.roles.delete(FOLDER_KEY);
+ });
+ assertEquals(exception.getResponseCode(), 404);
+ } catch (IOException | PermitApiError | PermitContextError e) {
+ fail("got error: " + e);
+ }
+ finally {
+ cleanup();
+ }
+ }
+}
diff --git a/src/test/java/io/permit/sdk/endpoints/RolesApiE2ETest.java b/src/test/java/io/permit/sdk/endpoints/RolesApiE2ETest.java
new file mode 100644
index 0000000..2c95631
--- /dev/null
+++ b/src/test/java/io/permit/sdk/endpoints/RolesApiE2ETest.java
@@ -0,0 +1,228 @@
+package io.permit.sdk.endpoints;
+
+import com.google.gson.Gson;
+import com.google.gson.internal.LinkedTreeMap;
+import io.permit.sdk.Permit;
+import io.permit.sdk.PermitE2ETestBase;
+import io.permit.sdk.api.PermitApiError;
+import io.permit.sdk.api.PermitContextError;
+import io.permit.sdk.openapi.models.*;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.stream.Collectors;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * this e2e test should run against a clean permit environment.
+ * if the environment contains any objects the test will fail.
+ * eventually we want to create an environment programmatically
+ * and then extract the api key and start the test.
+ */
+public class RolesApiE2ETest extends PermitE2ETestBase {
+ private static final String DOCUMENT_KEY = "document";
+ private static final String ADMIN_KEY = "testadmin";
+ private static final String EMPTY_ROLE_KEY = "emptyrole";
+ private static ResourceCreate documentData;
+ private static RoleCreate adminData;
+ private static RoleCreate duplicateRoleData;
+ private static RoleCreate emptyRoleData;
+
+ @BeforeAll
+ static void setup() {
+ // resource actions
+ HashMap actions = new HashMap<>();
+ actions.put("create", new ActionBlockEditable());
+ actions.put("read", new ActionBlockEditable().withName("Read").withDescription("Read Action"));
+ actions.put("update", new ActionBlockEditable());
+ actions.put("delete", new ActionBlockEditable());
+
+ // create document resource
+ documentData = ((
+ new ResourceCreate("document", "Document", actions)
+ )
+ .withUrn("prn:gdrive:document")
+ .withDescription("google drive document")
+ );
+
+ adminData = new RoleCreate(ADMIN_KEY, "Admin")
+ .withDescription("a test role")
+ // Assuming there is a method to add permissions
+ .withPermissions(Arrays.asList(
+ String.format("%s:create", DOCUMENT_KEY),
+ String.format("%s:read", DOCUMENT_KEY)
+ ));
+
+ duplicateRoleData = new RoleCreate(ADMIN_KEY, "Admin2").withDescription("a test duplicate role");
+
+ emptyRoleData = new RoleCreate(EMPTY_ROLE_KEY, "Empty").withDescription("empty role");
+ }
+
+ void cleanup() {
+ Permit permit = new Permit(this.config);
+ try {
+ try {
+ permit.api.roles.delete(adminData.key);
+ } catch (PermitApiError e) {
+ logger.info("SKIPPING delete of role: " + adminData.key);
+ }
+ try {
+ permit.api.roles.delete(emptyRoleData.key);
+ } catch (PermitApiError e) {
+ logger.info("SKIPPING delete of role: " + emptyRoleData.key);
+ }
+ try {
+ permit.api.resources.delete(DOCUMENT_KEY);
+ } catch (PermitApiError e) {
+ logger.info("SKIPPING delete of resource: " + DOCUMENT_KEY);
+ }
+ } catch (PermitContextError e) {
+ fail("got error: " + e);
+ } catch (IOException e) {
+ fail("got error: " + e);
+ }
+ }
+
+ @Test
+ void testRolesApi() {
+ // init the client
+ Permit permit = new Permit(this.config);
+ Gson gson = new Gson();
+
+ // roles lifecycle
+ try {
+ logger.info("check original roles length");
+ int lenRolesOriginal = permit.api.roles.list().length;
+
+ logger.info("create document with permissions");
+ permit.api.resources.create(documentData);
+
+ logger.info("create role with permissions");
+ RoleRead admin = permit.api.roles.create(adminData);
+ assertNotNull(admin);
+ assertEquals(admin.key, adminData.key);
+ assertEquals(admin.name, adminData.name);
+ assertEquals(admin.description, adminData.description);
+ assertNotNull(admin.permissions);
+ assertTrue(admin.permissions.contains(DOCUMENT_KEY + ":create"));
+ assertTrue(admin.permissions.contains(DOCUMENT_KEY + ":read"));
+
+ logger.info("verify number of roles increased by 1");
+ RoleRead[] roles = permit.api.roles.list();
+ assertEquals(roles.length, lenRolesOriginal + 1);
+
+ logger.info("verify can find new role in the new list");
+ assertTrue(Arrays.stream(roles).map(r -> r.key).collect(Collectors.toList()).contains(admin.key));
+
+ logger.info("get non existing role -> 404");
+ PermitApiError notFoundError = assertThrows(PermitApiError.class, () -> {
+ permit.api.roles.get("editor");
+ });
+ assertEquals(notFoundError.getMessage(), "Got error status code: 404");
+ assertEquals(notFoundError.getResponseCode(), 404);
+ LinkedTreeMap error = notFoundError.getErrorObject();
+ assertEquals(error.get("error_code"), "NOT_FOUND");
+ assertTrue(error.get("message").toString().startsWith("The requested data could not be found"));
+
+ logger.info("create existing role -> 409");
+ PermitApiError duplicateError = assertThrows(PermitApiError.class, () -> {
+ permit.api.roles.create(duplicateRoleData);
+ });
+ assertEquals(duplicateError.getResponseCode(), 409);
+
+ logger.info("create empty role");
+ RoleRead emptyRole = permit.api.roles.create(emptyRoleData);
+ assertNotNull(emptyRole);
+ assertEquals(emptyRole.key, emptyRoleData.key);
+ assertEquals(emptyRole.name, emptyRoleData.name);
+ assertEquals(emptyRole.description, emptyRoleData.description);
+ assertNotNull(emptyRole.permissions);
+ assertEquals(emptyRole.permissions.size(), 0);
+
+ logger.info("verify number of roles increased by 1");
+ RoleRead[] roles2 = permit.api.roles.list();
+ assertEquals(roles2.length, lenRolesOriginal + 2);
+
+ logger.info("assign permissions to roles");
+ RoleRead assignedEmpty = permit.api.roles.assignPermissions(
+ emptyRole.key,
+ new ArrayList<>(Arrays.asList(DOCUMENT_KEY + ":delete"))
+ );
+
+ logger.info("Ensure permissions are assigned as expected");
+ assertNotNull(assignedEmpty);
+ assertEquals(assignedEmpty.key, emptyRole.key);
+ assertEquals(assignedEmpty.permissions.size(), 1);
+ assertTrue(assignedEmpty.permissions.contains(DOCUMENT_KEY + ":delete"));
+
+ logger.info("Remove permissions from role");
+ permit.api.roles.removePermissions(
+ admin.key,
+ new ArrayList<>(Arrays.asList(DOCUMENT_KEY + ":create"))
+ );
+
+ logger.info("Get admin role");
+ RoleRead updatedAdmin = permit.api.roles.get(adminData.key);
+ assertNotNull(updatedAdmin);
+ assertEquals(updatedAdmin.key, adminData.key);
+ assertEquals(updatedAdmin.name, adminData.name);
+ assertNotNull(updatedAdmin.permissions);
+ assertFalse(updatedAdmin.permissions.contains(DOCUMENT_KEY + ":create"));
+ assertTrue(updatedAdmin.permissions.contains(DOCUMENT_KEY + ":read"));
+
+ logger.info("Update admin role");
+ permit.api.roles.update(
+ admin.key,
+ new RoleUpdate().withDescription("wat")
+ );
+
+ logger.info("admin changed again");
+ updatedAdmin = permit.api.roles.get(adminData.key);
+ assertNotNull(updatedAdmin);
+ assertEquals(updatedAdmin.key, adminData.key);
+ assertEquals(updatedAdmin.name, adminData.name);
+ assertEquals(updatedAdmin.description, "wat");
+ assertNotNull(updatedAdmin.permissions);
+ assertFalse(updatedAdmin.permissions.contains(DOCUMENT_KEY + ":create"));
+ assertTrue(updatedAdmin.permissions.contains(DOCUMENT_KEY + ":read"));
+
+ logger.info("Delete objects...");
+ try {
+ permit.api.roles.delete(adminData.key);
+ } catch (PermitApiError e) {
+ fail("got error: " + e);
+ }
+ try {
+ permit.api.roles.delete(emptyRoleData.key);
+ } catch (PermitApiError e) {
+ fail("got error: " + e);
+ }
+ try {
+ permit.api.resources.delete(DOCUMENT_KEY);
+ } catch (PermitApiError e) {
+ fail("got error: " + e);
+ }
+
+ logger.info("Verify that again we have the initial number of roles");
+ roles = permit.api.roles.list();
+ assertEquals(roles.length, lenRolesOriginal);
+
+ logger.info("Verify deleted role cannot be deleted again");
+ PermitApiError exception = assertThrows(PermitApiError.class, () -> {
+ permit.api.roles.delete(emptyRole.key);
+ });
+ assertEquals(exception.getResponseCode(), 404);
+ } catch (IOException | PermitApiError | PermitContextError e) {
+ fail("got error: " + e);
+ }
+ finally {
+ cleanup();
+ }
+ }
+}