Files
minerops/backend/tests/test_agent_enrollment.py
T

158 lines
4.7 KiB
Python

"""Focused tests for secure Agent enrollment."""
import re
import unittest
from datetime import datetime, timedelta, timezone
from uuid import UUID
from app.agent_auth.service import hash_agent_secret
from app.agent_enrollment.models import (
AgentEnrollmentCreateRequest,
AgentEnrollRequest,
)
from app.agent_enrollment.service import AgentEnrollmentService
from app.identity import machine_agent_request, required_api_permission
SITE_ID = UUID("00000000-0000-4000-8000-000000001700")
ZONE_ID = UUID("00000000-0000-4000-8000-000000001701")
USER_ID = UUID("00000000-0000-4000-8000-000000001702")
ENROLLMENT_ID = UUID("00000000-0000-4000-8000-000000001703")
NOW = datetime(2026, 8, 26, tzinfo=timezone.utc)
class FakeAgentEnrollmentRepository:
def __init__(self):
self.created = None
self.redeemed = None
def create_enrollment(self, **kwargs):
self.created = kwargs
return {
"id": ENROLLMENT_ID,
"site_id": SITE_ID,
"site_name": "Test Site",
"agent_zone_id": ZONE_ID,
"agent_zone_name": "Test Zone",
"display_name": kwargs["display_name"],
"created_at": NOW,
"expires_at": NOW + timedelta(minutes=30),
}
def list_enrollments(self, **kwargs):
return []
def redeem_enrollment(self, **kwargs):
self.redeemed = kwargs
return {
"agent_id": kwargs["agent_id"],
"site_id": SITE_ID,
"site_name": "Test Site",
"agent_zone_id": ZONE_ID,
"agent_zone_name": "Test Zone",
"display_name": "Test Agent",
"ip_ranges": ["10.30.0.0/22"],
}
class AgentEnrollmentServiceTests(unittest.TestCase):
def test_create_returns_plaintext_token_once_but_repository_gets_only_hash(self):
repository = FakeAgentEnrollmentRepository()
service = AgentEnrollmentService(repository)
result = service.create_enrollment(
AgentEnrollmentCreateRequest(
site_id=SITE_ID,
agent_zone_id=ZONE_ID,
display_name=" Test Agent ",
),
actor_user_id=USER_ID,
)
token = result["enrollment_token"]
self.assertGreaterEqual(len(token), 32)
self.assertNotEqual(repository.created["token_hash"], token)
self.assertEqual(
repository.created["token_hash"],
hash_agent_secret(token),
)
self.assertRegex(
repository.created["token_hash"],
r"^[0-9a-f]{64}$",
)
self.assertEqual(
repository.created["display_name"],
"Test Agent",
)
serialized = repr(repository.created)
self.assertNotIn(token, serialized)
def test_redeem_returns_plaintext_secret_but_repository_gets_only_hash(self):
repository = FakeAgentEnrollmentRepository()
service = AgentEnrollmentService(repository)
result = service.redeem(
AgentEnrollRequest(
token="A" * 43,
)
)
secret = result["agent_secret"]
self.assertGreaterEqual(len(secret), 32)
self.assertNotEqual(
repository.redeemed["agent_secret_hash"],
secret,
)
self.assertEqual(
repository.redeemed["agent_secret_hash"],
hash_agent_secret(secret),
)
self.assertRegex(
repository.redeemed["agent_secret_hash"],
r"^[0-9a-f]{64}$",
)
self.assertRegex(
result["agent_id"],
r"^agent-[0-9a-f]{32}$",
)
serialized = repr(repository.redeemed)
self.assertNotIn(secret, serialized)
def test_enrollment_admin_permission_mapping_is_explicit(self):
self.assertEqual(
required_api_permission("GET", "/api/agent-enrollments"),
"agents.view",
)
self.assertEqual(
required_api_permission("POST", "/api/agent-enrollments"),
"agents.manage",
)
def test_bootstrap_endpoint_is_machine_exempt_but_admin_endpoint_is_not(self):
self.assertTrue(machine_agent_request("/api/agent/enroll"))
self.assertFalse(
machine_agent_request("/api/agent-enrollments")
)
def test_generated_identifiers_are_bounded(self):
repository = FakeAgentEnrollmentRepository()
service = AgentEnrollmentService(repository)
result = service.redeem(
AgentEnrollRequest(token="B" * 43)
)
self.assertLessEqual(len(result["agent_id"]), 255)
self.assertTrue(
re.fullmatch(r"agent-[0-9a-f]{32}", result["agent_id"])
)
if __name__ == "__main__":
unittest.main()