472 lines
17 KiB
MySQL
472 lines
17 KiB
MySQL
-- ============================================================
|
|
-- 46_kb_stakeholder_token_permission_example.sql
|
|
--
|
|
-- KB_STAKEHOLDERS를 토큰의 업무 주체로 연결하고, 접근 규칙 화면에서
|
|
-- 관리하는 설계사/지점장 예제 권한을 등록한다.
|
|
--
|
|
-- Prerequisite: 17, 25, 26 scripts. Execute as ADMIN.
|
|
-- 26 must include STAKEHOLDER_SELF / STAKEHOLDER_CHANNEL rule support.
|
|
-- ============================================================
|
|
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
|
SET ECHO OFF
|
|
SET FEEDBACK ON
|
|
SET DEFINE OFF
|
|
|
|
PROMPT === 1. Adding stakeholder bridge columns ===
|
|
DECLARE
|
|
PROCEDURE add_column_if_missing(
|
|
p_table_name IN VARCHAR2,
|
|
p_column_name IN VARCHAR2,
|
|
p_ddl IN VARCHAR2
|
|
) IS
|
|
v_count NUMBER;
|
|
BEGIN
|
|
SELECT COUNT(*)
|
|
INTO v_count
|
|
FROM user_tab_columns
|
|
WHERE table_name = p_table_name
|
|
AND column_name = p_column_name;
|
|
|
|
IF v_count = 0 THEN
|
|
EXECUTE IMMEDIATE p_ddl;
|
|
END IF;
|
|
END;
|
|
BEGIN
|
|
add_column_if_missing(
|
|
'CB_APP_USER',
|
|
'STAKEHOLDER_USER_ID',
|
|
'ALTER TABLE cb_app_user ADD (stakeholder_user_id VARCHAR2(30))'
|
|
);
|
|
add_column_if_missing(
|
|
'CB_AGENT_BEARER_KEY',
|
|
'STAKEHOLDER_USER_ID',
|
|
'ALTER TABLE cb_agent_bearer_key ADD (stakeholder_user_id VARCHAR2(30))'
|
|
);
|
|
END;
|
|
/
|
|
|
|
PROMPT === 2. Resolving Bearer Token to stakeholder context ===
|
|
CREATE OR REPLACE PACKAGE cb_agent_ctx_pkg AUTHID DEFINER AS
|
|
PROCEDURE clear_user;
|
|
PROCEDURE set_user(p_user_id IN NUMBER);
|
|
PROCEDURE set_user_values(
|
|
p_user_id IN NUMBER,
|
|
p_emp_no IN VARCHAR2,
|
|
p_dept_code IN VARCHAR2,
|
|
p_can_read_contents IN VARCHAR2
|
|
);
|
|
PROCEDURE set_user_by_bearer(p_bearer_key IN VARCHAR2);
|
|
END;
|
|
/
|
|
|
|
CREATE OR REPLACE PACKAGE BODY cb_agent_ctx_pkg AS
|
|
PROCEDURE clear_stakeholder_context AS
|
|
BEGIN
|
|
DBMS_SESSION.SET_CONTEXT('CB_AGENT_CTX', 'STAKEHOLDER_USER_ID', NULL);
|
|
DBMS_SESSION.SET_CONTEXT('CB_AGENT_CTX', 'STAKEHOLDER_ROLE', NULL);
|
|
DBMS_SESSION.SET_CONTEXT('CB_AGENT_CTX', 'STAKEHOLDER_CHANNEL', NULL);
|
|
END;
|
|
|
|
PROCEDURE clear_user AS
|
|
BEGIN
|
|
DBMS_SESSION.SET_CONTEXT('CB_AGENT_CTX', 'USER_ID', NULL);
|
|
DBMS_SESSION.SET_CONTEXT('CB_AGENT_CTX', 'EMP_NO', NULL);
|
|
DBMS_SESSION.SET_CONTEXT('CB_AGENT_CTX', 'DEPT_CODE', NULL);
|
|
DBMS_SESSION.SET_CONTEXT('CB_AGENT_CTX', 'CAN_READ_CONTENTS', NULL);
|
|
clear_stakeholder_context;
|
|
END;
|
|
|
|
PROCEDURE set_user_values(
|
|
p_user_id IN NUMBER,
|
|
p_emp_no IN VARCHAR2,
|
|
p_dept_code IN VARCHAR2,
|
|
p_can_read_contents IN VARCHAR2
|
|
) AS
|
|
BEGIN
|
|
DBMS_SESSION.SET_CONTEXT('CB_AGENT_CTX', 'USER_ID', TO_CHAR(p_user_id));
|
|
DBMS_SESSION.SET_CONTEXT('CB_AGENT_CTX', 'EMP_NO', p_emp_no);
|
|
DBMS_SESSION.SET_CONTEXT('CB_AGENT_CTX', 'DEPT_CODE', p_dept_code);
|
|
DBMS_SESSION.SET_CONTEXT('CB_AGENT_CTX', 'CAN_READ_CONTENTS', p_can_read_contents);
|
|
clear_stakeholder_context;
|
|
END;
|
|
|
|
PROCEDURE set_stakeholder_context(
|
|
p_stakeholder_user_id IN VARCHAR2,
|
|
p_role IN VARCHAR2,
|
|
p_channel IN VARCHAR2
|
|
) AS
|
|
v_channel VARCHAR2(50);
|
|
BEGIN
|
|
v_channel := CASE TRIM(p_channel)
|
|
WHEN '설계사채널' THEN '설계사'
|
|
WHEN 'GA채널' THEN 'GA'
|
|
ELSE TRIM(p_channel)
|
|
END;
|
|
DBMS_SESSION.SET_CONTEXT('CB_AGENT_CTX', 'STAKEHOLDER_USER_ID', p_stakeholder_user_id);
|
|
DBMS_SESSION.SET_CONTEXT('CB_AGENT_CTX', 'STAKEHOLDER_ROLE', p_role);
|
|
DBMS_SESSION.SET_CONTEXT('CB_AGENT_CTX', 'STAKEHOLDER_CHANNEL', v_channel);
|
|
END;
|
|
|
|
PROCEDURE set_user(p_user_id IN NUMBER) AS
|
|
v_emp_no cb_app_user.employee_no%TYPE;
|
|
v_dept_code cb_app_user.dept_code%TYPE;
|
|
v_can_read_contents cb_app_user.can_read_contents%TYPE;
|
|
BEGIN
|
|
SELECT employee_no,
|
|
dept_code,
|
|
CASE
|
|
WHEN EXISTS (
|
|
SELECT 1
|
|
FROM cb_user_role ur
|
|
JOIN cb_permission p ON p.role_id = ur.role_id
|
|
JOIN cb_permission_column pc ON pc.permission_id = p.perm_id
|
|
WHERE ur.user_id = p_user_id
|
|
AND p.target_name = 'CB_V_SEARCH_DOCUMENTS'
|
|
AND p.action_name = 'SELECT'
|
|
AND pc.column_name = 'CONTENTS'
|
|
) THEN 'Y'
|
|
ELSE 'N'
|
|
END
|
|
INTO v_emp_no, v_dept_code, v_can_read_contents
|
|
FROM cb_app_user
|
|
WHERE user_id = p_user_id
|
|
AND active = 'Y';
|
|
|
|
set_user_values(p_user_id, v_emp_no, v_dept_code, v_can_read_contents);
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND THEN
|
|
clear_user;
|
|
RAISE_APPLICATION_ERROR(-20003, 'Mapped application user not found');
|
|
END;
|
|
|
|
PROCEDURE set_user_by_bearer(p_bearer_key IN VARCHAR2) AS
|
|
v_user_id cb_app_user.user_id%TYPE;
|
|
v_emp_no cb_app_user.employee_no%TYPE;
|
|
v_dept_code cb_app_user.dept_code%TYPE;
|
|
v_can_read_contents cb_app_user.can_read_contents%TYPE;
|
|
v_stakeholder_user_id VARCHAR2(30);
|
|
v_stakeholder_role VARCHAR2(50);
|
|
v_stakeholder_channel VARCHAR2(50);
|
|
BEGIN
|
|
IF p_bearer_key IS NULL THEN
|
|
clear_user;
|
|
RAISE_APPLICATION_ERROR(-20001, 'Authorization Bearer key is required');
|
|
END IF;
|
|
|
|
SELECT u.user_id,
|
|
u.employee_no,
|
|
u.dept_code,
|
|
CASE
|
|
WHEN EXISTS (
|
|
SELECT 1
|
|
FROM cb_user_role ur
|
|
JOIN cb_permission p ON p.role_id = ur.role_id
|
|
JOIN cb_permission_column pc ON pc.permission_id = p.perm_id
|
|
WHERE ur.user_id = u.user_id
|
|
AND p.target_name = 'CB_V_SEARCH_DOCUMENTS'
|
|
AND p.action_name = 'SELECT'
|
|
AND pc.column_name = 'CONTENTS'
|
|
) THEN 'Y'
|
|
ELSE 'N'
|
|
END,
|
|
COALESCE(k.stakeholder_user_id, u.stakeholder_user_id)
|
|
INTO v_user_id, v_emp_no, v_dept_code, v_can_read_contents, v_stakeholder_user_id
|
|
FROM cb_agent_bearer_key k
|
|
JOIN cb_app_user u ON u.user_id = k.user_id
|
|
WHERE k.key_hash = STANDARD_HASH(p_bearer_key, 'SHA256')
|
|
AND k.active = 'Y'
|
|
AND k.revoked_at IS NULL
|
|
AND (k.expires_at IS NULL OR k.expires_at > SYSDATE)
|
|
AND u.active = 'Y';
|
|
|
|
-- USER_ID를 먼저 넣어야 KB_STAKEHOLDERS 자체가 VPD 보호된 뒤에도
|
|
-- 해당 주체의 자기 행만 안전하게 해석할 수 있다.
|
|
set_user_values(v_user_id, v_emp_no, v_dept_code, v_can_read_contents);
|
|
|
|
IF v_stakeholder_user_id IS NOT NULL THEN
|
|
DBMS_SESSION.SET_CONTEXT('CB_AGENT_CTX', 'STAKEHOLDER_USER_ID', v_stakeholder_user_id);
|
|
SELECT role, channel
|
|
INTO v_stakeholder_role, v_stakeholder_channel
|
|
FROM poc_2.kb_stakeholders
|
|
WHERE user_id = v_stakeholder_user_id;
|
|
set_stakeholder_context(v_stakeholder_user_id, v_stakeholder_role, v_stakeholder_channel);
|
|
END IF;
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND THEN
|
|
clear_user;
|
|
RAISE_APPLICATION_ERROR(-20002, 'Invalid or expired Bearer key');
|
|
END;
|
|
END;
|
|
/
|
|
SHOW ERRORS PACKAGE BODY cb_agent_ctx_pkg
|
|
|
|
PROMPT === 3. Syncing stakeholder bridge and example permissions ===
|
|
DECLARE
|
|
v_designer_role_id NUMBER;
|
|
v_manager_role_id NUMBER;
|
|
v_object_id NUMBER;
|
|
v_user_id NUMBER;
|
|
|
|
PROCEDURE ensure_role(
|
|
p_role_name IN VARCHAR2,
|
|
p_max_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_max_level);
|
|
END;
|
|
|
|
PROCEDURE ensure_object(
|
|
p_object_name IN VARCHAR2,
|
|
p_description IN VARCHAR2,
|
|
p_object_id OUT NUMBER
|
|
) IS
|
|
BEGIN
|
|
SELECT object_id INTO p_object_id
|
|
FROM cb_protected_object
|
|
WHERE owner = 'POC_2'
|
|
AND object_name = p_object_name;
|
|
|
|
UPDATE cb_protected_object
|
|
SET enabled_yn = 'Y',
|
|
ords_path = 'cb-ords/cb-object-query/poc_2/' || LOWER(p_object_name),
|
|
description = p_description
|
|
WHERE object_id = p_object_id;
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND THEN
|
|
SELECT NVL(MAX(object_id), 0) + 1 INTO p_object_id FROM cb_protected_object;
|
|
INSERT INTO cb_protected_object(
|
|
object_id, owner, object_name, ords_path, enabled_yn, description
|
|
) VALUES (
|
|
p_object_id, 'POC_2', p_object_name,
|
|
'cb-ords/cb-object-query/poc_2/' || LOWER(p_object_name), 'Y', p_description
|
|
);
|
|
END;
|
|
|
|
FUNCTION is_sensitive(p_object_name IN VARCHAR2, p_column_name IN VARCHAR2) RETURN CHAR IS
|
|
BEGIN
|
|
IF (p_object_name = 'KB_CUSTOMERS' AND p_column_name IN ('CUST_NM', 'RRN_MASKED'))
|
|
OR (p_object_name = 'KB_CLAIMS' AND p_column_name IN ('CLAIM_AMT', 'PAID_AMT'))
|
|
OR (p_object_name = 'KB_EXTERNAL_HOLDINGS'
|
|
AND p_column_name IN ('EXT_INSURER', 'EXT_PRODUCT_GRP', 'EXT_PRODUCT_TYPE')) THEN
|
|
RETURN 'Y';
|
|
END IF;
|
|
RETURN 'N';
|
|
END;
|
|
|
|
PROCEDURE ensure_columns(p_object_name IN VARCHAR2, p_object_id IN NUMBER) IS
|
|
v_column_id NUMBER;
|
|
v_count NUMBER;
|
|
v_sensitive CHAR(1);
|
|
BEGIN
|
|
FOR c IN (
|
|
SELECT column_name
|
|
FROM all_tab_columns
|
|
WHERE owner = 'POC_2'
|
|
AND table_name = p_object_name
|
|
ORDER BY column_id
|
|
) LOOP
|
|
v_sensitive := is_sensitive(p_object_name, c.column_name);
|
|
SELECT COUNT(*) INTO v_count
|
|
FROM cb_protected_column
|
|
WHERE object_id = p_object_id
|
|
AND column_name = c.column_name;
|
|
|
|
IF v_count = 0 THEN
|
|
SELECT NVL(MAX(column_id), 0) + 1 INTO v_column_id FROM cb_protected_column;
|
|
INSERT INTO cb_protected_column(
|
|
column_id, object_id, column_name, sensitive_yn, sensitivity_level, redaction_method
|
|
) VALUES (
|
|
v_column_id, p_object_id, c.column_name, v_sensitive,
|
|
CASE v_sensitive WHEN 'Y' THEN 'CONFIDENTIAL' ELSE 'PUBLIC' END,
|
|
CASE v_sensitive WHEN 'Y' THEN 'NULLIFY' ELSE 'NONE' END
|
|
);
|
|
ELSIF v_sensitive = 'Y' THEN
|
|
UPDATE cb_protected_column
|
|
SET sensitive_yn = 'Y', sensitivity_level = 'CONFIDENTIAL', redaction_method = 'NULLIFY'
|
|
WHERE object_id = p_object_id
|
|
AND column_name = c.column_name;
|
|
END IF;
|
|
END LOOP;
|
|
END;
|
|
|
|
PROCEDURE ensure_user_role(p_user_id IN NUMBER, p_role_id IN NUMBER) IS
|
|
v_count NUMBER;
|
|
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_permission(
|
|
p_role_id IN NUMBER,
|
|
p_target_name IN VARCHAR2,
|
|
p_rule_column IN VARCHAR2,
|
|
p_rule_type IN VARCHAR2,
|
|
p_rule_value IN VARCHAR2
|
|
) IS
|
|
v_permission_id NUMBER;
|
|
BEGIN
|
|
SELECT perm_id INTO v_permission_id
|
|
FROM cb_permission
|
|
WHERE role_id = p_role_id
|
|
AND target_name = p_target_name
|
|
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, p_role_id, p_target_name, '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, p_rule_column, p_rule_type, p_rule_value);
|
|
END;
|
|
BEGIN
|
|
ensure_role('KB_DESIGNER_ROLE', 'CONFIDENTIAL', v_designer_role_id);
|
|
ensure_role('KB_BRANCH_MANAGER_ROLE', 'CONFIDENTIAL', v_manager_role_id);
|
|
|
|
FOR s IN (
|
|
SELECT user_id, user_nm, role, channel
|
|
FROM poc_2.kb_stakeholders
|
|
ORDER BY user_id
|
|
) LOOP
|
|
BEGIN
|
|
SELECT user_id INTO v_user_id
|
|
FROM cb_app_user
|
|
WHERE stakeholder_user_id = s.user_id;
|
|
|
|
UPDATE cb_app_user
|
|
SET user_name = s.user_nm,
|
|
employee_no = s.user_id,
|
|
dept_code = s.channel,
|
|
active = 'Y'
|
|
WHERE user_id = v_user_id;
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND THEN
|
|
SELECT NVL(MAX(user_id), 0) + 1 INTO v_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_user_id, s.user_nm, s.user_id, s.channel, s.user_id, 'N', 'Y'
|
|
);
|
|
END;
|
|
|
|
IF s.role = '지점장' THEN
|
|
ensure_user_role(v_user_id, v_manager_role_id);
|
|
ELSIF s.role = '설계사' THEN
|
|
ensure_user_role(v_user_id, v_designer_role_id);
|
|
END IF;
|
|
END LOOP;
|
|
|
|
FOR o IN (
|
|
SELECT 'KB_STAKEHOLDERS' object_name, '토큰 업무 주체·역할·채널 원장' description FROM dual
|
|
UNION ALL SELECT 'KB_CUSTOMERS', '고객 기본정보 원장' FROM dual
|
|
UNION ALL SELECT 'KB_PRODUCTS', '보험상품 마스터' FROM dual
|
|
UNION ALL SELECT 'KB_CONTRACTS', '보험계약 원장' FROM dual
|
|
UNION ALL SELECT 'KB_COVERAGES', '담보·특약 원장' FROM dual
|
|
UNION ALL SELECT 'KB_CLAIMS', '보험금 청구·지급 원장' FROM dual
|
|
UNION ALL SELECT 'KB_EXTERNAL_HOLDINGS', '외부보유정보 원장' FROM dual
|
|
) LOOP
|
|
ensure_object(o.object_name, o.description, v_object_id);
|
|
ensure_columns(o.object_name, v_object_id);
|
|
END LOOP;
|
|
|
|
-- 토큰은 모든 이해당사자에게 발급되지만, 아래 역할이 없는 주체는
|
|
-- 권한 레코드가 없으므로 VPD가 1=0으로 fail-closed 된다.
|
|
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', '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;
|
|
|
|
PROMPT === 4. Applying row VPD policies to KB business tables ===
|
|
DECLARE
|
|
PROCEDURE replace_row_policy(p_object_name IN VARCHAR2) IS
|
|
BEGIN
|
|
BEGIN
|
|
DBMS_RLS.DROP_POLICY(
|
|
object_schema => 'POC_2', object_name => p_object_name,
|
|
policy_name => 'KB_' || p_object_name || '_ROW_POLICY'
|
|
);
|
|
EXCEPTION WHEN OTHERS THEN NULL;
|
|
END;
|
|
DBMS_RLS.ADD_POLICY(
|
|
object_schema => 'POC_2',
|
|
object_name => p_object_name,
|
|
policy_name => 'KB_' || p_object_name || '_ROW_POLICY',
|
|
function_schema => USER,
|
|
policy_function => 'CB_AGENT_DOC_VPD_FILTER',
|
|
statement_types => 'SELECT',
|
|
policy_type => DBMS_RLS.DYNAMIC,
|
|
enable => TRUE
|
|
);
|
|
END;
|
|
BEGIN
|
|
replace_row_policy('KB_STAKEHOLDERS');
|
|
replace_row_policy('KB_CUSTOMERS');
|
|
replace_row_policy('KB_PRODUCTS');
|
|
replace_row_policy('KB_CONTRACTS');
|
|
replace_row_policy('KB_COVERAGES');
|
|
replace_row_policy('KB_CLAIMS');
|
|
replace_row_policy('KB_EXTERNAL_HOLDINGS');
|
|
END;
|
|
/
|
|
|
|
PROMPT === 5. Removing deprecated VPD column NULL policies ===
|
|
-- Architecture rule: VPD applies row predicates only. ASO/Data Redaction
|
|
-- owns all column masking and its user-specific original-value exceptions.
|
|
DECLARE
|
|
PROCEDURE drop_column_policy(p_object_name IN VARCHAR2, p_policy_name IN VARCHAR2) IS
|
|
BEGIN
|
|
DBMS_RLS.DROP_POLICY(
|
|
object_schema => 'POC_2', object_name => p_object_name, policy_name => p_policy_name
|
|
);
|
|
EXCEPTION
|
|
WHEN OTHERS THEN
|
|
IF SQLCODE != -28102 THEN RAISE; END IF;
|
|
END;
|
|
BEGIN
|
|
drop_column_policy('KB_CUSTOMERS', 'KB_CUST_NM_CLS_POLICY');
|
|
drop_column_policy('KB_CUSTOMERS', 'KB_RRN_CLS_POLICY');
|
|
drop_column_policy('KB_CLAIMS', 'KB_CLAIM_AMT_CLS_POLICY');
|
|
drop_column_policy('KB_CLAIMS', 'KB_PAID_AMT_CLS_POLICY');
|
|
drop_column_policy('KB_EXTERNAL_HOLDINGS', 'KB_EXT_INSURER_CLS_POLICY');
|
|
drop_column_policy('KB_EXTERNAL_HOLDINGS', 'KB_EXT_PRODUCT_GRP_CLS_POLICY');
|
|
drop_column_policy('KB_EXTERNAL_HOLDINGS', 'KB_EXT_PRODUCT_TYPE_CLS_POLICY');
|
|
END;
|
|
/
|
|
|
|
PROMPT === 6. Example configuration summary ===
|
|
SELECT r.role_name,
|
|
p.target_name,
|
|
pr.rule_column,
|
|
pr.rule_type,
|
|
NVL(pr.rule_value, '-') AS rule_value
|
|
FROM cb_permission p
|
|
JOIN cb_app_role r ON r.role_id = p.role_id
|
|
JOIN cb_permission_rule pr ON pr.perm_id = p.perm_id
|
|
WHERE r.role_name IN ('KB_DESIGNER_ROLE', 'KB_BRANCH_MANAGER_ROLE')
|
|
ORDER BY r.role_name, p.target_name, pr.rule_id;
|
|
|
|
PROMPT === KB stakeholder token permission example complete ===
|