[Developer] #424 load permission rule columns dynamically

This commit is contained in:
devmrko
2026-06-23 14:34:19 +09:00
parent ae3dd6667e
commit e5ba9aedd7
3 changed files with 54 additions and 7 deletions

View File

@@ -33,6 +33,10 @@ public class ProtectedObjectService {
return mapper.findDatabaseObjects(); return mapper.findDatabaseObjects();
} }
public List<String> findDatabaseColumns(String owner, String objectName) {
return mapper.findDatabaseColumns(owner, objectName);
}
public ProtectedObject assertEnabled(long objectId) { public ProtectedObject assertEnabled(long objectId) {
ProtectedObject object = mapper.findById(objectId); ProtectedObject object = mapper.findById(objectId);
if (object == null || !object.enabled()) { if (object == null || !object.enabled()) {

View File

@@ -12,6 +12,7 @@ import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes; import org.springframework.web.servlet.mvc.support.RedirectAttributes;
@Controller @Controller
@@ -28,6 +29,34 @@ public class PermissionController {
this.protectedObjectService = protectedObjectService; this.protectedObjectService = protectedObjectService;
} }
@GetMapping("/permissions/object-columns")
@ResponseBody
public List<String> objectColumns(@RequestParam String objectRef) {
if (objectRef == null || objectRef.isBlank()) {
return List.of();
}
if (objectRef.startsWith("protected:")) {
long objectId;
try {
objectId = Long.parseLong(objectRef.substring("protected:".length()));
} catch (NumberFormatException exception) {
return List.of();
}
return protectedObjectService.findColumns(objectId).stream()
.map(column -> column.columnName())
.toList();
}
if (objectRef.startsWith("db:")) {
String value = objectRef.substring("db:".length());
int dot = value.indexOf('.');
if (dot < 1 || dot == value.length() - 1) {
return List.of();
}
return protectedObjectService.findDatabaseColumns(value.substring(0, dot), value.substring(dot + 1));
}
return List.of();
}
@GetMapping("/permissions") @GetMapping("/permissions")
public String permissions(Model model) { public String permissions(Model model) {
var objects = protectedObjectService.findEnabled(); var objects = protectedObjectService.findEnabled();

View File

@@ -28,13 +28,7 @@ function filterUserRoleDetail() {
empty.hidden = shown !== 0; empty.hidden = shown !== 0;
} }
function syncRuleColumnOptions() { function renderRuleColumnOptions(columns) {
const objectSelect = document.querySelector('select[name="objectRef"]');
if (!objectSelect) {
return;
}
const selectedOption = objectSelect.options[objectSelect.selectedIndex];
const columns = (selectedOption?.dataset.columns || '').split(',').filter(Boolean);
document.querySelectorAll('.rule-column-select').forEach((select) => { document.querySelectorAll('.rule-column-select').forEach((select) => {
const current = select.value; const current = select.value;
select.innerHTML = '<option value="">전체 행</option>' + columns select.innerHTML = '<option value="">전체 행</option>' + columns
@@ -46,6 +40,26 @@ function syncRuleColumnOptions() {
}); });
} }
async function syncRuleColumnOptions() {
const objectSelect = document.querySelector('select[name="objectRef"]');
if (!objectSelect) {
return;
}
const selectedOption = objectSelect.options[objectSelect.selectedIndex];
const fallbackColumns = (selectedOption?.dataset.columns || '').split(',').filter(Boolean);
renderRuleColumnOptions(fallbackColumns);
try {
const response = await fetch(`/permissions/object-columns?objectRef=${encodeURIComponent(objectSelect.value)}`);
if (!response.ok) {
return;
}
const columns = await response.json();
renderRuleColumnOptions(Array.isArray(columns) ? columns : fallbackColumns);
} catch (error) {
renderRuleColumnOptions(fallbackColumns);
}
}
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const master = document.getElementById('userRoleMaster'); const master = document.getElementById('userRoleMaster');
if (master) { if (master) {