"""Integration tests for security router""" import pytest def test_security_logs_endpoint(test_app, admin_headers, mock_docker_client): """Test security logs endpoint returns expected format""" # Mock Authelia container logs mock_container = mock_docker_client.containers.get.return_value mock_container.logs.return_value = b'{"level":"error","msg":"Unsuccessful 1FA authentication attempt","time":"2024-01-01T10:00:00Z","username":"testuser","remote_ip":"1.2.3.4"}\n' response = test_app.get("/api/security/logs", headers=admin_headers) assert response.status_code == 200 data = response.json() assert "logs" in data assert isinstance(data["logs"], list) def test_security_logs_with_filters(test_app, admin_headers, mock_docker_client): """Test security logs with type and IP filters""" mock_container = mock_docker_client.containers.get.return_value mock_container.logs.return_value = b'{"level":"error","msg":"Unsuccessful 1FA authentication attempt","time":"2024-01-01T10:00:00Z","username":"testuser","remote_ip":"1.2.3.4"}\n' response = test_app.get("/api/security/logs?type=auth_failure&ip=1.2.3.4", headers=admin_headers) assert response.status_code == 200 data = response.json() assert "logs" in data def test_security_logs_with_date_range(test_app, admin_headers, mock_docker_client): """Test security logs with date range filter""" mock_container = mock_docker_client.containers.get.return_value mock_container.logs.return_value = b'{"level":"error","msg":"Unsuccessful 1FA authentication attempt","time":"2024-01-01T10:00:00Z","username":"testuser","remote_ip":"1.2.3.4"}\n' response = test_app.get( "/api/security/logs?start_date=2024-01-01&end_date=2024-01-31", headers=admin_headers ) assert response.status_code == 200 data = response.json() assert "logs" in data def test_security_logs_tail_limit(test_app, admin_headers, mock_docker_client): """Test security logs respects tail and limit parameters""" mock_container = mock_docker_client.containers.get.return_value mock_container.logs.return_value = b'{"level":"error","msg":"Unsuccessful 1FA authentication attempt","time":"2024-01-01T10:00:00Z","username":"testuser","remote_ip":"1.2.3.4"}\n' response = test_app.get("/api/security/logs?tail=100&limit=50", headers=admin_headers) assert response.status_code == 200 data = response.json() assert "logs" in data assert len(data["logs"]) <= 50 def test_security_logs_handles_missing_container(test_app, admin_headers, mock_docker_client): """Test security logs handles missing Authelia container gracefully""" import docker.errors mock_docker_client.containers.get.side_effect = docker.errors.NotFound("Container not found") response = test_app.get("/api/security/logs", headers=admin_headers) assert response.status_code == 200 data = response.json() assert "logs" in data assert isinstance(data["logs"], list) def test_security_stats_endpoint(test_app, admin_headers, mock_docker_client): """Test security stats endpoint returns expected format""" mock_container = mock_docker_client.containers.get.return_value mock_container.logs.return_value = b'{"level":"error","msg":"Unsuccessful 1FA authentication attempt","time":"2024-01-01T10:00:00Z","username":"testuser","remote_ip":"1.2.3.4"}\n' response = test_app.get("/api/security/stats", headers=admin_headers) assert response.status_code == 200 data = response.json() assert "failed_logins_24h" in data assert "suspicious_requests" in data assert "unique_ips" in data assert "top_ips" in data assert "timeline" in data assert isinstance(data["top_ips"], list) assert isinstance(data["timeline"], list) def test_security_stats_timeline_format(test_app, admin_headers, mock_docker_client): """Test security stats timeline has correct format""" mock_container = mock_docker_client.containers.get.return_value mock_container.logs.return_value = b'{"level":"error","msg":"Unsuccessful 1FA authentication attempt","time":"2024-01-01T10:00:00Z","username":"testuser","remote_ip":"1.2.3.4"}\n' response = test_app.get("/api/security/stats", headers=admin_headers) assert response.status_code == 200 data = response.json() assert len(data["timeline"]) == 24 # 24 hours for entry in data["timeline"]: assert "hours_ago" in entry assert "count" in entry def test_security_stats_top_ips_format(test_app, admin_headers, mock_docker_client): """Test security stats top IPs have correct format""" mock_container = mock_docker_client.containers.get.return_value mock_container.logs.return_value = b'{"level":"error","msg":"Unsuccessful 1FA authentication attempt","time":"2024-01-01T10:00:00Z","username":"testuser","remote_ip":"1.2.3.4"}\n' response = test_app.get("/api/security/stats", headers=admin_headers) assert response.status_code == 200 data = response.json() for entry in data["top_ips"]: assert "ip" in entry assert "count" in entry def test_security_logs_parses_logfmt(test_app, admin_headers, mock_docker_client): """Test security logs can parse logfmt format""" mock_container = mock_docker_client.containers.get.return_value mock_container.logs.return_value = ( b'level=error msg="Unsuccessful 1FA authentication attempt" time=2024-01-01T10:00:00Z username=testuser remote_ip=1.2.3.4\n' ) response = test_app.get("/api/security/logs", headers=admin_headers) assert response.status_code == 200 data = response.json() assert "logs" in data def test_security_logs_filters_suspicious_paths(test_app, admin_headers, mock_docker_client): """Test security logs identifies suspicious paths""" mock_container = mock_docker_client.containers.get.return_value # Simulate Caddy log with suspicious path (though Caddy logs are disabled in current implementation) mock_container.logs.return_value = b'{"level":"error","msg":"Unsuccessful 1FA authentication attempt","time":"2024-01-01T10:00:00Z","username":"testuser","remote_ip":"1.2.3.4"}\n' response = test_app.get("/api/security/logs", headers=admin_headers) assert response.status_code == 200 data = response.json() assert "logs" in data def test_security_stats_handles_errors(test_app, admin_headers, mock_docker_client): """Test security stats handles Docker errors gracefully""" mock_docker_client.containers.get.side_effect = Exception("Docker error") response = test_app.get("/api/security/stats", headers=admin_headers) assert response.status_code == 200 data = response.json() assert "failed_logins_24h" in data assert data["failed_logins_24h"] == 0