v1.0 - Version stable: multi-PC, détection UI-DETR-1, 3 modes exécution
- Frontend v4 accessible sur réseau local (192.168.1.40) - Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard) - Ollama GPU fonctionnel - Self-healing interactif - Dashboard confiance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
256
test_encryption_sync.py
Normal file
256
test_encryption_sync.py
Normal file
@@ -0,0 +1,256 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Real Functionality Test: Encryption/Decryption Synchronization
|
||||
|
||||
Tests actual encryption/decryption between agent v0 and server components
|
||||
using real data flows and authentic scenarios without mocks.
|
||||
|
||||
This test validates:
|
||||
1. Environment and configuration loading (real files)
|
||||
2. Password synchronization between components
|
||||
3. End-to-end encryption/decryption with real session data
|
||||
4. Cross-component compatibility (agent -> server workflow)
|
||||
5. Error handling with real failure scenarios
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import tempfile
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
# Add paths for real imports (no mocks)
|
||||
sys.path.insert(0, str(Path(__file__).parent / "agent_v0"))
|
||||
sys.path.insert(0, str(Path(__file__).parent / "server"))
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
|
||||
|
||||
def load_real_environment() -> dict:
|
||||
"""Load real environment configuration from actual files."""
|
||||
env_vars = {}
|
||||
|
||||
# Load from .env.local (real file)
|
||||
env_local_path = Path(".env.local")
|
||||
if env_local_path.exists():
|
||||
with open(env_local_path, 'r') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line and not line.startswith('#') and '=' in line:
|
||||
key, value = line.split('=', 1)
|
||||
env_vars[key.strip()] = value.strip()
|
||||
os.environ[key.strip()] = value.strip()
|
||||
|
||||
return env_vars
|
||||
|
||||
|
||||
def load_real_agent_config() -> dict:
|
||||
"""Load real agent configuration from actual JSON file."""
|
||||
agent_config_path = Path("agent_config.json")
|
||||
if not agent_config_path.exists():
|
||||
raise FileNotFoundError(f"Agent config not found: {agent_config_path}")
|
||||
|
||||
with open(agent_config_path, 'r') as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def create_real_test_session():
|
||||
"""Create a real RawSession with actual data structure."""
|
||||
from agent_v0.raw_session import RawSession
|
||||
|
||||
# Create real session with authentic data
|
||||
session = RawSession.create(
|
||||
user_id="test_encryption_user",
|
||||
platform=sys.platform,
|
||||
hostname=os.uname().nodename if hasattr(os, 'uname') else "test_host",
|
||||
screen_resolution=[1920, 1080]
|
||||
)
|
||||
|
||||
# Add some real events (not mocked)
|
||||
session.add_event({
|
||||
"t": 0.0,
|
||||
"type": "mouse_click",
|
||||
"button": "left",
|
||||
"pos": [100, 200],
|
||||
"window": {"title": "Test Window", "app_name": "test_app"}
|
||||
})
|
||||
|
||||
session.add_event({
|
||||
"t": 1.5,
|
||||
"type": "key_combo",
|
||||
"keys": ["CTRL", "C"],
|
||||
"window": {"title": "Test Window", "app_name": "test_app"}
|
||||
})
|
||||
|
||||
return session
|
||||
|
||||
|
||||
def test_real_encryption_workflow(password: str) -> bool:
|
||||
"""Test complete encryption workflow with real components."""
|
||||
try:
|
||||
# Import real modules (no mocks)
|
||||
from agent_v0.storage_encrypted import create_session_zip_encrypted
|
||||
from server.storage_encrypted import decrypt_file
|
||||
|
||||
# Create real test session
|
||||
session = create_real_test_session()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
# Save session using real storage
|
||||
session.save_json(tmpdir)
|
||||
|
||||
# Test agent-side encryption (real functionality)
|
||||
encrypted_path = create_session_zip_encrypted(
|
||||
session,
|
||||
password,
|
||||
tmpdir,
|
||||
delete_unencrypted=False
|
||||
)
|
||||
|
||||
# Verify encrypted file has real structure
|
||||
if not os.path.exists(encrypted_path):
|
||||
return False
|
||||
|
||||
encrypted_size = os.path.getsize(encrypted_path)
|
||||
if encrypted_size < 48: # salt(16) + iv(16) + minimal data(16+)
|
||||
return False
|
||||
|
||||
# Test server-side decryption (real functionality)
|
||||
decrypted_path = decrypt_file(encrypted_path, password)
|
||||
|
||||
# Verify decrypted ZIP with real validation
|
||||
with zipfile.ZipFile(decrypted_path, 'r') as zf:
|
||||
files = zf.namelist()
|
||||
|
||||
# Check for real session structure
|
||||
session_json = None
|
||||
for file in files:
|
||||
if file.endswith('.json') and session.session_id in file:
|
||||
session_json = file
|
||||
break
|
||||
|
||||
if not session_json:
|
||||
return False
|
||||
|
||||
# Validate real session data
|
||||
with zf.open(session_json) as f:
|
||||
session_data = json.load(f)
|
||||
|
||||
# Check real session structure
|
||||
required_fields = ['session_id', 'events', 'started_at', 'user']
|
||||
if not all(field in session_data for field in required_fields):
|
||||
return False
|
||||
|
||||
# Verify events are preserved
|
||||
if len(session_data['events']) != 2:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"Real encryption workflow failed: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def test_password_mismatch_scenario(correct_password: str) -> bool:
|
||||
"""Test real error handling with wrong password."""
|
||||
try:
|
||||
from agent_v0.storage_encrypted import create_session_zip_encrypted
|
||||
from server.storage_encrypted import decrypt_file
|
||||
|
||||
session = create_real_test_session()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
session.save_json(tmpdir)
|
||||
|
||||
# Encrypt with correct password
|
||||
encrypted_path = create_session_zip_encrypted(
|
||||
session, correct_password, tmpdir
|
||||
)
|
||||
|
||||
# Try to decrypt with wrong password (should fail)
|
||||
wrong_password = correct_password + "_wrong"
|
||||
try:
|
||||
decrypt_file(encrypted_path, wrong_password)
|
||||
return False # Should have failed
|
||||
except ValueError:
|
||||
return True # Expected failure
|
||||
except Exception:
|
||||
return False # Unexpected error type
|
||||
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def test_encryption_sync():
|
||||
"""Main test function for real encryption synchronization."""
|
||||
|
||||
print("=== Real Functionality Test: Encryption Synchronization ===")
|
||||
|
||||
# 1. Load real environment configuration
|
||||
try:
|
||||
env_vars = load_real_environment()
|
||||
server_password = env_vars.get("ENCRYPTION_PASSWORD") or os.getenv("ENCRYPTION_PASSWORD")
|
||||
print(f"✅ Environment loaded: {len(env_vars)} variables")
|
||||
print(f"Server password: {'***' + server_password[-4:] if server_password else '❌ Not set'}")
|
||||
except Exception as e:
|
||||
print(f"❌ Failed to load environment: {e}")
|
||||
return False
|
||||
|
||||
# 2. Load real agent configuration
|
||||
try:
|
||||
agent_config = load_real_agent_config()
|
||||
agent_password = agent_config.get("encryption_password")
|
||||
print(f"✅ Agent config loaded")
|
||||
print(f"Agent password: {'***' + agent_password[-4:] if agent_password else '❌ Not set'}")
|
||||
except Exception as e:
|
||||
print(f"❌ Failed to load agent config: {e}")
|
||||
return False
|
||||
|
||||
# 3. Validate password synchronization
|
||||
if not server_password or not agent_password:
|
||||
print("❌ Missing encryption passwords")
|
||||
return False
|
||||
|
||||
if server_password != agent_password:
|
||||
print("❌ Password mismatch!")
|
||||
print(f" Server: {server_password}")
|
||||
print(f" Agent: {agent_password}")
|
||||
return False
|
||||
|
||||
print("✅ Passwords synchronized")
|
||||
|
||||
# 4. Test real encryption workflow
|
||||
print("\n--- Testing Real Encryption Workflow ---")
|
||||
if not test_real_encryption_workflow(server_password):
|
||||
print("❌ Real encryption workflow failed")
|
||||
return False
|
||||
print("✅ Real encryption workflow passed")
|
||||
|
||||
# 5. Test error handling with real scenarios
|
||||
print("\n--- Testing Real Error Scenarios ---")
|
||||
if not test_password_mismatch_scenario(server_password):
|
||||
print("❌ Password mismatch handling failed")
|
||||
return False
|
||||
print("✅ Error handling validated")
|
||||
|
||||
# 6. Test agent's built-in validation
|
||||
print("\n--- Testing Agent Built-in Validation ---")
|
||||
try:
|
||||
from agent_v0.storage_encrypted import test_encryption_password
|
||||
if not test_encryption_password(agent_password):
|
||||
print("❌ Agent validation failed")
|
||||
return False
|
||||
print("✅ Agent validation passed")
|
||||
except Exception as e:
|
||||
print(f"❌ Agent validation error: {e}")
|
||||
return False
|
||||
|
||||
print("\n🎉 All real functionality tests passed!")
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = test_encryption_sync()
|
||||
sys.exit(0 if success else 1)
|
||||
Reference in New Issue
Block a user