| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- """用实际授权 INSERT 验证迁移:停用/隐藏入口不得派生维护权限。"""
- from pathlib import Path
- import re
- import sqlite3
- from uuid import uuid4
- import pytest
- MIGRATION = Path(__file__).resolve().parents[2] / 'docs/sql/migrations/2026-10-26-manual-dispatch-calendar.sql'
- def database(prefix, *, existing_target=True):
- db = sqlite3.connect(':memory:')
- db.create_function('UUID', 0, lambda: str(uuid4()))
- db.create_function('NOW', 0, lambda: '2026-10-26 12:00:00')
- common = "tenant_no TEXT DEFAULT 't1', order_num INT, remark TEXT, create_by TEXT, create_dept_id TEXT, create_time TEXT, update_time TEXT, del_flag INT DEFAULT 0"
- db.execute(f"CREATE TABLE sys_menu (id TEXT PRIMARY KEY, menu_name TEXT, parent_id TEXT DEFAULT '0', menu_type TEXT, path TEXT, component TEXT, perms TEXT, is_frame INT, visible TEXT DEFAULT '1', status TEXT DEFAULT '1', {common})")
- db.execute(f"CREATE TABLE sys_role (id TEXT PRIMARY KEY, status TEXT DEFAULT '1', {common})")
- db.execute(f"CREATE TABLE sys_role_menu (id TEXT PRIMARY KEY, role_id TEXT, menu_id TEXT, {common})")
- def menu(record_id, parent_id, path=None, perms=None):
- db.execute('INSERT INTO sys_menu (id,parent_id,path,perms) VALUES (?,?,?,?)', (record_id, parent_id, path, perms))
- is_web = prefix == 'pl'
- menu('root', '0', '/web' if is_web else '/mini')
- menu('parent', 'root', '/pl' if is_web else '/mini/pl')
- if is_web:
- menu('folder', 'parent', 'calendar-module')
- menu('leaf', 'folder' if is_web else 'parent', perms=prefix + ':dispatch-calendar:list')
- menu('source', 'parent', perms='pl:plan:list' if is_web else 'mini:pl:plan:manage')
- if existing_target:
- menu('target', 'leaf', perms=prefix + ':dispatch-calendar:manage')
- db.execute("INSERT INTO sys_role (id) VALUES ('r1')")
- db.execute("INSERT INTO sys_role_menu (id,role_id,menu_id) VALUES ('calendar-grant','r1','leaf')")
- db.execute("INSERT INTO sys_role_menu (id,role_id,menu_id) VALUES ('source-grant','r1','source')")
- return db
- def migrate(db):
- for sql in re.findall(r'INSERT INTO sys_(?:menu|role_menu)\s*\(.*?;', MIGRATION.read_text(), re.S):
- db.execute(sql)
- def grants(db):
- return db.execute("SELECT COUNT(*) FROM sys_role_menu rm JOIN sys_menu m ON m.id=rm.menu_id WHERE m.perms LIKE '%dispatch-calendar:manage' AND rm.del_flag=0").fetchone()[0]
- @pytest.mark.parametrize('prefix,part', [(prefix, part) for prefix in ['pl', 'mini:pl']
- for part in ['source', 'leaf', 'parent', 'root', 'target']]
- + [('pl', 'folder')])
- @pytest.mark.parametrize('field', ['status', 'visible'])
- def test_inactive_menu_cannot_grant_manage(prefix, part, field):
- with database(prefix) as db:
- db.execute(f'UPDATE sys_menu SET {field}=? WHERE id=?', ('0', part))
- migrate(db)
- assert grants(db) == 0
- @pytest.mark.parametrize('prefix', ['pl', 'mini:pl'])
- def test_active_permissions_are_granted_once_and_revocation_is_preserved(prefix):
- with database(prefix, existing_target=False) as db:
- migrate(db)
- migrate(db)
- assert grants(db) == 1
- db.execute("UPDATE sys_role_menu SET del_flag=1 WHERE menu_id IN (SELECT id FROM sys_menu WHERE perms LIKE '%dispatch-calendar:manage')")
- migrate(db)
- assert grants(db) == 0
- assert db.execute("SELECT COUNT(*) FROM sys_role_menu WHERE del_flag=1").fetchone()[0] == 1
- @pytest.mark.parametrize('prefix', ['pl', 'mini:pl'])
- @pytest.mark.parametrize('part', ['leaf', 'parent', 'root'])
- def test_inactive_calendar_ancestors_do_not_create_manage_menu(prefix, part):
- with database(prefix, existing_target=False) as db:
- db.execute('UPDATE sys_menu SET status=? WHERE id=?', ('0', part))
- migrate(db)
- assert db.execute("SELECT COUNT(*) FROM sys_menu WHERE perms LIKE '%dispatch-calendar:manage'").fetchone()[0] == 0
|