228
database/adb/51_kb_vpd_admin_token.sql
Normal file
228
database/adb/51_kb_vpd_admin_token.sql
Normal file
@@ -0,0 +1,228 @@
|
||||
-- ============================================================
|
||||
-- 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 full-access 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, 'STATIC_SQL', '1 = 1');
|
||||
|
||||
-- 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 the only full-access administrator token.
|
||||
UPDATE cb_agent_bearer_key
|
||||
SET active = 'N',
|
||||
revoked_at = SYSDATE
|
||||
WHERE stakeholder_user_id = c_stakeholder_user_id
|
||||
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 ===
|
||||
Reference in New Issue
Block a user