# Permission Manager SDK for Java A Spring Boot SDK for integrating permission management into your Java applications. This library provides a robust and flexible way to manage user permissions across different domains and scopes. ## Features - Annotation-based permission checks - Programmatic permission management - Integration with Spring Security - Support for domain-based permissions - Scope-based access control - Multi-domain permission management - Flexible user ID resolution ## Requirements - Java 21 or higher - Spring Boot 3.3.0 or higher - Spring Cloud 2023.0.2 or higher ## Installation Add the following dependency to your `pom.xml`: ```xml de.mumme-it permission-manager-sdk 0.1.1 ``` ## Configuration ### 1. Enable the SDK Add the `@EnablePermissionManager` annotation to your Spring Boot application class: ```java import de.mummeit.common.annotations.EnablePermissionManager; @SpringBootApplication @EnablePermissionManager public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } } ``` ### 2. Configuration Properties Add the following properties to your Spring Boot application properties file (`application.yml` or `application.properties`): ```yaml permission-manager: base-url: http://your-permission-manager-url # Required: URL of your Permission Manager instance security: enabled: true # Optional: Enable/disable security checks (defaults to true) ``` These properties can be configured in any valid Spring Boot configuration source (application.yml, application.properties, environment variables, etc.) following Spring Boot's standard property resolution order. ## Usage ### 1. Annotation-Based Permission Checks Use the `@RequiresPermission` annotation to protect your methods: ```java import de.mummeit.pmg.api.annotation.RequiresPermission; @RestController @RequestMapping("/api") public class YourController { @RequiresPermission(domain = "users", permission = "read", scope = "*") @GetMapping("/users") public List getUsers() { // This method will only execute if the user has the "read" permission in the "users" domain // The "*" scope means this permission applies to all scopes return userService.findAll(); } @RequiresPermission( domain = "orders", permission = "update", scope = "region-#orderId", // Example of prefix-based scope userIdExpression = "#request.getHeader('X-User-Id')" ) @PutMapping("/orders/{orderId}") public Order updateOrder(@PathVariable String orderId, @RequestBody Order order) { // This method checks permissions with a specific scope and custom user ID resolution return orderService.update(orderId, order); } @RequiresPermission( domain = "reports", permission = "view", scope = "region-*" // Example of wildcard scope matching all regions ) @GetMapping("/reports") public List getReports() { // This method allows access to users with permission for any region return reportService.findAll(); } } ``` ### 2. Multiple Permission Requirements You can require multiple permissions using repeated annotations: ```java @RequiresPermission(domain = "users", permission = "read") @RequiresPermission(domain = "orders", permission = "write") public void methodRequiringMultiplePermissions() { // This method requires both permissions } ``` ### 3. Programmatic Permission Management Use the `PermissionManager` class to manage permissions programmatically: ```java @Service @RequiredArgsConstructor public class YourService { private final PermissionManager permissionManager; public void grantUserAccess(String userId) { // Grant access to all user-related operations permissionManager.grantAccess( userId, "users", List.of("read", "write"), List.of("user_role"), "*" // Wildcard scope - applies to all scopes ); // Grant access to specific region permissionManager.grantAccess( userId, "reports", List.of("view"), List.of("reporter"), "region-europe" // Specific region scope ); // Grant access to all regions permissionManager.grantAccess( userId, "reports", List.of("view"), List.of("global_reporter"), "region-*" // Wildcard scope - applies to all regions ); } public boolean checkAccess(String userId) { // Check access for all scopes boolean hasGlobalAccess = permissionManager.hasAccess( userId, "users", "read", "*" ); // Check access for specific region boolean hasRegionAccess = permissionManager.hasAccess( userId, "reports", "view", "region-europe" ); return hasGlobalAccess && hasRegionAccess; } public void revokeAccess(String userId) { permissionManager.revokeAccess( userId, "users", List.of("read", "write"), List.of("user_role"), "global" ); } } ``` ### 4. Multi-Domain Permission Management ```java List permits = List.of( new Permit("users", List.of("read"), List.of("user_role")), new Permit("orders", List.of("write"), List.of("order_manager")) ); permissionManager.grantMultiDomainAccess(userId, permits, "global"); ``` ### 5. User Permission Queries ```java List userPermissions = permissionManager.findUserPermissions(userId, "global"); ``` ## Exception Handling The SDK throws the following exceptions: - `AccessDeniedException`: When a permission check fails - `InvalidPermissionRequestException`: When invalid parameters are provided - `IntegrationFailedException`: When integration operations fail Example exception handler: ```java @ControllerAdvice public class PermissionExceptionHandler { @ExceptionHandler(AccessDeniedException.class) public ResponseEntity handleAccessDenied(AccessDeniedException e) { return ResponseEntity.status(HttpStatus.FORBIDDEN) .body("Access denied: " + e.getMessage()); } } ``` ## Best Practices 1. **Scope Usage**: - Use scopes to implement fine-grained access control at the resource level - Leverage wildcards (`*`) for global access - Use prefix-based wildcards (e.g., `region-*`) for category-wide access - Be consistent with scope naming conventions (e.g., `region-europe`, `region-asia`) 2. **User ID Resolution**: Customize user ID resolution using SpEL expressions when needed. 3. **Error Handling**: Always handle permission-related exceptions appropriately. 4. **Permission Granularity**: Design permissions with appropriate granularity for your use case. 5. **Security Context**: Ensure proper security context is available when using default user ID resolution. ## License This project is licensed under the Apache License 2.0 - see the LICENSE file for details.