[Developer] #424 add VPD policy settings view
This commit is contained in:
@@ -0,0 +1,27 @@
|
|||||||
|
package com.cloudhandson.vpdbackoffice.domain.vpd;
|
||||||
|
|
||||||
|
public record VpdPolicyView(
|
||||||
|
String objectOwner,
|
||||||
|
String objectName,
|
||||||
|
String policyGroup,
|
||||||
|
String policyName,
|
||||||
|
String functionOwner,
|
||||||
|
String packageName,
|
||||||
|
String functionName,
|
||||||
|
String statementTypes,
|
||||||
|
String checkOption,
|
||||||
|
String enabled,
|
||||||
|
String staticPolicy,
|
||||||
|
String policyType,
|
||||||
|
String longPredicate
|
||||||
|
) {
|
||||||
|
|
||||||
|
public String objectDisplayName() {
|
||||||
|
return objectOwner + "." + objectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String functionDisplayName() {
|
||||||
|
String packagePrefix = packageName == null || packageName.isBlank() ? "" : packageName + ".";
|
||||||
|
return functionOwner + "." + packagePrefix + functionName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.cloudhandson.vpdbackoffice.mapper;
|
||||||
|
|
||||||
|
import com.cloudhandson.vpdbackoffice.domain.vpd.VpdPolicyView;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface VpdPolicyMapper {
|
||||||
|
|
||||||
|
List<VpdPolicyView> findPolicies();
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.cloudhandson.vpdbackoffice.service;
|
||||||
|
|
||||||
|
import com.cloudhandson.vpdbackoffice.domain.vpd.VpdPolicyView;
|
||||||
|
import com.cloudhandson.vpdbackoffice.mapper.VpdPolicyMapper;
|
||||||
|
import java.util.List;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class VpdPolicyService {
|
||||||
|
|
||||||
|
private final VpdPolicyMapper mapper;
|
||||||
|
|
||||||
|
public VpdPolicyService(VpdPolicyMapper mapper) {
|
||||||
|
this.mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<VpdPolicyView> findPolicies() {
|
||||||
|
return mapper.findPolicies();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.cloudhandson.vpdbackoffice.web;
|
||||||
|
|
||||||
|
import com.cloudhandson.vpdbackoffice.service.VpdPolicyService;
|
||||||
|
import java.util.List;
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class VpdPolicyController {
|
||||||
|
|
||||||
|
private final VpdPolicyService vpdPolicyService;
|
||||||
|
|
||||||
|
public VpdPolicyController(VpdPolicyService vpdPolicyService) {
|
||||||
|
this.vpdPolicyService = vpdPolicyService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/vpd-policies")
|
||||||
|
public String policies(Model model) {
|
||||||
|
try {
|
||||||
|
model.addAttribute("policies", vpdPolicyService.findPolicies());
|
||||||
|
} catch (DataAccessException exception) {
|
||||||
|
RuntimeErrorMessage message = RuntimeErrorMessages.dataAccess(exception);
|
||||||
|
model.addAttribute("runtimeError", message);
|
||||||
|
model.addAttribute("policies", List.of());
|
||||||
|
}
|
||||||
|
return "vpd-policies";
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/main/resources/mapper/VpdPolicyMapper.xml
Normal file
30
src/main/resources/mapper/VpdPolicyMapper.xml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.cloudhandson.vpdbackoffice.mapper.VpdPolicyMapper">
|
||||||
|
<select id="findPolicies" resultType="com.cloudhandson.vpdbackoffice.domain.vpd.VpdPolicyView">
|
||||||
|
SELECT
|
||||||
|
object_owner,
|
||||||
|
object_name,
|
||||||
|
policy_group,
|
||||||
|
policy_name,
|
||||||
|
pf_owner AS function_owner,
|
||||||
|
package AS package_name,
|
||||||
|
function AS function_name,
|
||||||
|
RTRIM(
|
||||||
|
CASE WHEN sel = 'YES' THEN 'SELECT,' ELSE '' END ||
|
||||||
|
CASE WHEN ins = 'YES' THEN 'INSERT,' ELSE '' END ||
|
||||||
|
CASE WHEN upd = 'YES' THEN 'UPDATE,' ELSE '' END ||
|
||||||
|
CASE WHEN del = 'YES' THEN 'DELETE,' ELSE '' END ||
|
||||||
|
CASE WHEN idx = 'YES' THEN 'INDEX,' ELSE '' END,
|
||||||
|
','
|
||||||
|
) AS statement_types,
|
||||||
|
chk_option AS check_option,
|
||||||
|
enable AS enabled,
|
||||||
|
static_policy,
|
||||||
|
policy_type,
|
||||||
|
long_predicate
|
||||||
|
FROM all_policies
|
||||||
|
ORDER BY object_owner, object_name, policy_name
|
||||||
|
</select>
|
||||||
|
</mapper>
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
<a class="nav-link" href="/tokens">토큰</a>
|
<a class="nav-link" href="/tokens">토큰</a>
|
||||||
<a class="nav-link" href="/probe">ORDS 검증</a>
|
<a class="nav-link" href="/probe">ORDS 검증</a>
|
||||||
<a class="nav-link" href="/mcp-reasoning">MCP Reasoning</a>
|
<a class="nav-link" href="/mcp-reasoning">MCP Reasoning</a>
|
||||||
|
<a class="nav-link" href="/vpd-policies">VPD 설정</a>
|
||||||
<a class="nav-link" href="/ords-handlers">ORDS 핸들러</a>
|
<a class="nav-link" href="/ords-handlers">ORDS 핸들러</a>
|
||||||
<a class="nav-link" href="/settings">설정</a>
|
<a class="nav-link" href="/settings">설정</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
68
src/main/resources/templates/vpd-policies.html
Normal file
68
src/main/resources/templates/vpd-policies.html
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head th:replace="~{fragments/layout :: head('VPD 설정')}"></head>
|
||||||
|
<body>
|
||||||
|
<nav th:replace="~{fragments/layout :: nav}"></nav>
|
||||||
|
<main class="container py-4">
|
||||||
|
<div class="page-title">
|
||||||
|
<h1>VPD 설정</h1>
|
||||||
|
<p>현재 계정에서 조회 가능한 Oracle VPD policy 설정을 확인합니다.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert alert-warning" th:if="${runtimeError}">
|
||||||
|
<strong th:text="${runtimeError.title()}">조회할 수 없습니다.</strong>
|
||||||
|
<span th:text="${runtimeError.message()}">message</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="content-band">
|
||||||
|
<div class="section-heading">
|
||||||
|
<h2>VPD Policies</h2>
|
||||||
|
<span class="badge text-bg-secondary" th:text="${#lists.size(policies)}">0</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-sm table-striped align-middle">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Object</th>
|
||||||
|
<th>Policy</th>
|
||||||
|
<th>Function</th>
|
||||||
|
<th>Statements</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Options</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr th:each="policy : ${policies}">
|
||||||
|
<td>
|
||||||
|
<strong th:text="${policy.objectDisplayName()}">ADMIN.TABLE</strong>
|
||||||
|
<div class="text-muted small" th:text="${policy.policyGroup()}">SYS_DEFAULT</div>
|
||||||
|
</td>
|
||||||
|
<td><code th:text="${policy.policyName()}">POLICY</code></td>
|
||||||
|
<td><code th:text="${policy.functionDisplayName()}">OWNER.FUNC</code></td>
|
||||||
|
<td th:text="${policy.statementTypes()} ?: '-'">SELECT</td>
|
||||||
|
<td>
|
||||||
|
<span class="badge"
|
||||||
|
th:classappend="${policy.enabled() == 'YES'} ? ' text-bg-success' : ' text-bg-secondary'"
|
||||||
|
th:text="${policy.enabled()}">YES</span>
|
||||||
|
</td>
|
||||||
|
<td th:text="${policy.policyType()}">DYNAMIC</td>
|
||||||
|
<td>
|
||||||
|
<span>Check: <strong th:text="${policy.checkOption()}">NO</strong></span>
|
||||||
|
<span class="ms-2">Static: <strong th:text="${policy.staticPolicy()}">NO</strong></span>
|
||||||
|
<span class="ms-2">Long: <strong th:text="${policy.longPredicate()}">NO</strong></span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr th:if="${#lists.isEmpty(policies)}">
|
||||||
|
<td colspan="7" class="text-muted">
|
||||||
|
조회 가능한 VPD policy가 없습니다. 정책이 없거나 현재 DB 계정에 dictionary 조회 권한이 없을 수 있습니다.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user