100
database/adb/62_kb_aso_masking_backoffice_metadata.sql
Normal file
100
database/adb/62_kb_aso_masking_backoffice_metadata.sql
Normal file
@@ -0,0 +1,100 @@
|
||||
-- ============================================================
|
||||
-- 62_kb_aso_masking_backoffice_metadata.sql
|
||||
--
|
||||
-- Creates the metadata used by the masking-rule backoffice pages.
|
||||
-- Run as ADMIN with SQLcl. This script does not create a DBMS_REDACT
|
||||
-- policy; run 63_kb_aso_masking_rule_runtime.sql after rules are
|
||||
-- connected to protected columns.
|
||||
-- ============================================================
|
||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||
SET DEFINE OFF
|
||||
SET FEEDBACK ON
|
||||
|
||||
PROMPT === Creating masking-rule metadata tables ===
|
||||
DECLARE
|
||||
PROCEDURE ensure_table(p_name IN VARCHAR2, p_ddl IN CLOB) IS
|
||||
BEGIN
|
||||
EXECUTE IMMEDIATE p_ddl;
|
||||
DBMS_OUTPUT.PUT_LINE('created ' || p_name);
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
IF SQLCODE = -955 THEN
|
||||
DBMS_OUTPUT.PUT_LINE('exists ' || p_name);
|
||||
ELSE
|
||||
RAISE;
|
||||
END IF;
|
||||
END;
|
||||
BEGIN
|
||||
ensure_table('CB_MASKING_RULE', q'[
|
||||
CREATE TABLE cb_masking_rule (
|
||||
rule_id NUMBER PRIMARY KEY,
|
||||
rule_code VARCHAR2(64) NOT NULL UNIQUE,
|
||||
rule_name VARCHAR2(100) NOT NULL,
|
||||
template_code VARCHAR2(30) NOT NULL,
|
||||
description VARCHAR2(400),
|
||||
enabled_yn CHAR(1) DEFAULT 'Y' CHECK (enabled_yn IN ('Y','N')) NOT NULL
|
||||
)]');
|
||||
|
||||
ensure_table('CB_COLUMN_MASKING_RULE', q'[
|
||||
CREATE TABLE cb_column_masking_rule (
|
||||
column_id NUMBER PRIMARY KEY,
|
||||
rule_id NUMBER NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL
|
||||
)]');
|
||||
|
||||
ensure_table('CB_USER_MASKING_RULE', q'[
|
||||
CREATE TABLE cb_user_masking_rule (
|
||||
user_id NUMBER NOT NULL,
|
||||
column_id NUMBER NOT NULL,
|
||||
decision VARCHAR2(10) NOT NULL CHECK (decision IN ('MASK','UNMASK')),
|
||||
active_yn CHAR(1) DEFAULT 'Y' CHECK (active_yn IN ('Y','N')) NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL,
|
||||
CONSTRAINT cb_user_masking_rule_pk PRIMARY KEY (user_id, column_id)
|
||||
)]');
|
||||
END;
|
||||
/
|
||||
|
||||
PROMPT === Seeding curated masking templates ===
|
||||
DECLARE
|
||||
v_next_rule_id NUMBER;
|
||||
|
||||
PROCEDURE ensure_rule(
|
||||
p_code IN VARCHAR2,
|
||||
p_name IN VARCHAR2,
|
||||
p_template IN VARCHAR2,
|
||||
p_description IN VARCHAR2
|
||||
) IS
|
||||
BEGIN
|
||||
MERGE INTO cb_masking_rule dst
|
||||
USING (
|
||||
SELECT p_code rule_code,
|
||||
p_name rule_name,
|
||||
p_template template_code,
|
||||
p_description description
|
||||
FROM dual
|
||||
) src
|
||||
ON (dst.rule_code = src.rule_code)
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT (rule_id, rule_code, rule_name, template_code, description, enabled_yn)
|
||||
VALUES (v_next_rule_id, src.rule_code, src.rule_name, src.template_code, src.description, 'Y');
|
||||
v_next_rule_id := v_next_rule_id + 1;
|
||||
END;
|
||||
BEGIN
|
||||
SELECT NVL(MAX(rule_id), 0) + 1 INTO v_next_rule_id FROM cb_masking_rule;
|
||||
ensure_rule('MASK_NULLIFY', '값 숨김 (NULL)', 'NULLIFY',
|
||||
'값을 NULL로 반환하는 기본 마스킹 방식');
|
||||
ensure_rule('MASK_FULL', '전체 마스킹', 'FULL',
|
||||
'문자형은 공백, 숫자형은 0으로 반환하는 전체 마스킹 방식');
|
||||
ensure_rule('MASK_TEXT_PARTIAL', '문자열 일부 마스킹', 'TEXT_PARTIAL',
|
||||
'첫 글자만 보이고 나머지는 가리는 문자열 마스킹 방식');
|
||||
ensure_rule('MASK_RRN_PARTIAL', '주민등록번호 부분 마스킹', 'RRN_PARTIAL',
|
||||
'앞 6자리만 보이고 나머지는 가리는 식별번호 마스킹 방식');
|
||||
END;
|
||||
/
|
||||
COMMIT;
|
||||
|
||||
PROMPT === Metadata ready ===
|
||||
SELECT rule_id, rule_code, rule_name, template_code, enabled_yn
|
||||
FROM cb_masking_rule
|
||||
ORDER BY rule_id;
|
||||
EXIT
|
||||
Reference in New Issue
Block a user