feat: Initial implementation of permission manager SDK - Add core permission management functionality with @RequiresPermission annotation - Implement permission checking aspect with Spring Security integration - Add comprehensive model classes for permissions, roles, and domains - Create integration builder for permission structure setup - Add configuration support for permission manager client - Implement exception handling for access control - Add extensive test coverage with integration tests - Configure Maven build with Spring Boot/Cloud dependencies
This commit is contained in:
299
src/main/java/de/mummeit/pmg/builder/IntegrationBuilder.java
Normal file
299
src/main/java/de/mummeit/pmg/builder/IntegrationBuilder.java
Normal file
@ -0,0 +1,299 @@
|
||||
package de.mummeit.pmg.service.builder;
|
||||
|
||||
import de.mummeit.pmg.api.model.integration.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A fluent builder for creating Permission Manager integrations.
|
||||
* This builder provides a type-safe way to create various types of integrations including:
|
||||
* - Domain integrations (create, update, delete)
|
||||
* - Permission integrations (create, update, delete)
|
||||
* - Role integrations (create, update, delete)
|
||||
* - Role-Permission relation integrations
|
||||
*
|
||||
* Example usage:
|
||||
* {@code
|
||||
* List<Integration<?>> integrations = IntegrationBuilder.create()
|
||||
* .createDomain("my-domain", "My Domain")
|
||||
* .addPermission("read", "Read Permission")
|
||||
* .addRole("user", "User Role")
|
||||
* .assignPermissionsToRole("user", Arrays.asList("read"))
|
||||
* .build();
|
||||
* }
|
||||
*/
|
||||
public class IntegrationBuilder {
|
||||
private final List<Integration<?>> integrations = new ArrayList<>();
|
||||
private String currentDomain;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the IntegrationBuilder.
|
||||
*
|
||||
* @return A new IntegrationBuilder instance
|
||||
*/
|
||||
public static IntegrationBuilder create() {
|
||||
return new IntegrationBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects a domain as the context for subsequent operations without creating an integration.
|
||||
* This is useful when you need to perform operations on an existing domain.
|
||||
*
|
||||
* @param name The name of the domain to select
|
||||
* @return This builder instance for method chaining
|
||||
*/
|
||||
public IntegrationBuilder selectDomain(String name) {
|
||||
this.currentDomain = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new domain integration with the specified name and description.
|
||||
* This also sets the domain context for subsequent operations.
|
||||
*
|
||||
* @param name The name of the domain
|
||||
* @param description The description of the domain
|
||||
* @return This builder instance for method chaining
|
||||
*/
|
||||
public IntegrationBuilder createDomain(String name, String description) {
|
||||
this.currentDomain = name;
|
||||
integrations.add(DomainIntegration.builder()
|
||||
.id(generateIntegrationId("domain", name, Integration.Action.create))
|
||||
.action(Integration.Action.create)
|
||||
.data(DomainIntegration.Data.builder()
|
||||
.name(name)
|
||||
.description(description)
|
||||
.build())
|
||||
.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing domain with a new name and/or description.
|
||||
* This also sets the domain context to the new name for subsequent operations.
|
||||
*
|
||||
* @param oldName The current name of the domain to update
|
||||
* @param newName The new name for the domain
|
||||
* @param description The new description for the domain
|
||||
* @return This builder instance for method chaining
|
||||
*/
|
||||
public IntegrationBuilder updateDomain(String oldName, String newName, String description) {
|
||||
integrations.add(DomainIntegration.builder()
|
||||
.id(generateIntegrationId("domain", oldName, Integration.Action.update))
|
||||
.action(Integration.Action.update)
|
||||
.data(DomainIntegration.Data.builder()
|
||||
.name(newName)
|
||||
.oldName(oldName)
|
||||
.description(description)
|
||||
.build())
|
||||
.build());
|
||||
this.currentDomain = newName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a domain.
|
||||
*
|
||||
* @param name The name of the domain to delete
|
||||
* @return This builder instance for method chaining
|
||||
*/
|
||||
public IntegrationBuilder deleteDomain(String name) {
|
||||
integrations.add(DomainIntegration.builder()
|
||||
.id(generateIntegrationId("domain", name, Integration.Action.delete))
|
||||
.action(Integration.Action.delete)
|
||||
.data(DomainIntegration.Data.builder()
|
||||
.name(name)
|
||||
.build())
|
||||
.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new permission to the current domain.
|
||||
*
|
||||
* @param name The name of the permission
|
||||
* @param description The description of the permission
|
||||
* @return This builder instance for method chaining
|
||||
* @throws IllegalStateException if no domain context has been set
|
||||
*/
|
||||
public IntegrationBuilder addPermission(String name, String description) {
|
||||
validateDomain();
|
||||
integrations.add(PermissionIntegration.builder()
|
||||
.id(generateIntegrationId("permission", currentDomain + ":" + name, Integration.Action.create))
|
||||
.action(Integration.Action.create)
|
||||
.data(PermissionIntegration.Data.builder()
|
||||
.domain(currentDomain)
|
||||
.name(name)
|
||||
.description(description)
|
||||
.build())
|
||||
.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing permission in the current domain.
|
||||
*
|
||||
* @param oldName The current name of the permission to update
|
||||
* @param newName The new name for the permission
|
||||
* @param description The new description for the permission
|
||||
* @return This builder instance for method chaining
|
||||
* @throws IllegalStateException if no domain context has been set
|
||||
*/
|
||||
public IntegrationBuilder updatePermission(String oldName, String newName, String description) {
|
||||
validateDomain();
|
||||
integrations.add(PermissionIntegration.builder()
|
||||
.id(generateIntegrationId("permission", currentDomain + ":" + oldName, Integration.Action.update))
|
||||
.action(Integration.Action.update)
|
||||
.data(PermissionIntegration.Data.builder()
|
||||
.domain(currentDomain)
|
||||
.name(newName)
|
||||
.oldName(oldName)
|
||||
.description(description)
|
||||
.build())
|
||||
.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a permission from the current domain.
|
||||
*
|
||||
* @param name The name of the permission to remove
|
||||
* @return This builder instance for method chaining
|
||||
* @throws IllegalStateException if no domain context has been set
|
||||
*/
|
||||
public IntegrationBuilder removePermission(String name) {
|
||||
validateDomain();
|
||||
integrations.add(PermissionIntegration.builder()
|
||||
.id(generateIntegrationId("permission", currentDomain + ":" + name, Integration.Action.delete))
|
||||
.action(Integration.Action.delete)
|
||||
.data(PermissionIntegration.Data.builder()
|
||||
.domain(currentDomain)
|
||||
.name(name)
|
||||
.build())
|
||||
.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new role to the current domain.
|
||||
*
|
||||
* @param name The name of the role
|
||||
* @param description The description of the role
|
||||
* @return This builder instance for method chaining
|
||||
* @throws IllegalStateException if no domain context has been set
|
||||
*/
|
||||
public IntegrationBuilder addRole(String name, String description) {
|
||||
validateDomain();
|
||||
integrations.add(RoleIntegration.builder()
|
||||
.id(generateIntegrationId("role", currentDomain + ":" + name, Integration.Action.create))
|
||||
.action(Integration.Action.create)
|
||||
.data(RoleIntegration.Data.builder()
|
||||
.domain(currentDomain)
|
||||
.name(name)
|
||||
.description(description)
|
||||
.build())
|
||||
.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing role in the current domain.
|
||||
*
|
||||
* @param oldName The current name of the role to update
|
||||
* @param newName The new name for the role
|
||||
* @param description The new description for the role
|
||||
* @return This builder instance for method chaining
|
||||
* @throws IllegalStateException if no domain context has been set
|
||||
*/
|
||||
public IntegrationBuilder updateRole(String oldName, String newName, String description) {
|
||||
validateDomain();
|
||||
integrations.add(RoleIntegration.builder()
|
||||
.id(generateIntegrationId("role", currentDomain + ":" + oldName, Integration.Action.update))
|
||||
.action(Integration.Action.update)
|
||||
.data(RoleIntegration.Data.builder()
|
||||
.domain(currentDomain)
|
||||
.name(newName)
|
||||
.oldName(oldName)
|
||||
.description(description)
|
||||
.build())
|
||||
.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a role from the current domain.
|
||||
*
|
||||
* @param name The name of the role to remove
|
||||
* @return This builder instance for method chaining
|
||||
* @throws IllegalStateException if no domain context has been set
|
||||
*/
|
||||
public IntegrationBuilder removeRole(String name) {
|
||||
validateDomain();
|
||||
integrations.add(RoleIntegration.builder()
|
||||
.id(generateIntegrationId("role", currentDomain + ":" + name, Integration.Action.delete))
|
||||
.action(Integration.Action.delete)
|
||||
.data(RoleIntegration.Data.builder()
|
||||
.domain(currentDomain)
|
||||
.name(name)
|
||||
.build())
|
||||
.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a list of permissions to a role in the current domain.
|
||||
*
|
||||
* @param role The name of the role to assign permissions to
|
||||
* @param permissions List of permission names to assign to the role
|
||||
* @return This builder instance for method chaining
|
||||
* @throws IllegalStateException if no domain context has been set
|
||||
*/
|
||||
public IntegrationBuilder assignPermissionsToRole(String role, List<String> permissions) {
|
||||
validateDomain();
|
||||
String permissionList = String.join(",", permissions);
|
||||
integrations.add(RolePermissionRelationIntegration.builder()
|
||||
.id(generateIntegrationId("role-permissions", currentDomain + ":" + role + ":" + permissionList, Integration.Action.create))
|
||||
.action(Integration.Action.create)
|
||||
.data(RolePermissionRelationIntegration.Data.builder()
|
||||
.domain(currentDomain)
|
||||
.role(role)
|
||||
.permissions(permissions)
|
||||
.build())
|
||||
.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and returns the list of integrations created by this builder.
|
||||
*
|
||||
* @return A new list containing all the integrations created by this builder
|
||||
*/
|
||||
public List<Integration<?>> build() {
|
||||
return new ArrayList<>(integrations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that a domain context has been set by a previous domain operation.
|
||||
*
|
||||
* @throws IllegalStateException if no domain context has been set
|
||||
*/
|
||||
private void validateDomain() {
|
||||
if (currentDomain == null || currentDomain.trim().isEmpty()) {
|
||||
throw new IllegalStateException("No domain context set. Create, update, or select a domain first.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a deterministic integration ID based on the integration type, name, and action.
|
||||
* This ensures that the same integration will always have the same ID across different runs.
|
||||
*
|
||||
* @param type The type of integration (domain, permission, role, etc.)
|
||||
* @param name The unique name or identifier for this integration
|
||||
* @param action The action being performed
|
||||
* @return A deterministic ID string
|
||||
*/
|
||||
private String generateIntegrationId(String type, String name, Integration.Action action) {
|
||||
return String.format("%s:%s:%s", type, name, action.name().toLowerCase());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user