fix #424: add schema bulk VPD policy apply

This commit is contained in:
devmrko
2026-06-25 17:16:15 +09:00
parent 6957dc05b9
commit f98729aa78
8 changed files with 330 additions and 2 deletions

View File

@@ -56,6 +56,20 @@
ORDER BY 1
</select>
<select id="findSchemaOwnerOptions" resultType="string">
SELECT DISTINCT o.owner
FROM all_objects o
JOIN all_users u ON u.username = o.owner
WHERE o.object_type IN ('TABLE', 'VIEW')
AND NVL(u.oracle_maintained, 'N') = 'N'
AND o.owner NOT IN ('SYS', 'SYSTEM', 'ORDS_METADATA', 'ORDS_PUBLIC_USER')
AND o.owner NOT LIKE 'APEX\_%' ESCAPE '\'
AND o.owner NOT LIKE 'C##%'
AND o.object_name NOT LIKE 'BIN$%'
ORDER BY o.owner
FETCH FIRST 200 ROWS ONLY
</select>
<select id="findOwnerOptions" resultType="string">
SELECT USER FROM dual
UNION
@@ -127,6 +141,18 @@
FETCH FIRST 300 ROWS ONLY
</select>
<select id="findSchemaObjects" resultType="com.cloudhandson.vpdbackoffice.domain.vpd.VpdSchemaObjectOption">
SELECT owner, object_name, object_type
FROM all_objects
WHERE owner = UPPER(#{owner,jdbcType=VARCHAR})
AND object_name NOT LIKE 'BIN$%'
AND (
(#{includeTablesYn,jdbcType=VARCHAR} = 'Y' AND object_type = 'TABLE')
OR (#{includeViewsYn,jdbcType=VARCHAR} = 'Y' AND object_type = 'VIEW')
)
ORDER BY object_type, object_name
</select>
<select id="findPolicy" resultType="com.cloudhandson.vpdbackoffice.domain.vpd.VpdPolicyView">
SELECT <include refid="policyColumns"><property name="alias" value="p."/></include>
FROM all_policies p
@@ -142,6 +168,14 @@
)
</select>
<select id="findAnyPolicy" resultType="com.cloudhandson.vpdbackoffice.domain.vpd.VpdPolicyView">
SELECT <include refid="policyColumns"><property name="alias" value="p."/></include>
FROM all_policies p
WHERE p.object_owner = UPPER(#{objectOwner,jdbcType=VARCHAR})
AND p.object_name = UPPER(#{objectName,jdbcType=VARCHAR})
AND p.policy_name = UPPER(#{policyName,jdbcType=VARCHAR})
</select>
<select id="findFunctionSource" resultType="string">
SELECT LISTAGG(text, '') WITHIN GROUP (ORDER BY line)
FROM all_source

View File

@@ -117,6 +117,107 @@
</form>
</section>
<section class="content-band">
<div class="section-heading">
<h2>스키마 벌크 적용</h2>
</div>
<form method="post" action="/vpd-policies/bulk" class="form-grid">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
<label>
Schema
<select class="form-select" name="schemaOwner" required>
<option th:each="owner : ${formOptions.schemaOwners()}"
th:value="${owner}"
th:text="${owner}"></option>
</select>
</label>
<div>
Object Types
<div class="checkbox-row">
<label class="form-check">
<input class="form-check-input" type="checkbox" name="includeTables" value="true" checked>
<span class="form-check-label">TABLE</span>
</label>
<label class="form-check">
<input class="form-check-input" type="checkbox" name="includeViews" value="true" checked>
<span class="form-check-label">VIEW</span>
</label>
</div>
</div>
<label class="span-2">
기존 Function 선택
<select class="form-select" name="functionKey">
<option value="">Filter predicate로 벌크 function 자동 생성</option>
<option th:each="function : ${formOptions.functions()}"
th:value="${function.value()}"
th:text="${function.label()}"></option>
</select>
</label>
<label>
Function Owner
<select class="form-select" name="functionOwner">
<option value="">현재 연결 사용자</option>
<option th:each="owner : ${formOptions.owners()}"
th:value="${owner}"
th:text="${owner}"></option>
</select>
</label>
<label>
Function 이름
<select class="form-select" name="functionName">
<option value="">SCHEMA_BULK_FILTER 자동 생성</option>
<option th:each="function : ${formOptions.functions()}"
th:value="${function.functionName()}"
th:text="${function.functionName()}"></option>
</select>
</label>
<div>
Statement Types
<div class="checkbox-row">
<label class="form-check" th:each="statement : ${formOptions.statementTypes()}">
<input class="form-check-input"
type="checkbox"
name="statementTypes"
th:value="${statement}"
th:checked="${statement == 'SELECT'}">
<span class="form-check-label" th:text="${statement}">SELECT</span>
</label>
</div>
</div>
<div class="form-check align-self-end">
<input class="form-check-input" id="vpd-bulk-enabled" type="checkbox" name="enabled" value="true" checked>
<label class="form-check-label" for="vpd-bulk-enabled">등록 즉시 활성화</label>
</div>
<div class="form-check span-2">
<input class="form-check-input" id="vpd-bulk-update-check" type="checkbox" name="updateCheck" value="true">
<label class="form-check-label" for="vpd-bulk-update-check">INSERT/UPDATE에도 predicate check 적용</label>
</div>
<label class="span-2">
Filter predicate
<textarea class="form-control" id="vpd-bulk-filter-predicate" name="filterPredicate" rows="4"
placeholder="기존 Function을 선택하지 않으면 이 predicate로 스키마 공통 function을 생성합니다."></textarea>
</label>
<div class="question-presets span-2" aria-label="Bulk filter predicate 예시">
<button class="btn rw-btn-secondary question-preset" type="button"
data-target="vpd-bulk-filter-predicate"
data-question="1=0">
전체 차단
</button>
<button class="btn rw-btn-secondary question-preset" type="button"
data-target="vpd-bulk-filter-predicate"
data-question="dept_code = SYS_CONTEXT('CB_AGENT_CTX', 'DEPT_CODE')">
부서 일치
</button>
<button class="btn rw-btn-secondary question-preset" type="button"
data-target="vpd-bulk-filter-predicate"
data-question="owner_emp_no = SYS_CONTEXT('CB_AGENT_CTX', 'EMP_NO')">
본인 소유
</button>
</div>
<button class="btn rw-btn-primary" type="submit">스키마 전체 적용</button>
</form>
</section>
<section class="content-band">
<div class="section-heading">
<h2>VPD Policies</h2>