- 新增 iam_schema_v1.sql DDL脚本 (iam_roles, iam_scopes, iam_role_scopes, iam_user_roles, iam_role_hierarchy) - 新增 PostgresIAMRepository 实现数据库-backed IAM仓储 - 新增 DatabaseIAMService 使用数据库-backed Repository - 新增 PostgresAuditRepository 实现数据库-backed Audit仓储 - 新增 DatabaseAuditService 使用数据库-backed Repository - 更新实施状态文档 v1.3 R-07~R-09 完成。
169 lines
7.4 KiB
PL/PgSQL
169 lines
7.4 KiB
PL/PgSQL
-- IAM (Identity and Access Management) schema
|
|
-- Purpose: 多角色权限系统核心表
|
|
-- Updated: 2026-04-03
|
|
-- Dependencies: platform_core_schema_v1.sql (core_tenants, iam_users)
|
|
|
|
BEGIN;
|
|
|
|
-- 角色表 (iam_roles)
|
|
CREATE TABLE IF NOT EXISTS iam_roles (
|
|
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
code VARCHAR(32) NOT NULL UNIQUE,
|
|
name VARCHAR(128) NOT NULL,
|
|
type VARCHAR(20) NOT NULL DEFAULT 'platform'
|
|
CHECK (type IN ('platform', 'supply', 'consumer')),
|
|
parent_role_id BIGINT REFERENCES iam_roles(id),
|
|
level INT NOT NULL DEFAULT 0,
|
|
description TEXT,
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
|
|
-- 审计字段
|
|
request_id VARCHAR(64),
|
|
created_ip INET,
|
|
updated_ip INET,
|
|
version INT NOT NULL DEFAULT 1,
|
|
|
|
-- 时间戳
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
-- 约束
|
|
CONSTRAINT chk_role_level_non_negative CHECK (level >= 0),
|
|
CONSTRAINT chk_role_code_format CHECK (code ~ '^[a-z][a-z0-9_]{0,31}$')
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_iam_roles_code ON iam_roles (code);
|
|
CREATE INDEX IF NOT EXISTS idx_iam_roles_type ON iam_roles (type);
|
|
CREATE INDEX IF NOT EXISTS idx_iam_roles_parent ON iam_roles (parent_role_id);
|
|
CREATE INDEX IF NOT EXISTS idx_iam_roles_level ON iam_roles (level);
|
|
CREATE INDEX IF NOT EXISTS idx_iam_roles_active ON iam_roles (is_active);
|
|
|
|
-- Scope权限表 (iam_scopes)
|
|
CREATE TABLE IF NOT EXISTS iam_scopes (
|
|
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
code VARCHAR(64) NOT NULL UNIQUE,
|
|
name VARCHAR(128) NOT NULL,
|
|
description TEXT,
|
|
category VARCHAR(32) NOT NULL DEFAULT 'generic'
|
|
CHECK (category IN ('generic', 'billing', 'audit', 'iam', 'gateway')),
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
|
|
-- 审计字段
|
|
request_id VARCHAR(64),
|
|
version INT NOT NULL DEFAULT 1,
|
|
|
|
-- 时间戳
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
-- 约束
|
|
CONSTRAINT chk_scope_code_format CHECK (code ~ '^[a-z][a-z0-9._]{0,63}$')
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_iam_scopes_code ON iam_scopes (code);
|
|
CREATE INDEX IF NOT EXISTS idx_iam_scopes_category ON iam_scopes (category);
|
|
CREATE INDEX IF NOT EXISTS idx_iam_scopes_active ON iam_scopes (is_active);
|
|
|
|
-- 角色-Scope关联表 (iam_role_scopes)
|
|
CREATE TABLE IF NOT EXISTS iam_role_scopes (
|
|
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
role_id BIGINT NOT NULL REFERENCES iam_roles(id) ON DELETE CASCADE,
|
|
scope_id BIGINT NOT NULL REFERENCES iam_scopes(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
-- 约束:唯一索引防止重复
|
|
UNIQUE (role_id, scope_id)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_iam_role_scopes_role ON iam_role_scopes (role_id);
|
|
CREATE INDEX IF NOT EXISTS idx_iam_role_scopes_scope ON iam_role_scopes (scope_id);
|
|
|
|
-- 用户-角色关联表 (iam_user_roles)
|
|
CREATE TABLE IF NOT EXISTS iam_user_roles (
|
|
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
user_id BIGINT NOT NULL REFERENCES iam_users(id) ON DELETE CASCADE,
|
|
role_id BIGINT NOT NULL REFERENCES iam_roles(id) ON DELETE CASCADE,
|
|
tenant_id BIGINT REFERENCES core_tenants(id),
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
granted_by BIGINT REFERENCES iam_users(id),
|
|
expires_at TIMESTAMPTZ,
|
|
|
|
-- 审计字段
|
|
request_id VARCHAR(64),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
-- 约束:唯一索引
|
|
UNIQUE (user_id, role_id, tenant_id)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_iam_user_roles_user ON iam_user_roles (user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_iam_user_roles_role ON iam_user_roles (role_id);
|
|
CREATE INDEX IF NOT EXISTS idx_iam_user_roles_tenant ON iam_user_roles (tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_iam_user_roles_active ON iam_user_roles (is_active);
|
|
CREATE INDEX IF NOT EXISTS idx_iam_user_roles_expires ON iam_user_roles (expires_at) WHERE expires_at IS NOT NULL;
|
|
|
|
-- 角色继承关系表 (iam_role_hierarchy)
|
|
-- 用于支持角色的继承关系,如 org_admin 继承自 super_admin
|
|
CREATE TABLE IF NOT EXISTS iam_role_hierarchy (
|
|
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
child_role_id BIGINT NOT NULL REFERENCES iam_roles(id) ON DELETE CASCADE,
|
|
parent_role_id BIGINT NOT NULL REFERENCES iam_roles(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
-- 约束:唯一索引
|
|
UNIQUE (child_role_id, parent_role_id),
|
|
-- 约束:防止自引用
|
|
CONSTRAINT chk_no_self_reference CHECK (child_role_id != parent_role_id)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_iam_role_hierarchy_child ON iam_role_hierarchy (child_role_id);
|
|
CREATE INDEX IF NOT EXISTS idx_iam_role_hierarchy_parent ON iam_role_hierarchy (parent_role_id);
|
|
|
|
-- 插入默认角色数据
|
|
INSERT INTO iam_roles (code, name, type, level, description, is_active) VALUES
|
|
('super_admin', '超级管理员', 'platform', 100, '平台超级管理员,拥有所有权限', TRUE),
|
|
('org_admin', '组织管理员', 'platform', 50, '组织管理员,管理整个组织', TRUE),
|
|
('supply_admin', '供应管理员', 'supply', 40, '供应管理员,管理供应链', TRUE),
|
|
('operator', '运营人员', 'platform', 30, '运营人员,执行日常操作', TRUE),
|
|
('developer', '开发人员', 'platform', 20, '开发人员,访问开发资源', TRUE),
|
|
('finops', '财务人员', 'platform', 20, '财务人员,访问账单和报表', TRUE),
|
|
('viewer', '只读用户', 'platform', 10, '只读用户,仅能查看资源', TRUE)
|
|
ON CONFLICT (code) DO NOTHING;
|
|
|
|
-- 插入默认Scope数据
|
|
INSERT INTO iam_scopes (code, name, category, description) VALUES
|
|
('*', '全部权限', 'generic', '超级管理员拥有的全部权限'),
|
|
('gateway.invoke', '网关调用', 'gateway', '调用网关API'),
|
|
('gateway.read', '网关读取', 'gateway', '读取网关配置'),
|
|
('gateway.write', '网关写入', 'gateway', '修改网关配置'),
|
|
('billing.read', '账单读取', 'billing', '读取账单信息'),
|
|
('billing.write', '账单写入', 'billing', '修改账单设置'),
|
|
('audit.read', '审计读取', 'audit', '读取审计日志'),
|
|
('audit.write', '审计写入', 'audit', '创建审计事件'),
|
|
('iam.read', 'IAM读取', 'iam', '读取IAM配置'),
|
|
('iam.write', 'IAM写入', 'iam', '修改IAM配置'),
|
|
('iam.admin', 'IAM管理', 'iam', '管理IAM所有设置')
|
|
ON CONFLICT (code) DO NOTHING;
|
|
|
|
-- 为超级管理员角色分配全部权限
|
|
INSERT INTO iam_role_scopes (role_id, scope_id)
|
|
SELECT r.id, s.id FROM iam_roles r, iam_scopes s
|
|
WHERE r.code = 'super_admin' AND s.code = '*'
|
|
ON CONFLICT DO NOTHING;
|
|
|
|
-- 为组织管理员分配主要管理权限
|
|
INSERT INTO iam_role_scopes (role_id, scope_id)
|
|
SELECT r.id, s.id FROM iam_roles r, iam_scopes s
|
|
WHERE r.code = 'org_admin' AND s.code IN ('gateway.invoke', 'gateway.read', 'billing.read', 'audit.read', 'iam.read')
|
|
ON CONFLICT DO NOTHING;
|
|
|
|
COMMIT;
|
|
|
|
-- 注释说明
|
|
COMMENT ON TABLE iam_roles IS '角色定义表,存储系统中的所有角色';
|
|
COMMENT ON TABLE iam_scopes IS '权限范围表,定义细粒度的权限';
|
|
COMMENT ON TABLE iam_role_scopes IS '角色与权限的关联表';
|
|
COMMENT ON TABLE iam_user_roles IS '用户与角色的关联表';
|
|
COMMENT ON TABLE iam_role_hierarchy IS '角色继承关系表';
|