fix #491: add permission effective preview

This commit is contained in:
devmrko
2026-06-26 13:32:39 +09:00
parent 9f63adeca5
commit cd7860e253
5 changed files with 277 additions and 14 deletions

View File

@@ -1,12 +1,20 @@
package com.cloudhandson.vpdbackoffice.web;
import com.cloudhandson.vpdbackoffice.domain.permission.AppRole;
import com.cloudhandson.vpdbackoffice.domain.permission.PermissionSetCommand;
import com.cloudhandson.vpdbackoffice.domain.permission.RuleCommand;
import com.cloudhandson.vpdbackoffice.domain.protectedobject.ProtectedColumn;
import com.cloudhandson.vpdbackoffice.service.GroupService;
import com.cloudhandson.vpdbackoffice.service.PermissionService;
import com.cloudhandson.vpdbackoffice.service.ProtectedObjectService;
import com.cloudhandson.vpdbackoffice.service.UserService;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -24,13 +32,19 @@ public class PermissionController {
private static final Logger log = LoggerFactory.getLogger(PermissionController.class);
private final PermissionService permissionService;
private final ProtectedObjectService protectedObjectService;
private final UserService userService;
private final GroupService groupService;
public PermissionController(
PermissionService permissionService,
ProtectedObjectService protectedObjectService
ProtectedObjectService protectedObjectService,
UserService userService,
GroupService groupService
) {
this.permissionService = permissionService;
this.protectedObjectService = protectedObjectService;
this.userService = userService;
this.groupService = groupService;
}
@GetMapping("/permissions/object-columns")
@@ -68,6 +82,8 @@ public class PermissionController {
long objectsAt = System.nanoTime();
var roles = permissionService.findRoles();
long rolesAt = System.nanoTime();
var roleImpact = buildRoleImpact(roles);
long roleImpactAt = System.nanoTime();
var columnsByObject = objects.stream()
.collect(Collectors.toMap(
object -> object.objectId(),
@@ -96,10 +112,11 @@ public class PermissionController {
long dbObjectsAt = System.nanoTime();
var permissions = permissionService.findPermissionViews();
long permissionsAt = System.nanoTime();
log.info("permissions page timings: objects={}ms roles={}ms columns={}ms dbObjects={}ms permissions={}ms total={}ms",
log.info("permissions page timings: objects={}ms roles={}ms roleImpact={}ms columns={}ms dbObjects={}ms permissions={}ms total={}ms",
elapsedMillis(started, objectsAt),
elapsedMillis(objectsAt, rolesAt),
elapsedMillis(rolesAt, columnsAt),
elapsedMillis(rolesAt, roleImpactAt),
elapsedMillis(roleImpactAt, columnsAt),
elapsedMillis(columnsAt, dbObjectsAt),
elapsedMillis(dbObjectsAt, permissionsAt),
elapsedMillis(started, permissionsAt));
@@ -108,11 +125,60 @@ public class PermissionController {
model.addAttribute("columnsByObject", columnsByObject);
model.addAttribute("maskableColumnsByObject", maskableColumnsByObject);
model.addAttribute("maskableColumnLabelsByObject", maskableColumnLabelsByObject);
model.addAttribute("directUsersByRole", roleImpact.directUsersByRole());
model.addAttribute("groupsByRole", roleImpact.groupsByRole());
model.addAttribute("groupUsersByRole", roleImpact.groupUsersByRole());
model.addAttribute("dbObjects", dbObjects);
model.addAttribute("permissions", permissions);
return "permissions";
}
private RoleImpact buildRoleImpact(List<AppRole> roles) {
Map<Long, Set<String>> directUsersByRole = emptyRoleSetMap(roles);
userService.findUserRoles().forEach(row ->
directUsersByRole.computeIfAbsent(row.roleId(), ignored -> new LinkedHashSet<>()).add(row.username()));
Map<Long, Set<String>> groupsByRole = emptyRoleSetMap(roles);
Map<Long, List<String>> usersByGroup = groupService.findGroupUsers().stream()
.collect(Collectors.groupingBy(
row -> row.groupId(),
LinkedHashMap::new,
Collectors.mapping(row -> row.username(), Collectors.toList())
));
Map<Long, Set<String>> groupUsersByRole = emptyRoleSetMap(roles);
groupService.findGroupRoles().forEach(row -> {
groupsByRole.computeIfAbsent(row.roleId(), ignored -> new LinkedHashSet<>())
.add(row.groupCode() + " / " + row.groupName());
groupUsersByRole.computeIfAbsent(row.roleId(), ignored -> new LinkedHashSet<>())
.addAll(usersByGroup.getOrDefault(row.groupId(), List.of()));
});
return new RoleImpact(
toListMap(directUsersByRole),
toListMap(groupsByRole),
toListMap(groupUsersByRole)
);
}
private Map<Long, Set<String>> emptyRoleSetMap(List<AppRole> roles) {
Map<Long, Set<String>> map = new LinkedHashMap<>();
roles.forEach(role -> map.put(role.roleId(), new LinkedHashSet<>()));
return map;
}
private Map<Long, List<String>> toListMap(Map<Long, Set<String>> source) {
Map<Long, List<String>> map = new LinkedHashMap<>();
source.forEach((key, values) -> map.put(key, new ArrayList<>(values)));
return map;
}
private record RoleImpact(
Map<Long, List<String>> directUsersByRole,
Map<Long, List<String>> groupsByRole,
Map<Long, List<String>> groupUsersByRole
) {
}
private long elapsedMillis(long from, long to) {
return (to - from) / 1_000_000;
}