Reviewer 역할 검증 보고서 smoke #9
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