116 lines
3.7 KiB
Python
116 lines
3.7 KiB
Python
"""超管账号与内置角色写保护:user id==1 与内置角色(种子数据)禁止被管理写操作影响。"""
|
|
import asyncio
|
|
import json
|
|
import types
|
|
|
|
from core import R
|
|
from core.base_service import BaseService
|
|
|
|
import modules.system.user.service as user_service
|
|
import modules.system.role.service as role_service
|
|
from modules.system.role.repository import role_repo
|
|
|
|
|
|
def _body(result):
|
|
return json.loads(result.body)
|
|
|
|
|
|
# ============ 超管账号(user id==1)写保护 ============
|
|
|
|
def test_delete_user_blocks_superadmin():
|
|
result = asyncio.run(user_service.delete_user('1'))
|
|
assert _body(result)['ok'] is False
|
|
assert '超管' in _body(result)['msg']
|
|
|
|
|
|
def test_delete_user_allows_normal_user(monkeypatch):
|
|
# 屏蔽会话与批量删除,仅验证非超管不会被误拦
|
|
class _FakeDelete:
|
|
def delete(self, *a, **k):
|
|
return 1
|
|
|
|
class _FakeQuery:
|
|
def filter(self, *a, **k):
|
|
return _FakeDelete()
|
|
|
|
monkeypatch.setattr(user_service, 'get_db_session',
|
|
lambda: types.SimpleNamespace(query=lambda m: _FakeQuery()))
|
|
|
|
captured = {}
|
|
|
|
def fake_batch_delete(repo, ids):
|
|
captured['ids'] = ids
|
|
return R.ok(msg="本次共删除{0}条数据".format(1))
|
|
|
|
monkeypatch.setattr(BaseService, 'batch_delete_with_r', staticmethod(fake_batch_delete))
|
|
|
|
async def fake_invalidate(uid):
|
|
pass
|
|
|
|
monkeypatch.setattr(user_service, 'invalidate_user_perms', fake_invalidate)
|
|
|
|
result = asyncio.run(user_service.delete_user('2'))
|
|
assert _body(result)['ok'] is True
|
|
assert captured['ids'] == '2'
|
|
|
|
|
|
def test_update_user_blocks_superadmin(fake_request):
|
|
result = asyncio.run(user_service.update_user(fake_request, types.SimpleNamespace(id=1)))
|
|
assert _body(result)['ok'] is False
|
|
assert '超管' in _body(result)['msg']
|
|
|
|
|
|
def test_update_user_status_blocks_superadmin(fake_request):
|
|
result = asyncio.run(
|
|
user_service.update_user_status(fake_request, types.SimpleNamespace(id=1, status=2)))
|
|
assert _body(result)['ok'] is False
|
|
assert '超管' in _body(result)['msg']
|
|
|
|
|
|
def test_reset_user_pwd_blocks_superadmin(fake_request):
|
|
result = user_service.reset_user_pwd(fake_request, types.SimpleNamespace(id=1))
|
|
assert _body(result)['ok'] is False
|
|
assert '超管' in _body(result)['msg']
|
|
|
|
|
|
def test_reset_user_pwd_allows_normal_user(monkeypatch, fake_request):
|
|
monkeypatch.setattr(user_service.user_repo, 'get_by_id', lambda uid: object())
|
|
monkeypatch.setattr(user_service.user_repo, 'update', lambda uid, fields: True)
|
|
result = user_service.reset_user_pwd(fake_request, types.SimpleNamespace(id=2))
|
|
assert _body(result)['ok'] is True
|
|
|
|
|
|
# ============ 内置角色写保护 ============
|
|
|
|
def test_delete_role_blocks_builtin():
|
|
result = asyncio.run(role_service.delete_role('1'))
|
|
assert _body(result)['ok'] is False
|
|
assert '内置' in _body(result)['msg']
|
|
|
|
|
|
def test_delete_role_blocks_mixed_builtin():
|
|
# 批量删除中混入内置角色 → 整体拒绝
|
|
result = asyncio.run(role_service.delete_role('2,5'))
|
|
assert _body(result)['ok'] is False
|
|
assert '内置' in _body(result)['msg']
|
|
|
|
|
|
def test_delete_role_allows_normal_role(monkeypatch, sqlite_db):
|
|
class _FakeRecord:
|
|
is_delete = 0
|
|
|
|
class _FakeQuery:
|
|
def all(self):
|
|
return [_FakeRecord()]
|
|
|
|
monkeypatch.setattr(role_repo, 'filter', lambda *a, **k: _FakeQuery())
|
|
|
|
async def fake_invalidate(rid):
|
|
pass
|
|
|
|
monkeypatch.setattr(role_service, 'invalidate_role_perms', fake_invalidate)
|
|
|
|
# sqlite_db 提供请求级 DB 会话(delete_role 会清理 user_role/role_menu 关联)
|
|
result = asyncio.run(role_service.delete_role('5'))
|
|
assert _body(result)['ok'] is True
|