forked from enviPath/enviPy
Add API key authentication to v1 API Also includes: - management command to create keys for users - Improvements to API tests Minor: - more robust way to start docker dev container. Reviewed-on: enviPath/enviPy#327 Co-authored-by: Tobias O <tobias.olenyi@envipath.com> Co-committed-by: Tobias O <tobias.olenyi@envipath.com>
95 lines
3.4 KiB
Python
95 lines
3.4 KiB
Python
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)
|