[Feature] Create API Key Authenticaton for v1 API (#327)

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>
This commit is contained in:
2026-02-11 02:29:54 +13:00
committed by jebus
parent c0cfdb9255
commit 5789f20e7f
15 changed files with 282 additions and 165 deletions

View File

@ -1,8 +1,34 @@
import hashlib
from ninja.security import HttpBearer
from ninja.errors import HttpError
from epdb.models import APIToken
class BearerTokenAuth(HttpBearer):
def authenticate(self, request, token):
# FIXME: placeholder; implement it in O(1) time
raise HttpError(401, "Invalid or expired token")
if token is None:
return None
hashed_token = hashlib.sha256(token.encode()).hexdigest()
user = APIToken.authenticate(hashed_token, hashed=True)
if not user:
raise HttpError(401, "Invalid or expired token")
request.user = user
return user
class OptionalBearerTokenAuth:
"""Bearer auth that allows unauthenticated access.
Validates the Bearer token if present (401 on invalid token),
otherwise lets the request through for anonymous/session access.
"""
def __init__(self):
self._bearer = BearerTokenAuth()
def __call__(self, request):
return self._bearer(request) or request.user

View File

@ -3,6 +3,7 @@ from ninja import Router
from ninja_extra.pagination import paginate
import logging
from ..auth import OptionalBearerTokenAuth
from ..dal import get_user_packages_for_read
from ..pagination import EnhancedPageNumberPagination
from ..schemas import PackageOutSchema, SelfReviewStatusFilter
@ -11,7 +12,11 @@ router = Router()
logger = logging.getLogger(__name__)
@router.get("/packages/", response=EnhancedPageNumberPagination.Output[PackageOutSchema], auth=None)
@router.get(
"/packages/",
response=EnhancedPageNumberPagination.Output[PackageOutSchema],
auth=OptionalBearerTokenAuth(),
)
@paginate(
EnhancedPageNumberPagination,
page_size=s.API_PAGINATION_DEFAULT_PAGE_SIZE,