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.
164 lines
6.3 KiB
Python
164 lines
6.3 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.ADMIN,
|
|
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.ADMIN,
|
|
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.ADMIN,
|
|
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.ADMIN,
|
|
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()
|
|
|