Skip to content

Commit 559e766

Browse files
committed
[fix] Use UUID converters for users API detail routes #487
User and organization API detail routes currently use string path converters even though the underlying resources are UUID-backed. This allows malformed IDs to resolve to DRF views and return 401 instead of being rejected at the routing boundary with 404. Update the five affected routes to use uuid converters and add a regression test covering malformed UUID paths. Closes #487
1 parent e904269 commit 559e766

2 files changed

Lines changed: 19 additions & 5 deletions

File tree

openwisp_users/api/urls.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def get_api_urls(api_views=None):
1616
name="organization_list",
1717
),
1818
path(
19-
"users/organization/<str:pk>/",
19+
"users/organization/<uuid:pk>/",
2020
views.organization_detail,
2121
name="organization_detail",
2222
),
@@ -25,19 +25,19 @@ def get_api_urls(api_views=None):
2525
views.user_list,
2626
name="user_list",
2727
),
28-
path("users/user/<str:pk>/", views.user_detail, name="user_detail"),
28+
path("users/user/<uuid:pk>/", views.user_detail, name="user_detail"),
2929
path(
30-
"users/user/<str:pk>/password/",
30+
"users/user/<uuid:pk>/password/",
3131
views.change_password,
3232
name="change_password",
3333
),
3434
path(
35-
"users/user/<str:pk>/email/",
35+
"users/user/<uuid:pk>/email/",
3636
views.email_list,
3737
name="email_list",
3838
),
3939
path(
40-
"users/user/<str:pk>/email/<int:email_id>/",
40+
"users/user/<uuid:pk>/email/<int:email_id>/",
4141
views.email_update,
4242
name="email_update",
4343
),

openwisp_users/tests/test_api/test_views.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,17 @@ def test_protected_api_mixin_view(self):
2424
self.assertEqual(response.headers["WWW-Authenticate"], "Bearer")
2525
self.assertEqual(response.data["detail"], auth_error)
2626
self.assertEqual(response.status_code, 401)
27+
28+
def test_invalid_uuid_routes_return_404(self):
29+
invalid_uuid_paths = (
30+
"/api/v1/users/user/not-a-uuid/",
31+
"/api/v1/users/organization/not-a-uuid/",
32+
"/api/v1/users/user/not-a-uuid/password/",
33+
"/api/v1/users/user/not-a-uuid/email/",
34+
"/api/v1/users/user/not-a-uuid/email/1/",
35+
)
36+
37+
for path in invalid_uuid_paths:
38+
with self.subTest(path=path):
39+
response = self.client.get(path)
40+
self.assertEqual(response.status_code, 404)

0 commit comments

Comments
 (0)