Skip to content

Commit

Permalink
Add UserView.get() to retrieve logged-in user details re #11261
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobtylerwalls committed Aug 13, 2024
1 parent eec0666 commit 1e796db
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 1 deletion.
1 change: 1 addition & 0 deletions arches/app/templates/arches_urls.htm
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
api_bulk_disambiguated_resource_instance="{% url 'api_bulk_disambiguated_resource_instance' %}"
api_resources='(resourceid)=>{return "{% url "resources" "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" %}".replace("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", resourceid)}'
api_search_component_data='"{% url "api_search_component_data" "aaaa"%}".replace("aaaa", "")'
api_user="{% url 'api_user' %}"
api_user_incomplete_workflows="{% url 'api_user_incomplete_workflows' %}"
api_get_frontend_i18n_data="{% url 'get_frontend_i18n_data' %}"
geojson="{% url 'geojson' %}"
Expand Down
25 changes: 25 additions & 0 deletions arches/app/views/api/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from http import HTTPStatus

from django.utils.translation import gettext as _

from arches.app.utils.betterJSONSerializer import JSONSerializer
from arches.app.utils.response import JSONErrorResponse, JSONResponse
from arches.app.views.api import APIBase


class UserView(APIBase):
http_method_names = ["get"]

def get(self, request):
if not request.user.is_active:
return JSONErrorResponse(
title=_("Login required"),
message=_("This account is no longer active."),
status=HTTPStatus.FORBIDDEN,
)

# N.B.: SetAnonymousUser middleware provides an anonymous User,
# so don't infer from a 200 OK (or even is_authenticated, if we
# later serialize that) that you have an authenticated user.
fields = {"first_name", "last_name", "username"}
return JSONResponse(JSONSerializer().serialize(request.user, fields=fields))
3 changes: 2 additions & 1 deletion arches/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from django.contrib.auth import views as auth_views
from django.urls import include, path, re_path
from arches.app.views import concept, main, map, search, graph, api
from arches.app.views.api import auth as api_auth
from arches.app.views.api import auth as api_auth, user as api_user
from arches.app.views.admin import ReIndexResources, ClearUserPermissionCache
from arches.app.views.etl_manager import ETLManagerView
from arches.app.views.file import FileView, TempFileView
Expand Down Expand Up @@ -572,6 +572,7 @@
),
path("api/login", api_auth.Login.as_view(), name="api_login"),
path("api/logout", api_auth.Logout.as_view(), name="api_logout"),
path("api/user", api_user.UserView.as_view(), name="api_user"),
re_path(
r"^api/tiles/(?P<tileid>%s|())$" % (uuid_regex),
api.Tile.as_view(),
Expand Down
52 changes: 52 additions & 0 deletions tests/views/api/test_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from http import HTTPStatus

from django.contrib.auth.models import User
from django.test import TestCase
from django.urls import reverse

# these tests can be run from the command line via
# python manage.py test tests.views.api.test_user --settings="tests.test_settings"


class UserAPITests(TestCase):
@classmethod
def setUpTestData(cls):
cls.visitor = User.objects.create(
username="visitor",
first_name="Esperanza",
last_name="Spalding",
)
cls.visitor.set_password("jazz")
cls.visitor.save()

def test_logged_in_user(self):
self.client.force_login(self.visitor)
response = self.client.get(reverse("api_user"))
self.assertContains(
response,
'{"first_name": "Esperanza", "last_name": "Spalding", "username": "visitor"}',
status_code=HTTPStatus.OK,
)
self.assertNotContains(response, "password")

def test_anonymous_user(self):
response = self.client.get(reverse("api_user"))
self.assertContains(
response,
'{"first_name": "", "last_name": "", "username": "anonymous"}',
status_code=HTTPStatus.OK,
)
self.assertNotContains(response, "password")

def test_inactive_user(self):
self.visitor.is_active = False
self.visitor.save()

self.client.force_login(self.visitor)
with self.assertLogs("django.request", level="WARNING"):
response = self.client.get(reverse("api_user"))
self.assertContains(
response,
"This account is no longer active.",
status_code=HTTPStatus.FORBIDDEN,
)

0 comments on commit 1e796db

Please sign in to comment.