签入版本
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
"""超管账号与内置角色写保护: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
|
||||
Reference in New Issue
Block a user