Self-hosted, Docker-based agentic troubleshooting platform: FastAPI backend + LangGraph agent, Next.js UI, tiered LLM routing (local Ollama -> Gemini -> DeepSeek -> OpenRouter), MCP server manager, encrypted device credentials, RBAC, audit log, project-memory + Obsidian integrations, and editable troubleshooting decision rules tuned for the GeneseasX vessel stack. Co-authored-by: Cursor <cursoragent@cursor.com>
50 lines
1.4 KiB
Python
50 lines
1.4 KiB
Python
"""Unit tests for core security primitives (no external services required)."""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
|
|
os.environ.setdefault("SECRET_KEY", "test-secret-key-for-unit-tests-only")
|
|
|
|
from app.core.crypto import decrypt_secret, encrypt_secret # noqa: E402
|
|
from app.core.security import ( # noqa: E402
|
|
create_access_token,
|
|
decode_access_token,
|
|
hash_password,
|
|
verify_password,
|
|
)
|
|
from app.models.enums import Role # noqa: E402
|
|
|
|
|
|
def test_password_hash_roundtrip():
|
|
h = hash_password("s3cret!")
|
|
assert h != "s3cret!"
|
|
assert verify_password("s3cret!", h)
|
|
assert not verify_password("wrong", h)
|
|
|
|
|
|
def test_jwt_roundtrip():
|
|
token = create_access_token(subject="admin@agentic.local", role="admin")
|
|
payload = decode_access_token(token)
|
|
assert payload is not None
|
|
assert payload["sub"] == "admin@agentic.local"
|
|
assert payload["role"] == "admin"
|
|
|
|
|
|
def test_jwt_invalid():
|
|
assert decode_access_token("not-a-token") is None
|
|
|
|
|
|
def test_credential_encryption_roundtrip():
|
|
token = encrypt_secret("device-password")
|
|
assert token is not None
|
|
assert token != "device-password"
|
|
assert decrypt_secret(token) == "device-password"
|
|
assert encrypt_secret(None) is None
|
|
assert decrypt_secret(None) is None
|
|
|
|
|
|
def test_role_ranking():
|
|
from app.core.deps import _ROLE_RANK
|
|
|
|
assert _ROLE_RANK[Role.admin] > _ROLE_RANK[Role.support] > _ROLE_RANK[Role.readonly]
|