Работа с "подделкой" лицензии
This commit is contained in:
47
backend/routes/license_routes.py
Normal file
47
backend/routes/license_routes.py
Normal file
@@ -0,0 +1,47 @@
|
||||
from typing import Any
|
||||
from fastapi import APIRouter, Form, HTTPException, BackgroundTasks
|
||||
from fastapi.responses import FileResponse
|
||||
from ..services.license_service import generate_license_file
|
||||
|
||||
router: APIRouter = APIRouter()
|
||||
|
||||
|
||||
@router.post("/generate", response_class=FileResponse)
|
||||
async def generate_license(
|
||||
background_tasks: BackgroundTasks,
|
||||
name: str = Form(...),
|
||||
version: str = Form(...)
|
||||
) -> Any:
|
||||
"""
|
||||
Генерация лицензии Custom.mxtpro.
|
||||
Параметры:
|
||||
- name: str - имя пользователя
|
||||
- version: str - версия формата X.Y
|
||||
Возвращает:
|
||||
- FileResponse: сгенерированный ZIP файл с именем Custom.mxtpro
|
||||
"""
|
||||
if not name.strip() or not version.strip():
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="NAME и VERSION обязательны."
|
||||
)
|
||||
try:
|
||||
# Создаём временный файл на сервере
|
||||
filepath, temp_dir = generate_license_file(name, version)
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"Ошибка генерации лицензии: {e}"
|
||||
)
|
||||
|
||||
# Удаляем директорию (и файл внутри) после отправки пользователю
|
||||
background_tasks.add_task(temp_dir.cleanup)
|
||||
|
||||
# Отправляем с фиксированным именем Custom.mxtpro
|
||||
return FileResponse(
|
||||
filepath,
|
||||
media_type="application/octet-stream",
|
||||
headers={
|
||||
"Content-Disposition": 'attachment; filename="Custom.mxtpro"'
|
||||
}
|
||||
)
|
||||
48
backend/services/license_service.py
Normal file
48
backend/services/license_service.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import tempfile
|
||||
from zipfile import ZipFile
|
||||
from pathlib import Path
|
||||
from ..utils.encoding import variant_base64_encode
|
||||
from ..utils.crypto import encrypt_bytes
|
||||
|
||||
|
||||
class LicenseType:
|
||||
Professional: int = 1
|
||||
Educational: int = 3
|
||||
Personal: int = 4
|
||||
|
||||
|
||||
def generate_license_file(
|
||||
user_name: str,
|
||||
version: str,
|
||||
lic_type: int = LicenseType.Professional,
|
||||
count: int = 1
|
||||
) -> tuple[str, tempfile.TemporaryDirectory]:
|
||||
"""
|
||||
Генерация временного ZIP-файла с лицензией Custom.mxtpro.
|
||||
Возвращает путь к файлу и объект временной директории для cleanup.
|
||||
"""
|
||||
# Разбор версии
|
||||
try:
|
||||
major_str, minor_str = version.split(".")
|
||||
major_version: int = int(major_str)
|
||||
minor_version: int = int(minor_str)
|
||||
except Exception as e:
|
||||
raise ValueError(f"Неверный формат версии: {version}") from e
|
||||
|
||||
# Формирование строки лицензии
|
||||
license_str: str = (
|
||||
f"{lic_type}#{user_name}|{major_version}{minor_version}"
|
||||
f"#{count}#{major_version}3{minor_version}6{minor_version}#0#0#0#"
|
||||
)
|
||||
|
||||
# Шифрование и кодирование
|
||||
encrypted: bytes = encrypt_bytes(0x0787, license_str.encode("utf-8"))
|
||||
encoded: str = variant_base64_encode(encrypted).decode("ascii")
|
||||
|
||||
# Создание временной директории и файла с фиксированным именем
|
||||
temp_dir = tempfile.TemporaryDirectory()
|
||||
filepath = Path(temp_dir.name) / "Custom.mxtpro"
|
||||
with ZipFile(filepath, "w") as zf:
|
||||
zf.writestr("Pro.key", encoded)
|
||||
|
||||
return str(filepath), temp_dir
|
||||
Reference in New Issue
Block a user