From 1a6f101be93888a65b8ecc44c473e4c962ffa080 Mon Sep 17 00:00:00 2001 From: Felix Mumme Date: Wed, 8 Jan 2025 02:48:54 +0100 Subject: [PATCH] add readme --- README.md | 246 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..ebe80df --- /dev/null +++ b/README.md @@ -0,0 +1,246 @@ +# 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.0 + +``` + +## 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. \ No newline at end of file