refactor: consolidate checklist management into registry

This commit is contained in:
Luftmensch
2026-09-04 10:47:15 +07:00
parent 9f34cf8afd
commit 6e2e9e88b0
3 changed files with 13 additions and 123 deletions
+1 -73
View File
@@ -26,7 +26,7 @@ import ipaddress
import re
import requests as http_requests
from authenticator.radius_login import check_radius_login, check_radius_login_extended
from config_upload import install_config_files, normalize_json, validate_xlsx
from config_upload import normalize_json, validate_xlsx
from registry_service import (
RegistryError, RegistryNotFoundError, RegistryService, RegistryValidationError
)
@@ -3072,78 +3072,6 @@ async def admin_delete_tool(
params = urlencode({"msg": f"Lỗi khi xóa: {str(e)}", "msg_type": "error"})
return RedirectResponse(url=f"{request.url_for('admin_tools')}?{params}", status_code=303)
@app.post("/admin/checklists/upload", name="admin_checklists_upload")
async def admin_upload_checklist_config(
request: Request,
os_type: str = Form(...),
checklist_file: Optional[UploadFile] = File(None),
config_file: Optional[UploadFile] = File(None),
):
"""Upload/replace the checklist XLSX and rule JSON for an OS. Admin only."""
user = require_admin_session(request)
if not user:
return RedirectResponse(url=request.url_for('login'), status_code=303)
from urllib.parse import urlencode
os_info = OS_CONFIG.get(os_type)
if not os_info:
params = urlencode({"msg": "Hệ điều hành không hợp lệ", "msg_type": "error"})
return RedirectResponse(url=f"{request.url_for('admin_tools')}?{params}", status_code=303)
has_checklist = bool(checklist_file and checklist_file.filename)
has_config = bool(config_file and config_file.filename)
if not has_checklist and not has_config:
params = urlencode({"msg": "Cần chọn ít nhất một file checklist hoặc rule config", "msg_type": "error"})
return RedirectResponse(url=f"{request.url_for('admin_tools')}?{params}", status_code=303)
pending_files = []
try:
if has_checklist:
if not checklist_file.filename.lower().endswith('.xlsx'):
raise ValueError("Checklist phải là file .xlsx")
checklist_content = validate_xlsx(await checklist_file.read())
pending_files.append((os_info['checklist'], checklist_content))
if has_config:
if not config_file.filename.lower().endswith('.json'):
raise ValueError("Rule config phải là file .json")
normalized_config = normalize_json(await config_file.read())
pending_files.append((os_info['config'], normalized_config))
# Compatibility endpoint: translate the fixed OS form into a new immutable
# profile version. ``install_config_files`` remains available for old
# deployments, but registry artifacts are now the authoritative source.
resolved = resolve_audit_profile(os_type=os_type)
with open(resolved['checklist_path'], 'rb') as stream:
active_checklist = stream.read()
with open(resolved['rules_path'], 'rb') as stream:
active_rules = stream.read()
checklist_content = next((content for name, content in pending_files if name == os_info['checklist']),
active_checklist)
normalized_config = next((content for name, content in pending_files if name == os_info['config']),
active_rules)
version_id = datetime.now(timezone.utc).strftime("upload-%Y%m%dT%H%M%S%fZ")
registry_service.create_version(resolved['profile']['id'], version_id, checklist_content,
normalized_config, activate=True,
created_by=user.get('username', 'admin'))
print(Fore.GREEN + f"[ADMIN] Checklist/config updated for {os_type} by {user.get('username')}" + Fore.RESET)
changed = ', '.join(name for name, _ in pending_files)
params = urlencode({"msg": f"Đã cập nhật: {changed}", "msg_type": "success"})
except (ValueError, UnicodeDecodeError, json.JSONDecodeError) as exc:
for target_name, _ in pending_files:
temp_path = os.path.join(CONFIG_FOLDER, target_name) + '.tmp'
if os.path.exists(temp_path):
os.remove(temp_path)
params = urlencode({"msg": str(exc), "msg_type": "error"})
except Exception as exc:
print(Fore.RED + f"[ADMIN] Checklist/config upload error: {exc}" + Fore.RESET)
params = urlencode({"msg": f"Lỗi cập nhật checklist/config: {exc}", "msg_type": "error"})
return RedirectResponse(url=f"{request.url_for('admin_tools')}?{params}", status_code=303)
@app.post("/admin/docs/upload", name="admin_docs_upload")
async def admin_upload_doc(
request: Request,