82 lines
3.1 KiB
Python
82 lines
3.1 KiB
Python
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from exceptions.exception import PermissionException
|
|
from module_admin.entity.vo.user_vo import CurrentUserModel
|
|
from module_business.dao.test_batch_dao import TestBatchDao
|
|
from module_business.domain.enums import TestBatchStatus
|
|
from module_business.domain.test_batch_scope import TestBatchScope
|
|
from module_business.entity.do.test_batch_do import BizTestBatch
|
|
|
|
|
|
class TestBatchAccessService:
|
|
"""测试批次作用域与管理权限校验。"""
|
|
|
|
@staticmethod
|
|
def _is_super_admin(current_user: CurrentUserModel) -> bool:
|
|
return current_user.user is not None and current_user.user.admin is True
|
|
|
|
@staticmethod
|
|
def _raise_unavailable() -> None:
|
|
raise PermissionException({'reason': 'TEST_BATCH_UNAVAILABLE'}, '当前测试批次不可用')
|
|
|
|
@staticmethod
|
|
def _raise_closed() -> None:
|
|
raise PermissionException({'reason': 'TEST_BATCH_UNAVAILABLE'}, '当前测试批次已关闭')
|
|
|
|
@classmethod
|
|
def assert_super_admin(cls, current_user: CurrentUserModel) -> None:
|
|
"""确保当前用户由超级管理员标记明确授信。"""
|
|
if not cls._is_super_admin(current_user):
|
|
raise PermissionException('', '仅超级管理员可执行测试批次管理操作')
|
|
|
|
@classmethod
|
|
async def resolve_scope(
|
|
cls,
|
|
db: AsyncSession,
|
|
current_user: CurrentUserModel,
|
|
batch_id: int | None,
|
|
*,
|
|
write: bool = False,
|
|
) -> TestBatchScope:
|
|
"""解析并验证业务请求可使用的数据作用域。"""
|
|
if batch_id is None:
|
|
return TestBatchScope.formal()
|
|
|
|
batch = await TestBatchDao.get_batch(db, batch_id)
|
|
if batch is None or batch.status == TestBatchStatus.PURGED.value:
|
|
cls._raise_unavailable()
|
|
|
|
if not cls._is_super_admin(current_user):
|
|
user_id = current_user.user.user_id if current_user.user is not None else None
|
|
if user_id is None or not await TestBatchDao.user_is_authorized(db, batch_id, user_id):
|
|
cls._raise_unavailable()
|
|
|
|
if batch.status == TestBatchStatus.CLOSED.value:
|
|
if write:
|
|
cls._raise_closed()
|
|
cls._raise_unavailable()
|
|
if batch.status != TestBatchStatus.ACTIVE.value:
|
|
cls._raise_unavailable()
|
|
|
|
return TestBatchScope(
|
|
batch_id=batch_id,
|
|
mode='TEST',
|
|
status=TestBatchStatus.ACTIVE,
|
|
writable=True,
|
|
)
|
|
|
|
@classmethod
|
|
async def lock_active_batch(cls, db: AsyncSession, scope: TestBatchScope) -> BizTestBatch | None:
|
|
"""在写入前锁定并重新确认测试批次仍为 ACTIVE。"""
|
|
if scope.mode == 'FORMAL':
|
|
return None
|
|
|
|
batch = await TestBatchDao.get_batch_for_update(db, scope.batch_id)
|
|
if batch is None or batch.status == TestBatchStatus.PURGED.value:
|
|
cls._raise_unavailable()
|
|
if batch.status == TestBatchStatus.CLOSED.value:
|
|
cls._raise_closed()
|
|
if batch.status != TestBatchStatus.ACTIVE.value:
|
|
cls._raise_unavailable()
|
|
return batch
|