from datetime import timedelta from django.test import TestCase, tag from django.utils import timezone from epdb.logic import PackageManager, UserManager from epdb.models import APIToken @tag("api", "auth") class BearerTokenAuthTests(TestCase): @classmethod def setUpTestData(cls): cls.user = UserManager.create_user( "token-user", "token-user@envipath.com", "SuperSafe", set_setting=False, add_to_group=False, is_active=True, ) default_pkg = cls.user.default_package cls.user.default_package = None cls.user.save() if default_pkg: default_pkg.delete() cls.unreviewed_package = PackageManager.create_package( cls.user, "Token Auth Package", "Package for token auth tests" ) def _auth_header(self, raw_token): return {"HTTP_AUTHORIZATION": f"Bearer {raw_token}"} def test_valid_token_allows_access(self): _, raw_token = APIToken.create_token(self.user, name="Valid Token", expires_days=1) response = self.client.get("/api/v1/compounds/", **self._auth_header(raw_token)) self.assertEqual(response.status_code, 200) def test_expired_token_rejected(self): token, raw_token = APIToken.create_token(self.user, name="Expired Token", expires_days=1) token.expires_at = timezone.now() - timedelta(days=1) token.save(update_fields=["expires_at"]) response = self.client.get("/api/v1/compounds/", **self._auth_header(raw_token)) self.assertEqual(response.status_code, 401) def test_inactive_token_rejected(self): token, raw_token = APIToken.create_token(self.user, name="Inactive Token", expires_days=1) token.is_active = False token.save(update_fields=["is_active"]) response = self.client.get("/api/v1/compounds/", **self._auth_header(raw_token)) self.assertEqual(response.status_code, 401) def test_invalid_token_rejected(self): response = self.client.get("/api/v1/compounds/", HTTP_AUTHORIZATION="Bearer invalid-token") self.assertEqual(response.status_code, 401) def test_no_token_rejected(self): self.client.logout() response = self.client.get("/api/v1/compounds/") self.assertEqual(response.status_code, 401) def test_bearer_populates_request_user_for_packages(self): response = self.client.get("/api/v1/packages/") self.assertEqual(response.status_code, 200) payload = response.json() uuids = {item["uuid"] for item in payload["items"]} self.assertNotIn(str(self.unreviewed_package.uuid), uuids) _, raw_token = APIToken.create_token(self.user, name="Package Token", expires_days=1) response = self.client.get("/api/v1/packages/", **self._auth_header(raw_token)) self.assertEqual(response.status_code, 200) payload = response.json() uuids = {item["uuid"] for item in payload["items"]} self.assertIn(str(self.unreviewed_package.uuid), uuids) def test_session_auth_still_works_without_bearer(self): self.client.force_login(self.user) response = self.client.get("/api/v1/packages/") self.assertEqual(response.status_code, 200) payload = response.json() uuids = {item["uuid"] for item in payload["items"]} self.assertIn(str(self.unreviewed_package.uuid), uuids)