fix #557: guide permission-driven VPD flow

This commit is contained in:
devmrko
2026-06-29 12:11:25 +09:00
parent fbe3d4682b
commit 908ac9a386
57 changed files with 1952 additions and 312 deletions

View File

@@ -4,6 +4,8 @@ import com.cloudhandson.vpdbackoffice.domain.vpd.VpdPolicyCreateCommand;
import com.cloudhandson.vpdbackoffice.service.AppException;
import com.cloudhandson.vpdbackoffice.service.VpdPolicyService;
import java.util.List;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
@@ -42,10 +44,34 @@ public class VpdPolicyController {
private void populatePolicyModel(String schemaOwner, Model model) {
try {
String selectedSchemaOwner = schemaOwner == null ? "" : schemaOwner.trim().toUpperCase();
model.addAttribute("policies", vpdPolicyService.findPolicies());
List<com.cloudhandson.vpdbackoffice.domain.vpd.VpdPolicyView> policies = vpdPolicyService.findPolicies();
Map<String, String> policyDescriptions = new LinkedHashMap<>();
policies.forEach(policy -> policyDescriptions.put(
policy.objectDisplayName() + "|" + policy.policyName(),
vpdPolicyService.findPolicyDescription(policy.objectOwner(), policy.objectName(), policy.policyName())
));
model.addAttribute("policies", policies);
model.addAttribute("policyDescriptions", policyDescriptions);
model.addAttribute("vpdTargets", vpdPolicyService.findVpdTargets(selectedSchemaOwner));
model.addAttribute("selectedSchemaOwner", selectedSchemaOwner);
model.addAttribute("formOptions", vpdPolicyService.formOptions());
var formOptions = vpdPolicyService.formOptions();
Map<String, String> filterDescriptions = new LinkedHashMap<>();
formOptions.functions().forEach(function -> filterDescriptions.put(
function.owner() + "|" + function.functionName(),
vpdPolicyService.findFilterDescription(function.owner(), function.functionName())
));
policies.forEach(policy -> filterDescriptions.putIfAbsent(
policy.functionOwner() + "|" + policy.functionName(),
vpdPolicyService.findFilterDescription(policy.functionOwner(), policy.functionName())
));
Map<String, String> filterPredicates = new LinkedHashMap<>();
formOptions.functions().forEach(function -> filterPredicates.put(
function.owner() + "|" + function.functionName(),
vpdPolicyService.findFilterPredicate(function.owner(), function.packageName(), function.functionName())
));
model.addAttribute("formOptions", formOptions);
model.addAttribute("filterDescriptions", filterDescriptions);
model.addAttribute("filterPredicates", filterPredicates);
} catch (DataAccessException exception) {
RuntimeErrorMessage message = RuntimeErrorMessages.dataAccess(exception);
model.addAttribute("runtimeError", message);
@@ -53,12 +79,18 @@ public class VpdPolicyController {
model.addAttribute("vpdTargets", List.of());
model.addAttribute("selectedSchemaOwner", "");
model.addAttribute("formOptions", vpdPolicyService.emptyFormOptions());
model.addAttribute("policyDescriptions", Map.of());
model.addAttribute("filterDescriptions", Map.of());
model.addAttribute("filterPredicates", Map.of());
} catch (AppException exception) {
model.addAttribute("errorMessage", exception.getMessage());
model.addAttribute("policies", List.of());
model.addAttribute("vpdTargets", List.of());
model.addAttribute("selectedSchemaOwner", "");
model.addAttribute("formOptions", vpdPolicyService.emptyFormOptions());
model.addAttribute("policyDescriptions", Map.of());
model.addAttribute("filterDescriptions", Map.of());
model.addAttribute("filterPredicates", Map.of());
}
}
@@ -105,10 +137,18 @@ public class VpdPolicyController {
@RequestParam(required = false) String functionOwner,
@RequestParam String functionName,
@RequestParam String filterPredicate,
@RequestParam(defaultValue = "Filter function이 반환하는 predicate로 조회 행을 제한합니다.") String description,
RedirectAttributes redirectAttributes
) {
try {
vpdPolicyService.saveFilterFunction(functionOwner, functionName, filterPredicate);
vpdPolicyService.saveFilterDescription(
functionOwner == null || functionOwner.isBlank()
? vpdPolicyService.currentUser()
: functionOwner,
functionName,
description
);
redirectAttributes.addFlashAttribute("successMessage", "Filter function을 저장했습니다: " + functionName);
} catch (AppException exception) {
redirectAttributes.addFlashAttribute("errorMessage", exception.getMessage());
@@ -119,6 +159,23 @@ public class VpdPolicyController {
return "redirect:/vpd-filter-policies";
}
@PostMapping("/vpd-policies/description")
public String savePolicyDescription(
@RequestParam String objectOwner,
@RequestParam String objectName,
@RequestParam String policyName,
@RequestParam String description,
RedirectAttributes redirectAttributes
) {
try {
vpdPolicyService.savePolicyDescription(objectOwner, objectName, policyName, description);
redirectAttributes.addFlashAttribute("successMessage", "Policy 설명을 저장했습니다.");
} catch (AppException exception) {
redirectAttributes.addFlashAttribute("errorMessage", exception.getMessage());
}
return "redirect:/vpd-policies";
}
@PostMapping("/vpd-filter-policies/replace")
public String replaceFilterPolicy(
@RequestParam String oldObjectKey,