Files
2026-08-26 14:11:37 +07:00

1105 lines
25 KiB
Python

from pydantic import BaseModel, EmailStr, field_validator
from typing import Optional, List, Any
import datetime
from enum import Enum
# Role & Permission
class RoleBase(BaseModel):
name: str
description: Optional[str] = None
class RoleCreate(RoleBase):
pass
class Role(RoleBase):
id: int
class Config:
from_attributes = True
class SecurityIndexBase(BaseModel):
soc: int = 0
pentest: int = 0
access_policy: int = 0
two_fa_policy: int = 0
config_network: int = 0
config_server: int = 0
patch_security: int = 0
month_id: int
unit_id: int
description: Optional[str] = None
class SecurityIndexCreate(SecurityIndexBase):
pass
class SecurityIndex(SecurityIndexBase):
id: int
created_at: datetime.datetime
class Config:
from_attributes = True
class SecurityIndexDetail(SecurityIndex):
unit_name: Optional[str] = None
at1: float = 0
at2: float = 0
at: float = 0
rank: Optional[int] = None
# class PermissionBase và PermissionCreate giữ nguyên
class PermissionBase(BaseModel):
name: str
path: str
method: str
description: Optional[str] = None
class PermissionCreate(PermissionBase):
pass
class Permission(PermissionBase):
id: int
created_at: datetime.datetime
class Config:
from_attributes = True
# Units & Users
class UnitBase(BaseModel):
name: str
description: Optional[str] = None
class UnitCreate(UnitBase):
pass
class Unit(UnitBase):
id: int
class Config:
from_attributes = True
class UserBase(BaseModel):
email: EmailStr
fullname: str
unit_id: Optional[int] = None
role_id: Optional[int] = None
class UserCreate(UserBase):
password: Optional[str] = None
class User(UserBase):
id: int
status: int
created_at: datetime.datetime
updated_at: datetime.datetime
class Config:
from_attributes = True
class UserUpdate(BaseModel):
email: Optional[EmailStr] = None
fullname: Optional[str] = None
unit_id: Optional[int] = None
status: Optional[int] = None
password: Optional[str] = None
role_id: Optional[int] = None
# Category & Posts
class CategoryBase(BaseModel):
name: str
class CategoryCreate(CategoryBase):
pass
class Category(CategoryBase):
id: int
class Config:
from_attributes = True
class PostBase(BaseModel):
content: str
title: str
created_by: Optional[int] = None
category_id: Optional[int] = None
status: Optional[bool] = True
thumbnail: Optional[str] = None
thumbnail_base64: Optional[str] = None
thumbnail_filename: Optional[str] = None
class PostCreate(PostBase):
pass
class PostUpdate(BaseModel):
content: Optional[str] = None
title: Optional[str] = None
created_by: Optional[int] = None
category_id: Optional[int] = None
status: Optional[bool] = None
thumbnail: Optional[str] = None
thumbnail_base64: Optional[str] = None
thumbnail_filename: Optional[str] = None
class Post(PostBase):
id: int
created_at: datetime.datetime
class Config:
from_attributes = True
class PostResponse(Post):
created_by_name: Optional[str] = None
files: Optional[List[str]] = None
class Config:
from_attributes = True
# Month & stats
class MonthBase(BaseModel):
name: str
from_date: datetime.datetime
end_date: datetime.datetime
class MonthCreate(MonthBase):
pass
class Month(MonthBase):
id: int
class Config:
from_attributes = True
# Generic small stat create schemas
class NACCreate(BaseModel):
month_id: int
unit_id: int
total: Optional[int] = 0
installed: Optional[int] = 0
ignored: Optional[int] = 0
class NAC(BaseModel):
id: int
month_id: int
unit_id: int
total: int
installed: int
ignored: int
rate: float
created_at: datetime.datetime
class Config:
from_attributes = True
# Ticket / others
class TicketCreate(BaseModel):
unit_id: int
month_id: int
open_count: Optional[int] = 0
in_process: Optional[int] = 0
completed: Optional[int] = 0
class Ticket(BaseModel):
id: int
open_count: int
in_process: int
completed: int
unit_id: int
month_id: int
created_at: datetime.datetime
class Config:
from_attributes = True
# Mail and uploads
class MailHistoryCreate(BaseModel):
post_id: Optional[int]
subject: Optional[str] = None
role_id: Optional[int] = None
content: Optional[str]
status: Optional[int] = None
class MailHistory(BaseModel):
id: int
post_id: Optional[int] = None
subject: Optional[str] = None
role_id: Optional[int] = None
content: Optional[str] = None
status: Optional[int] = None
created_at: datetime.datetime
class Config:
from_attributes = True
class MailHistoryUpdate(BaseModel):
post_id: Optional[int] = None
subject: Optional[str] = None
role_id: Optional[int] = None
content: Optional[str] = None
status: Optional[int] = None
class FileUploadCreate(BaseModel):
path: str
table_name: str
table_id: int
class ImportHistoryCreate(BaseModel):
type: str
file_path: str
month_id: int
class ImportHistory(BaseModel):
id: int
type: str
file_path: str
month_id: int
created_at: datetime.datetime
class Config:
from_attributes = True
# Auth
class LoginRequest(BaseModel):
email: EmailStr
password: str
class LoginSSORequest(BaseModel):
email: EmailStr
password: str
otp: Optional[str] = None
class UserLoginResponse(BaseModel):
"""User info returned in login response with additional details."""
id: int
email: EmailStr
fullname: str
unit_id: Optional[int] = None
unit_name: Optional[str] = None
role_id: Optional[int] = None
role_name: Optional[str] = None
status: int
status_name: str
created_at: datetime.datetime
updated_at: datetime.datetime
class LoginResponse(BaseModel):
access_token: str
token_type: str = "bearer"
user: UserLoginResponse
class Config:
from_attributes = True
class APIResponse(BaseModel):
message: str
data: Optional[object] = None
class SystemGroupBase(BaseModel):
name: str
description: Optional[str] = None
class SystemGroupCreate(SystemGroupBase):
pass
class SystemGroupUpdate(BaseModel):
name: Optional[str] = None
description: Optional[str] = None
class SystemGroup(SystemGroupBase):
id: int
class Config:
from_attributes = True
# Pentest Service
class PentestServiceBase(BaseModel):
name: str
type: int
description: Optional[str] = None
due_date: Optional[datetime.datetime] = None
unit_id: Optional[int] = None
target_id: Optional[int] = None
class PentestServiceCreate(PentestServiceBase):
user_id: Optional[int] = None
list_process: Optional[List[int]] = None
other_assign: Optional[List[str]] = None
class PentestServiceUpdate(BaseModel):
name: Optional[str] = None
type: Optional[int] = None
description: Optional[str] = None
due_date: Optional[datetime.datetime] = None
status: Optional[int] = None
target_id: Optional[int] = None
unit_id: Optional[int] = None
user_id: Optional[int] = None
list_process: Optional[List[int]] = None
other_assign: Optional[List[str]] = None
class PentestService(PentestServiceBase):
id: int
code: str
file_path: Optional[str] = None
status: int
status_name: Optional[str] = None
unit_name: Optional[str] = None
user_id: Optional[int] = None
user_fullname: Optional[str] = None
list_assign: Optional[List[str]] = None
list_assign_name: Optional[List[str]] = None
other_assign: Optional[str] = None
created_at: datetime.datetime
created_at_str: Optional[str] = None
due_date_str: Optional[str] = None
class Config:
from_attributes = True
# SOC Target
class SocTargetAssignBase(BaseModel):
user_id: Optional[int] = None
email: Optional[str] = None
class SocTargetAssignCreate(SocTargetAssignBase):
pass
class SocTargetAssign(SocTargetAssignBase):
id: int
target_id: int
name: Optional[str] = None
created_at: datetime.datetime
class Config:
from_attributes = True
class SocTargetAttachmentBase(BaseModel):
file_name: str
file_path: str
file_size: Optional[int] = None
file_type: Optional[str] = None
class SocTargetAttachmentCreate(SocTargetAttachmentBase):
pass
class SocTargetAttachment(SocTargetAttachmentBase):
id: int
target_id: int
uploaded_by: Optional[int] = None
created_at: datetime.datetime
class Config:
from_attributes = True
class SocTargetCommentBase(BaseModel):
content: str
user_id: Optional[int] = None
email: Optional[str] = None
class SocTargetCommentCreate(SocTargetCommentBase):
pass
class SocTargetComment(SocTargetCommentBase):
id: Any
target_id: Any
name: Optional[str] = None
created_at: datetime.datetime
updated_at: datetime.datetime
class Config:
from_attributes = True
class SocTargetHistoryBase(BaseModel):
field_name: str
old_value: Optional[str] = None
new_value: Optional[str] = None
class SocTargetHistory(SocTargetHistoryBase):
id: Any
target_id: Any
changed_by: Optional[int] = None
changed_by_name: Optional[str] = None
changed_at: datetime.datetime
class Config:
from_attributes = True
class SocTargetTypeBase(BaseModel):
name: str
class SocTargetType(SocTargetTypeBase):
id: int
class Config:
from_attributes = True
class TicketRelatedBase(BaseModel):
soc_target_id: int
related_soc_target_id: int
class TicketRelated(TicketRelatedBase):
id: int
created_at: datetime.datetime
related_ticket_name: Optional[str] = None
related_ticket_code: Optional[str] = None
class Config:
from_attributes = True
class SocTargetBase(BaseModel):
unit_id: int
priority: int
name: str
code: Optional[str] = None
status: int = 0
deadline: Optional[datetime.datetime] = None
description: str
system_id: Optional[int] = None
system_type: Optional[int] = None
source_ip: Optional[str] = None
destination_ip: Optional[str] = None
soc_target_type_id: Optional[int] = None
class SocTargetCreate(SocTargetBase):
assign_internal: Optional[str] = None
assign_external: Optional[str] = None
related_ticket_ids: Optional[str] = None # CSV string of related ticket IDs
class SocTargetUpdate(BaseModel):
unit_id: Optional[int] = None
priority: Optional[int] = None
name: Optional[str] = None
status: Optional[int] = None
deadline: Optional[datetime.datetime] = None
description: Optional[str] = None
system_id: Optional[int] = None
system_type: Optional[int] = None
source_ip: Optional[str] = None
destination_ip: Optional[str] = None
soc_target_type_id: Optional[int] = None
assign_internal: Optional[str] = None
assign_external: Optional[str] = None
related_ticket_ids: Optional[str] = None # CSV string of related ticket IDs
class SocTarget(SocTargetBase):
id: Any
created_at: datetime.datetime
updated_at: datetime.datetime
created_by: Optional[int] = None
class Config:
from_attributes = True
class SocTargetDetail(SocTarget):
unit_name: Optional[str] = None
system_name: Optional[str] = None
system_type_name: Optional[str] = None
soc_type_name: Optional[str] = None
created_by_name: Optional[str] = None
updated_by_name: Optional[str] = None
assignees: List[SocTargetAssign] = []
attachments: List[SocTargetAttachment] = []
related_list: List[TicketRelated] = []
sla_status: Optional[str] = None # overdue, on_time, near_deadline
class Config:
from_attributes = True
class SocTargetPagination(BaseModel):
items: List[SocTargetDetail]
total: int
page: int
size: int
pages: int
class PentestServiceCommentBase(BaseModel):
content: str
pentest_service_id: int
class PentestServiceCommentAdd(BaseModel):
content: str
class PentestServiceCommentCreate(PentestServiceCommentBase):
pass
class PentestServiceComment(PentestServiceCommentBase):
id: int
user_id: int
created_at: datetime.datetime
user_fullname: Optional[str] = None
class Config:
from_attributes = True
class PentestServiceHistory(BaseModel):
id: int
pentest_service_id: int
old_status: Optional[int] = None
new_status: int
user_id: int
created_at: datetime.datetime
user_fullname: Optional[str] = None
old_status_name: Optional[str] = None
new_status_name: Optional[str] = None
class Config:
from_attributes = True
count: Optional[int] = None
# Post Comments
class PostCommentBase(BaseModel):
content: str
class PostCommentCreate(PostCommentBase):
pass
class PostCommentUpdate(PostCommentBase):
pass
class PostComment(PostCommentBase):
id: int
post_id: int
user_id: int
created_at: datetime.datetime
updated_at: datetime.datetime
user_fullname: Optional[str] = None
class Config:
from_attributes = True
class Config:
from_attributes = True
class SystemBase(BaseModel):
name: str
url_ip: Optional[str] = None
unit_id: Optional[int] = None
system_group_id: Optional[int] = None
description: Optional[str] = None
status: Optional[int] = None
class SystemCreate(SystemBase):
pass
class SystemUpdate(BaseModel):
name: Optional[str] = None
url_ip: Optional[str] = None
unit_id: Optional[int] = None
system_group_id: Optional[int] = None
description: Optional[str] = None
status: Optional[int] = None
class System(BaseModel):
id: int
name: str
url_ip: Optional[str] = None
unit_id: Optional[int] = None
system_group_id: Optional[int] = None
description: Optional[str] = None
status: Optional[int] = None
unit_name: Optional[str] = None
system_group_name: Optional[str] = None
class Config:
from_attributes = True
# Response wrappers for SystemGroup APIs
class SystemGroupResponse(BaseModel):
message: str
data: SystemGroup
class SystemGroupListResponse(BaseModel):
message: str
data: List[SystemGroup]
# Response wrappers for System APIs
class SystemResponse(BaseModel):
message: str
data: System
class SystemListResponse(BaseModel):
message: str
data: List[System]
class ManageSystemBase(BaseModel):
name: str
level: int
url_ip: Optional[str] = None
unit_id: Optional[int] = None
parent_id: Optional[int] = None
type: Optional[int] = None
private: Optional[bool] = None
priority_level: Optional[int] = None
status: Optional[bool] = None
@field_validator("unit_id", "parent_id", "type", "priority_level", mode="before")
def _coerce_int_optional(cls, v):
if v is None:
return None
if isinstance(v, str) and v.strip() == "":
return None
return v
@field_validator("private", "status", mode="before")
def _coerce_bool_optional(cls, v):
if v is None:
return None
if isinstance(v, str) and v.strip() == "":
return None
return v
class ManageSystemCreate(ManageSystemBase):
pass
class ManageSystemUpdate(BaseModel):
name: Optional[str] = None
level: Optional[int] = None
url_ip: Optional[str] = None
unit_id: Optional[int] = None
parent_id: Optional[int] = None
type: Optional[int] = None
private: Optional[bool] = None
priority_level: Optional[int] = None
status: Optional[bool] = None
class ManageSystem(BaseModel):
id: int
name: str
level: int
url_ip: Optional[str] = None
unit_id: Optional[int] = None
unit_name: Optional[str] = None
parent_id: Optional[int] = None
parent_name: Optional[str] = None
type: Optional[int] = None
private: Optional[bool] = None
priority_level: Optional[int] = None
status: Optional[bool] = None
created_at: datetime.datetime
updated_at: datetime.datetime
class Config:
from_attributes = True
class ManageSystemResponse(BaseModel):
message: str
data: ManageSystem
class ManageSystemListResponse(BaseModel):
message: str
data: List[ManageSystem]
class ManageSystemImportRowError(BaseModel):
row: int
error: str
class ManageSystemImportResponse(BaseModel):
message: str
total: int
upserted: int
failed: int
errors: List[ManageSystemImportRowError] = []
class SystemImportRowError(BaseModel):
row: int
error: str
class SystemImportResponse(BaseModel):
message: str
total: int
inserted: int
failed: int
errors: List[SystemImportRowError] = []
# Dùng chung cho delete (nếu chưa có ở file, thêm vào)
class DeleteResponse(BaseModel):
message: str
deleted: bool
class LogSourceCreate(BaseModel):
month_id: int
unit_id: int
name: str
log_id: Optional[int] = None
description: Optional[str] = None
is_enabled: Optional[bool] = True
source_type_id: Optional[int] = None
status: Optional[int] = None # 1=OK, 2=ERROR, 3=DISABLE, 4=NOT AVAILABLE
message: Optional[str] = None
other: Optional[str] = None
file_id: Optional[int] = None
created_at: Optional[datetime.datetime] = None
class LogSource(BaseModel):
id: int
month_id: int
unit_id: int
unit_name: Optional[str] = None
log_id: Optional[int] = None
name: str
description: Optional[str] = None
is_enabled: Optional[bool] = True
source_type_id: Optional[int] = None
status: Optional[int] = None # trả về mã số
source_type_name: Optional[str] = None
status_name: Optional[str] = None
message: Optional[str] = None
other: Optional[str] = None
file_id: Optional[int] = None
created_at: datetime.datetime
class Config:
from_attributes = True
class LogSourceCommentBase(BaseModel):
comment: str
class LogSourceCommentCreate(LogSourceCommentBase):
logsource_id: int
class LogSourceComment(LogSourceCommentBase):
id: int
logsource_id: int
user_id: int
user_fullname: Optional[str] = None
created_at: datetime.datetime
class Config:
from_attributes = True
class LogSourceImportRowError(BaseModel):
row: int
error: str
class LogSourceImportResponse(BaseModel):
message: str
total: int
inserted: int
failed: int
errors: List[LogSourceImportRowError] = []
class SmartIRDetailCreate(BaseModel):
month_id: int
unit_id: Optional[int] = None
vnpt_ma_nhan_vien: Optional[str] = None
name: Optional[str] = None
email: Optional[str] = None
phong_ban: Optional[str] = None
ip: Optional[str] = None
pc_name: Optional[str] = None
mac: Optional[str] = None
agent_version: Optional[str] = None
last_online: Optional[str] = None
status: Optional[int] = None
class SmartIRDetail(BaseModel):
id: int
month_id: int
unit_id: Optional[int] = None
unit_name: Optional[str] = None
vnpt_ma_nhan_vien: Optional[str] = None
name: Optional[str] = None
email: Optional[str] = None
phong_ban: Optional[str] = None
ip: Optional[str] = None
pc_name: Optional[str] = None
mac: Optional[str] = None
agent_version: Optional[str] = None
last_online: Optional[str] = None
status: Optional[int] = None
created_at: datetime.datetime
class Config:
from_attributes = True
class SmartIRDetailImportRowError(BaseModel):
row: int
error: str
class SmartIRDetailImportResponse(BaseModel):
message: str
total: int
inserted: int
failed: int
errors: List[SmartIRDetailImportRowError] = []
class NACDetailCreate(BaseModel):
month_id: int
unit_id: Optional[int] = None
name: Optional[str] = None
email: Optional[str] = None
status: Optional[int] = None
class NACDetail(BaseModel):
id: int
month_id: int
unit_id: Optional[int] = None
unit_name: Optional[str] = None
name: Optional[str] = None
email: Optional[str] = None
status: Optional[int] = None
created_at: datetime.datetime
class Config:
from_attributes = True
class NACDetailImportRowError(BaseModel):
row: int
error: str
class NACDetailImportResponse(BaseModel):
message: str
total: int
inserted: int
failed: int
errors: List[NACDetailImportRowError] = []
class ComplianceDetailCreate(BaseModel):
month_id: int
unit_id: Optional[int] = None
vnpt_ma_nhan_vien: Optional[str] = None
name: Optional[str] = None
email: Optional[str] = None
phong_ban: Optional[str] = None
windows_key: Optional[int] = None
office: Optional[int] = None
ms17010: Optional[int] = None
firewall: Optional[int] = None
uac: Optional[int] = None
winrar: Optional[int] = None
antivirus: Optional[int] = None
update_win: Optional[int] = None
status: Optional[int] = None
class ComplianceDetail(BaseModel):
id: int
month_id: int
unit_id: Optional[int] = None
unit_name: Optional[str] = None
vnpt_ma_nhan_vien: Optional[str] = None
name: Optional[str] = None
email: Optional[str] = None
phong_ban: Optional[str] = None
windows_key: Optional[int] = None
office: Optional[int] = None
ms17010: Optional[int] = None
firewall: Optional[int] = None
uac: Optional[int] = None
winrar: Optional[int] = None
antivirus: Optional[int] = None
update_win: Optional[int] = None
status: Optional[int] = None
created_at: datetime.datetime
class Config:
from_attributes = True
class ComplianceDetailImportRowError(BaseModel):
row: int
error: str
class ComplianceDetailImportResponse(BaseModel):
message: str
total: int
inserted: int
failed: int
errors: List[ComplianceDetailImportRowError] = []
class ComplianceSmartIRCreate(BaseModel):
month_id: int
unit_id: Optional[int] = None
vnpt_ma_nhan_vien: str
name: str
email: str
phong_ban: Optional[str] = None
ten_may_tinh: Optional[str] = None
mac: Optional[str] = None
active_windows: Optional[int] = None
bat_windows_firewall: Optional[int] = None
bat_uac: Optional[int] = None
cai_winrar_ban_moi: Optional[int] = None
bat_av_fullscan: Optional[int] = None
update_windows: Optional[int] = None
status: int = 0
class ComplianceSmartIR(BaseModel):
id: int
month_id: int
unit_id: Optional[int] = None
unit_name: Optional[str] = None
vnpt_ma_nhan_vien: str
name: str
email: str
phong_ban: Optional[str] = None
ten_may_tinh: Optional[str] = None
mac: Optional[str] = None
active_windows: Optional[int] = None
bat_windows_firewall: Optional[int] = None
bat_uac: Optional[int] = None
cai_winrar_ban_moi: Optional[int] = None
bat_av_fullscan: Optional[int] = None
update_windows: Optional[int] = None
status: int
created_at: datetime.datetime
updated_at: datetime.datetime
class Config:
from_attributes = True
class ComplianceSmartIRImportError(BaseModel):
row: int
error: str
class ComplianceSmartIRImportResponse(BaseModel):
message: str
total: int
upserted: int
failed: int
errors: List[ComplianceSmartIRImportError] = []
class MMFintechCreate(BaseModel):
month_id: int
unit_id: Optional[int] = None
file_path: str
class MMFintech(BaseModel):
id: int
month_id: int
unit_id: Optional[int] = None
file_path: str
created_at: datetime.datetime
class Config:
from_attributes = True
class ConvertHardeningCreate(BaseModel):
filename: str
user_id: int
class ConvertHardening(BaseModel):
id: int
filename: str
user_id: int
created_at: datetime.datetime
class Config:
from_attributes = True
class EmailRoleBase(BaseModel):
name: str
description: Optional[str] = None
class EmailRoleCreate(EmailRoleBase):
pass
class EmailRoleUpdate(BaseModel):
name: Optional[str] = None
description: Optional[str] = None
class EmailRole(BaseModel):
id: int
name: str
description: Optional[str] = None
class Config:
from_attributes = True
class EmailUserBase(BaseModel):
email: EmailStr
name: Optional[str] = None
role_id: int
type: int
class EmailUserCreate(EmailUserBase):
pass
class EmailUserUpdate(BaseModel):
email: Optional[EmailStr] = None
name: Optional[str] = None
role_id: Optional[int] = None
type: Optional[int] = None
class EmailUser(BaseModel):
id: int
email: EmailStr
name: Optional[str] = None
role_id: int
type: int
class Config:
from_attributes = True
class DocumentBase(BaseModel):
name: str
number_doc: str
sign_date: Optional[datetime.datetime] = None
level: int
validate_date: Optional[datetime.datetime] = None
file_path: Optional[str] = None
class DocumentCreate(DocumentBase):
pass
class DocumentUpdate(BaseModel):
name: Optional[str] = None
number_doc: Optional[str] = None
sign_date: Optional[datetime.datetime] = None
level: Optional[int] = None
validate_date: Optional[datetime.datetime] = None
file_path: Optional[str] = None
class Document(BaseModel):
id: int
name: str
number_doc: str
sign_date: Optional[datetime.datetime] = None
level: int
validate_date: Optional[datetime.datetime] = None
file_path: Optional[str] = None
class Config:
from_attributes = True