fix #477: add group based role grants

This commit is contained in:
devmrko
2026-06-26 09:33:49 +09:00
parent 3c9bcfdc0a
commit 1ea8d34f31
14 changed files with 654 additions and 10 deletions

View File

@@ -72,6 +72,54 @@ EXCEPTION
END;
/
PROMPT === Creating group role support tables ===
BEGIN
EXECUTE IMMEDIATE '
CREATE TABLE cb_app_group (
group_id NUMBER PRIMARY KEY,
group_code VARCHAR2(100) NOT NULL UNIQUE,
group_name VARCHAR2(100) NOT NULL,
description VARCHAR2(200),
active_yn CHAR(1) DEFAULT ''Y'' CHECK (active_yn IN (''Y'',''N'')) NOT NULL
)';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -955 THEN
RAISE;
END IF;
END;
/
BEGIN
EXECUTE IMMEDIATE '
CREATE TABLE cb_user_group (
group_id NUMBER NOT NULL,
user_id NUMBER NOT NULL,
CONSTRAINT cb_user_group_pk PRIMARY KEY (group_id, user_id)
)';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -955 THEN
RAISE;
END IF;
END;
/
BEGIN
EXECUTE IMMEDIATE '
CREATE TABLE cb_group_role (
group_id NUMBER NOT NULL,
role_id NUMBER NOT NULL,
CONSTRAINT cb_group_role_pk PRIMARY KEY (group_id, role_id)
)';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -955 THEN
RAISE;
END IF;
END;
/
CREATE TABLE cb_protected_object (
object_id NUMBER PRIMARY KEY,
owner VARCHAR2(128) NOT NULL,
@@ -226,13 +274,25 @@ BEGIN
SELECT COUNT(*)
INTO v_allowed
FROM cb_user_role ur
FROM (
SELECT ur.role_id
FROM cb_user_role ur
WHERE ur.user_id = TO_NUMBER(SYS_CONTEXT('CB_AGENT_CTX', 'USER_ID'))
UNION
SELECT gr.role_id
FROM cb_user_group ug
JOIN cb_app_group g
ON g.group_id = ug.group_id
AND g.active_yn = 'Y'
JOIN cb_group_role gr
ON gr.group_id = ug.group_id
WHERE ug.user_id = TO_NUMBER(SYS_CONTEXT('CB_AGENT_CTX', 'USER_ID'))
) er
JOIN cb_permission p
ON p.role_id = ur.role_id
ON p.role_id = er.role_id
JOIN cb_permission_column pc
ON pc.permission_id = p.perm_id
WHERE ur.user_id = TO_NUMBER(SYS_CONTEXT('CB_AGENT_CTX', 'USER_ID'))
AND p.target_name = UPPER(p_target_name)
WHERE p.target_name = UPPER(p_target_name)
AND p.action_name = 'SELECT'
AND pc.column_name = UPPER(p_column_name);

View File

@@ -3,7 +3,8 @@
-- Replaces the demo VPD filter with a whitelist predicate builder.
--
-- The function does not hardcode object names or rule values. It reads:
-- CB_AGENT_CTX.USER_ID -> CB_USER_ROLE -> CB_PERMISSION -> CB_PERMISSION_RULE
-- 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.
-- ============================================================
WHENEVER SQLERROR EXIT SQL.SQLCODE
@@ -94,17 +95,30 @@ BEGIN
v_target := UPPER(TRIM(p_object));
FOR r IN (
WITH effective_role AS (
SELECT ur.role_id
FROM cb_user_role ur
WHERE ur.user_id = v_user_id
UNION
SELECT gr.role_id
FROM cb_user_group ug
JOIN cb_app_group g
ON g.group_id = ug.group_id
AND g.active_yn = 'Y'
JOIN cb_group_role gr
ON gr.group_id = ug.group_id
WHERE ug.user_id = v_user_id
)
SELECT 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
FROM cb_user_role ur
FROM effective_role er
JOIN cb_permission p
ON p.role_id = ur.role_id
ON p.role_id = er.role_id
JOIN cb_permission_rule r
ON r.perm_id = p.perm_id
WHERE ur.user_id = v_user_id
AND p.target_name = v_target
WHERE p.target_name = v_target
AND p.action_name = 'SELECT'
ORDER BY r.rule_id
) LOOP