diff --git a/src/main/java/com/klaroworks/runtime/role/RoleMatrixRuntime.java b/src/main/java/com/klaroworks/runtime/role/RoleMatrixRuntime.java new file mode 100644 index 0000000..c1d2c16 --- /dev/null +++ b/src/main/java/com/klaroworks/runtime/role/RoleMatrixRuntime.java @@ -0,0 +1,128 @@ +package com.klaroworks.runtime.role; + +import java.util.Map; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; +import java.util.Optional; + +/** + * Runtime role matrix management and evaluation. + * Core runtime class for role-based access control. + */ +public class RoleMatrixRuntime { + + private final Map roleDefinitions; + private final Map> roleHierarchy; + private RoleContext currentContext; + + public RoleMatrixRuntime() { + this.roleDefinitions = new HashMap<>(); + this.roleHierarchy = new HashMap<>(); + initializeDefaultRoles(); + } + + private void initializeDefaultRoles() { + registerRole("ADMIN", 100, List.of("*")); + registerRole("MANAGER", 50, List.of("read", "write", "approve")); + registerRole("USER", 10, List.of("read", "write")); + registerRole("GUEST", 1, List.of("read")); + + roleHierarchy.put("ADMIN", List.of("MANAGER", "USER", "GUEST")); + roleHierarchy.put("MANAGER", List.of("USER", "GUEST")); + roleHierarchy.put("USER", List.of("GUEST")); + } + + public void registerRole(String roleName, int level, List permissions) { + roleDefinitions.put(roleName, new RoleDefinition(roleName, level, permissions)); + } + + public boolean evaluateRole(String roleName, String requiredPermission) { + RoleDefinition definition = roleDefinitions.get(roleName); + if (definition == null) { + return false; + } + return definition.hasPermission(requiredPermission); + } + + public boolean hasPermission(String permission) { + if (currentContext == null) { + return false; + } + return currentContext.hasPermission(permission); + } + + public void setContext(RoleContext context) { + this.currentContext = context; + } + + public RoleContext getContext() { + return currentContext; + } + + public void clearContext() { + this.currentContext = null; + } + + public boolean isInRole(String roleName) { + if (currentContext == null) { + return false; + } + return currentContext.getRole().equals(roleName); + } + + public boolean isInRoleHierarchy(String roleName) { + if (currentContext == null) { + return false; + } + String currentRole = currentContext.getRole(); + return hasRoleInHierarchy(currentRole, roleName); + } + + private boolean hasRoleInHierarchy(String currentRole, String targetRole) { + if (currentRole.equals(targetRole)) { + return true; + } + List parents = roleHierarchy.get(currentRole); + if (parents == null) { + return false; + } + for (String parent : parents) { + if (hasRoleInHierarchy(parent, targetRole)) { + return true; + } + } + return false; + } + + public Optional getRoleDefinition(String roleName) { + return Optional.ofNullable(roleDefinitions.get(roleName)); + } + + public Map getAllRoleDefinitions() { + return Map.copyOf(roleDefinitions); + } + + /** + * Role definition record. + */ + public record RoleDefinition(String name, int level, List permissions) { + public boolean hasPermission(String permission) { + if (permissions.contains("*")) { + return true; + } + return permissions.contains(permission); + } + + public boolean isHigherThan(RoleDefinition other) { + return this.level > other.level; + } + } + + /** + * Create a nested role for testing. + */ + public static Nested.InnerRole createNestedRole(String name, int priority) { + return Nested.createRole(name, priority); + } +}