feat: role CRUD
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
"""add system:role:view permission + grant it to admin
|
||||
|
||||
Revision ID: j4k5l6m7n8o9
|
||||
Revises: e1f2a3b4c5d6
|
||||
Create Date: 2026-08-25
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
from collections.abc import Sequence
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "j4k5l6m7n8o9"
|
||||
down_revision: str | Sequence[str] | None = "e1f2a3b4c5d6"
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
# ── seed constants ───────────────────────────────────────────────
|
||||
ADMIN_ROLE_ID = "0000000000000000000000000A"
|
||||
|
||||
PERMISSION_CODE = "system:role:view"
|
||||
PERMISSION_NAME = "查看角色管理"
|
||||
MODULE_CODE = "system"
|
||||
PERMISSION_DESCRIPTION = "查看角色管理与权限配置"
|
||||
|
||||
CROCKFORD_BASE32 = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
|
||||
|
||||
def _deterministic_permission_id(code: str) -> str:
|
||||
"""Stable 26-char ULID-shaped id derived from permission_code.
|
||||
|
||||
Mirrors ``e1f2a3b4c5d6_rebuild_baseline._deterministic_permission_id``
|
||||
so the id for a given code matches what the baseline would derive.
|
||||
"""
|
||||
digest = hashlib.sha256(
|
||||
f"model-platform-permission-v1:{code}".encode()
|
||||
).digest()
|
||||
value = int.from_bytes(b"\x00" * 6 + digest[:10], byteorder="big")
|
||||
encoded = ["0"] * 26
|
||||
for index in range(25, -1, -1):
|
||||
encoded[index] = CROCKFORD_BASE32[value & 31]
|
||||
value >>= 5
|
||||
return "".join(encoded)
|
||||
|
||||
def upgrade() -> None:
|
||||
"""Add system:role:view permission and grant it to admin only."""
|
||||
permission_id = _deterministic_permission_id(PERMISSION_CODE)
|
||||
|
||||
permissions_table = sa.table(
|
||||
"permissions",
|
||||
sa.column("permission_id", sa.CHAR(26)),
|
||||
sa.column("permission_code", sa.String(128)),
|
||||
sa.column("permission_name", sa.String(100)),
|
||||
sa.column("module_code", sa.String(64)),
|
||||
sa.column("description", sa.String(500)),
|
||||
)
|
||||
op.bulk_insert(
|
||||
permissions_table,
|
||||
[
|
||||
{
|
||||
"permission_id": permission_id,
|
||||
"permission_code": PERMISSION_CODE,
|
||||
"permission_name": PERMISSION_NAME,
|
||||
"module_code": MODULE_CODE,
|
||||
"description": PERMISSION_DESCRIPTION,
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
# admin 持有全部 system:*(沿用基线约定);developer 不授予 system:*.
|
||||
role_permissions_table = sa.table(
|
||||
"role_permissions",
|
||||
sa.column("role_id", sa.CHAR(26)),
|
||||
sa.column("permission_id", sa.CHAR(26)),
|
||||
)
|
||||
op.bulk_insert(
|
||||
role_permissions_table,
|
||||
[
|
||||
{
|
||||
"role_id": ADMIN_ROLE_ID,
|
||||
"permission_id": permission_id,
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
def downgrade() -> None:
|
||||
"""Remove admin's system:role:view grant and soft-delete the permission."""
|
||||
permission_id = _deterministic_permission_id(PERMISSION_CODE)
|
||||
|
||||
# 软删 role_permissions 关联行(与后端 soft-delete 约定一致).
|
||||
role_permissions_table = sa.table(
|
||||
"role_permissions",
|
||||
sa.column("role_id", sa.CHAR(26)),
|
||||
sa.column("permission_id", sa.CHAR(26)),
|
||||
sa.column("is_deleted", sa.Integer),
|
||||
sa.column("deleted_at", sa.DateTime),
|
||||
)
|
||||
op.execute(
|
||||
role_permissions_table.update()
|
||||
.where(role_permissions_table.c.role_id == ADMIN_ROLE_ID)
|
||||
.where(role_permissions_table.c.permission_id == permission_id)
|
||||
.where(role_permissions_table.c.is_deleted == 0)
|
||||
.values(is_deleted=1, deleted_at=sa.text("CURRENT_TIMESTAMP(3)"))
|
||||
)
|
||||
|
||||
# 软删 permissions 行(基线表含 is_deleted,优先软删除).
|
||||
permissions_table = sa.table(
|
||||
"permissions",
|
||||
sa.column("permission_id", sa.CHAR(26)),
|
||||
sa.column("is_deleted", sa.Integer),
|
||||
sa.column("deleted_at", sa.DateTime),
|
||||
)
|
||||
op.execute(
|
||||
permissions_table.update()
|
||||
.where(permissions_table.c.permission_id == permission_id)
|
||||
.where(permissions_table.c.is_deleted == 0)
|
||||
.values(is_deleted=1, deleted_at=sa.text("CURRENT_TIMESTAMP(3)"))
|
||||
)
|
||||
Reference in New Issue
Block a user