Reviewer 역할 검증 보고서 smoke (runtime-role-matrix-live-20260714101723-v7-reviewer-001)
This commit is contained in:
parent
2fe0d81b55
commit
ab42d41baa
1 changed files with 132 additions and 0 deletions
132
src/main/java/com/klaroworks/runtime/role/RoleMatrixRuntime.java
Normal file
132
src/main/java/com/klaroworks/runtime/role/RoleMatrixRuntime.java
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
package com.klaroworks.runtime.role;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runtime engine for evaluating role-based access and permissions.
|
||||||
|
*/
|
||||||
|
public final class RoleMatrixRuntime {
|
||||||
|
|
||||||
|
private final Map<String, Set<String>> roleHierarchy;
|
||||||
|
private final Map<String, Set<String>> rolePermissions;
|
||||||
|
private final RoleValidator validator;
|
||||||
|
private final ThreadLocal<RoleContext> currentContext;
|
||||||
|
|
||||||
|
public RoleMatrixRuntime() {
|
||||||
|
this(new HashMap<>(), new HashMap<>(), new RoleValidator());
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoleMatrixRuntime(Map<String, Set<String>> roleHierarchy, Map<String, Set<String>> rolePermissions, RoleValidator validator) {
|
||||||
|
this.roleHierarchy = new ConcurrentHashMap<>(roleHierarchy);
|
||||||
|
this.rolePermissions = new ConcurrentHashMap<>(rolePermissions);
|
||||||
|
this.validator = validator != null ? validator : new RoleValidator();
|
||||||
|
this.currentContext = ThreadLocal.withInitial(() -> null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasRole(RoleContext context, String role) {
|
||||||
|
if (context == null || role == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Set<String> userRoles = getUserRoles(context);
|
||||||
|
return userRoles.contains(role) || hasRoleInHierarchy(role, userRoles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPermission(RoleContext context, String permission) {
|
||||||
|
if (context == null || permission == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Set<String> userRoles = getUserRoles(context);
|
||||||
|
for (String role : userRoles) {
|
||||||
|
Set<String> perms = rolePermissions.get(role);
|
||||||
|
if (perms != null && perms.contains(permission)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean evaluateRole(RoleContext context, String roleExpression) {
|
||||||
|
if (context == null || roleExpression == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String[] parts = roleExpression.split("\\|");
|
||||||
|
for (String part : parts) {
|
||||||
|
String trimmed = part.trim();
|
||||||
|
if (trimmed.startsWith("!") && hasRole(context, trimmed.substring(1))) {
|
||||||
|
return false;
|
||||||
|
} else if (hasRole(context, trimmed)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContext(RoleContext context) {
|
||||||
|
currentContext.set(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoleContext getContext() {
|
||||||
|
return currentContext.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearContext() {
|
||||||
|
currentContext.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void defineRole(String role, Set<String> parentRoles) {
|
||||||
|
roleHierarchy.put(role, Set.copyOf(parentRoles));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assignPermissions(String role, Set<String> permissions) {
|
||||||
|
rolePermissions.put(role, Set.copyOf(permissions));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> getUserRoles(RoleContext context) {
|
||||||
|
Object rolesObj = context.getAttribute("roles");
|
||||||
|
if (rolesObj instanceof Collection) {
|
||||||
|
Set<String> roles = new HashSet<>();
|
||||||
|
for (Object r : (Collection<?>) rolesObj) {
|
||||||
|
if (r != null) {
|
||||||
|
roles.add(r.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasRoleInHierarchy(String targetRole, Set<String> userRoles) {
|
||||||
|
for (String userRole : userRoles) {
|
||||||
|
if (hasInHierarchy(targetRole, userRole, new HashSet<>())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasInHierarchy(String target, String current, Set<String> visited) {
|
||||||
|
if (visited.contains(current)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
visited.add(current);
|
||||||
|
Set<String> parents = roleHierarchy.get(current);
|
||||||
|
if (parents != null) {
|
||||||
|
if (parents.contains(target)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (String parent : parents) {
|
||||||
|
if (hasInHierarchy(target, parent, visited)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Nested {
|
||||||
|
public static boolean evaluate(RoleMatrixRuntime runtime, RoleContext context, String expression) {
|
||||||
|
return runtime.evaluateRole(context, expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue