You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
6.7 KiB
Python
206 lines
6.7 KiB
Python
from enum import Enum
|
|
|
|
from admin_app.db.models import AuditLog
|
|
from admin_app.repositories import AuditLogRepository
|
|
|
|
|
|
class AdminAuditEventType(str, Enum):
|
|
STAFF_LOGIN_SUCCEEDED = "staff.login.succeeded"
|
|
STAFF_LOGIN_FAILED = "staff.login.failed"
|
|
STAFF_LOGOUT_SUCCEEDED = "staff.logout.succeeded"
|
|
STAFF_ACCOUNT_CREATED = "staff.account.created"
|
|
STAFF_ACCOUNT_STATUS_UPDATED = "staff.account.status.updated"
|
|
TOOL_APPROVAL_RECORDED = "tool.approval.recorded"
|
|
TOOL_PUBLICATION_RECORDED = "tool.publication.recorded"
|
|
|
|
|
|
class AdminAuditOutcome(str, Enum):
|
|
SUCCESS = "success"
|
|
FAILED = "failed"
|
|
|
|
|
|
class AuditService:
|
|
def __init__(self, repository: AuditLogRepository):
|
|
self.repository = repository
|
|
|
|
def record_event(
|
|
self,
|
|
*,
|
|
actor_staff_account_id: int | None,
|
|
event_type: AdminAuditEventType,
|
|
resource_type: str,
|
|
resource_id: str | None,
|
|
outcome: AdminAuditOutcome,
|
|
message: str | None,
|
|
payload_json: dict | None,
|
|
ip_address: str | None,
|
|
user_agent: str | None,
|
|
) -> AuditLog:
|
|
return self.repository.create(
|
|
actor_staff_account_id=actor_staff_account_id,
|
|
event_type=event_type.value,
|
|
resource_type=resource_type,
|
|
resource_id=resource_id,
|
|
outcome=outcome.value,
|
|
message=message,
|
|
payload_json=payload_json,
|
|
ip_address=ip_address,
|
|
user_agent=user_agent,
|
|
)
|
|
|
|
def record_login_succeeded(
|
|
self,
|
|
*,
|
|
actor_staff_account_id: int,
|
|
session_id: int,
|
|
email: str,
|
|
role: str,
|
|
ip_address: str | None,
|
|
user_agent: str | None,
|
|
) -> AuditLog:
|
|
return self.record_event(
|
|
actor_staff_account_id=actor_staff_account_id,
|
|
event_type=AdminAuditEventType.STAFF_LOGIN_SUCCEEDED,
|
|
resource_type="staff_account",
|
|
resource_id=str(actor_staff_account_id),
|
|
outcome=AdminAuditOutcome.SUCCESS,
|
|
message="Login administrativo concluido.",
|
|
payload_json={"session_id": session_id, "email": email, "role": role},
|
|
ip_address=ip_address,
|
|
user_agent=user_agent,
|
|
)
|
|
|
|
def record_login_failed(
|
|
self,
|
|
*,
|
|
email: str,
|
|
ip_address: str | None,
|
|
user_agent: str | None,
|
|
) -> AuditLog:
|
|
return self.record_event(
|
|
actor_staff_account_id=None,
|
|
event_type=AdminAuditEventType.STAFF_LOGIN_FAILED,
|
|
resource_type="staff_account",
|
|
resource_id=email,
|
|
outcome=AdminAuditOutcome.FAILED,
|
|
message="Tentativa de login administrativo falhou.",
|
|
payload_json={"email": email},
|
|
ip_address=ip_address,
|
|
user_agent=user_agent,
|
|
)
|
|
|
|
def record_logout_succeeded(
|
|
self,
|
|
*,
|
|
actor_staff_account_id: int,
|
|
session_id: int,
|
|
ip_address: str | None,
|
|
user_agent: str | None,
|
|
) -> AuditLog:
|
|
return self.record_event(
|
|
actor_staff_account_id=actor_staff_account_id,
|
|
event_type=AdminAuditEventType.STAFF_LOGOUT_SUCCEEDED,
|
|
resource_type="staff_session",
|
|
resource_id=str(session_id),
|
|
outcome=AdminAuditOutcome.SUCCESS,
|
|
message="Sessao administrativa encerrada.",
|
|
payload_json={"session_id": session_id},
|
|
ip_address=ip_address,
|
|
user_agent=user_agent,
|
|
)
|
|
|
|
def record_staff_account_created(
|
|
self,
|
|
*,
|
|
actor_staff_account_id: int,
|
|
created_staff_account_id: int,
|
|
email: str,
|
|
role: str,
|
|
ip_address: str | None,
|
|
user_agent: str | None,
|
|
) -> AuditLog:
|
|
return self.record_event(
|
|
actor_staff_account_id=actor_staff_account_id,
|
|
event_type=AdminAuditEventType.STAFF_ACCOUNT_CREATED,
|
|
resource_type="staff_account",
|
|
resource_id=str(created_staff_account_id),
|
|
outcome=AdminAuditOutcome.SUCCESS,
|
|
message="Conta administrativa de colaborador criada.",
|
|
payload_json={
|
|
"created_staff_account_id": created_staff_account_id,
|
|
"email": email,
|
|
"role": role,
|
|
},
|
|
ip_address=ip_address,
|
|
user_agent=user_agent,
|
|
)
|
|
|
|
def record_staff_account_status_updated(
|
|
self,
|
|
*,
|
|
actor_staff_account_id: int,
|
|
target_staff_account_id: int,
|
|
is_active: bool,
|
|
ip_address: str | None,
|
|
user_agent: str | None,
|
|
) -> AuditLog:
|
|
return self.record_event(
|
|
actor_staff_account_id=actor_staff_account_id,
|
|
event_type=AdminAuditEventType.STAFF_ACCOUNT_STATUS_UPDATED,
|
|
resource_type="staff_account",
|
|
resource_id=str(target_staff_account_id),
|
|
outcome=AdminAuditOutcome.SUCCESS,
|
|
message="Status de colaborador administrativo atualizado.",
|
|
payload_json={
|
|
"target_staff_account_id": target_staff_account_id,
|
|
"is_active": is_active,
|
|
},
|
|
ip_address=ip_address,
|
|
user_agent=user_agent,
|
|
)
|
|
|
|
def record_tool_approval(
|
|
self,
|
|
*,
|
|
actor_staff_account_id: int,
|
|
tool_name: str,
|
|
tool_version: int,
|
|
ip_address: str | None,
|
|
user_agent: str | None,
|
|
) -> AuditLog:
|
|
return self.record_event(
|
|
actor_staff_account_id=actor_staff_account_id,
|
|
event_type=AdminAuditEventType.TOOL_APPROVAL_RECORDED,
|
|
resource_type="tool_publication",
|
|
resource_id=tool_name,
|
|
outcome=AdminAuditOutcome.SUCCESS,
|
|
message="Aprovacao de tool registrada.",
|
|
payload_json={"tool_name": tool_name, "tool_version": tool_version},
|
|
ip_address=ip_address,
|
|
user_agent=user_agent,
|
|
)
|
|
|
|
def record_tool_publication(
|
|
self,
|
|
*,
|
|
actor_staff_account_id: int,
|
|
tool_name: str,
|
|
tool_version: int,
|
|
ip_address: str | None,
|
|
user_agent: str | None,
|
|
) -> AuditLog:
|
|
return self.record_event(
|
|
actor_staff_account_id=actor_staff_account_id,
|
|
event_type=AdminAuditEventType.TOOL_PUBLICATION_RECORDED,
|
|
resource_type="tool_publication",
|
|
resource_id=tool_name,
|
|
outcome=AdminAuditOutcome.SUCCESS,
|
|
message="Publicacao de tool registrada.",
|
|
payload_json={"tool_name": tool_name, "tool_version": tool_version},
|
|
ip_address=ip_address,
|
|
user_agent=user_agent,
|
|
)
|
|
|
|
def list_recent(self, limit: int = 50) -> list[AuditLog]:
|
|
return self.repository.list_recent(limit=limit)
|