From 63d30e3787015ff4ee1c2dfdc8abf74e34c7fbe4 Mon Sep 17 00:00:00 2001 From: 2uan2 <2uan20004@gmail.com> Date: Sat, 13 Dec 2025 15:51:03 +0700 Subject: [PATCH 1/6] added partial implementation for Groups SDK --- .../java/io/permit/sdk/api/ApiClient.java | 5 + .../java/io/permit/sdk/api/GroupsApi.java | 337 ++++++++++++++++++ .../sdk/openapi/models/GroupAddRole.java | 110 ++++++ .../sdk/openapi/models/GroupAssignUser.java | 52 +++ .../sdk/openapi/models/GroupCreate.java | 94 +++++ .../permit/sdk/openapi/models/GroupRead.java | 128 +++++++ .../sdk/endpoints/GroupsApiE2ETest.java | 246 +++++++++++++ 7 files changed, 972 insertions(+) create mode 100644 src/main/java/io/permit/sdk/api/GroupsApi.java create mode 100644 src/main/java/io/permit/sdk/openapi/models/GroupAddRole.java create mode 100644 src/main/java/io/permit/sdk/openapi/models/GroupAssignUser.java create mode 100644 src/main/java/io/permit/sdk/openapi/models/GroupCreate.java create mode 100644 src/main/java/io/permit/sdk/openapi/models/GroupRead.java create mode 100644 src/test/java/io/permit/sdk/endpoints/GroupsApiE2ETest.java diff --git a/src/main/java/io/permit/sdk/api/ApiClient.java b/src/main/java/io/permit/sdk/api/ApiClient.java index 78d8374..1483bb4 100644 --- a/src/main/java/io/permit/sdk/api/ApiClient.java +++ b/src/main/java/io/permit/sdk/api/ApiClient.java @@ -119,6 +119,10 @@ public class ApiClient implements IDeprecatedApis { */ public final ElementsApi elements; + /** + * The {@code GroupsApi} instance for accessing Permit Groups related API endpoints. + */ + public final GroupsApi groups; /** * Constructs a new instance of the {@code ApiClient} class with the specified configuration. @@ -148,6 +152,7 @@ public ApiClient(PermitConfig config) { this.relationshipTuples = new RelationshipTuplesApi(this.client, this.config); this.conditionSetRules = new ConditionSetRulesApi(this.client, this.config); this.elements = new ElementsApi(this.client, this.config); + this.groups = new GroupsApi(this.client, this.config); } /** diff --git a/src/main/java/io/permit/sdk/api/GroupsApi.java b/src/main/java/io/permit/sdk/api/GroupsApi.java new file mode 100644 index 0000000..d870d51 --- /dev/null +++ b/src/main/java/io/permit/sdk/api/GroupsApi.java @@ -0,0 +1,337 @@ +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.*; +import okhttp3.*; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.*; + +interface IGroupsApi { +// GroupRead[] list(String resource, Boolean includeTotalCount, int page, int perPage, String search) throws IOException, PermitApiError, PermitContextError; + GroupRead[] list(int page, int perPage) throws IOException, PermitApiError, PermitContextError; + GroupRead[] list(int page) throws IOException, PermitApiError, PermitContextError; + GroupRead[] list() throws IOException, PermitApiError, PermitContextError; + GroupRead create(GroupCreate groupData) throws IOException, PermitApiError, PermitContextError; + void delete(String groupInstanceKey) throws IOException, PermitApiError, PermitContextError; + GroupRead get(String groupInstanceKey) throws IOException, PermitApiError, PermitContextError; + GroupRead getByKey(String groupInstanceKey) throws IOException, PermitApiError, PermitContextError; + GroupRead getById(UUID groupInstanceId) throws IOException, PermitApiError, PermitContextError; + GroupRead assignRoleToGroup(String groupInstanceKey, GroupAddRole groupAddRole) throws IOException, PermitApiError, PermitContextError; + GroupRead assignUserToGroup(String userId, String groupInstanceKey, String tenant) throws IOException, PermitApiError, PermitContextError; + void removeRoleFromGroup(String groupInstanceKey, GroupAddRole groupAddRole) throws IOException, PermitApiError, PermitContextError; + void removeUserFromGroup(String userId, String groupInstanceKey, String tenant) throws IOException, PermitApiError, PermitContextError; + + +// GroupReadSchema getDirectGroup(String projId, String envId, String groupInstanceKey) throws IOException, PermitApiError, PermitContextError; +// PaginatedResultGroupReadSchema listDirectGroup(String projId, String envId, String tenant, String resource, Integer page, Integer perPage, String search) throws IOException, PermitApiError, PermitContextError; +// PaginatedResultGroupReadSchema listGroupChildren(String projId, String envId, String groupInstanceKey, Integer page, Integer perPage) throws IOException, PermitApiError, PermitContextError; +// PaginatedResultGroupReadSchema listGroupParents(String projId, String envId, String groupInstanceKey, Integer page, Integer perPage) throws IOException, PermitApiError, PermitContextError; +// PaginatedResultGroupRoleReadSchema listGroupRoles(String projId, String envId, String groupInstanceKey, Integer page, Integer perPage) throws IOException, PermitApiError, PermitContextError; +// PaginatedResultGroupUserReadSchema listGroupUsers(String projId, String envId, String groupInstanceKey, Integer page, Integer perPage) throws IOException, PermitApiError, PermitContextError; +// GroupRead assignGroupToGroup(String projId, String envId, String groupInstanceKey, GroupAssignment groupAssignment) throws IOException, PermitApiError, PermitContextError; +// void removeGroupFromGroup(String projId, String envId, String groupInstanceKey, GroupAssignment groupAssignment) throws IOException, PermitApiError, PermitContextError; +} + +public class GroupsApi extends BaseApi implements IGroupsApi { + /** + * Constructs a new GroupsApi instance. + * + * @param client The OkHttpClient instance used for making HTTP requests. + * @param config The PermitConfig instance containing the SDK configuration. + */ + public GroupsApi(OkHttpClient client, PermitConfig config) { + super(client, config, LoggerFactory.getLogger(GroupsApi.class)); + } + + /** + * Constructs the URL for the Groups API. + * + * @param url The URL fragment. + * @return The constructed URL string. + */ + private String getGroupsUrl(String url) { + return buildUrl( + String.format( + "/v2/schema/%s/%s/groups%s", + config.getContext().getProject(), + config.getContext().getEnvironment(), + url + ) + ); + } + + /** + * Retrieves a paginated result of groups. + * + * @param page The page number of the result set to retrieve. + * @param perPage The number of items per page. + * @return A PaginatedResultUserRead object representing the retrieved paginated result of groups. + * @throws IOException If an I/O error occurs during the HTTP 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 GroupRead[] list(int page, int perPage) throws IOException, PermitApiError, PermitContextError { + ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY); + ensureContext(ApiContextLevel.ENVIRONMENT); + String url = getGroupsUrl(""); + HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder(); + Request request = buildRequest( + new Request.Builder() + .url( + urlBuilder +// .addQueryParameter("page", Integer.toString(page)) +// .addQueryParameter("per_page", Integer.toString(perPage)) + .build() + ) + .get() + ); + + try (Response response = client.newCall(request).execute()) { + String responseString = processResponseBody(response); + return (new Gson()).fromJson(responseString, GroupRead[].class); + } + } + + /** + * Retrieves a paginated result of groups with the default number of items per page. + * + * @param page The page number of the result set to retrieve. + * @return A PaginatedResultUserRead object representing the retrieved paginated result of groups. + * @throws IOException If an I/O error occurs during the HTTP 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 GroupRead[] list(int page) throws IOException, PermitApiError, PermitContextError { + return this.list(page, 100); + } + + /** + * Retrieves a paginated result of groups with default pagination. + * + * @return A PaginatedResultUserRead object representing the retrieved paginated result of groups. + * @throws IOException If an I/O error occurs during the HTTP 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 GroupRead[] list() throws IOException, PermitApiError, PermitContextError { + return this.list(1); + } + + /** + * Retrieves a group by its group instance key. + * + * @param groupInstanceKey The key of the group. + * @return The {@link GroupRead} object representing the group. + * @throws IOException If an I/O error occurs during the HTTP 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 GroupRead get(String groupInstanceKey) throws IOException, PermitApiError, PermitContextError { + ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY); + ensureContext(ApiContextLevel.ENVIRONMENT); + String url = getGroupsUrl(String.format("/%s", groupInstanceKey)); + Request request = buildRequest( + new Request.Builder() + .url(url) + .get() + ); + + return this.callApiAndParseJson(request, GroupRead.class); + } + + /** + * Retrieves a group by its group instance key. + * + * @param groupInstanceKey The key of the group. + * @return The {@link GroupRead} object representing the group. + * @throws IOException If an I/O error occurs during the HTTP 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 GroupRead getByKey(String groupInstanceKey) throws IOException, PermitApiError, PermitContextError { + return this.get(groupInstanceKey); + } + + /** + * Retrieves a group by its ID. + * + * @param groupInstanceId The ID of the group. + * @return The {@link GroupRead} object representing the group. + * @throws IOException If an I/O error occurs during the HTTP 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 GroupRead getById(UUID groupInstanceId) throws IOException, PermitApiError, PermitContextError { + return this.get(groupInstanceId.toString()); + } + + /** + * Creates a new group. + * + * @param groupData The {@link GroupCreate} object representing the group data. + * @return A {@link GroupRead} object representing the created group. + * @throws IOException If an I/O error occurs during the HTTP 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 GroupRead create(GroupCreate groupData) throws IOException, PermitApiError, PermitContextError { + ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY); + ensureContext(ApiContextLevel.ENVIRONMENT); + String url = getGroupsUrl(""); + RequestBody jsonBody = getJsonRequestBody(groupData); + + Request request = buildRequest( + new Request.Builder() + .url(url) + .post(jsonBody) + ); + + return this.callApiAndParseJson(request, GroupRead.class); + } + + /** + * Deletes a group with the specified group instance key. + * + * @param groupInstanceKey The key of the group to delete. + * @throws IOException If an I/O error occurs during the HTTP 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 void delete(String groupInstanceKey) throws IOException, PermitApiError, PermitContextError { + ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY); + ensureContext(ApiContextLevel.ENVIRONMENT); + String url = getGroupsUrl(String.format("/%s", groupInstanceKey)); + Request request = buildRequest( + new Request.Builder() + .url(url) + .delete() + ); + + try (Response response = client.newCall(request).execute()) { + processResponseBody(response, false); + } + } + + /** + * Assign a role to the group, all users in this group will now have this role. + * It will create relation between the group and the resource, relationship between the resource instances and derivation from the member role to this role. + * + * @param groupInstanceKey The key of the group to assign the user. + * @param groupAddRole The {@link GroupAddRole} object containing the assignment data. + * @return The {@link GroupRead} object representing the group after assigning the role. + * @throws IOException If an I/O error occurs during the HTTP 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 GroupRead assignRoleToGroup(String groupInstanceKey, GroupAddRole groupAddRole) throws IOException, PermitApiError, PermitContextError { + ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY); + ensureContext(ApiContextLevel.ENVIRONMENT); + String url = getGroupsUrl(String.format("/%s/roles", groupInstanceKey)); + RequestBody jsonBody = getJsonRequestBody(groupAddRole); + + Request request = buildRequest( + new Request.Builder() + .url(url) + .post(jsonBody) + ); + + return this.callApiAndParseJson(request, GroupRead.class); + } + + /** + * Assign a user to the group. + * + * @param userId The id of the user to assign to the group. + * @param groupInstanceKey The key of the group to assign the user to. + * @param tenant The tenant key or id that the user belongs to. + * @return The {@link GroupRead} object representing the group after assigning the user. + * @throws IOException If an I/O error occurs during the HTTP 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 GroupRead assignUserToGroup(String userId, String groupInstanceKey, String tenant) throws IOException, PermitApiError, PermitContextError { + ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY); + ensureContext(ApiContextLevel.ENVIRONMENT); + String url = getGroupsUrl(String.format("/%s/users/%s", groupInstanceKey, userId)); + RequestBody jsonBody = getJsonRequestBody(new GroupAssignUser(tenant)); + + Request request = buildRequest( + new Request.Builder() + .url(url) + .put(jsonBody) + ); + + return this.callApiAndParseJson(request, GroupRead.class); + } + + /** + * Remove a role to the group, all users in this group will lose this role. + * + * @param groupInstanceKey The key of the group to assign the user. + * @param groupAddRole The {@link GroupAddRole} object containing the assignment data. + * @throws IOException If an I/O error occurs during the HTTP 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 void removeRoleFromGroup(String groupInstanceKey, GroupAddRole groupAddRole) throws IOException, PermitApiError, PermitContextError { + ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY); + ensureContext(ApiContextLevel.ENVIRONMENT); + String url = getGroupsUrl(String.format("/%s/roles", groupInstanceKey)); + RequestBody jsonBody = getJsonRequestBody(groupAddRole); + + Request request = buildRequest( + new Request.Builder() + .url(url) + .delete(jsonBody) + ); + + try (Response response = client.newCall(request).execute()) { + processResponseBody(response, false); + } + } + + /** + * Remove a user from the group. + * + * @param userId The id of the user to remove from the group. + * @param groupInstanceKey The key of the group to remove the user from. + * @param tenant The tenant key or id that the user belongs to. + * @throws IOException If an I/O error occurs during the HTTP 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 void removeUserFromGroup(String userId, String groupInstanceKey, String tenant) throws IOException, PermitApiError, PermitContextError { + ensureAccessLevel(ApiKeyLevel.ENVIRONMENT_LEVEL_API_KEY); + ensureContext(ApiContextLevel.ENVIRONMENT); + String url = getGroupsUrl(String.format("/%s/users/%s", groupInstanceKey, userId)); + RequestBody jsonBody = getJsonRequestBody(new GroupAssignUser(tenant)); + + Request request = buildRequest( + new Request.Builder() + .url(url) + .delete(jsonBody) + ); + + try (Response response = client.newCall(request).execute()) { + processResponseBody(response, false); + } + } +} diff --git a/src/main/java/io/permit/sdk/openapi/models/GroupAddRole.java b/src/main/java/io/permit/sdk/openapi/models/GroupAddRole.java new file mode 100644 index 0000000..752f234 --- /dev/null +++ b/src/main/java/io/permit/sdk/openapi/models/GroupAddRole.java @@ -0,0 +1,110 @@ +/* + * Permit.io API + * Authorization as a service + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package io.permit.sdk.openapi.models; + +import javax.annotation.Generated; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + + +/** + * GroupAddRole + *

+ * + * + */ +@Generated("jsonschema2pojo") +public class GroupAddRole { + /** + * Role + *

+ * The role key or id that will be assigned to the group. + * (Required) + * + */ + @SerializedName("role") + @Expose + public String role; + /** + * Resource + *

+ * The resource key or id that the role belongs to. + * (Required) + * + */ + @SerializedName("resource") + @Expose + public String resource; + /** + * ResoruceInstance + *

+ * The resource instance key or id that the role belongs to. + * (Required) + * + */ + @SerializedName("resource_instance") + @Expose + public String resourceInstance; + /** + * Tenant + *

+ * The tenant key or id that the role belongs to. + * (Required) + * + */ + @SerializedName("tenant") + @Expose + public String tenant; + + /** + * No args constructor for use in serialization + * + */ + public GroupAddRole() { + } + + /** + * + * @param resourceInstance + * @param tenant + */ + public GroupAddRole(java.lang.String role, java.lang.String resourceInstance, java.lang.String resource, java.lang.String tenant) { + super(); + this.role = role; + this.resourceInstance = resourceInstance; + this.resource = resource; + this.tenant = tenant; + } + + public GroupAddRole withRole(java.lang.String role) { + this.role = role; + return this; + } + + public GroupAddRole withResourceInstanceKey(java.lang.String resourceInstance) { + this.resourceInstance = resourceInstance; + return this; + } + + public GroupAddRole withResource(java.lang.String resource) { + this.resource = resource; + return this; + } + + public GroupAddRole withTenant(java.lang.String tenant) { + this.tenant = tenant; + return this; + } +} + diff --git a/src/main/java/io/permit/sdk/openapi/models/GroupAssignUser.java b/src/main/java/io/permit/sdk/openapi/models/GroupAssignUser.java new file mode 100644 index 0000000..c20ba5f --- /dev/null +++ b/src/main/java/io/permit/sdk/openapi/models/GroupAssignUser.java @@ -0,0 +1,52 @@ +/* + * Permit.io API + * Authorization as a service + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package io.permit.sdk.openapi.models; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * GroupAssignUser + *

+ * + * + */ +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2025-11-26T18:29:37.439030+07:00[Asia/Ho_Chi_Minh]", comments = "Generator version: 7.17.0") +public class GroupAssignUser { + /** + * Tenant + *

+ * the tenant key or id that the user belongs to. + * (Required) + */ + @SerializedName("tenant") + @Expose + public String tenant; + + /** + * + * @param groupInstanceKey + * @param tenant + */ + public GroupAssignUser(java.lang.String tenant) { + super(); + this.tenant = tenant; + } + + public GroupAssignUser withTenant(java.lang.String tenant) { + this.tenant = tenant; + return this; + } +} + diff --git a/src/main/java/io/permit/sdk/openapi/models/GroupCreate.java b/src/main/java/io/permit/sdk/openapi/models/GroupCreate.java new file mode 100644 index 0000000..a8090f2 --- /dev/null +++ b/src/main/java/io/permit/sdk/openapi/models/GroupCreate.java @@ -0,0 +1,94 @@ +/* + * Permit.io API + * Authorization as a service + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package io.permit.sdk.openapi.models; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import javax.annotation.Generated; + +/** + * GroupCreate + *

+ * + * + */ +@Generated("jsonschema2pojo") +public class GroupCreate { + /** + * Group Resource Type Key + *

+ * The key of the resource type that the group belongs to. + * + */ + @SerializedName("group_resource_type_key") + @Expose + public java.lang.String groupResourceTypeKey = "group"; + + /** + * Group Instance Key + *

+ * Either the unique id of the resource instance that that the group belongs to, or the URL-friendly key of the (i.e: file:my_file) + * (Required) + * + */ + @SerializedName("group_instance_key") + @Expose + public java.lang.String groupInstanceKey; + + /** + * Group Tenant + *

+ * The tenant key or id that the group belongs to. + * (Required) + * + */ + @SerializedName("group_tenant") + @Expose + public java.lang.String groupTenant; + + /** + * No args constructor for use in serialization + * + */ + public GroupCreate() { + } + + /** + * + * @param groupInstanceKey + * @param groupTenant + */ + public GroupCreate(java.lang.String groupInstanceKey, java.lang.String groupTenant) { + super(); + this.groupInstanceKey = groupInstanceKey; + this.groupTenant = groupTenant; + } + + public GroupCreate withGroupInstanceKey(java.lang.String groupInstanceKey) { + this.groupInstanceKey = groupInstanceKey; + return this; + } + + public GroupCreate withGroupTenant(java.lang.String groupTenant) { + this.groupTenant = groupTenant; + return this; + } + + public GroupCreate withGroupResourceTypeKey(java.lang.String groupResourceTypeKey) { + this.groupResourceTypeKey = groupResourceTypeKey; + return this; + } +} + diff --git a/src/main/java/io/permit/sdk/openapi/models/GroupRead.java b/src/main/java/io/permit/sdk/openapi/models/GroupRead.java new file mode 100644 index 0000000..92a4e47 --- /dev/null +++ b/src/main/java/io/permit/sdk/openapi/models/GroupRead.java @@ -0,0 +1,128 @@ +/* + * Permit.io API + * Authorization as a service + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package io.permit.sdk.openapi.models; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; +import javax.annotation.Generated; + +import java.util.ArrayList; +import java.util.List; + + +/** + * GroupRead + *

+ * + * + */ +@Generated("jsonschema2pojo") +public class GroupRead { + /** + * Assigned Roles + *

+ * List of roles that are assigned to this group + * + */ + @SerializedName("assigned_roles") + @Expose + public List assignedRoles = new ArrayList<>(); + /** + * Users + *

+ * List of user ids that are assigned to this group + * + */ + @SerializedName("users") + @Expose + public List users = new ArrayList<>(); + /** + * GroupResourceTypeKey + *

+ * The key of the resource type that the group belongs to. + * + */ + @SerializedName("group_resource_type_key") + @Expose + public String groupResourceTypeKey = "group"; + /** + * GroupInstanceKey + *

+ * Either the unique id of the resource instance that that the group belongs to, or the URL-friendly key of the (i.e: file:my_file) + * (Required) + * + */ + @SerializedName("group_instance_key") + @Expose + public String groupInstanceKey; + /** + * Tenant + *

+ * The tenant key or id that the group belongs to. + * (Required) + * + */ + @SerializedName("group_tenant") + @Expose + public String groupTenant; + + /** + * No args constructor for use in serialization + * + */ + public GroupRead() { + } + + /** + * + * @param groupTenant + * @param groupInstanceKey + */ + public GroupRead(java.lang.String groupInstanceKey, java.lang.String groupTenant) { + super(); + this.groupTenant = groupTenant; + this.groupInstanceKey = groupInstanceKey; + } + + public GroupRead withAssignedRoles(List assignedRoles) { + this.assignedRoles = assignedRoles; + return this; + } + + public GroupRead withUsers(List users) { + this.users = users; + return this; + } + + public GroupRead withGroupResourceTypeKey(java.lang.String groupResourceTypeKey) { + this.groupResourceTypeKey = groupResourceTypeKey; + return this; + } + + public GroupRead withGroupInstanceKey(java.lang.String groupInstanceKey) { + this.groupInstanceKey = groupInstanceKey; + return this; + } + + public GroupRead withGroupTenant(java.lang.String groupTenant) { + this.groupTenant = groupTenant; + return this; + } + + @Override + public String toString() { + return String.format("{%s:%s, %s, %s}", this.groupResourceTypeKey, this.groupInstanceKey, this.assignedRoles, this.users); + } +} + diff --git a/src/test/java/io/permit/sdk/endpoints/GroupsApiE2ETest.java b/src/test/java/io/permit/sdk/endpoints/GroupsApiE2ETest.java new file mode 100644 index 0000000..bb0f97c --- /dev/null +++ b/src/test/java/io/permit/sdk/endpoints/GroupsApiE2ETest.java @@ -0,0 +1,246 @@ +package io.permit.sdk.endpoints; + +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 static org.junit.jupiter.api.Assertions.*; + +public class GroupsApiE2ETest extends PermitE2ETestBase { + private static final String TEAM_KEY = "teams"; + private static final String MARKETING_KEY = "marketing"; + private static final String GROUP_KEY = TEAM_KEY + ":" + MARKETING_KEY; + private static final String DEFAULT_TENANT = "default"; + private static GroupCreate marketingData; + + private static ResourceCreate socialMediaData; + private static ResourceInstanceCreate trainingVideoData; + private static ResourceRoleCreate editorRole; + + private static UserCreate bobData; + private static GroupAddRole groupRoleData; + + @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()); + + marketingData = new GroupCreate(MARKETING_KEY, DEFAULT_TENANT).withGroupResourceTypeKey(TEAM_KEY); + + socialMediaData = new ResourceCreate("social_media", "social media", actions); + trainingVideoData = new ResourceInstanceCreate("training_video", socialMediaData.key).withTenant(DEFAULT_TENANT); + editorRole = new ResourceRoleCreate("editor", "editor"); + + bobData = new UserCreate("bob"); + groupRoleData = new GroupAddRole(editorRole.key, trainingVideoData.key, socialMediaData.key, DEFAULT_TENANT); + } + + void cleanup() { + Permit permit = new Permit(this.config); + logger.info("cleaning"); + try { + try { + permit.api.resourceRoles.delete(socialMediaData.key, editorRole.key); + } catch (PermitApiError e) { + logger.info(String.format("SKIPPING delete of role %s on resource instance %s", editorRole.key, trainingVideoData.key)); + } + try { + permit.api.resourceInstances.delete(trainingVideoData.resource + ":" + trainingVideoData.key); + } catch (PermitApiError e) { + logger.info("SKIPPING delete of resource instance: " + trainingVideoData.key); + } + try { + permit.api.users.delete(bobData.key); + } catch (PermitApiError e) { + logger.info("SKIPPING delete of user: " + bobData.key); + } + try { + permit.api.groups.delete(GROUP_KEY); + } catch (PermitApiError e) { + logger.info("SKIPPING delete of group: " + GROUP_KEY); + } + try { + permit.api.resourceRoles.delete(TEAM_KEY, "member"); + } catch (PermitApiError e) { + logger.info("SKIPPING delete of resource role: " + TEAM_KEY + " member"); + } + try { + permit.api.resources.delete(socialMediaData.key); + } catch (PermitApiError e) { + logger.info("SKIPPING delete of resource: " + socialMediaData.key); + } + try { + permit.api.resources.delete(TEAM_KEY); + } catch (PermitApiError e) { + logger.info("SKIPPING delete of resource: " + TEAM_KEY); + } + try { + permit.api.resourceRelations.delete(socialMediaData.key, TEAM_KEY + "_group_" + editorRole.key); + } catch (PermitApiError e) { + logger.info("SKIPPING delete of resource relation: " + TEAM_KEY + "_group_" + editorRole.key); + } + try { + permit.api.groups.removeRoleFromGroup(GROUP_KEY, groupRoleData); + } catch (PermitApiError e) { + logger.info("SKIPPING delete of resource relation: " + TEAM_KEY + "_group_" + editorRole.key); + } + } catch (PermitContextError e) { + fail("clean up got error: " + e); + } catch (IOException e) { + fail("clean up got IOexception: " + e); + } + } + + @Test + void testGroupsApi() { + Permit permit = new Permit(this.config); + try { + logger.info("check original groups length"); + int originalLength = permit.api.groups.list().length; + + GroupRead marketingGroup = permit.api.groups.create(marketingData); + assertNotNull(marketingGroup); + assertNotNull(marketingGroup.groupResourceTypeKey); + assertEquals(marketingGroup.groupResourceTypeKey, marketingData.groupResourceTypeKey); + assertEquals(marketingGroup.groupTenant, marketingData.groupTenant); + assertEquals(marketingGroup.groupInstanceKey, marketingData.groupInstanceKey); + boolean foundMember = false; + for (String role : marketingGroup.assignedRoles) { + if (role.contains("member")) { + foundMember = true; + break; + } + } + assertTrue(foundMember); + + logger.info("verify number of items increased by 1"); + GroupRead[] groups = permit.api.groups.list(); + assertEquals(groups.length, originalLength + 1); + + logger.info("verify can find new group in the new list"); +// logger.info(Arrays.stream(groups).map(r -> r.groupInstanceKey).toList().toString()); + assertTrue(Arrays.stream(groups).map(r -> r.groupInstanceKey).toList().toString().contains(marketingData.groupInstanceKey)); + + logger.info("get non existing group -> 404"); + PermitApiError notFoundError = assertThrows(PermitApiError.class, () -> { + permit.api.groups.get("group"); + }); + assertEquals("Got error status code: 404", notFoundError.getMessage()); + assertEquals(404, notFoundError.getResponseCode()); + LinkedTreeMap error = notFoundError.getErrorObject(); + assertEquals("NOT_FOUND", error.get("error_code")); + assertTrue(error.get("message").toString().startsWith("The requested data could not be found")); + + logger.info("create existing group -> 409"); + PermitApiError duplicateError = assertThrows(PermitApiError.class, () -> { + permit.api.groups.create(marketingData); + }); + assertEquals(409, duplicateError.getResponseCode()); + + + // test assign user + logger.info("Adding user to group"); + UserRead bob = permit.api.users.create(bobData); + GroupRead afterAddingUser = permit.api.groups.assignUserToGroup(bobData.key, GROUP_KEY, DEFAULT_TENANT); + assertTrue(afterAddingUser.users.contains(bob.id)); + assertEquals(1, afterAddingUser.users.size()); + + logger.info("Adding user already in group"); + GroupRead afterAddingUserAgain = permit.api.groups.assignUserToGroup(bobData.key, GROUP_KEY, DEFAULT_TENANT); + assertEquals(afterAddingUserAgain.users.size(), afterAddingUser.users.size()); + logger.info("Removing user from group"); + permit.api.groups.removeUserFromGroup(bobData.key, GROUP_KEY, DEFAULT_TENANT); + GroupRead afterRemovingUser = permit.api.groups.get(GROUP_KEY); + assertEquals(0, afterRemovingUser.users.size()); + + // test assign role + logger.info("Adding role to group"); + + try { + permit.api.resources.create(socialMediaData); + } catch (PermitApiError e) { + logger.info("SKIPPING creating resource: " + socialMediaData.key); + } + try { + permit.api.resourceInstances.create(trainingVideoData); + } catch (PermitApiError e) { + logger.info("SKIPPING creating resource instances: " + trainingVideoData.key); + } + try { + permit.api.resourceRoles.create(socialMediaData.key, editorRole); + } catch (PermitApiError e) { + logger.info("SKIPPING creating resource role: " + socialMediaData.key + editorRole.key); + } + + GroupRead afterAddingRole = permit.api.groups.assignRoleToGroup(GROUP_KEY, groupRoleData); + boolean foundRole = false; + boolean foundResource = false; + boolean foundResourceInstance = false; + for (String role : afterAddingRole.assignedRoles) { + if (role.contains(groupRoleData.role)) + foundRole = true; + if (role.contains(groupRoleData.resource)) + foundResource = true; + if (role.contains(groupRoleData.resourceInstance)) + foundResourceInstance = true; + } + assertTrue(foundRole); + assertTrue(foundResource); + assertTrue(foundResourceInstance); + assertEquals(2, afterAddingRole.assignedRoles.size()); + + logger.info("Removing role from group"); +// String trainingVideoFullKey = groupRoleData.resource + ":" + groupRoleData.resourceInstance; + permit.api.groups.removeRoleFromGroup(GROUP_KEY, groupRoleData); + GroupRead afterRemovingRole = permit.api.groups.get(GROUP_KEY); + for (String role : afterRemovingRole.assignedRoles) { + if (!role.contains(groupRoleData.role)) + foundRole = false; + if (!role.contains(groupRoleData.resource)) + foundResource = false; + if (!role.contains(groupRoleData.resourceInstance)) + foundResourceInstance = false; + } + assertFalse(foundRole); + assertFalse(foundResource); + assertFalse(foundResourceInstance); + assertEquals(1, marketingGroup.assignedRoles.size()); + + // delete group + logger.info("Delete group..."); + try { + permit.api.groups.delete(GROUP_KEY); + } catch (PermitApiError e) { + fail("got error: " + e); + } + + logger.info("Verify that again we have the initial number of groups"); + GroupRead[] groupsAfterDelete = permit.api.groups.list(); + assertEquals(groupsAfterDelete.length, originalLength); + + logger.info("Verify deleted groups cannot be deleted again"); + PermitApiError exception = assertThrows(PermitApiError.class, () -> { + permit.api.groups.delete(GROUP_KEY); + }); + assertEquals(404, exception.getResponseCode()); + + } catch (IOException | PermitApiError | PermitContextError e) { + fail("testGroupsApi got error: " + e); + } finally { + cleanup(); + } + } +} From 2c6a3d0d863660abdbfe58d71559b22ba36ccb42 Mon Sep 17 00:00:00 2001 From: 2uan2 <2uan20004@gmail.com> Date: Sat, 13 Dec 2025 15:51:57 +0700 Subject: [PATCH 2/6] fixed some typos --- src/main/java/io/permit/sdk/api/RelationshipTuplesApi.java | 6 +++--- src/main/java/io/permit/sdk/api/ResourceInstancesApi.java | 1 + src/main/java/io/permit/sdk/api/ResourceRelationsApi.java | 2 +- src/main/java/io/permit/sdk/api/UsersApi.java | 2 +- .../java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java | 4 ++-- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/io/permit/sdk/api/RelationshipTuplesApi.java b/src/main/java/io/permit/sdk/api/RelationshipTuplesApi.java index 161d7d7..cf196b2 100644 --- a/src/main/java/io/permit/sdk/api/RelationshipTuplesApi.java +++ b/src/main/java/io/permit/sdk/api/RelationshipTuplesApi.java @@ -114,7 +114,7 @@ public RelationshipTupleRead[] list(String subject, String relation, String obje * @param object The object of the relationship (a resource instance key). * @param page The page number of the results. * @return An array of RelationshipTupleRead objects representing the relationship tuples. - * @throws IOException If an I/Oerror occurs during the HTTP request. + * @throws IOException If an I/O error occurs during the HTTP 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. */ @@ -129,7 +129,7 @@ public RelationshipTupleRead[] list(String subject, String relation, String obje * @param relation The relation between the two resource instances. * @param object The object of the relationship (a resource instance key). * @return An array of RelationshipTupleRead objects representing the relationship tuples. - * @throws IOException If an I/Oerror occurs during the HTTP request. + * @throws IOException If an I/O error occurs during the HTTP 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. */ @@ -141,7 +141,7 @@ public RelationshipTupleRead[] list(String subject, String relation, String obje * Lists all relationship tuples with the default pagination parameters. * * @return An array of RelationshipTupleRead objects representing the relationship tuples. - * @throws IOException If an I/Oerror occurs during the HTTP request. + * @throws IOException If an I/O error occurs during the HTTP 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. */ diff --git a/src/main/java/io/permit/sdk/api/ResourceInstancesApi.java b/src/main/java/io/permit/sdk/api/ResourceInstancesApi.java index 36e8f0f..619e5e4 100644 --- a/src/main/java/io/permit/sdk/api/ResourceInstancesApi.java +++ b/src/main/java/io/permit/sdk/api/ResourceInstancesApi.java @@ -146,6 +146,7 @@ public ResourceInstanceRead get(String instanceKey) throws IOException, PermitAp /** * Retrieves a resource instance by its key. + * This is an alias for the {@link #get} method. * * @param instanceKey The key of the resource instance. * @return A ResourceInstanceRead object representing the retrieved resource instance. diff --git a/src/main/java/io/permit/sdk/api/ResourceRelationsApi.java b/src/main/java/io/permit/sdk/api/ResourceRelationsApi.java index 08b864b..a863287 100644 --- a/src/main/java/io/permit/sdk/api/ResourceRelationsApi.java +++ b/src/main/java/io/permit/sdk/api/ResourceRelationsApi.java @@ -172,7 +172,7 @@ public RelationRead getById(UUID resourceId, UUID relationId) throws IOException /** * Creates a new relation under the specified resource. - * Since resource respresents a type, the relation itself represents a type and not a value. + * Since resource represents a type, the relation itself represents a type and not a value. * * @param resourceKey The key of the resource. * @param relationData The {@link RelationCreate} object containing the data for the new resource relation. diff --git a/src/main/java/io/permit/sdk/api/UsersApi.java b/src/main/java/io/permit/sdk/api/UsersApi.java index 2c55cb7..9110960 100644 --- a/src/main/java/io/permit/sdk/api/UsersApi.java +++ b/src/main/java/io/permit/sdk/api/UsersApi.java @@ -135,7 +135,7 @@ public PaginatedResultUserRead list() throws IOException, PermitApiError, Permit /** * Retrieves a user by its key. * - * @param userKey The key of theuser. + * @param userKey The key of the user. * @return A UserRead object representing the retrieved user. * @throws IOException If an I/O error occurs during the HTTP request. * @throws PermitApiError If the Permit API returns a response with an error status code. diff --git a/src/test/java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java b/src/test/java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java index 71e613b..5379019 100644 --- a/src/test/java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java +++ b/src/test/java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java @@ -85,7 +85,7 @@ void testResourcesApi() { Permit permit = new Permit(this.config); Gson gson = new Gson(); - // roles lifecycle + // users lifecycle try { logger.info("check original resource length"); int originalLength = permit.api.resources.list().length; @@ -111,7 +111,7 @@ void testResourcesApi() { 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"); + logger.info("get non existing user -> 404"); PermitApiError notFoundError = assertThrows(PermitApiError.class, () -> { permit.api.resources.get("group"); }); From d879a6d9de0431cfcfa7e8c68f15ae811ecb2077 Mon Sep 17 00:00:00 2001 From: 2uan2 <2uan20004@gmail.com> Date: Tue, 16 Dec 2025 21:05:27 +0700 Subject: [PATCH 3/6] removed commented out lines and fix some comments --- .../java/io/permit/sdk/api/GroupsApi.java | 22 +++++-------------- .../sdk/endpoints/GroupsApiE2ETest.java | 5 ++--- .../sdk/endpoints/ResourcesApiE2ETest.java | 2 +- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/main/java/io/permit/sdk/api/GroupsApi.java b/src/main/java/io/permit/sdk/api/GroupsApi.java index d870d51..061ead8 100644 --- a/src/main/java/io/permit/sdk/api/GroupsApi.java +++ b/src/main/java/io/permit/sdk/api/GroupsApi.java @@ -12,8 +12,8 @@ import java.io.IOException; import java.util.*; +// This is a partial support for the Groups API, some methods are currently missing. interface IGroupsApi { -// GroupRead[] list(String resource, Boolean includeTotalCount, int page, int perPage, String search) throws IOException, PermitApiError, PermitContextError; GroupRead[] list(int page, int perPage) throws IOException, PermitApiError, PermitContextError; GroupRead[] list(int page) throws IOException, PermitApiError, PermitContextError; GroupRead[] list() throws IOException, PermitApiError, PermitContextError; @@ -26,16 +26,6 @@ interface IGroupsApi { GroupRead assignUserToGroup(String userId, String groupInstanceKey, String tenant) throws IOException, PermitApiError, PermitContextError; void removeRoleFromGroup(String groupInstanceKey, GroupAddRole groupAddRole) throws IOException, PermitApiError, PermitContextError; void removeUserFromGroup(String userId, String groupInstanceKey, String tenant) throws IOException, PermitApiError, PermitContextError; - - -// GroupReadSchema getDirectGroup(String projId, String envId, String groupInstanceKey) throws IOException, PermitApiError, PermitContextError; -// PaginatedResultGroupReadSchema listDirectGroup(String projId, String envId, String tenant, String resource, Integer page, Integer perPage, String search) throws IOException, PermitApiError, PermitContextError; -// PaginatedResultGroupReadSchema listGroupChildren(String projId, String envId, String groupInstanceKey, Integer page, Integer perPage) throws IOException, PermitApiError, PermitContextError; -// PaginatedResultGroupReadSchema listGroupParents(String projId, String envId, String groupInstanceKey, Integer page, Integer perPage) throws IOException, PermitApiError, PermitContextError; -// PaginatedResultGroupRoleReadSchema listGroupRoles(String projId, String envId, String groupInstanceKey, Integer page, Integer perPage) throws IOException, PermitApiError, PermitContextError; -// PaginatedResultGroupUserReadSchema listGroupUsers(String projId, String envId, String groupInstanceKey, Integer page, Integer perPage) throws IOException, PermitApiError, PermitContextError; -// GroupRead assignGroupToGroup(String projId, String envId, String groupInstanceKey, GroupAssignment groupAssignment) throws IOException, PermitApiError, PermitContextError; -// void removeGroupFromGroup(String projId, String envId, String groupInstanceKey, GroupAssignment groupAssignment) throws IOException, PermitApiError, PermitContextError; } public class GroupsApi extends BaseApi implements IGroupsApi { @@ -71,7 +61,7 @@ private String getGroupsUrl(String url) { * * @param page The page number of the result set to retrieve. * @param perPage The number of items per page. - * @return A PaginatedResultUserRead object representing the retrieved paginated result of groups. + * @return An array of GroupRead objects representing the retrieved groups. * @throws IOException If an I/O error occurs during the HTTP 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. @@ -86,8 +76,8 @@ public GroupRead[] list(int page, int perPage) throws IOException, PermitApiErro new Request.Builder() .url( urlBuilder -// .addQueryParameter("page", Integer.toString(page)) -// .addQueryParameter("per_page", Integer.toString(perPage)) + .addQueryParameter("page", Integer.toString(page)) + .addQueryParameter("per_page", Integer.toString(perPage)) .build() ) .get() @@ -230,7 +220,7 @@ public void delete(String groupInstanceKey) throws IOException, PermitApiError, * Assign a role to the group, all users in this group will now have this role. * It will create relation between the group and the resource, relationship between the resource instances and derivation from the member role to this role. * - * @param groupInstanceKey The key of the group to assign the user. + * @param groupInstanceKey The key of the group to assign the role to. * @param groupAddRole The {@link GroupAddRole} object containing the assignment data. * @return The {@link GroupRead} object representing the group after assigning the role. * @throws IOException If an I/O error occurs during the HTTP request. @@ -281,7 +271,7 @@ public GroupRead assignUserToGroup(String userId, String groupInstanceKey, Strin } /** - * Remove a role to the group, all users in this group will lose this role. + * Remove a role from the group, all users in this group will lose this role. * * @param groupInstanceKey The key of the group to assign the user. * @param groupAddRole The {@link GroupAddRole} object containing the assignment data. diff --git a/src/test/java/io/permit/sdk/endpoints/GroupsApiE2ETest.java b/src/test/java/io/permit/sdk/endpoints/GroupsApiE2ETest.java index bb0f97c..2913ab2 100644 --- a/src/test/java/io/permit/sdk/endpoints/GroupsApiE2ETest.java +++ b/src/test/java/io/permit/sdk/endpoints/GroupsApiE2ETest.java @@ -12,6 +12,7 @@ import java.io.IOException; import java.util.Arrays; import java.util.HashMap; +import java.util.stream.Collectors; import static org.junit.jupiter.api.Assertions.*; @@ -131,8 +132,7 @@ void testGroupsApi() { assertEquals(groups.length, originalLength + 1); logger.info("verify can find new group in the new list"); -// logger.info(Arrays.stream(groups).map(r -> r.groupInstanceKey).toList().toString()); - assertTrue(Arrays.stream(groups).map(r -> r.groupInstanceKey).toList().toString().contains(marketingData.groupInstanceKey)); + assertTrue(Arrays.stream(groups).map(r -> r.groupInstanceKey).collect(Collectors.toList()).toString().contains(marketingData.groupInstanceKey)); logger.info("get non existing group -> 404"); PermitApiError notFoundError = assertThrows(PermitApiError.class, () -> { @@ -203,7 +203,6 @@ void testGroupsApi() { assertEquals(2, afterAddingRole.assignedRoles.size()); logger.info("Removing role from group"); -// String trainingVideoFullKey = groupRoleData.resource + ":" + groupRoleData.resourceInstance; permit.api.groups.removeRoleFromGroup(GROUP_KEY, groupRoleData); GroupRead afterRemovingRole = permit.api.groups.get(GROUP_KEY); for (String role : afterRemovingRole.assignedRoles) { diff --git a/src/test/java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java b/src/test/java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java index 5379019..762c4c7 100644 --- a/src/test/java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java +++ b/src/test/java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java @@ -85,7 +85,7 @@ void testResourcesApi() { Permit permit = new Permit(this.config); Gson gson = new Gson(); - // users lifecycle + // Resource lifecycle. try { logger.info("check original resource length"); int originalLength = permit.api.resources.list().length; From 35fbb30844b8b9bcee536d243efea0da49a2d8a4 Mon Sep 17 00:00:00 2001 From: Zeev Manilovich Date: Sun, 21 Dec 2025 15:00:07 +0200 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/main/java/io/permit/sdk/api/GroupsApi.java | 2 +- src/main/java/io/permit/sdk/openapi/models/GroupAddRole.java | 2 +- src/main/java/io/permit/sdk/openapi/models/GroupAssignUser.java | 2 +- src/test/java/io/permit/sdk/endpoints/GroupsApiE2ETest.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/permit/sdk/api/GroupsApi.java b/src/main/java/io/permit/sdk/api/GroupsApi.java index 061ead8..606b126 100644 --- a/src/main/java/io/permit/sdk/api/GroupsApi.java +++ b/src/main/java/io/permit/sdk/api/GroupsApi.java @@ -273,7 +273,7 @@ public GroupRead assignUserToGroup(String userId, String groupInstanceKey, Strin /** * Remove a role from the group, all users in this group will lose this role. * - * @param groupInstanceKey The key of the group to assign the user. + * @param groupInstanceKey The key of the group to remove the role from. * @param groupAddRole The {@link GroupAddRole} object containing the assignment data. * @throws IOException If an I/O error occurs during the HTTP request. * @throws PermitApiError If the Permit API returns a response with an error status code. diff --git a/src/main/java/io/permit/sdk/openapi/models/GroupAddRole.java b/src/main/java/io/permit/sdk/openapi/models/GroupAddRole.java index 752f234..cda65e2 100644 --- a/src/main/java/io/permit/sdk/openapi/models/GroupAddRole.java +++ b/src/main/java/io/permit/sdk/openapi/models/GroupAddRole.java @@ -47,7 +47,7 @@ public class GroupAddRole { @Expose public String resource; /** - * ResoruceInstance + * ResourceInstance *

* The resource instance key or id that the role belongs to. * (Required) diff --git a/src/main/java/io/permit/sdk/openapi/models/GroupAssignUser.java b/src/main/java/io/permit/sdk/openapi/models/GroupAssignUser.java index c20ba5f..23d5717 100644 --- a/src/main/java/io/permit/sdk/openapi/models/GroupAssignUser.java +++ b/src/main/java/io/permit/sdk/openapi/models/GroupAssignUser.java @@ -36,7 +36,7 @@ public class GroupAssignUser { /** * - * @param groupInstanceKey + * @param tenant */ public GroupAssignUser(java.lang.String tenant) { diff --git a/src/test/java/io/permit/sdk/endpoints/GroupsApiE2ETest.java b/src/test/java/io/permit/sdk/endpoints/GroupsApiE2ETest.java index 2913ab2..fea72f3 100644 --- a/src/test/java/io/permit/sdk/endpoints/GroupsApiE2ETest.java +++ b/src/test/java/io/permit/sdk/endpoints/GroupsApiE2ETest.java @@ -216,7 +216,7 @@ void testGroupsApi() { assertFalse(foundRole); assertFalse(foundResource); assertFalse(foundResourceInstance); - assertEquals(1, marketingGroup.assignedRoles.size()); + assertEquals(1, afterRemovingRole.assignedRoles.size()); // delete group logger.info("Delete group..."); From 36c6ceb2fd49e937ec5304ccb31f6730b45c71fa Mon Sep 17 00:00:00 2001 From: Zeev Manilovich Date: Sun, 21 Dec 2025 16:02:38 +0200 Subject: [PATCH 5/6] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../java/io/permit/sdk/openapi/models/GroupAddRole.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/permit/sdk/openapi/models/GroupAddRole.java b/src/main/java/io/permit/sdk/openapi/models/GroupAddRole.java index cda65e2..eab3080 100644 --- a/src/main/java/io/permit/sdk/openapi/models/GroupAddRole.java +++ b/src/main/java/io/permit/sdk/openapi/models/GroupAddRole.java @@ -75,9 +75,12 @@ public GroupAddRole() { } /** + * Constructs a new GroupAddRole with all required identifiers. * - * @param resourceInstance - * @param tenant + * @param role the role key or id to assign to the group + * @param resourceInstance the resource instance key or id that the role belongs to + * @param resource the resource key or id that the role belongs to + * @param tenant the tenant key or id that the role belongs to */ public GroupAddRole(java.lang.String role, java.lang.String resourceInstance, java.lang.String resource, java.lang.String tenant) { super(); From 3ccf6853f90d53758c90fcb44d515a64ef70ebf8 Mon Sep 17 00:00:00 2001 From: 2uan2 <2uan20004@gmail.com> Date: Thu, 25 Dec 2025 15:22:49 +0700 Subject: [PATCH 6/6] fixed some documentations mismatch --- src/main/java/io/permit/sdk/api/GroupsApi.java | 8 ++++---- .../java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/permit/sdk/api/GroupsApi.java b/src/main/java/io/permit/sdk/api/GroupsApi.java index 061ead8..ea6f9a3 100644 --- a/src/main/java/io/permit/sdk/api/GroupsApi.java +++ b/src/main/java/io/permit/sdk/api/GroupsApi.java @@ -61,7 +61,7 @@ private String getGroupsUrl(String url) { * * @param page The page number of the result set to retrieve. * @param perPage The number of items per page. - * @return An array of GroupRead objects representing the retrieved groups. + * @return An array of {@link GroupRead} objects representing the retrieved groups. * @throws IOException If an I/O error occurs during the HTTP 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. @@ -90,10 +90,10 @@ public GroupRead[] list(int page, int perPage) throws IOException, PermitApiErro } /** - * Retrieves a paginated result of groups with the default number of items per page. + * Retrieves a paginated result of groups with default pagination. * * @param page The page number of the result set to retrieve. - * @return A PaginatedResultUserRead object representing the retrieved paginated result of groups. + * @return A list of {@link GroupRead} objects representing the retrieved paginated result of groups. * @throws IOException If an I/O error occurs during the HTTP 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. @@ -106,7 +106,7 @@ public GroupRead[] list(int page) throws IOException, PermitApiError, PermitCont /** * Retrieves a paginated result of groups with default pagination. * - * @return A PaginatedResultUserRead object representing the retrieved paginated result of groups. + * @return A list of {@link GroupRead} objects representing the retrieved paginated result of groups. * @throws IOException If an I/O error occurs during the HTTP 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. diff --git a/src/test/java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java b/src/test/java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java index 762c4c7..1dd9289 100644 --- a/src/test/java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java +++ b/src/test/java/io/permit/sdk/endpoints/ResourcesApiE2ETest.java @@ -111,7 +111,7 @@ void testResourcesApi() { 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 user -> 404"); + logger.info("get non existing resource -> 404"); PermitApiError notFoundError = assertThrows(PermitApiError.class, () -> { permit.api.resources.get("group"); });