From df85cc967c2e951cb02c8ea3b9074dc6bd7dc301 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Sat, 20 Jan 2024 11:12:05 -0600 Subject: [PATCH 1/8] Fixes: #14840 - Forces API to use proxy model --- netbox/users/api/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/users/api/views.py b/netbox/users/api/views.py index 62a32c71b8b..487d4769c04 100644 --- a/netbox/users/api/views.py +++ b/netbox/users/api/views.py @@ -15,7 +15,7 @@ from netbox.api.viewsets import NetBoxModelViewSet from users import filtersets -from users.models import ObjectPermission, Token, UserConfig +from users.models import ObjectPermission, Token, UserConfig, NetBoxUser from utilities.querysets import RestrictedQuerySet from utilities.utils import deepmerge from . import serializers @@ -34,7 +34,7 @@ def get_view_name(self): # class UserViewSet(NetBoxModelViewSet): - queryset = RestrictedQuerySet(model=get_user_model()).prefetch_related('groups').order_by('username') + queryset = RestrictedQuerySet(model=NetBoxUser).prefetch_related('groups').order_by('username') serializer_class = serializers.UserSerializer filterset_class = filtersets.UserFilterSet From 1d784cfe5d689a00ae3c75edc56ce226e62e8fc3 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Mon, 22 Jan 2024 16:19:34 -0600 Subject: [PATCH 2/8] Update tests to use proxy model --- netbox/users/tests/test_api.py | 32 +++++++++------------ netbox/users/tests/test_filtersets.py | 39 ++++++++++++-------------- netbox/users/tests/test_models.py | 14 ++++----- netbox/users/tests/test_preferences.py | 6 ++-- 4 files changed, 40 insertions(+), 51 deletions(-) diff --git a/netbox/users/tests/test_api.py b/netbox/users/tests/test_api.py index 090ccc263d4..b64351cdb9c 100644 --- a/netbox/users/tests/test_api.py +++ b/netbox/users/tests/test_api.py @@ -1,16 +1,12 @@ -from django.contrib.auth import get_user_model from django.contrib.auth.models import Group from django.contrib.contenttypes.models import ContentType from django.urls import reverse -from users.models import ObjectPermission, Token +from users.models import ObjectPermission, Token, NetBoxUser from utilities.testing import APIViewTestCases, APITestCase, create_test_user from utilities.utils import deepmerge -User = get_user_model() - - class AppTest(APITestCase): def test_root(self): @@ -22,7 +18,7 @@ def test_root(self): class UserTest(APIViewTestCases.APIViewTestCase): - model = User + model = NetBoxUser view_namespace = 'users' brief_fields = ['display', 'id', 'url', 'username'] validation_excluded_fields = ['password'] @@ -48,11 +44,11 @@ class UserTest(APIViewTestCases.APIViewTestCase): def setUpTestData(cls): users = ( - User(username='User_1', password='password1'), - User(username='User_2', password='password2'), - User(username='User_3', password='password3'), + NetBoxUser(username='User_1', password='password1'), + NetBoxUser(username='User_2', password='password2'), + NetBoxUser(username='User_3', password='password3'), ) - User.objects.bulk_create(users) + NetBoxUser.objects.bulk_create(users) def test_that_password_is_changed(self): """ @@ -71,7 +67,7 @@ def test_that_password_is_changed(self): 'username': 'user1', 'password': 'abc123', } - user = User.objects.create_user(**user_credentials) + user = NetBoxUser.objects.create_user(**user_credentials) data = { 'password': 'newpassword' @@ -82,7 +78,7 @@ def test_that_password_is_changed(self): self.assertEqual(response.status_code, 200) - updated_user = User.objects.get(id=user.id) + updated_user = NetBoxUser.objects.get(id=user.id) self.assertTrue(updated_user.check_password(data['password'])) @@ -177,7 +173,7 @@ def test_provision_token_valid(self): 'username': 'user1', 'password': 'abc123', } - user = User.objects.create_user(**user_credentials) + user = NetBoxUser.objects.create_user(**user_credentials) data = { **user_credentials, @@ -216,7 +212,7 @@ def test_provision_token_other_user(self): ObjectPermission.objects.filter(users=self.user).delete() self.add_permissions('users.add_token') - user2 = User.objects.create_user(username='testuser2') + user2 = NetBoxUser.objects.create_user(username='testuser2') data = { 'user': user2.id, } @@ -254,11 +250,11 @@ def setUpTestData(cls): Group.objects.bulk_create(groups) users = ( - User(username='User 1', is_active=True), - User(username='User 2', is_active=True), - User(username='User 3', is_active=True), + NetBoxUser(username='User 1', is_active=True), + NetBoxUser(username='User 2', is_active=True), + NetBoxUser(username='User 3', is_active=True), ) - User.objects.bulk_create(users) + NetBoxUser.objects.bulk_create(users) object_type = ContentType.objects.get(app_label='dcim', model='device') diff --git a/netbox/users/tests/test_filtersets.py b/netbox/users/tests/test_filtersets.py index 38a0df813bc..e02bdb39153 100644 --- a/netbox/users/tests/test_filtersets.py +++ b/netbox/users/tests/test_filtersets.py @@ -1,20 +1,17 @@ import datetime -from django.contrib.auth import get_user_model from django.contrib.auth.models import Group from django.contrib.contenttypes.models import ContentType from django.test import TestCase from django.utils.timezone import make_aware from users import filtersets -from users.models import ObjectPermission, Token +from users.models import ObjectPermission, Token, NetBoxUser from utilities.testing import BaseFilterSetTests -User = get_user_model() - class UserTestCase(TestCase, BaseFilterSetTests): - queryset = User.objects.all() + queryset = NetBoxUser.objects.all() filterset = filtersets.UserFilterSet @classmethod @@ -28,7 +25,7 @@ def setUpTestData(cls): Group.objects.bulk_create(groups) users = ( - User( + NetBoxUser( username='User1', first_name='Hank', last_name='Hill', @@ -36,32 +33,32 @@ def setUpTestData(cls): is_staff=True, is_superuser=True ), - User( + NetBoxUser( username='User2', first_name='Dale', last_name='Gribble', email='dale@dalesdeadbug.com' ), - User( + NetBoxUser( username='User3', first_name='Bill', last_name='Dauterive', email='bill.dauterive@army.mil' ), - User( + NetBoxUser( username='User4', first_name='Jeff', last_name='Boomhauer', email='boomhauer@dangolemail.com' ), - User( + NetBoxUser( username='User5', first_name='Debbie', last_name='Grund', is_active=False ) ) - User.objects.bulk_create(users) + NetBoxUser.objects.bulk_create(users) users[0].groups.set([groups[0]]) users[1].groups.set([groups[1]]) @@ -145,11 +142,11 @@ def setUpTestData(cls): Group.objects.bulk_create(groups) users = ( - User(username='User1'), - User(username='User2'), - User(username='User3'), + NetBoxUser(username='User1'), + NetBoxUser(username='User2'), + NetBoxUser(username='User3'), ) - User.objects.bulk_create(users) + NetBoxUser.objects.bulk_create(users) object_types = ( ContentType.objects.get(app_label='dcim', model='site'), @@ -192,7 +189,7 @@ def test_group(self): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_user(self): - users = User.objects.filter(username__in=['User1', 'User2']) + users = NetBoxUser.objects.filter(username__in=['User1', 'User2']) params = {'user_id': [users[0].pk, users[1].pk]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'user': [users[0].username, users[1].username]} @@ -232,11 +229,11 @@ class TokenTestCase(TestCase, BaseFilterSetTests): def setUpTestData(cls): users = ( - User(username='User1'), - User(username='User2'), - User(username='User3'), + NetBoxUser(username='User1'), + NetBoxUser(username='User2'), + NetBoxUser(username='User3'), ) - User.objects.bulk_create(users) + NetBoxUser.objects.bulk_create(users) future_date = make_aware(datetime.datetime(3000, 1, 1)) past_date = make_aware(datetime.datetime(2000, 1, 1)) @@ -252,7 +249,7 @@ def test_q(self): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) def test_user(self): - users = User.objects.order_by('id')[:2] + users = NetBoxUser.objects.order_by('id')[:2] params = {'user_id': [users[0].pk, users[1].pk]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'user': [users[0].username, users[1].username]} diff --git a/netbox/users/tests/test_models.py b/netbox/users/tests/test_models.py index 791ea8fb4ee..effaeb29a52 100644 --- a/netbox/users/tests/test_models.py +++ b/netbox/users/tests/test_models.py @@ -1,8 +1,6 @@ -from django.contrib.auth import get_user_model from django.test import TestCase - -User = get_user_model() +from users.models import NetBoxUser class UserConfigTest(TestCase): @@ -10,7 +8,7 @@ class UserConfigTest(TestCase): @classmethod def setUpTestData(cls): - user = User.objects.create_user(username='testuser') + user = NetBoxUser.objects.create_user(username='testuser') user.config.data = { 'a': True, 'b': { @@ -32,7 +30,7 @@ def setUpTestData(cls): user.config.save() def test_get(self): - userconfig = User.objects.get(username='testuser').config + userconfig = NetBoxUser.objects.get(username='testuser').config # Retrieve root and nested values self.assertEqual(userconfig.get('a'), True) @@ -52,7 +50,7 @@ def test_get(self): self.assertEqual(userconfig.get('b.foo.x.invalid', 'DEFAULT'), 'DEFAULT') def test_all(self): - userconfig = User.objects.get(username='testuser').config + userconfig = NetBoxUser.objects.get(username='testuser').config flattened_data = { 'a': True, 'b.foo': 101, @@ -66,7 +64,7 @@ def test_all(self): self.assertEqual(userconfig.all(), flattened_data) def test_set(self): - userconfig = User.objects.get(username='testuser').config + userconfig = NetBoxUser.objects.get(username='testuser').config # Overwrite existing values userconfig.set('a', 'abc') @@ -95,7 +93,7 @@ def test_set(self): userconfig.set('a.x', 1) def test_clear(self): - userconfig = User.objects.get(username='testuser').config + userconfig = NetBoxUser.objects.get(username='testuser').config # Clear existing values userconfig.clear('a') diff --git a/netbox/users/tests/test_preferences.py b/netbox/users/tests/test_preferences.py index 203a67bdd32..6d0b731634d 100644 --- a/netbox/users/tests/test_preferences.py +++ b/netbox/users/tests/test_preferences.py @@ -5,6 +5,7 @@ from dcim.models import Site from dcim.tables import SiteTable +from users.models import NetBoxUser from users.preferences import UserPreference from utilities.testing import TestCase @@ -16,9 +17,6 @@ } -User = get_user_model() - - class UserPreferencesTest(TestCase): user_permissions = ['dcim.view_site'] @@ -42,7 +40,7 @@ def test_userpreference(self): @override_settings(DEFAULT_USER_PREFERENCES=DEFAULT_USER_PREFERENCES) def test_default_preferences(self): - user = User.objects.create(username='User 1') + user = NetBoxUser.objects.create(username='User 1') userconfig = user.config self.assertEqual(userconfig.data, DEFAULT_USER_PREFERENCES) From 773daedf8cd75d8c181477b5d4a2b91e73e57606 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Wed, 24 Jan 2024 10:42:39 -0600 Subject: [PATCH 3/8] Revert "Update tests to use proxy model" This reverts commit 1d784cfe5d689a00ae3c75edc56ce226e62e8fc3. --- netbox/users/tests/test_api.py | 32 ++++++++++++--------- netbox/users/tests/test_filtersets.py | 39 ++++++++++++++------------ netbox/users/tests/test_models.py | 14 +++++---- netbox/users/tests/test_preferences.py | 6 ++-- 4 files changed, 51 insertions(+), 40 deletions(-) diff --git a/netbox/users/tests/test_api.py b/netbox/users/tests/test_api.py index b64351cdb9c..090ccc263d4 100644 --- a/netbox/users/tests/test_api.py +++ b/netbox/users/tests/test_api.py @@ -1,12 +1,16 @@ +from django.contrib.auth import get_user_model from django.contrib.auth.models import Group from django.contrib.contenttypes.models import ContentType from django.urls import reverse -from users.models import ObjectPermission, Token, NetBoxUser +from users.models import ObjectPermission, Token from utilities.testing import APIViewTestCases, APITestCase, create_test_user from utilities.utils import deepmerge +User = get_user_model() + + class AppTest(APITestCase): def test_root(self): @@ -18,7 +22,7 @@ def test_root(self): class UserTest(APIViewTestCases.APIViewTestCase): - model = NetBoxUser + model = User view_namespace = 'users' brief_fields = ['display', 'id', 'url', 'username'] validation_excluded_fields = ['password'] @@ -44,11 +48,11 @@ class UserTest(APIViewTestCases.APIViewTestCase): def setUpTestData(cls): users = ( - NetBoxUser(username='User_1', password='password1'), - NetBoxUser(username='User_2', password='password2'), - NetBoxUser(username='User_3', password='password3'), + User(username='User_1', password='password1'), + User(username='User_2', password='password2'), + User(username='User_3', password='password3'), ) - NetBoxUser.objects.bulk_create(users) + User.objects.bulk_create(users) def test_that_password_is_changed(self): """ @@ -67,7 +71,7 @@ def test_that_password_is_changed(self): 'username': 'user1', 'password': 'abc123', } - user = NetBoxUser.objects.create_user(**user_credentials) + user = User.objects.create_user(**user_credentials) data = { 'password': 'newpassword' @@ -78,7 +82,7 @@ def test_that_password_is_changed(self): self.assertEqual(response.status_code, 200) - updated_user = NetBoxUser.objects.get(id=user.id) + updated_user = User.objects.get(id=user.id) self.assertTrue(updated_user.check_password(data['password'])) @@ -173,7 +177,7 @@ def test_provision_token_valid(self): 'username': 'user1', 'password': 'abc123', } - user = NetBoxUser.objects.create_user(**user_credentials) + user = User.objects.create_user(**user_credentials) data = { **user_credentials, @@ -212,7 +216,7 @@ def test_provision_token_other_user(self): ObjectPermission.objects.filter(users=self.user).delete() self.add_permissions('users.add_token') - user2 = NetBoxUser.objects.create_user(username='testuser2') + user2 = User.objects.create_user(username='testuser2') data = { 'user': user2.id, } @@ -250,11 +254,11 @@ def setUpTestData(cls): Group.objects.bulk_create(groups) users = ( - NetBoxUser(username='User 1', is_active=True), - NetBoxUser(username='User 2', is_active=True), - NetBoxUser(username='User 3', is_active=True), + User(username='User 1', is_active=True), + User(username='User 2', is_active=True), + User(username='User 3', is_active=True), ) - NetBoxUser.objects.bulk_create(users) + User.objects.bulk_create(users) object_type = ContentType.objects.get(app_label='dcim', model='device') diff --git a/netbox/users/tests/test_filtersets.py b/netbox/users/tests/test_filtersets.py index e02bdb39153..38a0df813bc 100644 --- a/netbox/users/tests/test_filtersets.py +++ b/netbox/users/tests/test_filtersets.py @@ -1,17 +1,20 @@ import datetime +from django.contrib.auth import get_user_model from django.contrib.auth.models import Group from django.contrib.contenttypes.models import ContentType from django.test import TestCase from django.utils.timezone import make_aware from users import filtersets -from users.models import ObjectPermission, Token, NetBoxUser +from users.models import ObjectPermission, Token from utilities.testing import BaseFilterSetTests +User = get_user_model() + class UserTestCase(TestCase, BaseFilterSetTests): - queryset = NetBoxUser.objects.all() + queryset = User.objects.all() filterset = filtersets.UserFilterSet @classmethod @@ -25,7 +28,7 @@ def setUpTestData(cls): Group.objects.bulk_create(groups) users = ( - NetBoxUser( + User( username='User1', first_name='Hank', last_name='Hill', @@ -33,32 +36,32 @@ def setUpTestData(cls): is_staff=True, is_superuser=True ), - NetBoxUser( + User( username='User2', first_name='Dale', last_name='Gribble', email='dale@dalesdeadbug.com' ), - NetBoxUser( + User( username='User3', first_name='Bill', last_name='Dauterive', email='bill.dauterive@army.mil' ), - NetBoxUser( + User( username='User4', first_name='Jeff', last_name='Boomhauer', email='boomhauer@dangolemail.com' ), - NetBoxUser( + User( username='User5', first_name='Debbie', last_name='Grund', is_active=False ) ) - NetBoxUser.objects.bulk_create(users) + User.objects.bulk_create(users) users[0].groups.set([groups[0]]) users[1].groups.set([groups[1]]) @@ -142,11 +145,11 @@ def setUpTestData(cls): Group.objects.bulk_create(groups) users = ( - NetBoxUser(username='User1'), - NetBoxUser(username='User2'), - NetBoxUser(username='User3'), + User(username='User1'), + User(username='User2'), + User(username='User3'), ) - NetBoxUser.objects.bulk_create(users) + User.objects.bulk_create(users) object_types = ( ContentType.objects.get(app_label='dcim', model='site'), @@ -189,7 +192,7 @@ def test_group(self): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_user(self): - users = NetBoxUser.objects.filter(username__in=['User1', 'User2']) + users = User.objects.filter(username__in=['User1', 'User2']) params = {'user_id': [users[0].pk, users[1].pk]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'user': [users[0].username, users[1].username]} @@ -229,11 +232,11 @@ class TokenTestCase(TestCase, BaseFilterSetTests): def setUpTestData(cls): users = ( - NetBoxUser(username='User1'), - NetBoxUser(username='User2'), - NetBoxUser(username='User3'), + User(username='User1'), + User(username='User2'), + User(username='User3'), ) - NetBoxUser.objects.bulk_create(users) + User.objects.bulk_create(users) future_date = make_aware(datetime.datetime(3000, 1, 1)) past_date = make_aware(datetime.datetime(2000, 1, 1)) @@ -249,7 +252,7 @@ def test_q(self): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) def test_user(self): - users = NetBoxUser.objects.order_by('id')[:2] + users = User.objects.order_by('id')[:2] params = {'user_id': [users[0].pk, users[1].pk]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'user': [users[0].username, users[1].username]} diff --git a/netbox/users/tests/test_models.py b/netbox/users/tests/test_models.py index effaeb29a52..791ea8fb4ee 100644 --- a/netbox/users/tests/test_models.py +++ b/netbox/users/tests/test_models.py @@ -1,6 +1,8 @@ +from django.contrib.auth import get_user_model from django.test import TestCase -from users.models import NetBoxUser + +User = get_user_model() class UserConfigTest(TestCase): @@ -8,7 +10,7 @@ class UserConfigTest(TestCase): @classmethod def setUpTestData(cls): - user = NetBoxUser.objects.create_user(username='testuser') + user = User.objects.create_user(username='testuser') user.config.data = { 'a': True, 'b': { @@ -30,7 +32,7 @@ def setUpTestData(cls): user.config.save() def test_get(self): - userconfig = NetBoxUser.objects.get(username='testuser').config + userconfig = User.objects.get(username='testuser').config # Retrieve root and nested values self.assertEqual(userconfig.get('a'), True) @@ -50,7 +52,7 @@ def test_get(self): self.assertEqual(userconfig.get('b.foo.x.invalid', 'DEFAULT'), 'DEFAULT') def test_all(self): - userconfig = NetBoxUser.objects.get(username='testuser').config + userconfig = User.objects.get(username='testuser').config flattened_data = { 'a': True, 'b.foo': 101, @@ -64,7 +66,7 @@ def test_all(self): self.assertEqual(userconfig.all(), flattened_data) def test_set(self): - userconfig = NetBoxUser.objects.get(username='testuser').config + userconfig = User.objects.get(username='testuser').config # Overwrite existing values userconfig.set('a', 'abc') @@ -93,7 +95,7 @@ def test_set(self): userconfig.set('a.x', 1) def test_clear(self): - userconfig = NetBoxUser.objects.get(username='testuser').config + userconfig = User.objects.get(username='testuser').config # Clear existing values userconfig.clear('a') diff --git a/netbox/users/tests/test_preferences.py b/netbox/users/tests/test_preferences.py index 6d0b731634d..203a67bdd32 100644 --- a/netbox/users/tests/test_preferences.py +++ b/netbox/users/tests/test_preferences.py @@ -5,7 +5,6 @@ from dcim.models import Site from dcim.tables import SiteTable -from users.models import NetBoxUser from users.preferences import UserPreference from utilities.testing import TestCase @@ -17,6 +16,9 @@ } +User = get_user_model() + + class UserPreferencesTest(TestCase): user_permissions = ['dcim.view_site'] @@ -40,7 +42,7 @@ def test_userpreference(self): @override_settings(DEFAULT_USER_PREFERENCES=DEFAULT_USER_PREFERENCES) def test_default_preferences(self): - user = NetBoxUser.objects.create(username='User 1') + user = User.objects.create(username='User 1') userconfig = user.config self.assertEqual(userconfig.data, DEFAULT_USER_PREFERENCES) From 3ab8caa6154af6c074993a1c515842d39f3fb8e2 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Wed, 24 Jan 2024 10:42:40 -0600 Subject: [PATCH 4/8] Revert "Fixes: #14840 - Forces API to use proxy model" This reverts commit df85cc967c2e951cb02c8ea3b9074dc6bd7dc301. --- netbox/users/api/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/users/api/views.py b/netbox/users/api/views.py index 487d4769c04..62a32c71b8b 100644 --- a/netbox/users/api/views.py +++ b/netbox/users/api/views.py @@ -15,7 +15,7 @@ from netbox.api.viewsets import NetBoxModelViewSet from users import filtersets -from users.models import ObjectPermission, Token, UserConfig, NetBoxUser +from users.models import ObjectPermission, Token, UserConfig from utilities.querysets import RestrictedQuerySet from utilities.utils import deepmerge from . import serializers @@ -34,7 +34,7 @@ def get_view_name(self): # class UserViewSet(NetBoxModelViewSet): - queryset = RestrictedQuerySet(model=NetBoxUser).prefetch_related('groups').order_by('username') + queryset = RestrictedQuerySet(model=get_user_model()).prefetch_related('groups').order_by('username') serializer_class = serializers.UserSerializer filterset_class = filtersets.UserFilterSet From 15df8082aafbebf32c932c4c38b970851492eea8 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Wed, 24 Jan 2024 11:07:53 -0600 Subject: [PATCH 5/8] More realistic change to resole issue with netboxusers-list --- netbox/users/api/urls.py | 1 + netbox/users/api/views.py | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/netbox/users/api/urls.py b/netbox/users/api/urls.py index 599d0bb6158..2befc99717f 100644 --- a/netbox/users/api/urls.py +++ b/netbox/users/api/urls.py @@ -9,6 +9,7 @@ # Users and groups router.register('users', views.UserViewSet) +router.register('netboxusers', views.NetBoxUserViewSet) router.register('groups', views.GroupViewSet) # Tokens diff --git a/netbox/users/api/views.py b/netbox/users/api/views.py index 62a32c71b8b..822f274f495 100644 --- a/netbox/users/api/views.py +++ b/netbox/users/api/views.py @@ -5,6 +5,7 @@ from django.db.models import Count from drf_spectacular.utils import extend_schema from drf_spectacular.types import OpenApiTypes +from rest_framework.decorators import action from rest_framework.exceptions import AuthenticationFailed from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response @@ -15,7 +16,7 @@ from netbox.api.viewsets import NetBoxModelViewSet from users import filtersets -from users.models import ObjectPermission, Token, UserConfig +from users.models import ObjectPermission, Token, UserConfig, NetBoxUser from utilities.querysets import RestrictedQuerySet from utilities.utils import deepmerge from . import serializers @@ -33,6 +34,12 @@ def get_view_name(self): # Users and groups # +class NetBoxUserViewSet(NetBoxModelViewSet): + queryset = RestrictedQuerySet(model=NetBoxUser).prefetch_related('groups').order_by('username') + serializer_class = serializers.UserSerializer + filterset_class = filtersets.UserFilterSet + + class UserViewSet(NetBoxModelViewSet): queryset = RestrictedQuerySet(model=get_user_model()).prefetch_related('groups').order_by('username') serializer_class = serializers.UserSerializer From 979b71446d957d113926577fc3ad379bda50d222 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Fri, 26 Jan 2024 15:26:49 -0600 Subject: [PATCH 6/8] Revert "More realistic change to resole issue with netboxusers-list" This reverts commit 15df8082aafbebf32c932c4c38b970851492eea8. --- netbox/users/api/urls.py | 1 - netbox/users/api/views.py | 9 +-------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/netbox/users/api/urls.py b/netbox/users/api/urls.py index 2befc99717f..599d0bb6158 100644 --- a/netbox/users/api/urls.py +++ b/netbox/users/api/urls.py @@ -9,7 +9,6 @@ # Users and groups router.register('users', views.UserViewSet) -router.register('netboxusers', views.NetBoxUserViewSet) router.register('groups', views.GroupViewSet) # Tokens diff --git a/netbox/users/api/views.py b/netbox/users/api/views.py index 822f274f495..62a32c71b8b 100644 --- a/netbox/users/api/views.py +++ b/netbox/users/api/views.py @@ -5,7 +5,6 @@ from django.db.models import Count from drf_spectacular.utils import extend_schema from drf_spectacular.types import OpenApiTypes -from rest_framework.decorators import action from rest_framework.exceptions import AuthenticationFailed from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response @@ -16,7 +15,7 @@ from netbox.api.viewsets import NetBoxModelViewSet from users import filtersets -from users.models import ObjectPermission, Token, UserConfig, NetBoxUser +from users.models import ObjectPermission, Token, UserConfig from utilities.querysets import RestrictedQuerySet from utilities.utils import deepmerge from . import serializers @@ -34,12 +33,6 @@ def get_view_name(self): # Users and groups # -class NetBoxUserViewSet(NetBoxModelViewSet): - queryset = RestrictedQuerySet(model=NetBoxUser).prefetch_related('groups').order_by('username') - serializer_class = serializers.UserSerializer - filterset_class = filtersets.UserFilterSet - - class UserViewSet(NetBoxModelViewSet): queryset = RestrictedQuerySet(model=get_user_model()).prefetch_related('groups').order_by('username') serializer_class = serializers.UserSerializer From 8be1f9d5a17c76a04d48647640035e77187c7ce0 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Fri, 26 Jan 2024 15:31:36 -0600 Subject: [PATCH 7/8] Fixes: #14840 - Better fix for netboxusers-list --- netbox/utilities/utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/netbox/utilities/utils.py b/netbox/utilities/utils.py index f3f8c7c5042..05597b80c9b 100644 --- a/netbox/utilities/utils.py +++ b/netbox/utilities/utils.py @@ -52,6 +52,8 @@ def get_viewname(model, action=None, rest_api=False): # Alter the app_label for group and user model_name to point to users app if app_label == 'auth' and model_name in ['group', 'user']: app_label = 'users' + if app_label == 'users' and model._meta.proxy and model_name in ['netboxuser', 'netboxgroup']: + model_name = model._meta.proxy_for_model._meta.model_name viewname = f'{app_label}-api:{model_name}' # Append the action, if any From 1990a9c28c8ce291501a26b59defadca3720626a Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Fri, 2 Feb 2024 16:03:29 -0600 Subject: [PATCH 8/8] Swap model for serializer from proxy model --- netbox/utilities/api.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/netbox/utilities/api.py b/netbox/utilities/api.py index 50bb033e481..b53edf53ae0 100644 --- a/netbox/utilities/api.py +++ b/netbox/utilities/api.py @@ -27,6 +27,13 @@ def get_serializer_for_model(model, prefix=''): # Serializers for Django's auth models are in the users app if app_name == 'auth': app_name = 'users' + # Account for changes using Proxy model + if app_name == 'users': + if model_name == 'NetBoxUser': + model_name = 'User' + elif model_name == 'NetBoxGroup': + model_name = 'Group' + serializer_name = f'{app_name}.api.serializers.{prefix}{model_name}Serializer' try: return dynamic_import(serializer_name)