You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
orquestrador/tests/test_admin_panel_auth_web.py

165 lines
6.4 KiB
Python

import unittest
from fastapi.testclient import TestClient
from admin_app.api.dependencies import get_auth_service, get_current_panel_staff_context
from admin_app.api.panel_session import PANEL_ACCESS_COOKIE_NAME, PANEL_REFRESH_COOKIE_NAME
from admin_app.app_factory import create_app
from admin_app.core import (
AdminAuthenticatedSession,
AdminSettings,
AuthenticatedStaffContext,
AuthenticatedStaffPrincipal,
)
from shared.contracts import StaffRole
class _FakePanelAuthService:
def login(self, email: str, password: str, *, ip_address: str | None, user_agent: str | None):
if email == "admin@empresa.com" and password == "SenhaMuitoSegura!123":
principal = AuthenticatedStaffPrincipal(
id=1,
email="admin@empresa.com",
display_name="Administrador",
role=StaffRole.DIRETOR,
is_active=True,
)
return AdminAuthenticatedSession(
session_id=77,
access_token="panel-access-token",
refresh_token="panel-refresh-token",
token_type="bearer",
expires_in_seconds=1800,
principal=principal,
)
return None
def refresh_session(self, refresh_token: str, *, ip_address: str | None, user_agent: str | None):
if refresh_token == "panel-refresh-token":
principal = AuthenticatedStaffPrincipal(
id=1,
email="admin@empresa.com",
display_name="Administrador",
role=StaffRole.DIRETOR,
is_active=True,
)
return AdminAuthenticatedSession(
session_id=77,
access_token="panel-access-token-next",
refresh_token="panel-refresh-token-next",
token_type="bearer",
expires_in_seconds=1800,
principal=principal,
)
return None
def get_authenticated_context(self, access_token: str) -> AuthenticatedStaffContext:
if access_token in {"panel-access-token", "panel-access-token-next"}:
return AuthenticatedStaffContext(
principal=AuthenticatedStaffPrincipal(
id=1,
email="admin@empresa.com",
display_name="Administrador",
role=StaffRole.DIRETOR,
is_active=True,
),
session_id=77,
)
raise ValueError("invalid token")
def logout(
self,
session_id: int,
*,
actor_staff_account_id: int | None,
ip_address: str | None,
user_agent: str | None,
) -> bool:
return session_id == 77
def logout_by_refresh_token(
self,
refresh_token: str,
*,
ip_address: str | None,
user_agent: str | None,
) -> int | None:
if refresh_token in {"panel-refresh-token", "panel-refresh-token-next"}:
return 77
return None
class AdminPanelAuthWebTests(unittest.TestCase):
def setUp(self):
app = create_app(AdminSettings(admin_auth_token_secret="test-secret"))
app.dependency_overrides[get_auth_service] = lambda: _FakePanelAuthService()
self.client = TestClient(app)
self.app = app
def tearDown(self):
self.app.dependency_overrides.clear()
def test_panel_login_sets_http_only_cookies_and_returns_session_payload(self):
response = self.client.post(
"/panel/auth/login",
json={"email": "admin@empresa.com", "password": "SenhaMuitoSegura!123"},
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json()["session_id"], 77)
self.assertEqual(response.json()["redirect_to"], "/panel/admin")
self.assertEqual(response.cookies.get(PANEL_ACCESS_COOKIE_NAME), "panel-access-token")
self.assertEqual(response.cookies.get(PANEL_REFRESH_COOKIE_NAME), "panel-refresh-token")
set_cookie_headers = response.headers.get_list("set-cookie")
self.assertTrue(any("HttpOnly" in header for header in set_cookie_headers))
def test_panel_refresh_rotates_cookie_backed_session(self):
self.client.cookies.set(PANEL_REFRESH_COOKIE_NAME, "panel-refresh-token")
response = self.client.post("/panel/auth/refresh")
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json()["message"], "Sessao administrativa web renovada.")
self.assertEqual(response.cookies.get(PANEL_ACCESS_COOKIE_NAME), "panel-access-token-next")
self.assertEqual(response.cookies.get(PANEL_REFRESH_COOKIE_NAME), "panel-refresh-token-next")
def test_panel_session_reads_authenticated_staff_from_cookie_context(self):
app = create_app(AdminSettings(admin_auth_token_secret="test-secret"))
app.dependency_overrides[get_current_panel_staff_context] = lambda: AuthenticatedStaffContext(
principal=AuthenticatedStaffPrincipal(
id=1,
email="admin@empresa.com",
display_name="Administrador",
role=StaffRole.DIRETOR,
is_active=True,
),
session_id=77,
)
client = TestClient(app)
try:
response = client.get("/panel/auth/session")
finally:
app.dependency_overrides.clear()
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json()["staff_account"]["email"], "admin@empresa.com")
self.assertEqual(response.json()["session_id"], 77)
def test_panel_logout_clears_cookies_and_returns_login_redirect(self):
self.client.cookies.set(PANEL_ACCESS_COOKIE_NAME, "panel-access-token")
self.client.cookies.set(PANEL_REFRESH_COOKIE_NAME, "panel-refresh-token")
response = self.client.post("/panel/auth/logout")
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json()["redirect_to"], "/login")
set_cookie_headers = response.headers.get_list("set-cookie")
self.assertTrue(any(PANEL_ACCESS_COOKIE_NAME in header and "Max-Age=0" in header for header in set_cookie_headers))
self.assertTrue(any(PANEL_REFRESH_COOKIE_NAME in header and "Max-Age=0" in header for header in set_cookie_headers))
if __name__ == "__main__":
unittest.main()