[Developer] #619 focus POC on KB VPD permissions
This commit is contained in:
@@ -76,7 +76,7 @@ CREATE TABLE cb_permission_rule (
|
||||
perm_id NUMBER NOT NULL REFERENCES cb_permission(perm_id),
|
||||
rule_column VARCHAR2(128),
|
||||
rule_type VARCHAR2(30) NOT NULL,
|
||||
rule_value VARCHAR2(100)
|
||||
rule_value VARCHAR2(1000 CHAR)
|
||||
);
|
||||
|
||||
CREATE TABLE cb_permission_column (
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
-- CB_AGENT_CTX.USER_ID -> direct CB_USER_ROLE + group CB_USER_GROUP/CB_GROUP_ROLE
|
||||
-- -> CB_PERMISSION -> CB_PERMISSION_RULE
|
||||
-- and builds a row predicate for the object passed by DBMS_RLS.
|
||||
-- Supported rule types include TAG. TAG matches a token in a comma-delimited
|
||||
-- TECH_TAG value, allowing the vector search view to remain one row per chunk.
|
||||
-- A permission's rules are combined with AND. Separate ALLOW permissions are
|
||||
-- combined with OR and DENY permissions are subtracted at the end. This lets
|
||||
-- a token-context condition be narrowed by a literal static SQL condition.
|
||||
-- ============================================================
|
||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||
SET ECHO OFF
|
||||
@@ -27,6 +28,10 @@ AS
|
||||
v_target VARCHAR2(128);
|
||||
v_allow_predicate VARCHAR2(32767);
|
||||
v_deny_predicate VARCHAR2(32767);
|
||||
v_active_permission_id NUMBER;
|
||||
v_active_permission_effect VARCHAR2(10);
|
||||
v_permission_predicate VARCHAR2(32767);
|
||||
v_permission_invalid BOOLEAN := FALSE;
|
||||
|
||||
FUNCTION quote_literal(p_value IN VARCHAR2) RETURN VARCHAR2 IS
|
||||
BEGIN
|
||||
@@ -64,7 +69,79 @@ AS
|
||||
RETURN NULL;
|
||||
END;
|
||||
|
||||
PROCEDURE append_or(p_effect IN VARCHAR2, p_clause IN VARCHAR2) IS
|
||||
FUNCTION safe_static_predicate(
|
||||
p_owner IN VARCHAR2,
|
||||
p_table_name IN VARCHAR2,
|
||||
p_predicate IN VARCHAR2
|
||||
) RETURN VARCHAR2 IS
|
||||
v_predicate VARCHAR2(32767) := TRIM(p_predicate);
|
||||
v_lexical VARCHAR2(32767);
|
||||
v_token VARCHAR2(128);
|
||||
v_index PLS_INTEGER := 1;
|
||||
v_count NUMBER;
|
||||
v_has_column BOOLEAN := FALSE;
|
||||
BEGIN
|
||||
-- STATIC_SQL is intentionally an expression only: no statement
|
||||
-- separator/comment/bind/database-link/qualified object is accepted.
|
||||
-- Every identifier outside a string literal must be a column of the
|
||||
-- protected object or an allowlisted SQL operator/function.
|
||||
IF v_predicate IS NULL
|
||||
OR LENGTH(v_predicate) > 1000
|
||||
OR INSTR(v_predicate, ';') > 0
|
||||
OR INSTR(v_predicate, '--') > 0
|
||||
OR INSTR(v_predicate, '/*') > 0
|
||||
OR INSTR(v_predicate, '*/') > 0
|
||||
OR INSTR(v_predicate, ':') > 0
|
||||
OR INSTR(v_predicate, '@') > 0
|
||||
OR INSTR(v_predicate, '||') > 0
|
||||
OR REGEXP_LIKE(v_predicate, '[[:cntrl:]]')
|
||||
OR MOD(LENGTH(v_predicate) - LENGTH(REPLACE(v_predicate, '''', '')), 2) <> 0 THEN
|
||||
RETURN NULL;
|
||||
END IF;
|
||||
|
||||
-- Replace SQL string literals before extracting identifiers. Doubled
|
||||
-- quotes in a literal are supported by the expression below.
|
||||
v_lexical := REGEXP_REPLACE(v_predicate, '''(''''|[^''])*''', ' ');
|
||||
IF REGEXP_LIKE(v_lexical, '[[:alpha:]_$#][[:alnum:]_$#]*[[:space:]]*\.') THEN
|
||||
RETURN NULL;
|
||||
END IF;
|
||||
|
||||
LOOP
|
||||
v_token := UPPER(REGEXP_SUBSTR(
|
||||
v_lexical, '[[:alpha:]_$#][[:alnum:]_$#]*', 1, v_index
|
||||
));
|
||||
EXIT WHEN v_token IS NULL;
|
||||
v_index := v_index + 1;
|
||||
|
||||
IF v_token IN (
|
||||
'AND', 'OR', 'NOT', 'NULL', 'IS', 'IN', 'LIKE', 'BETWEEN', 'ESCAPE',
|
||||
'TRUE', 'FALSE', 'UPPER', 'LOWER', 'TRIM', 'NVL', 'COALESCE',
|
||||
'TO_CHAR', 'TO_DATE', 'REGEXP_LIKE', 'INSTR', 'LENGTH', 'SUBSTR',
|
||||
'REPLACE', 'CAST', 'AS', 'DATE', 'TIMESTAMP', 'NUMBER', 'VARCHAR2', 'CHAR'
|
||||
) THEN
|
||||
NULL;
|
||||
ELSE
|
||||
SELECT COUNT(*)
|
||||
INTO v_count
|
||||
FROM all_tab_columns
|
||||
WHERE owner = UPPER(p_owner)
|
||||
AND table_name = UPPER(p_table_name)
|
||||
AND column_name = v_token;
|
||||
|
||||
IF v_count = 0 THEN
|
||||
RETURN NULL;
|
||||
END IF;
|
||||
v_has_column := TRUE;
|
||||
END IF;
|
||||
END LOOP;
|
||||
|
||||
RETURN CASE WHEN v_has_column THEN v_predicate ELSE NULL END;
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
RETURN NULL;
|
||||
END;
|
||||
|
||||
PROCEDURE append_permission(p_effect IN VARCHAR2, p_clause IN VARCHAR2) IS
|
||||
BEGIN
|
||||
IF p_clause IS NULL THEN
|
||||
RETURN;
|
||||
@@ -72,16 +149,39 @@ AS
|
||||
|
||||
IF p_effect = 'DENY' THEN
|
||||
IF v_deny_predicate IS NULL THEN
|
||||
v_deny_predicate := '(' || p_clause || ')';
|
||||
v_deny_predicate := p_clause;
|
||||
ELSE
|
||||
v_deny_predicate := v_deny_predicate || ' OR (' || p_clause || ')';
|
||||
v_deny_predicate := '(' || v_deny_predicate || ') OR (' || p_clause || ')';
|
||||
END IF;
|
||||
ELSIF v_allow_predicate IS NULL THEN
|
||||
v_allow_predicate := '(' || p_clause || ')';
|
||||
v_allow_predicate := p_clause;
|
||||
ELSE
|
||||
v_allow_predicate := v_allow_predicate || ' OR (' || p_clause || ')';
|
||||
v_allow_predicate := '(' || v_allow_predicate || ') OR (' || p_clause || ')';
|
||||
END IF;
|
||||
END;
|
||||
|
||||
PROCEDURE append_rule(p_clause IN VARCHAR2) IS
|
||||
BEGIN
|
||||
IF p_clause IS NULL THEN
|
||||
v_permission_invalid := TRUE;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
IF v_permission_predicate IS NULL THEN
|
||||
v_permission_predicate := p_clause;
|
||||
ELSE
|
||||
v_permission_predicate := '(' || v_permission_predicate || ') AND (' || p_clause || ')';
|
||||
END IF;
|
||||
END;
|
||||
|
||||
PROCEDURE flush_permission IS
|
||||
BEGIN
|
||||
IF NOT v_permission_invalid THEN
|
||||
append_permission(v_active_permission_effect, v_permission_predicate);
|
||||
END IF;
|
||||
v_permission_predicate := NULL;
|
||||
v_permission_invalid := FALSE;
|
||||
END;
|
||||
BEGIN
|
||||
BEGIN
|
||||
v_user_id := TO_NUMBER(SYS_CONTEXT('CB_AGENT_CTX', 'USER_ID'));
|
||||
@@ -111,7 +211,8 @@ BEGIN
|
||||
ON gr.group_id = ug.group_id
|
||||
WHERE ug.user_id = v_user_id
|
||||
)
|
||||
SELECT UPPER(TRIM(r.rule_type)) AS rule_type,
|
||||
SELECT p.perm_id,
|
||||
UPPER(TRIM(r.rule_type)) AS rule_type,
|
||||
UPPER(TRIM(r.rule_column)) AS rule_column,
|
||||
NVL(UPPER(TRIM(p.permission_effect)), 'ALLOW') AS permission_effect,
|
||||
r.rule_value
|
||||
@@ -122,148 +223,135 @@ BEGIN
|
||||
ON r.perm_id = p.perm_id
|
||||
WHERE p.target_name = v_target
|
||||
AND p.action_name = 'SELECT'
|
||||
ORDER BY r.rule_id
|
||||
ORDER BY p.perm_id, r.rule_id
|
||||
) LOOP
|
||||
IF v_active_permission_id IS NULL THEN
|
||||
v_active_permission_id := r.perm_id;
|
||||
v_active_permission_effect := r.permission_effect;
|
||||
ELSIF v_active_permission_id <> r.perm_id THEN
|
||||
flush_permission;
|
||||
v_active_permission_id := r.perm_id;
|
||||
v_active_permission_effect := r.permission_effect;
|
||||
END IF;
|
||||
|
||||
DECLARE
|
||||
v_column VARCHAR2(128);
|
||||
v_column VARCHAR2(128);
|
||||
v_static_predicate VARCHAR2(32767);
|
||||
BEGIN
|
||||
IF r.rule_type = 'ALL' THEN
|
||||
IF r.permission_effect = 'DENY' THEN
|
||||
RETURN '1 = 0';
|
||||
END IF;
|
||||
v_allow_predicate := '(1 = 1)';
|
||||
append_rule('1 = 1');
|
||||
ELSIF r.rule_type = 'MY_DEPT' THEN
|
||||
-- NULL rule_column keeps backward compatibility with the demo seed.
|
||||
v_column := safe_column(p_schema, p_object, NVL(r.rule_column, 'DEPT_CODE'));
|
||||
IF v_column IS NOT NULL THEN
|
||||
append_or(r.permission_effect, v_column || ' = SYS_CONTEXT(''CB_AGENT_CTX'', ''DEPT_CODE'')');
|
||||
append_rule(v_column || ' = SYS_CONTEXT(''CB_AGENT_CTX'', ''DEPT_CODE'')');
|
||||
END IF;
|
||||
ELSIF r.rule_type = 'SELF' THEN
|
||||
-- NULL rule_column keeps backward compatibility with the demo seed.
|
||||
v_column := safe_column(p_schema, p_object, NVL(r.rule_column, 'OWNER_EMP_NO'));
|
||||
IF v_column IS NOT NULL THEN
|
||||
append_or(r.permission_effect, v_column || ' = SYS_CONTEXT(''CB_AGENT_CTX'', ''EMP_NO'')');
|
||||
append_rule(v_column || ' = SYS_CONTEXT(''CB_AGENT_CTX'', ''EMP_NO'')');
|
||||
END IF;
|
||||
ELSIF r.rule_type = 'DEPT' THEN
|
||||
v_column := safe_column(p_schema, p_object, NVL(r.rule_column, 'DEPT_CODE'));
|
||||
IF v_column IS NOT NULL THEN
|
||||
append_or(r.permission_effect, v_column || ' = ' || quote_literal(r.rule_value));
|
||||
append_rule(v_column || ' = ' || quote_literal(r.rule_value));
|
||||
END IF;
|
||||
ELSIF r.rule_type = 'EMP_NO' THEN
|
||||
v_column := safe_column(p_schema, p_object, NVL(r.rule_column, 'OWNER_EMP_NO'));
|
||||
IF v_column IS NOT NULL THEN
|
||||
append_or(r.permission_effect, v_column || ' = ' || quote_literal(r.rule_value));
|
||||
append_rule(v_column || ' = ' || quote_literal(r.rule_value));
|
||||
END IF;
|
||||
ELSIF r.rule_type = 'TAG' THEN
|
||||
-- A TAG rule defaults to the ingestion metadata column TECH_TAG.
|
||||
-- Multiple ALLOW TAG rows are accumulated by append_or, so any
|
||||
-- matching tag grants visibility. DENY rows are accumulated
|
||||
-- separately and removed from the final result.
|
||||
v_column := safe_column(p_schema, p_object, NVL(r.rule_column, 'TECH_TAG'));
|
||||
IF v_column IS NOT NULL
|
||||
AND r.rule_value IS NOT NULL
|
||||
AND REGEXP_LIKE(TRIM(r.rule_value), '^[A-Za-z0-9_-]+$') THEN
|
||||
append_or(
|
||||
r.permission_effect,
|
||||
append_rule(
|
||||
'REGEXP_LIKE(UPPER(' || v_column || '), ' ||
|
||||
quote_literal('(^|,)' || UPPER(TRIM(r.rule_value)) || '(,|$)') || ')'
|
||||
);
|
||||
END IF;
|
||||
ELSIF r.rule_type IN ('STAKEHOLDER_SELF', 'STAKEHOLDER_CHANNEL') THEN
|
||||
-- CB_AGENT_CTX_PKG가 Bearer token -> KB_STAKEHOLDERS를 한 번
|
||||
-- 해석해 USER_ID/ROLE/CHANNEL을 secure context로 설정한다.
|
||||
-- 따라서 보호 테이블 predicate에서 KB_STAKEHOLDERS를 다시 조인하지
|
||||
-- 않고, 해당 context와 KB_CONTRACTS 관계만 사용한다.
|
||||
ELSIF r.rule_type IN (
|
||||
'TOKEN_SUBJECT', 'OWN_CONTRACT', 'CHANNEL_CONTRACT', 'OWN_CUSTOMER', 'CHANNEL_CUSTOMER'
|
||||
) THEN
|
||||
-- 백오피스 권한 설정의 조건 코드를 안전한 WHERE 조각으로 확장한다.
|
||||
-- token -> stakeholder 해석은 context package가 한 번만 수행하며,
|
||||
-- VPD filter는 context와 대상/계약원장만 쓴다.
|
||||
v_column := safe_column(p_schema, p_object, r.rule_column);
|
||||
IF v_column IS NOT NULL
|
||||
AND UPPER(p_schema) = 'POC_2' THEN
|
||||
DECLARE
|
||||
v_contract_key VARCHAR2(30);
|
||||
v_role_condition VARCHAR2(500);
|
||||
BEGIN
|
||||
-- 각 ALLOW rule은 append_or로 OR 분기가 된다. rule_value는
|
||||
-- 권한 설정에 저장된 해당 분기의 역할값이다. identity rule은
|
||||
-- NULL value를 허용해 모든 토큰 주체가 자기 mapping을 해석한다.
|
||||
v_role_condition := CASE
|
||||
WHEN TRIM(r.rule_value) IS NULL THEN '1 = 1'
|
||||
ELSE 'SYS_CONTEXT(''CB_AGENT_CTX'', ''STAKEHOLDER_ROLE'') = '
|
||||
|| quote_literal(TRIM(r.rule_value))
|
||||
END;
|
||||
|
||||
IF r.rule_type = 'STAKEHOLDER_SELF'
|
||||
AND v_target = 'KB_CONTRACTS'
|
||||
AND v_column = 'FC_ID' THEN
|
||||
append_or(
|
||||
r.permission_effect,
|
||||
'(' || v_role_condition ||
|
||||
' AND FC_ID = SYS_CONTEXT(''CB_AGENT_CTX'', ''STAKEHOLDER_USER_ID''))'
|
||||
);
|
||||
ELSIF r.rule_type = 'STAKEHOLDER_CHANNEL'
|
||||
AND v_target = 'KB_CONTRACTS'
|
||||
AND v_column = 'FC_CHANNEL' THEN
|
||||
append_or(
|
||||
r.permission_effect,
|
||||
'(' || v_role_condition ||
|
||||
' AND FC_CHANNEL = SYS_CONTEXT(''CB_AGENT_CTX'', ''STAKEHOLDER_CHANNEL''))'
|
||||
);
|
||||
ELSIF r.rule_type = 'STAKEHOLDER_SELF'
|
||||
AND v_target = 'KB_STAKEHOLDERS'
|
||||
AND v_column = 'USER_ID' THEN
|
||||
append_or(
|
||||
r.permission_effect,
|
||||
'(' || v_role_condition ||
|
||||
' AND USER_ID = SYS_CONTEXT(''CB_AGENT_CTX'', ''STAKEHOLDER_USER_ID''))'
|
||||
);
|
||||
ELSIF v_target IN ('KB_CUSTOMERS', 'KB_COVERAGES', 'KB_CLAIMS', 'KB_EXTERNAL_HOLDINGS')
|
||||
AND v_column IN ('CUST_ID', 'CONTRACT_NO') THEN
|
||||
IF r.rule_type = 'TOKEN_SUBJECT'
|
||||
AND v_target = 'KB_STAKEHOLDERS'
|
||||
AND v_column = 'USER_ID' THEN
|
||||
append_rule(
|
||||
'USER_ID = SYS_CONTEXT(''CB_AGENT_CTX'', ''STAKEHOLDER_USER_ID'')'
|
||||
);
|
||||
ELSIF r.rule_type = 'OWN_CONTRACT'
|
||||
AND v_target = 'KB_CONTRACTS'
|
||||
AND v_column = 'FC_ID' THEN
|
||||
append_rule(
|
||||
'FC_ID = SYS_CONTEXT(''CB_AGENT_CTX'', ''STAKEHOLDER_USER_ID'')'
|
||||
);
|
||||
ELSIF r.rule_type = 'CHANNEL_CONTRACT'
|
||||
AND v_target = 'KB_CONTRACTS'
|
||||
AND v_column = 'FC_CHANNEL' THEN
|
||||
append_rule(
|
||||
'FC_CHANNEL = SYS_CONTEXT(''CB_AGENT_CTX'', ''STAKEHOLDER_CHANNEL'')'
|
||||
);
|
||||
ELSIF r.rule_type IN ('OWN_CUSTOMER', 'CHANNEL_CUSTOMER')
|
||||
AND v_target IN ('KB_CUSTOMERS', 'KB_COVERAGES', 'KB_CLAIMS', 'KB_EXTERNAL_HOLDINGS')
|
||||
AND v_column IN ('CUST_ID', 'CONTRACT_NO') THEN
|
||||
DECLARE
|
||||
v_contract_key VARCHAR2(30);
|
||||
v_subject_filter VARCHAR2(500);
|
||||
BEGIN
|
||||
v_contract_key := CASE v_column
|
||||
WHEN 'CUST_ID' THEN 'CUST_ID'
|
||||
WHEN 'CONTRACT_NO' THEN 'CONTRACT_NO'
|
||||
END;
|
||||
IF r.rule_type = 'STAKEHOLDER_SELF' THEN
|
||||
append_or(
|
||||
r.permission_effect,
|
||||
'EXISTS (SELECT 1 FROM (' ||
|
||||
'SELECT c.' || v_contract_key || ' AS access_key ' ||
|
||||
'FROM POC_2.KB_CONTRACTS c ' ||
|
||||
'WHERE ' || v_role_condition ||
|
||||
' AND c.FC_ID = SYS_CONTEXT(''CB_AGENT_CTX'', ''STAKEHOLDER_USER_ID'')) allowed_contract ' ||
|
||||
'WHERE allowed_contract.access_key = ' || v_column || ')'
|
||||
);
|
||||
ELSE
|
||||
append_or(
|
||||
r.permission_effect,
|
||||
'EXISTS (SELECT 1 FROM (' ||
|
||||
'SELECT c.' || v_contract_key || ' AS access_key ' ||
|
||||
'FROM POC_2.KB_CONTRACTS c ' ||
|
||||
'WHERE ' || v_role_condition ||
|
||||
' AND c.FC_CHANNEL = SYS_CONTEXT(''CB_AGENT_CTX'', ''STAKEHOLDER_CHANNEL'')) allowed_contract ' ||
|
||||
'WHERE allowed_contract.access_key = ' || v_column || ')'
|
||||
);
|
||||
END IF;
|
||||
END IF;
|
||||
END;
|
||||
v_subject_filter := CASE r.rule_type
|
||||
WHEN 'OWN_CUSTOMER' THEN
|
||||
'c.FC_ID = SYS_CONTEXT(''CB_AGENT_CTX'', ''STAKEHOLDER_USER_ID'')'
|
||||
ELSE
|
||||
'c.FC_CHANNEL = SYS_CONTEXT(''CB_AGENT_CTX'', ''STAKEHOLDER_CHANNEL'')'
|
||||
END;
|
||||
append_rule(
|
||||
'EXISTS (SELECT 1 FROM (SELECT c.' || v_contract_key || ' AS access_key ' ||
|
||||
'FROM POC_2.KB_CONTRACTS c WHERE ' || v_subject_filter ||
|
||||
') allowed_contract WHERE allowed_contract.access_key = ' || v_column || ')'
|
||||
);
|
||||
END;
|
||||
END IF;
|
||||
END IF;
|
||||
ELSIF r.rule_type = 'STATIC_SQL' THEN
|
||||
v_static_predicate := safe_static_predicate(p_schema, p_object, r.rule_value);
|
||||
append_rule(v_static_predicate);
|
||||
ELSIF r.rule_type = '=' THEN
|
||||
v_column := safe_column(p_schema, p_object, r.rule_column);
|
||||
IF v_column IS NOT NULL THEN
|
||||
append_or(r.permission_effect, 'TO_CHAR(' || v_column || ') = ' || quote_literal(r.rule_value));
|
||||
append_rule('TO_CHAR(' || v_column || ') = ' || quote_literal(r.rule_value));
|
||||
END IF;
|
||||
ELSIF r.rule_type IN ('!=', '<>') THEN
|
||||
v_column := safe_column(p_schema, p_object, r.rule_column);
|
||||
IF v_column IS NOT NULL THEN
|
||||
append_or(r.permission_effect, 'TO_CHAR(' || v_column || ') <> ' || quote_literal(r.rule_value));
|
||||
append_rule('TO_CHAR(' || v_column || ') <> ' || quote_literal(r.rule_value));
|
||||
END IF;
|
||||
ELSE
|
||||
append_rule(NULL);
|
||||
END IF;
|
||||
END;
|
||||
END LOOP;
|
||||
|
||||
flush_permission;
|
||||
|
||||
IF v_allow_predicate IS NULL THEN
|
||||
RETURN '1 = 0';
|
||||
END IF;
|
||||
|
||||
IF v_deny_predicate IS NULL THEN
|
||||
IF v_allow_predicate = '(1 = 1)' THEN
|
||||
IF v_allow_predicate = '1 = 1' THEN
|
||||
RETURN '1 = 1';
|
||||
END IF;
|
||||
RETURN '(' || v_allow_predicate || ')';
|
||||
|
||||
@@ -67,6 +67,12 @@ BEGIN
|
||||
INSERT INTO cb_app_user(user_id, user_name, employee_no, dept_code, can_read_contents, active)
|
||||
VALUES (456112, 'rule_test_deny_only', 'E456112', 'HR', 'N', 'Y');
|
||||
|
||||
INSERT INTO cb_app_user(user_id, user_name, employee_no, dept_code, can_read_contents, active)
|
||||
VALUES (456113, 'rule_test_static_and', 'E456113', 'HR', 'N', 'Y');
|
||||
|
||||
INSERT INTO cb_app_user(user_id, user_name, employee_no, dept_code, can_read_contents, active)
|
||||
VALUES (456114, 'rule_test_static_invalid', 'E456114', 'HR', 'N', 'Y');
|
||||
|
||||
INSERT INTO cb_app_role(role_id, role_name) VALUES (456101, 'RULE_TEST_MY_DEPT');
|
||||
INSERT INTO cb_app_role(role_id, role_name) VALUES (456102, 'RULE_TEST_SELF');
|
||||
INSERT INTO cb_app_role(role_id, role_name) VALUES (456103, 'RULE_TEST_ALL');
|
||||
@@ -79,6 +85,8 @@ BEGIN
|
||||
INSERT INTO cb_app_role(role_id, role_name) VALUES (456110, 'RULE_TEST_TARGET_MISMATCH');
|
||||
INSERT INTO cb_app_role(role_id, role_name) VALUES (456111, 'RULE_TEST_ALLOW_DENY');
|
||||
INSERT INTO cb_app_role(role_id, role_name) VALUES (456112, 'RULE_TEST_DENY_ONLY');
|
||||
INSERT INTO cb_app_role(role_id, role_name) VALUES (456113, 'RULE_TEST_STATIC_AND');
|
||||
INSERT INTO cb_app_role(role_id, role_name) VALUES (456114, 'RULE_TEST_STATIC_INVALID');
|
||||
|
||||
INSERT INTO cb_user_role(user_id, role_id) VALUES (456101, 456101);
|
||||
INSERT INTO cb_user_role(user_id, role_id) VALUES (456102, 456102);
|
||||
@@ -92,6 +100,8 @@ BEGIN
|
||||
INSERT INTO cb_user_role(user_id, role_id) VALUES (456110, 456110);
|
||||
INSERT INTO cb_user_role(user_id, role_id) VALUES (456111, 456111);
|
||||
INSERT INTO cb_user_role(user_id, role_id) VALUES (456112, 456112);
|
||||
INSERT INTO cb_user_role(user_id, role_id) VALUES (456113, 456113);
|
||||
INSERT INTO cb_user_role(user_id, role_id) VALUES (456114, 456114);
|
||||
|
||||
INSERT INTO cb_permission(perm_id, role_id, target_name, action_name)
|
||||
VALUES (456101, 456101, 'CB_V_SEARCH_DOCUMENTS', 'SELECT');
|
||||
@@ -132,6 +142,12 @@ BEGIN
|
||||
INSERT INTO cb_permission(perm_id, role_id, target_name, action_name, permission_effect)
|
||||
VALUES (456113, 456112, 'CB_V_SEARCH_DOCUMENTS', 'SELECT', 'DENY');
|
||||
|
||||
INSERT INTO cb_permission(perm_id, role_id, target_name, action_name, permission_effect)
|
||||
VALUES (456114, 456113, 'CB_V_SEARCH_DOCUMENTS', 'SELECT', 'ALLOW');
|
||||
|
||||
INSERT INTO cb_permission(perm_id, role_id, target_name, action_name, permission_effect)
|
||||
VALUES (456115, 456114, 'CB_V_SEARCH_DOCUMENTS', 'SELECT', 'ALLOW');
|
||||
|
||||
INSERT INTO cb_permission_rule(rule_id, perm_id, rule_column, rule_type, rule_value)
|
||||
VALUES (456101, 456101, NULL, 'MY_DEPT', NULL);
|
||||
|
||||
@@ -171,6 +187,15 @@ BEGIN
|
||||
INSERT INTO cb_permission_rule(rule_id, perm_id, rule_column, rule_type, rule_value)
|
||||
VALUES (456113, 456113, 'DEPT_CODE', '=', 'HR');
|
||||
|
||||
INSERT INTO cb_permission_rule(rule_id, perm_id, rule_column, rule_type, rule_value)
|
||||
VALUES (456114, 456114, 'DEPT_CODE', '=', 'HR');
|
||||
|
||||
INSERT INTO cb_permission_rule(rule_id, perm_id, rule_column, rule_type, rule_value)
|
||||
VALUES (456115, 456114, NULL, 'STATIC_SQL', 'OWNER_EMP_NO = ''E456113''');
|
||||
|
||||
INSERT INTO cb_permission_rule(rule_id, perm_id, rule_column, rule_type, rule_value)
|
||||
VALUES (456116, 456115, NULL, 'STATIC_SQL', 'DEPT_CODE = ''HR''; 1 = 1');
|
||||
|
||||
COMMIT;
|
||||
END;
|
||||
/
|
||||
@@ -260,6 +285,8 @@ BEGIN
|
||||
assert_contains('ALLOW_ALL_MINUS_DENY_DEPT', 456111, 'AND NOT');
|
||||
assert_contains('ALLOW_ALL_MINUS_DENY_DEPT_DETAIL', 456111, 'TO_CHAR(DEPT_CODE) = ''HR''');
|
||||
assert_equals('DENY_ONLY_DENIES', 456112, '1 = 0');
|
||||
assert_contains('CONTEXT_AND_STATIC_SQL', 456113, 'TO_CHAR(DEPT_CODE) = ''HR'') AND (OWNER_EMP_NO = ''E456113'')');
|
||||
assert_equals('INVALID_STATIC_SQL_DENIES', 456114, '1 = 0');
|
||||
cb_agent_ctx_pkg.clear_user;
|
||||
END;
|
||||
/
|
||||
|
||||
@@ -383,20 +383,18 @@ BEGIN
|
||||
|
||||
-- 토큰은 모든 이해당사자에게 발급되지만, 아래 역할이 없는 주체는
|
||||
-- 권한 레코드가 없으므로 VPD가 1=0으로 fail-closed 된다.
|
||||
ensure_permission(v_designer_role_id, 'KB_STAKEHOLDERS', 'USER_ID', 'STAKEHOLDER_SELF', '설계사');
|
||||
ensure_permission(v_manager_role_id, 'KB_STAKEHOLDERS', 'USER_ID', 'STAKEHOLDER_SELF', '지점장');
|
||||
ensure_permission(v_designer_role_id, 'KB_PRODUCTS', NULL, 'ALL', NULL);
|
||||
ensure_permission(v_manager_role_id, 'KB_PRODUCTS', NULL, 'ALL', NULL);
|
||||
ensure_permission(v_designer_role_id, 'KB_CONTRACTS', 'FC_ID', 'STAKEHOLDER_SELF', '설계사');
|
||||
ensure_permission(v_manager_role_id, 'KB_CONTRACTS', 'FC_CHANNEL', 'STAKEHOLDER_CHANNEL', '지점장');
|
||||
ensure_permission(v_designer_role_id, 'KB_CUSTOMERS', 'CUST_ID', 'STAKEHOLDER_SELF', '설계사');
|
||||
ensure_permission(v_manager_role_id, 'KB_CUSTOMERS', 'CUST_ID', 'STAKEHOLDER_CHANNEL', '지점장');
|
||||
ensure_permission(v_designer_role_id, 'KB_COVERAGES', 'CUST_ID', 'STAKEHOLDER_SELF', '설계사');
|
||||
ensure_permission(v_manager_role_id, 'KB_COVERAGES', 'CUST_ID', 'STAKEHOLDER_CHANNEL', '지점장');
|
||||
ensure_permission(v_designer_role_id, 'KB_CLAIMS', 'CUST_ID', 'STAKEHOLDER_SELF', '설계사');
|
||||
ensure_permission(v_manager_role_id, 'KB_CLAIMS', 'CUST_ID', 'STAKEHOLDER_CHANNEL', '지점장');
|
||||
ensure_permission(v_designer_role_id, 'KB_EXTERNAL_HOLDINGS', 'CUST_ID', 'STAKEHOLDER_SELF', '설계사');
|
||||
ensure_permission(v_manager_role_id, 'KB_EXTERNAL_HOLDINGS', 'CUST_ID', 'STAKEHOLDER_CHANNEL', '지점장');
|
||||
ensure_permission(v_designer_role_id, 'KB_CONTRACTS', 'FC_ID', 'OWN_CONTRACT', NULL);
|
||||
ensure_permission(v_manager_role_id, 'KB_CONTRACTS', 'FC_CHANNEL', 'CHANNEL_CONTRACT', NULL);
|
||||
ensure_permission(v_designer_role_id, 'KB_CUSTOMERS', 'CUST_ID', 'OWN_CUSTOMER', NULL);
|
||||
ensure_permission(v_manager_role_id, 'KB_CUSTOMERS', 'CUST_ID', 'CHANNEL_CUSTOMER', NULL);
|
||||
ensure_permission(v_designer_role_id, 'KB_COVERAGES', 'CUST_ID', 'OWN_CUSTOMER', NULL);
|
||||
ensure_permission(v_manager_role_id, 'KB_COVERAGES', 'CUST_ID', 'CHANNEL_CUSTOMER', NULL);
|
||||
ensure_permission(v_designer_role_id, 'KB_CLAIMS', 'CUST_ID', 'OWN_CUSTOMER', NULL);
|
||||
ensure_permission(v_manager_role_id, 'KB_CLAIMS', 'CUST_ID', 'CHANNEL_CUSTOMER', NULL);
|
||||
ensure_permission(v_designer_role_id, 'KB_EXTERNAL_HOLDINGS', 'CUST_ID', 'OWN_CUSTOMER', NULL);
|
||||
ensure_permission(v_manager_role_id, 'KB_EXTERNAL_HOLDINGS', 'CUST_ID', 'CHANNEL_CUSTOMER', NULL);
|
||||
END;
|
||||
/
|
||||
COMMIT;
|
||||
|
||||
@@ -81,7 +81,7 @@ BEGIN
|
||||
INSERT INTO cb_permission(perm_id, role_id, target_name, action_name, permission_effect)
|
||||
VALUES (v_permission_id, v_role_id, 'KB_STAKEHOLDERS', 'SELECT', 'ALLOW');
|
||||
INSERT INTO cb_permission_rule(rule_id, perm_id, rule_column, rule_type, rule_value)
|
||||
VALUES (cb_permission_rule_seq.NEXTVAL, v_permission_id, 'USER_ID', 'STAKEHOLDER_SELF', NULL);
|
||||
VALUES (cb_permission_rule_seq.NEXTVAL, v_permission_id, 'USER_ID', 'TOKEN_SUBJECT', NULL);
|
||||
END;
|
||||
END;
|
||||
/
|
||||
|
||||
137
sql/adb/48_kb_permission_condition_codes.sql
Normal file
137
sql/adb/48_kb_permission_condition_codes.sql
Normal file
@@ -0,0 +1,137 @@
|
||||
-- ============================================================
|
||||
-- 48_kb_permission_condition_codes.sql
|
||||
--
|
||||
-- Replaces the first KB example's stakeholder-specific predicate types with
|
||||
-- policy condition codes. CB_AGENT_DOC_VPD_FILTER expands these codes into
|
||||
-- the target object's WHERE predicate.
|
||||
-- Execute as ADMIN after 25 and 46.
|
||||
-- ============================================================
|
||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||
SET ECHO OFF
|
||||
SET FEEDBACK ON
|
||||
SET DEFINE OFF
|
||||
|
||||
ALTER SESSION DISABLE PARALLEL DML;
|
||||
|
||||
PROMPT === 1. Replacing KB example rules with filter condition codes ===
|
||||
UPDATE cb_permission_rule r
|
||||
SET rule_type = CASE
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM cb_permission p JOIN cb_app_role ar ON ar.role_id = p.role_id
|
||||
WHERE p.perm_id = r.perm_id AND ar.role_name = 'KB_DESIGNER_ROLE'
|
||||
AND p.target_name = 'KB_CONTRACTS'
|
||||
) THEN 'OWN_CONTRACT'
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM cb_permission p JOIN cb_app_role ar ON ar.role_id = p.role_id
|
||||
WHERE p.perm_id = r.perm_id AND ar.role_name = 'KB_BRANCH_MANAGER_ROLE'
|
||||
AND p.target_name = 'KB_CONTRACTS'
|
||||
) THEN 'CHANNEL_CONTRACT'
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM cb_permission p JOIN cb_app_role ar ON ar.role_id = p.role_id
|
||||
WHERE p.perm_id = r.perm_id AND ar.role_name = 'KB_DESIGNER_ROLE'
|
||||
AND p.target_name IN ('KB_CUSTOMERS', 'KB_COVERAGES', 'KB_CLAIMS', 'KB_EXTERNAL_HOLDINGS')
|
||||
) THEN 'OWN_CUSTOMER'
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM cb_permission p JOIN cb_app_role ar ON ar.role_id = p.role_id
|
||||
WHERE p.perm_id = r.perm_id AND ar.role_name = 'KB_BRANCH_MANAGER_ROLE'
|
||||
AND p.target_name IN ('KB_CUSTOMERS', 'KB_COVERAGES', 'KB_CLAIMS', 'KB_EXTERNAL_HOLDINGS')
|
||||
) THEN 'CHANNEL_CUSTOMER'
|
||||
ELSE r.rule_type
|
||||
END,
|
||||
rule_value = NULL
|
||||
WHERE r.rule_type IN ('STAKEHOLDER_SELF', 'STAKEHOLDER_CHANNEL')
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM cb_permission p
|
||||
JOIN cb_app_role ar ON ar.role_id = p.role_id
|
||||
WHERE p.perm_id = r.perm_id
|
||||
AND ar.role_name IN ('KB_DESIGNER_ROLE', 'KB_BRANCH_MANAGER_ROLE')
|
||||
AND p.target_name IN ('KB_CONTRACTS', 'KB_CUSTOMERS', 'KB_COVERAGES', 'KB_CLAIMS', 'KB_EXTERNAL_HOLDINGS')
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
|
||||
PROMPT === 2. Keeping token subject access as an identity-only permission ===
|
||||
DECLARE
|
||||
v_identity_role_id NUMBER;
|
||||
v_permission_id NUMBER;
|
||||
v_count NUMBER;
|
||||
BEGIN
|
||||
BEGIN
|
||||
SELECT role_id INTO v_identity_role_id
|
||||
FROM cb_app_role
|
||||
WHERE role_name = 'KB_STAKEHOLDER_IDENTITY_ROLE';
|
||||
EXCEPTION
|
||||
WHEN NO_DATA_FOUND THEN
|
||||
SELECT NVL(MAX(role_id), 0) + 1 INTO v_identity_role_id FROM cb_app_role;
|
||||
INSERT INTO cb_app_role(role_id, role_name, max_sensitivity_level)
|
||||
VALUES (v_identity_role_id, 'KB_STAKEHOLDER_IDENTITY_ROLE', 'INTERNAL');
|
||||
END;
|
||||
|
||||
FOR u IN (
|
||||
SELECT user_id FROM cb_app_user
|
||||
WHERE stakeholder_user_id IS NOT NULL AND active = 'Y'
|
||||
) LOOP
|
||||
SELECT COUNT(*) INTO v_count
|
||||
FROM cb_user_role
|
||||
WHERE user_id = u.user_id AND role_id = v_identity_role_id;
|
||||
IF v_count = 0 THEN
|
||||
INSERT INTO cb_user_role(user_id, role_id) VALUES (u.user_id, v_identity_role_id);
|
||||
END IF;
|
||||
END LOOP;
|
||||
|
||||
-- Business roles do not need to grant the stakeholder source row. The
|
||||
-- identity role alone lets a valid token resolve its own stakeholder row.
|
||||
DELETE FROM cb_permission_column
|
||||
WHERE permission_id IN (
|
||||
SELECT p.perm_id
|
||||
FROM cb_permission p JOIN cb_app_role ar ON ar.role_id = p.role_id
|
||||
WHERE ar.role_name IN ('KB_DESIGNER_ROLE', 'KB_BRANCH_MANAGER_ROLE')
|
||||
AND p.target_name = 'KB_STAKEHOLDERS'
|
||||
);
|
||||
DELETE FROM cb_permission_rule
|
||||
WHERE perm_id IN (
|
||||
SELECT p.perm_id
|
||||
FROM cb_permission p JOIN cb_app_role ar ON ar.role_id = p.role_id
|
||||
WHERE ar.role_name IN ('KB_DESIGNER_ROLE', 'KB_BRANCH_MANAGER_ROLE')
|
||||
AND p.target_name = 'KB_STAKEHOLDERS'
|
||||
);
|
||||
DELETE FROM cb_permission
|
||||
WHERE perm_id IN (
|
||||
SELECT p.perm_id
|
||||
FROM cb_permission p JOIN cb_app_role ar ON ar.role_id = p.role_id
|
||||
WHERE ar.role_name IN ('KB_DESIGNER_ROLE', 'KB_BRANCH_MANAGER_ROLE')
|
||||
AND p.target_name = 'KB_STAKEHOLDERS'
|
||||
);
|
||||
|
||||
BEGIN
|
||||
SELECT perm_id INTO v_permission_id
|
||||
FROM cb_permission
|
||||
WHERE role_id = v_identity_role_id
|
||||
AND target_name = 'KB_STAKEHOLDERS'
|
||||
AND action_name = 'SELECT';
|
||||
EXCEPTION
|
||||
WHEN NO_DATA_FOUND THEN
|
||||
SELECT cb_permission_seq.NEXTVAL INTO v_permission_id FROM dual;
|
||||
INSERT INTO cb_permission(perm_id, role_id, target_name, action_name, permission_effect)
|
||||
VALUES (v_permission_id, v_identity_role_id, 'KB_STAKEHOLDERS', 'SELECT', 'ALLOW');
|
||||
END;
|
||||
|
||||
DELETE FROM cb_permission_rule WHERE perm_id = v_permission_id;
|
||||
INSERT INTO cb_permission_rule(rule_id, perm_id, rule_column, rule_type, rule_value)
|
||||
VALUES (cb_permission_rule_seq.NEXTVAL, v_permission_id, 'USER_ID', 'TOKEN_SUBJECT', NULL);
|
||||
END;
|
||||
/
|
||||
COMMIT;
|
||||
|
||||
PROMPT === 3. Condition codes consumed by the VPD filter ===
|
||||
SELECT ar.role_name, p.target_name, r.rule_column, r.rule_type
|
||||
FROM cb_permission p
|
||||
JOIN cb_app_role ar ON ar.role_id = p.role_id
|
||||
JOIN cb_permission_rule r ON r.perm_id = p.perm_id
|
||||
WHERE ar.role_name IN (
|
||||
'KB_DESIGNER_ROLE', 'KB_BRANCH_MANAGER_ROLE', 'KB_STAKEHOLDER_IDENTITY_ROLE'
|
||||
)
|
||||
ORDER BY ar.role_name, p.target_name, r.rule_id;
|
||||
|
||||
PROMPT === KB permission condition codes ready ===
|
||||
35
sql/adb/49_permission_static_sql_condition.sql
Normal file
35
sql/adb/49_permission_static_sql_condition.sql
Normal file
@@ -0,0 +1,35 @@
|
||||
-- ============================================================
|
||||
-- 49_permission_static_sql_condition.sql
|
||||
--
|
||||
-- Makes room for a literal, static WHERE condition attached to an
|
||||
-- allowlisted permission rule. The VPD function validates the expression
|
||||
-- again before returning it as part of a predicate.
|
||||
-- ============================================================
|
||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||
SET ECHO OFF
|
||||
SET FEEDBACK ON
|
||||
SET DEFINE OFF
|
||||
|
||||
PROMPT === Enlarging rule value for static SQL conditions ===
|
||||
DECLARE
|
||||
v_data_length NUMBER;
|
||||
BEGIN
|
||||
SELECT data_length
|
||||
INTO v_data_length
|
||||
FROM user_tab_columns
|
||||
WHERE table_name = 'CB_PERMISSION_RULE'
|
||||
AND column_name = 'RULE_VALUE';
|
||||
|
||||
IF v_data_length < 1000 THEN
|
||||
EXECUTE IMMEDIATE
|
||||
'ALTER TABLE cb_permission_rule MODIFY (rule_value VARCHAR2(1000 CHAR))';
|
||||
END IF;
|
||||
END;
|
||||
/
|
||||
|
||||
SELECT column_name, data_type, char_length
|
||||
FROM user_tab_columns
|
||||
WHERE table_name = 'CB_PERMISSION_RULE'
|
||||
AND column_name = 'RULE_VALUE';
|
||||
|
||||
PROMPT === Static SQL condition storage ready ===
|
||||
229
sql/adb/51_kb_vpd_admin_token.sql
Normal file
229
sql/adb/51_kb_vpd_admin_token.sql
Normal file
@@ -0,0 +1,229 @@
|
||||
-- ============================================================
|
||||
-- 51_kb_vpd_admin_token.sql
|
||||
--
|
||||
-- Creates an application-level KB VPD administrator. This is not an
|
||||
-- EXEMPT ACCESS POLICY database account: the token is resolved to an
|
||||
-- application context and the existing VPD policy function returns ALL
|
||||
-- only because KB_VPD_ADMIN_ROLE has explicit ALL permissions.
|
||||
-- ============================================================
|
||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||
SET ECHO OFF
|
||||
SET FEEDBACK ON
|
||||
SET DEFINE OFF
|
||||
SET SERVEROUTPUT ON
|
||||
|
||||
PROMPT === Creating KB VPD administrator, permissions, and one-time token ===
|
||||
GRANT EXECUTE ON cb_agent_ctx_pkg TO POC_2;
|
||||
|
||||
DECLARE
|
||||
c_stakeholder_user_id CONSTANT VARCHAR2(30) := 'KB_VPD_ADMIN';
|
||||
c_role_name CONSTANT VARCHAR2(80) := 'KB_VPD_ADMIN_ROLE';
|
||||
c_token_description CONSTANT VARCHAR2(200) := 'KB VPD admin bootstrap token';
|
||||
|
||||
v_admin_role_id NUMBER;
|
||||
v_identity_role_id NUMBER;
|
||||
v_app_user_id NUMBER;
|
||||
v_permission_id NUMBER;
|
||||
v_bearer_token VARCHAR2(128);
|
||||
v_count NUMBER;
|
||||
|
||||
PROCEDURE ensure_role(
|
||||
p_role_name IN VARCHAR2,
|
||||
p_level IN VARCHAR2,
|
||||
p_role_id OUT NUMBER
|
||||
) IS
|
||||
BEGIN
|
||||
SELECT role_id
|
||||
INTO p_role_id
|
||||
FROM cb_app_role
|
||||
WHERE role_name = p_role_name;
|
||||
EXCEPTION
|
||||
WHEN NO_DATA_FOUND THEN
|
||||
SELECT NVL(MAX(role_id), 0) + 1
|
||||
INTO p_role_id
|
||||
FROM cb_app_role;
|
||||
INSERT INTO cb_app_role(role_id, role_name, max_sensitivity_level)
|
||||
VALUES (p_role_id, p_role_name, p_level);
|
||||
END;
|
||||
|
||||
PROCEDURE ensure_user_role(p_user_id IN NUMBER, p_role_id IN NUMBER) IS
|
||||
BEGIN
|
||||
SELECT COUNT(*)
|
||||
INTO v_count
|
||||
FROM cb_user_role
|
||||
WHERE user_id = p_user_id
|
||||
AND role_id = p_role_id;
|
||||
|
||||
IF v_count = 0 THEN
|
||||
INSERT INTO cb_user_role(user_id, role_id) VALUES (p_user_id, p_role_id);
|
||||
END IF;
|
||||
END;
|
||||
|
||||
PROCEDURE ensure_all_permission(p_target_name IN VARCHAR2) IS
|
||||
BEGIN
|
||||
SELECT MIN(perm_id)
|
||||
INTO v_permission_id
|
||||
FROM cb_permission
|
||||
WHERE role_id = v_admin_role_id
|
||||
AND target_name = p_target_name
|
||||
AND action_name = 'SELECT';
|
||||
|
||||
IF v_permission_id IS NULL THEN
|
||||
SELECT cb_permission_seq.NEXTVAL INTO v_permission_id FROM dual;
|
||||
INSERT INTO cb_permission(
|
||||
perm_id, role_id, target_name, action_name, permission_effect
|
||||
) VALUES (
|
||||
v_permission_id, v_admin_role_id, p_target_name, 'SELECT', 'ALLOW'
|
||||
);
|
||||
ELSE
|
||||
UPDATE cb_permission
|
||||
SET permission_effect = 'ALLOW'
|
||||
WHERE perm_id = v_permission_id;
|
||||
END IF;
|
||||
|
||||
DELETE FROM cb_permission_rule WHERE perm_id = v_permission_id;
|
||||
INSERT INTO cb_permission_rule(rule_id, perm_id, rule_column, rule_type, rule_value)
|
||||
VALUES (cb_permission_rule_seq.NEXTVAL, v_permission_id, NULL, 'ALL', NULL);
|
||||
|
||||
-- CB_ORDS is the non-exempt data runtime. VPD still applies after
|
||||
-- this object privilege is granted.
|
||||
EXECUTE IMMEDIATE
|
||||
'GRANT SELECT ON POC_2.' || DBMS_ASSERT.SIMPLE_SQL_NAME(p_target_name) || ' TO CB_ORDS';
|
||||
END;
|
||||
|
||||
PROCEDURE allow_original_column(
|
||||
p_target_name IN VARCHAR2,
|
||||
p_column_name IN VARCHAR2
|
||||
) IS
|
||||
BEGIN
|
||||
SELECT MIN(perm_id)
|
||||
INTO v_permission_id
|
||||
FROM cb_permission
|
||||
WHERE role_id = v_admin_role_id
|
||||
AND target_name = p_target_name
|
||||
AND action_name = 'SELECT';
|
||||
|
||||
SELECT COUNT(*)
|
||||
INTO v_count
|
||||
FROM cb_permission_column
|
||||
WHERE permission_id = v_permission_id
|
||||
AND column_name = p_column_name;
|
||||
|
||||
IF v_count = 0 THEN
|
||||
INSERT INTO cb_permission_column(permission_id, column_name)
|
||||
VALUES (v_permission_id, p_column_name);
|
||||
END IF;
|
||||
END;
|
||||
BEGIN
|
||||
MERGE INTO poc_2.kb_stakeholders target
|
||||
USING (
|
||||
SELECT c_stakeholder_user_id AS user_id,
|
||||
'VPD 관리자' AS user_nm,
|
||||
'관리자' AS role,
|
||||
'관리자채널' AS channel,
|
||||
'전체 KB 원장 및 민감 컬럼 접근' AS access_scope,
|
||||
'권한 테이블의 KB_VPD_ADMIN_ROLE / ALL 규칙으로 적용' AS rls_filter
|
||||
FROM dual
|
||||
) source
|
||||
ON (target.user_id = source.user_id)
|
||||
WHEN MATCHED THEN UPDATE SET
|
||||
target.user_nm = source.user_nm,
|
||||
target.role = source.role,
|
||||
target.channel = source.channel,
|
||||
target.access_scope = source.access_scope,
|
||||
target.rls_filter = source.rls_filter
|
||||
WHEN NOT MATCHED THEN INSERT (
|
||||
user_id, user_nm, role, channel, access_scope, rls_filter
|
||||
) VALUES (
|
||||
source.user_id, source.user_nm, source.role, source.channel,
|
||||
source.access_scope, source.rls_filter
|
||||
);
|
||||
|
||||
BEGIN
|
||||
SELECT user_id
|
||||
INTO v_app_user_id
|
||||
FROM cb_app_user
|
||||
WHERE stakeholder_user_id = c_stakeholder_user_id;
|
||||
EXCEPTION
|
||||
WHEN NO_DATA_FOUND THEN
|
||||
SELECT NVL(MAX(user_id), 0) + 1 INTO v_app_user_id FROM cb_app_user;
|
||||
INSERT INTO cb_app_user(
|
||||
user_id, user_name, employee_no, dept_code,
|
||||
stakeholder_user_id, can_read_contents, active
|
||||
) VALUES (
|
||||
v_app_user_id, 'VPD 관리자', c_stakeholder_user_id, '관리자채널',
|
||||
c_stakeholder_user_id, 'Y', 'Y'
|
||||
);
|
||||
END;
|
||||
|
||||
UPDATE cb_app_user
|
||||
SET user_name = 'VPD 관리자',
|
||||
employee_no = c_stakeholder_user_id,
|
||||
dept_code = '관리자채널',
|
||||
can_read_contents = 'Y',
|
||||
active = 'Y'
|
||||
WHERE user_id = v_app_user_id;
|
||||
|
||||
ensure_role(c_role_name, 'RESTRICTED', v_admin_role_id);
|
||||
ensure_role('KB_STAKEHOLDER_IDENTITY_ROLE', 'INTERNAL', v_identity_role_id);
|
||||
ensure_user_role(v_app_user_id, v_admin_role_id);
|
||||
ensure_user_role(v_app_user_id, v_identity_role_id);
|
||||
|
||||
FOR object_name IN (
|
||||
SELECT column_value
|
||||
FROM TABLE(sys.odcivarchar2list(
|
||||
'KB_CUSTOMERS', 'KB_PRODUCTS', 'KB_CONTRACTS', 'KB_COVERAGES',
|
||||
'KB_CLAIMS', 'KB_EXTERNAL_HOLDINGS', 'KB_STAKEHOLDERS'
|
||||
))
|
||||
) LOOP
|
||||
ensure_all_permission(object_name.column_value);
|
||||
END LOOP;
|
||||
|
||||
allow_original_column('KB_CUSTOMERS', 'CUST_NM');
|
||||
allow_original_column('KB_CUSTOMERS', 'RRN_MASKED');
|
||||
allow_original_column('KB_CLAIMS', 'CLAIM_AMT');
|
||||
allow_original_column('KB_CLAIMS', 'PAID_AMT');
|
||||
allow_original_column('KB_EXTERNAL_HOLDINGS', 'EXT_INSURER');
|
||||
allow_original_column('KB_EXTERNAL_HOLDINGS', 'EXT_PRODUCT_GRP');
|
||||
allow_original_column('KB_EXTERNAL_HOLDINGS', 'EXT_PRODUCT_TYPE');
|
||||
|
||||
-- Re-running this script rotates only the bootstrap administrator token.
|
||||
UPDATE cb_agent_bearer_key
|
||||
SET active = 'N',
|
||||
revoked_at = SYSDATE
|
||||
WHERE stakeholder_user_id = c_stakeholder_user_id
|
||||
AND description = c_token_description
|
||||
AND active = 'Y';
|
||||
|
||||
v_bearer_token := 'kbvpdadm_' || DBMS_RANDOM.STRING('x', 48);
|
||||
INSERT INTO cb_agent_bearer_key(
|
||||
key_id, user_id, stakeholder_user_id, key_prefix, key_hash,
|
||||
issued_at, expires_at, revoked_at, active, description
|
||||
) VALUES (
|
||||
cb_agent_bearer_key_seq.NEXTVAL, v_app_user_id, c_stakeholder_user_id,
|
||||
'kbvpdadm', STANDARD_HASH(v_bearer_token, 'SHA256'),
|
||||
SYSDATE, ADD_MONTHS(SYSDATE, 12), NULL, 'Y', c_token_description
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- This is the application step that binds the Bearer Token to the trusted
|
||||
-- context. DBMS_RLS then invokes CB_AGENT_DOC_VPD_FILTER automatically.
|
||||
cb_agent_ctx_pkg.set_user_by_bearer(v_bearer_token);
|
||||
DBMS_OUTPUT.PUT_LINE('STAKEHOLDER_USER_ID='
|
||||
|| SYS_CONTEXT('CB_AGENT_CTX', 'STAKEHOLDER_USER_ID'));
|
||||
DBMS_OUTPUT.PUT_LINE('EFFECTIVE_ROLE=' || c_role_name);
|
||||
DBMS_OUTPUT.PUT_LINE('KB_CUSTOMERS_PREDICATE='
|
||||
|| cb_agent_doc_vpd_filter('POC_2', 'KB_CUSTOMERS'));
|
||||
DBMS_OUTPUT.PUT_LINE('KB_CLAIMS_PREDICATE='
|
||||
|| cb_agent_doc_vpd_filter('POC_2', 'KB_CLAIMS'));
|
||||
DBMS_OUTPUT.PUT_LINE('KB_EXTERNAL_HOLDINGS_PREDICATE='
|
||||
|| cb_agent_doc_vpd_filter('POC_2', 'KB_EXTERNAL_HOLDINGS'));
|
||||
cb_agent_ctx_pkg.clear_user;
|
||||
|
||||
-- Show once. The raw token is never stored; only its SHA-256 hash remains.
|
||||
DBMS_OUTPUT.PUT_LINE('BEARER_TOKEN=' || v_bearer_token);
|
||||
END;
|
||||
/
|
||||
|
||||
PROMPT === KB VPD administrator token ready ===
|
||||
223
sql/adb/52_cleanup_to_kb_vpd_poc.sql
Normal file
223
sql/adb/52_cleanup_to_kb_vpd_poc.sql
Normal file
@@ -0,0 +1,223 @@
|
||||
-- ============================================================
|
||||
-- 52_cleanup_to_kb_vpd_poc.sql
|
||||
--
|
||||
-- Removes legacy document/Vector/DDS/test examples and keeps only
|
||||
-- the KB structured-data VPD POC:
|
||||
-- POC_2.KB_* seven ledgers, stakeholder identity, KB roles,
|
||||
-- bearer-token permission metadata, and their VPD policies.
|
||||
--
|
||||
-- Oracle-maintained ANNOTATIONS_* / VECTOR$* auxiliary objects are
|
||||
-- not dropped directly. Their owning RAG/vector tables are dropped.
|
||||
-- ============================================================
|
||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||
SET ECHO OFF
|
||||
SET FEEDBACK ON
|
||||
SET DEFINE OFF
|
||||
SET SERVEROUTPUT ON
|
||||
ALTER SESSION DISABLE PARALLEL DML;
|
||||
|
||||
PROMPT === 1. Removing document, legacy role, and test permissions ===
|
||||
DECLARE
|
||||
c_role_keep_1 CONSTANT VARCHAR2(80) := 'KB_DESIGNER_ROLE';
|
||||
c_role_keep_2 CONSTANT VARCHAR2(80) := 'KB_BRANCH_MANAGER_ROLE';
|
||||
c_role_keep_3 CONSTANT VARCHAR2(80) := 'KB_STAKEHOLDER_IDENTITY_ROLE';
|
||||
c_role_keep_4 CONSTANT VARCHAR2(80) := 'KB_VPD_ADMIN_ROLE';
|
||||
BEGIN
|
||||
DELETE FROM cb_permission_column
|
||||
WHERE permission_id IN (
|
||||
SELECT p.perm_id
|
||||
FROM cb_permission p
|
||||
JOIN cb_app_role r ON r.role_id = p.role_id
|
||||
WHERE r.role_name NOT IN (c_role_keep_1, c_role_keep_2, c_role_keep_3, c_role_keep_4)
|
||||
OR p.target_name NOT IN (
|
||||
'KB_CUSTOMERS', 'KB_PRODUCTS', 'KB_CONTRACTS', 'KB_COVERAGES',
|
||||
'KB_CLAIMS', 'KB_EXTERNAL_HOLDINGS', 'KB_STAKEHOLDERS'
|
||||
)
|
||||
);
|
||||
|
||||
DELETE FROM cb_permission_rule
|
||||
WHERE perm_id IN (
|
||||
SELECT p.perm_id
|
||||
FROM cb_permission p
|
||||
JOIN cb_app_role r ON r.role_id = p.role_id
|
||||
WHERE r.role_name NOT IN (c_role_keep_1, c_role_keep_2, c_role_keep_3, c_role_keep_4)
|
||||
OR p.target_name NOT IN (
|
||||
'KB_CUSTOMERS', 'KB_PRODUCTS', 'KB_CONTRACTS', 'KB_COVERAGES',
|
||||
'KB_CLAIMS', 'KB_EXTERNAL_HOLDINGS', 'KB_STAKEHOLDERS'
|
||||
)
|
||||
);
|
||||
|
||||
DELETE FROM cb_permission
|
||||
WHERE perm_id IN (
|
||||
SELECT p.perm_id
|
||||
FROM cb_permission p
|
||||
JOIN cb_app_role r ON r.role_id = p.role_id
|
||||
WHERE r.role_name NOT IN (c_role_keep_1, c_role_keep_2, c_role_keep_3, c_role_keep_4)
|
||||
OR p.target_name NOT IN (
|
||||
'KB_CUSTOMERS', 'KB_PRODUCTS', 'KB_CONTRACTS', 'KB_COVERAGES',
|
||||
'KB_CLAIMS', 'KB_EXTERNAL_HOLDINGS', 'KB_STAKEHOLDERS'
|
||||
)
|
||||
);
|
||||
|
||||
DELETE FROM cb_user_role
|
||||
WHERE role_id IN (
|
||||
SELECT role_id
|
||||
FROM cb_app_role
|
||||
WHERE role_name NOT IN (c_role_keep_1, c_role_keep_2, c_role_keep_3, c_role_keep_4)
|
||||
);
|
||||
|
||||
DELETE FROM cb_group_role;
|
||||
DELETE FROM cb_user_group;
|
||||
DELETE FROM cb_app_group;
|
||||
|
||||
DELETE FROM cb_app_role
|
||||
WHERE role_name NOT IN (c_role_keep_1, c_role_keep_2, c_role_keep_3, c_role_keep_4);
|
||||
|
||||
-- Keep only tokens attached to an actual KB stakeholder.
|
||||
DELETE FROM cb_agent_bearer_key
|
||||
WHERE stakeholder_user_id IS NULL;
|
||||
|
||||
-- Non-stakeholder users were document/test sample principals.
|
||||
DELETE FROM cb_app_user
|
||||
WHERE stakeholder_user_id IS NULL;
|
||||
|
||||
DELETE FROM cb_vpd_filter_note;
|
||||
DELETE FROM cb_vpd_policy_note;
|
||||
DELETE FROM cb_ords_probe_audit;
|
||||
|
||||
DELETE FROM cb_protected_column
|
||||
WHERE object_id IN (
|
||||
SELECT object_id
|
||||
FROM cb_protected_object
|
||||
WHERE NOT (
|
||||
owner = 'POC_2'
|
||||
AND object_name IN (
|
||||
'KB_CUSTOMERS', 'KB_PRODUCTS', 'KB_CONTRACTS', 'KB_COVERAGES',
|
||||
'KB_CLAIMS', 'KB_EXTERNAL_HOLDINGS', 'KB_STAKEHOLDERS'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
DELETE FROM cb_protected_object
|
||||
WHERE NOT (
|
||||
owner = 'POC_2'
|
||||
AND object_name IN (
|
||||
'KB_CUSTOMERS', 'KB_PRODUCTS', 'KB_CONTRACTS', 'KB_COVERAGES',
|
||||
'KB_CLAIMS', 'KB_EXTERNAL_HOLDINGS', 'KB_STAKEHOLDERS'
|
||||
)
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
END;
|
||||
/
|
||||
|
||||
PROMPT === 2. Removing legacy document VPD/redaction and source objects ===
|
||||
BEGIN
|
||||
DBMS_REDACT.DROP_POLICY(
|
||||
object_schema => 'ADMIN',
|
||||
object_name => 'CB_V_SEARCH_DOCUMENTS',
|
||||
policy_name => 'CB_CONTENTS_REDACT'
|
||||
);
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
-- The policy may already be absent in a reduced POC schema.
|
||||
DBMS_OUTPUT.PUT_LINE('redaction policy not removed: ' || SQLERRM);
|
||||
END;
|
||||
/
|
||||
|
||||
DECLARE
|
||||
v_count NUMBER;
|
||||
BEGIN
|
||||
SELECT COUNT(*)
|
||||
INTO v_count
|
||||
FROM all_policies
|
||||
WHERE object_owner = 'ADMIN'
|
||||
AND object_name = 'CB_V_SEARCH_DOCUMENTS'
|
||||
AND policy_name = 'CB_AGENT_DOC_POLICY';
|
||||
|
||||
IF v_count > 0 THEN
|
||||
DBMS_RLS.DROP_POLICY(
|
||||
object_schema => 'ADMIN',
|
||||
object_name => 'CB_V_SEARCH_DOCUMENTS',
|
||||
policy_name => 'CB_AGENT_DOC_POLICY'
|
||||
);
|
||||
END IF;
|
||||
END;
|
||||
/
|
||||
|
||||
BEGIN
|
||||
EXECUTE IMMEDIATE 'DROP VIEW cb_v_search_documents';
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
IF SQLCODE != -942 THEN
|
||||
RAISE;
|
||||
END IF;
|
||||
END;
|
||||
/
|
||||
|
||||
BEGIN
|
||||
EXECUTE IMMEDIATE 'DROP TABLE cb_search_documents PURGE';
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
IF SQLCODE != -942 THEN
|
||||
RAISE;
|
||||
END IF;
|
||||
END;
|
||||
/
|
||||
|
||||
PROMPT === 3. Dropping unrelated POC_2 backup, RAG, and security-example tables ===
|
||||
DECLARE
|
||||
PROCEDURE drop_table_if_exists(p_table_name IN VARCHAR2) IS
|
||||
BEGIN
|
||||
EXECUTE IMMEDIATE
|
||||
'DROP TABLE POC_2.' || DBMS_ASSERT.SIMPLE_SQL_NAME(p_table_name)
|
||||
|| ' CASCADE CONSTRAINTS PURGE';
|
||||
DBMS_OUTPUT.PUT_LINE('dropped POC_2.' || p_table_name);
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
IF SQLCODE = -942 THEN
|
||||
NULL;
|
||||
ELSE
|
||||
RAISE;
|
||||
END IF;
|
||||
END;
|
||||
BEGIN
|
||||
drop_table_if_exists('BKP_CLM_20260701144052');
|
||||
drop_table_if_exists('BKP_CONT_20260701144052');
|
||||
drop_table_if_exists('BKP_COV_20260701144052');
|
||||
drop_table_if_exists('BKP_CUST_20260701144052');
|
||||
drop_table_if_exists('BKP_EXT_20260701144052');
|
||||
drop_table_if_exists('BKP_PROD_20260701144052');
|
||||
drop_table_if_exists('KB_CUST_BAK_202607011343');
|
||||
drop_table_if_exists('KB_CUST_BAK_20260701134439');
|
||||
drop_table_if_exists('KB_AIDP_RAG_CORPUS_CONFIG');
|
||||
drop_table_if_exists('KB_AIDP_RAG_QUERY_CACHE');
|
||||
drop_table_if_exists('KB_COMPETITOR_TERMS_CHUNKS');
|
||||
drop_table_if_exists('KB_COMPETITOR_TERMS_DOCUMENTS');
|
||||
drop_table_if_exists('KB_OWN_TERMS_CHUNKS');
|
||||
drop_table_if_exists('KB_OWN_TERMS_DOCUMENTS');
|
||||
drop_table_if_exists('KB_SECURITY_AUDIT_LOG');
|
||||
drop_table_if_exists('KB_SECURITY_POLICY_CATALOG');
|
||||
END;
|
||||
/
|
||||
|
||||
PROMPT === 4. Remaining KB VPD POC inventory ===
|
||||
SELECT object_name
|
||||
FROM cb_protected_object
|
||||
WHERE owner = 'POC_2'
|
||||
ORDER BY object_name;
|
||||
|
||||
SELECT role_name
|
||||
FROM cb_app_role
|
||||
ORDER BY role_name;
|
||||
|
||||
SELECT key_id, stakeholder_user_id, key_prefix, active, expires_at
|
||||
FROM cb_agent_bearer_key
|
||||
ORDER BY key_id;
|
||||
|
||||
SELECT object_owner, object_name, policy_name, function, enable
|
||||
FROM all_policies
|
||||
WHERE object_owner = 'POC_2'
|
||||
ORDER BY object_name, policy_name;
|
||||
|
||||
PROMPT === KB VPD POC cleanup complete ===
|
||||
101
sql/adb/53_drop_legacy_poc_objects.sql
Normal file
101
sql/adb/53_drop_legacy_poc_objects.sql
Normal file
@@ -0,0 +1,101 @@
|
||||
-- ============================================================
|
||||
-- 53_drop_legacy_poc_objects.sql
|
||||
-- Completes the physical-object portion of the KB VPD POC cleanup
|
||||
-- after 52 has removed legacy permissions, roles, tokens and users.
|
||||
-- ============================================================
|
||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||
SET ECHO OFF
|
||||
SET FEEDBACK ON
|
||||
SET DEFINE OFF
|
||||
SET SERVEROUTPUT ON
|
||||
|
||||
PROMPT === Removing legacy document VPD/redaction and source objects ===
|
||||
BEGIN
|
||||
DBMS_REDACT.DROP_POLICY(
|
||||
object_schema => 'ADMIN',
|
||||
object_name => 'CB_V_SEARCH_DOCUMENTS',
|
||||
policy_name => 'CB_CONTENTS_REDACT'
|
||||
);
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
DBMS_OUTPUT.PUT_LINE('redaction policy not removed: ' || SQLERRM);
|
||||
END;
|
||||
/
|
||||
|
||||
DECLARE
|
||||
v_count NUMBER;
|
||||
BEGIN
|
||||
SELECT COUNT(*)
|
||||
INTO v_count
|
||||
FROM all_policies
|
||||
WHERE object_owner = 'ADMIN'
|
||||
AND object_name = 'CB_V_SEARCH_DOCUMENTS'
|
||||
AND policy_name = 'CB_AGENT_DOC_POLICY';
|
||||
|
||||
IF v_count > 0 THEN
|
||||
DBMS_RLS.DROP_POLICY(
|
||||
object_schema => 'ADMIN',
|
||||
object_name => 'CB_V_SEARCH_DOCUMENTS',
|
||||
policy_name => 'CB_AGENT_DOC_POLICY'
|
||||
);
|
||||
END IF;
|
||||
END;
|
||||
/
|
||||
|
||||
BEGIN
|
||||
EXECUTE IMMEDIATE 'DROP VIEW cb_v_search_documents';
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
IF SQLCODE != -942 THEN
|
||||
RAISE;
|
||||
END IF;
|
||||
END;
|
||||
/
|
||||
|
||||
BEGIN
|
||||
EXECUTE IMMEDIATE 'DROP TABLE cb_search_documents PURGE';
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
IF SQLCODE != -942 THEN
|
||||
RAISE;
|
||||
END IF;
|
||||
END;
|
||||
/
|
||||
|
||||
PROMPT === Dropping unrelated POC_2 backup, RAG, and security-example tables ===
|
||||
DECLARE
|
||||
PROCEDURE drop_table_if_exists(p_table_name IN VARCHAR2) IS
|
||||
BEGIN
|
||||
EXECUTE IMMEDIATE
|
||||
'DROP TABLE POC_2.' || DBMS_ASSERT.SIMPLE_SQL_NAME(p_table_name)
|
||||
|| ' CASCADE CONSTRAINTS PURGE';
|
||||
DBMS_OUTPUT.PUT_LINE('dropped POC_2.' || p_table_name);
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
IF SQLCODE = -942 THEN
|
||||
NULL;
|
||||
ELSE
|
||||
RAISE;
|
||||
END IF;
|
||||
END;
|
||||
BEGIN
|
||||
drop_table_if_exists('BKP_CLM_20260701144052');
|
||||
drop_table_if_exists('BKP_CONT_20260701144052');
|
||||
drop_table_if_exists('BKP_COV_20260701144052');
|
||||
drop_table_if_exists('BKP_CUST_20260701144052');
|
||||
drop_table_if_exists('BKP_EXT_20260701144052');
|
||||
drop_table_if_exists('BKP_PROD_20260701144052');
|
||||
drop_table_if_exists('KB_CUST_BAK_202607011343');
|
||||
drop_table_if_exists('KB_CUST_BAK_20260701134439');
|
||||
drop_table_if_exists('KB_AIDP_RAG_CORPUS_CONFIG');
|
||||
drop_table_if_exists('KB_AIDP_RAG_QUERY_CACHE');
|
||||
drop_table_if_exists('KB_COMPETITOR_TERMS_CHUNKS');
|
||||
drop_table_if_exists('KB_COMPETITOR_TERMS_DOCUMENTS');
|
||||
drop_table_if_exists('KB_OWN_TERMS_CHUNKS');
|
||||
drop_table_if_exists('KB_OWN_TERMS_DOCUMENTS');
|
||||
drop_table_if_exists('KB_SECURITY_AUDIT_LOG');
|
||||
drop_table_if_exists('KB_SECURITY_POLICY_CATALOG');
|
||||
END;
|
||||
/
|
||||
|
||||
PROMPT === Legacy physical objects removed ===
|
||||
47
sql/adb/54_drop_legacy_dds_ords_examples.sql
Normal file
47
sql/adb/54_drop_legacy_dds_ords_examples.sql
Normal file
@@ -0,0 +1,47 @@
|
||||
-- ============================================================
|
||||
-- 54_drop_legacy_dds_ords_examples.sql
|
||||
-- Removes only the former document-search ORDS/DDS example objects.
|
||||
-- It deliberately keeps CB_ORDS because it is the non-exempt KB VPD
|
||||
-- runtime principal.
|
||||
-- ============================================================
|
||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||
SET ECHO OFF
|
||||
SET FEEDBACK ON
|
||||
SET DEFINE OFF
|
||||
SET SERVEROUTPUT ON
|
||||
|
||||
BEGIN
|
||||
ORDS.DELETE_MODULE(p_module_name => 'cb.agent.security');
|
||||
DBMS_OUTPUT.PUT_LINE('dropped ORDS module cb.agent.security');
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
DBMS_OUTPUT.PUT_LINE('ORDS module not removed: ' || SQLERRM);
|
||||
END;
|
||||
/
|
||||
|
||||
DECLARE
|
||||
PROCEDURE drop_ddl_if_present(p_ddl IN VARCHAR2) IS
|
||||
BEGIN
|
||||
EXECUTE IMMEDIATE p_ddl;
|
||||
DBMS_OUTPUT.PUT_LINE('dropped: ' || p_ddl);
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
DBMS_OUTPUT.PUT_LINE('not present: ' || p_ddl);
|
||||
END;
|
||||
BEGIN
|
||||
drop_ddl_if_present('DROP DATA GRANT admin.cb_dg_hr_docs');
|
||||
drop_ddl_if_present('DROP DATA GRANT admin.cb_dg_fin_docs');
|
||||
drop_ddl_if_present('DROP DATA GRANT admin.cb_dg_all_docs');
|
||||
drop_ddl_if_present('DROP END USER "cb_dds_hr"');
|
||||
drop_ddl_if_present('DROP END USER "cb_dds_fin"');
|
||||
drop_ddl_if_present('DROP END USER "cb_dds_all"');
|
||||
drop_ddl_if_present('DROP END USER "cb_dds_none"');
|
||||
drop_ddl_if_present('DROP DATA ROLE cb_dds_hr_role');
|
||||
drop_ddl_if_present('DROP DATA ROLE cb_dds_fin_role');
|
||||
drop_ddl_if_present('DROP DATA ROLE cb_dds_all_role');
|
||||
drop_ddl_if_present('DROP DATA ROLE cb_dds_connect_only_role');
|
||||
drop_ddl_if_present('DROP ROLE cb_dds_connect_role');
|
||||
END;
|
||||
/
|
||||
|
||||
PROMPT === Legacy DDS/ORDS examples removed ===
|
||||
Reference in New Issue
Block a user