- vstore 独立安装包(8094):解析/嵌入/加密 vault/faiss 检索,存储路径支持本地 file 与 http(s):// URL,启动握手校验,集群化预留(embed 独立模块) - BFF docgen 路由:上传入库/generate/编辑/导出/下载/主库管理,意图护栏(与前端同词典),vstore 失败兜底,quota 507 与 TTL 惰性清理 - 前端:自然触发意图路由、拖拽上传 chips、能力徽标、右侧文档 TAB(WYSIWYG 编辑/prompt 修改/PDF+DOCX 导出下载)、右栏拖宽+手柄仿左栏 - 批量导入工具 docgen_import.py(并发 8、导入即加密+删源明文) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
64 lines
1.6 KiB
Python
64 lines
1.6 KiB
Python
"""test_crypto.py —— Fernet 加解密 / 落盘 / secure_delete。"""
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from vstore.crypto import (
|
|
CryptoError,
|
|
decrypt_bytes,
|
|
dump_encrypted,
|
|
encrypt_bytes,
|
|
load_encrypted,
|
|
secure_delete,
|
|
)
|
|
|
|
|
|
def test_roundtrip_bytes():
|
|
plain = "小麦育种试验报告——2026".encode("utf-8")
|
|
token = encrypt_bytes(plain)
|
|
assert token != plain
|
|
assert decrypt_bytes(token) == plain
|
|
|
|
|
|
def test_decrypt_wrong_key():
|
|
from cryptography.fernet import Fernet
|
|
|
|
other_key = Fernet.generate_key()
|
|
token = encrypt_bytes(b"hello")
|
|
with pytest.raises(CryptoError):
|
|
decrypt_bytes(token, key=other_key)
|
|
|
|
|
|
def test_empty_inputs():
|
|
with pytest.raises(CryptoError):
|
|
encrypt_bytes(b"")
|
|
with pytest.raises(CryptoError):
|
|
decrypt_bytes(b"")
|
|
|
|
|
|
def test_dump_load_encrypted(tmp_path):
|
|
target = tmp_path / "doc.enc"
|
|
plain = b"secret plaintext 123"
|
|
dump_encrypted(target, plain)
|
|
raw = target.read_bytes()
|
|
assert b"secret plaintext 123" not in raw # 密文不包含明文
|
|
assert load_encrypted(target) == plain
|
|
|
|
|
|
def test_dump_atomic_no_tmp_left(tmp_path):
|
|
target = tmp_path / "a.enc"
|
|
dump_encrypted(target, b"data")
|
|
assert not (tmp_path / "a.enc.tmp").exists()
|
|
assert target.exists()
|
|
|
|
|
|
def test_secure_delete(tmp_path):
|
|
target = tmp_path / "x.bin"
|
|
target.write_bytes(b"0123456789")
|
|
secure_delete(target)
|
|
assert not target.exists()
|
|
|
|
|
|
def test_secure_delete_missing_ok(tmp_path):
|
|
secure_delete(tmp_path / "nope.bin") # 不抛异常
|