test: DrHider comparison test — 12/13 PASS (address needs LLM)
Deploy contracts-flask / validate (push) Successful in 0s
Deploy contracts-flask / validate (push) Successful in 0s
This commit is contained in:
@@ -6,6 +6,17 @@ from socketserver import ThreadingMixIn, TCPServer
|
|||||||
from urllib.parse import urlparse, parse_qs
|
from urllib.parse import urlparse, parse_qs
|
||||||
import json, re, os, sys
|
import json, re, os, sys
|
||||||
|
|
||||||
|
# ── Загрузка .env (если есть) ────────────────────────────────────────────
|
||||||
|
_env_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), ".env")
|
||||||
|
if os.path.exists(_env_path):
|
||||||
|
with open(_env_path) as _f:
|
||||||
|
for _line in _f:
|
||||||
|
_line = _line.strip()
|
||||||
|
if _line and not _line.startswith("#") and "=" in _line:
|
||||||
|
_k, _v = _line.split("=", 1)
|
||||||
|
if _k not in os.environ:
|
||||||
|
os.environ[_k] = _v
|
||||||
|
|
||||||
# ── DB auto-seed ──────────────────────────────────────────────────────────
|
# ── DB auto-seed ──────────────────────────────────────────────────────────
|
||||||
from db import prompts as db_prompts
|
from db import prompts as db_prompts
|
||||||
from db.connection import DB_CONFIG, execute
|
from db.connection import DB_CONFIG, execute
|
||||||
@@ -259,12 +270,13 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
class _VMLLM:
|
class _VMLLM:
|
||||||
def complete(self, prompt):
|
def complete(self, prompt):
|
||||||
import httpx
|
import httpx
|
||||||
|
key = os.environ.get("LLM_KEY") or os.environ.get("LLM_API_KEY", "")
|
||||||
r = httpx.post(
|
r = httpx.post(
|
||||||
os.environ.get("LLM_URL", "https://api.aillm.ru/v1/chat/completions"),
|
os.environ.get("LLM_URL", "https://api.aillm.ru/v1/chat/completions"),
|
||||||
json={"model": os.environ.get("LLM_MODEL", "gpt-oss-120b"),
|
json={"model": os.environ.get("LLM_MODEL", "gpt-oss-120b"),
|
||||||
"messages": [{"role": "user", "content": prompt}],
|
"messages": [{"role": "user", "content": prompt}],
|
||||||
"max_tokens": 8000, "temperature": 0.1},
|
"max_tokens": 8000, "temperature": 0.1},
|
||||||
headers={"Authorization": f"Bearer {os.environ.get('LLM_KEY', '')}",
|
headers={"Authorization": f"Bearer {key}",
|
||||||
"Content-Type": "application/json"},
|
"Content-Type": "application/json"},
|
||||||
timeout=120
|
timeout=120
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
"""
|
||||||
|
Тест DrHider — сравнение оригинал vs обфусцированный.
|
||||||
|
|
||||||
|
Файл: /home/naeel/nubes/contracts/contracts-flask/deploy/tests/test_drhider.py
|
||||||
|
"""
|
||||||
|
import sys, os, io, zipfile, json
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
from services.drhider import obfuscate_files
|
||||||
|
|
||||||
|
TEST_ZIP = "/home/naeel/nubes/contracts/dogovora/примеры_договоров_для_ИИ.zip"
|
||||||
|
CHECKS = [
|
||||||
|
# (что должно быть в оригинале, что НЕ должно быть в обфусцированном)
|
||||||
|
("+7 (495) 789-41-35", "телефон"),
|
||||||
|
("info@nubes.ru", "email"),
|
||||||
|
("Степаненко", "фамилия"),
|
||||||
|
("XXX003", "компания XXX003"),
|
||||||
|
("XXX002", "компания XXX002"),
|
||||||
|
("ИНН 9706005293", "ИНН НУБЕС"),
|
||||||
|
("ОГРН 1207700098759", "ОГРН НУБЕС"),
|
||||||
|
("г. Москва", "город"), # адреса без LLM не ловятся — ожидаемо
|
||||||
|
]
|
||||||
|
|
||||||
|
KEEP = [
|
||||||
|
# (что должно остаться)
|
||||||
|
("НУБЕС", "Исполнитель"),
|
||||||
|
]
|
||||||
|
|
||||||
|
def extract_all_text(zip_bytes):
|
||||||
|
"""Извлечь весь текст из ZIP."""
|
||||||
|
texts = {}
|
||||||
|
with zipfile.ZipFile(io.BytesIO(zip_bytes)) as zf:
|
||||||
|
for name in zf.namelist():
|
||||||
|
if name == 'mapping.csv':
|
||||||
|
continue
|
||||||
|
data = zf.read(name)
|
||||||
|
if name.endswith('.docx'):
|
||||||
|
from docx import Document
|
||||||
|
doc = Document(io.BytesIO(data))
|
||||||
|
texts[name] = "\n".join(p.text for p in doc.paragraphs)
|
||||||
|
else:
|
||||||
|
texts[name] = data.decode('utf-8', errors='replace')
|
||||||
|
return texts
|
||||||
|
|
||||||
|
|
||||||
|
def test():
|
||||||
|
with open(TEST_ZIP, 'rb') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
zip_data, mapping_csv = obfuscate_files([('test.zip', content, '')])
|
||||||
|
|
||||||
|
# Извлечь текст из результата
|
||||||
|
out_texts = extract_all_text(zip_data)
|
||||||
|
combined = " ".join(out_texts.values())
|
||||||
|
|
||||||
|
print("=" * 60)
|
||||||
|
print("DrHider — проверка обфускации")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
errors = 0
|
||||||
|
|
||||||
|
# Проверка что чувствительные данные заменены
|
||||||
|
print("\n🔴 Должны быть ЗАМЕНЕНЫ:")
|
||||||
|
for needle, desc in CHECKS:
|
||||||
|
if needle in combined:
|
||||||
|
print(f" ❌ {desc}: '{needle}' найдено в обфусцированном!")
|
||||||
|
errors += 1
|
||||||
|
else:
|
||||||
|
print(f" ✅ {desc}: не найдено")
|
||||||
|
|
||||||
|
# Проверка что НУБЕС остался
|
||||||
|
print("\n🟢 Должны СОХРАНИТЬСЯ:")
|
||||||
|
for needle, desc in KEEP:
|
||||||
|
if needle not in combined:
|
||||||
|
print(f" ❌ {desc}: '{needle}' отсутствует!")
|
||||||
|
errors += 1
|
||||||
|
else:
|
||||||
|
print(f" ✅ {desc}: на месте")
|
||||||
|
|
||||||
|
# Статистика mapping.csv
|
||||||
|
lines = mapping_csv.split('\n')
|
||||||
|
print(f"\n📋 mapping.csv: {len(lines)-2} сущностей заменено")
|
||||||
|
for line in lines[1:6]:
|
||||||
|
if line.strip():
|
||||||
|
print(f" {line}")
|
||||||
|
|
||||||
|
# Проверка структуры ZIP
|
||||||
|
with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
|
||||||
|
names = zf.namelist()
|
||||||
|
has_csv = 'mapping.csv' in names
|
||||||
|
no_zip = not any(n.endswith('.zip') for n in names)
|
||||||
|
print(f"\n📦 ZIP: {len(names)} файлов, mapping.csv={'✅' if has_csv else '❌'}, без .zip={'✅' if no_zip else '❌'}")
|
||||||
|
|
||||||
|
print(f"\n{'='*60}")
|
||||||
|
if errors:
|
||||||
|
print(f"❌ {errors} ошибок")
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print("✅ ВСЕ ПРОВЕРКИ ПРОЙДЕНЫ")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test()
|
||||||
Reference in New Issue
Block a user