feat(be-auth): add flow to query current authenticated user

This commit is contained in:
Marc 2024-01-03 16:23:47 -05:00
parent e80bb69e32
commit 39d71e2032
Signed by: marc
GPG key ID: 048E042F22B5DC79
3 changed files with 79 additions and 11 deletions

View file

@ -0,0 +1,18 @@
from rest_framework import serializers
from django.contrib.auth import get_user_model
class UserSerializer(serializers.ModelSerializer):
"""Serializes an instance of AuthUser"""
class Meta:
model = get_user_model()
fields = [
"id",
"username",
"first_name",
"last_name",
"email",
"date_joined",
"last_login",
]

View file

@ -1,7 +1,7 @@
import logging
import datetime
import django.http
from django.http import HttpResponse, JsonResponse, HttpRequest
import django.contrib.auth
import rest_framework.views
import rest_framework.status
@ -9,6 +9,7 @@ import rest_framework.status
import identity.jwt
from identity.models import AuthenticationToken
from identity.token_management import revoke_token_by_id
from identity.serializers import UserSerializer
AuthUser = django.contrib.auth.get_user_model()
@ -20,7 +21,7 @@ class SessionListView(rest_framework.views.APIView):
Views handling authenticated user sessions.
"""
def post(self, request: django.http.HttpRequest) -> django.http.HttpResponse:
def post(self, request: HttpRequest) -> HttpResponse:
"""
Handles signing in for existing users.
@ -56,7 +57,7 @@ class SessionListView(rest_framework.views.APIView):
expires_at=datetime.datetime.fromtimestamp(token_data["exp"]),
)
response = django.http.JsonResponse(
response = JsonResponse(
{"refresh_token": token_tracker.refresh_token}, status=201
)
@ -66,9 +67,9 @@ class SessionListView(rest_framework.views.APIView):
return response
return django.http.HttpResponse(status=401)
return HttpResponse(status=401)
def delete(self, request: django.http.HttpRequest) -> django.http.HttpResponse:
def delete(self, request: HttpRequest) -> HttpResponse:
"""
Logs out the requesting user.
@ -79,12 +80,12 @@ class SessionListView(rest_framework.views.APIView):
current_token_id = request.session.get("token_id", None)
if current_token_id is None:
return django.http.HttpResponse(status=400)
return HttpResponse(status=400)
revoke_token_by_id(current_token_id)
django.contrib.auth.logout(request)
return django.http.HttpResponse(status=204)
return HttpResponse(status=204)
class UserListView(rest_framework.views.APIView):
@ -92,7 +93,9 @@ class UserListView(rest_framework.views.APIView):
Routes dealing with non-specific users (without IDs).
"""
def post(self, request: django.http.HttpRequest) -> django.http.HttpResponse:
queryset = AuthUser.objects.all()
def post(self, request: HttpRequest) -> HttpResponse:
"""
Allows the creation of new users.
@ -115,8 +118,24 @@ class UserListView(rest_framework.views.APIView):
)
except Exception as e: # pylint: disable=broad-exception-caught
logger.exception(e)
return django.http.HttpResponse(status=400)
return HttpResponse(status=400)
return django.http.JsonResponse(
return JsonResponse(
{"username": new_user.username, "id": new_user.id}, status=201
)
def get(self, request: HttpRequest) -> HttpResponse:
"""
Retrieves data about the current user.
If the request is made unauthenticated, a 403 is returned.
"""
if not request.user.is_authenticated:
return HttpResponse(status=403)
current_user = self.queryset.get(id=request.user.id)
current_user_data = UserSerializer(current_user).data
return JsonResponse(current_user_data, status=200)

View file

@ -1,10 +1,13 @@
import typing
import pytest
import django.urls
import django.contrib.auth
from django.test import Client
import identity.jwt
from identity.models import AuthenticationToken
from identity.serializers import UserSerializer
AuthUser = django.contrib.auth.get_user_model()
@ -41,6 +44,15 @@ def fixture_logout_request(auth_client):
return _logout_request
@pytest.fixture(name="get_current_user_request")
def fixture_get_current_user(auth_client):
def _get_current_user_request(client: typing.Optional[Client] = None):
chosen_client = client if client is not None else auth_client
return chosen_client.get(django.urls.reverse("auth-user-list"))
return _get_current_user_request
def test_create_new_user_returns_created_resource_on_success(create_user_request):
mock_uname = "user"
mock_pwd = "password"
@ -99,3 +111,22 @@ def test_user_logout_ends_session(login_request, logout_request, test_user_crede
assert logout_response.status_code == 204
assert token_record.revoked
def test_get_current_user_returns_data_if_authenticated(
test_user, login_request, test_user_credentials, get_current_user_request
):
login_request(test_user_credentials["username"], test_user_credentials["password"])
response = get_current_user_request()
test_user.refresh_from_db()
assert response.status_code == 200
assert response.json() == UserSerializer(test_user).data
def test_get_current_user_returns_403_if_unauthenticated(
no_auth_client, get_current_user_request
):
response = get_current_user_request(no_auth_client)
assert response.status_code == 403