1
0
mirror of https://github.com/django/django.git synced 2024-12-22 17:16:24 +00:00

Fixed #35959 -- Checked for change permission to show "password" field.

Removed "password" from UserAdmin fieldset for users without change
permission, omitting ReadOnlyPasswordHashField in UserChangeForm.

Thanks to Sarah Boyce for help with implementation!
Co-authored-by: Sarah Boyce <sarahvboyce95@gmail.com>
This commit is contained in:
Brock 2024-12-06 16:52:26 -05:00
parent c075d4c2c8
commit e1971467d7
2 changed files with 21 additions and 3 deletions

View File

@ -1,3 +1,5 @@
import copy
from django.conf import settings
from django.contrib import admin, messages
from django.contrib.admin.options import IS_POPUP_VAR
@ -82,10 +84,23 @@ class UserAdmin(admin.ModelAdmin):
"user_permissions",
)
@staticmethod
def _remove_fields_from_fieldsets(fieldsets, fields):
fieldset_without_fields = []
for fieldset_name, fieldset in copy.deepcopy(fieldsets):
fieldset["fields"] = [f for f in fieldset["fields"] if f not in fields]
fieldset_without_fields.append((fieldset_name, fieldset))
return fieldset_without_fields
def get_fieldsets(self, request, obj=None):
if not obj:
return self.add_fieldsets
return super().get_fieldsets(request, obj)
fieldsets = super().get_fieldsets(request, obj)
if not self.has_change_permission(request, obj):
return self._remove_fields_from_fieldsets(
fieldsets=fieldsets, fields=["password"]
)
return fieldsets
def get_form(self, request, obj=None, **kwargs):
"""

View File

@ -1680,7 +1680,7 @@ class ChangelistTests(MessagesTestMixin, AuthViewsTestCase):
(_request, user), _kwargs = has_change_permission.call_args
self.assertEqual(user.pk, self.admin.pk)
def test_view_user_password_is_readonly(self):
def test_password_not_viewable_for_user_without_change_permission(self):
u = User.objects.get(username="testclient")
u.is_superuser = False
u.save()
@ -1692,7 +1692,7 @@ class ChangelistTests(MessagesTestMixin, AuthViewsTestCase):
algo, salt, hash_string = u.password.split("$")
self.assertContains(response, '<div class="readonly">testclient</div>')
# ReadOnlyPasswordHashWidget is used to render the field.
self.assertContains(
self.assertNotContains(
response,
"<strong>algorithm</strong>: <bdi>%s</bdi>\n\n"
"<strong>salt</strong>: <bdi>%s********************</bdi>\n\n"
@ -1704,6 +1704,9 @@ class ChangelistTests(MessagesTestMixin, AuthViewsTestCase):
),
html=True,
)
self.assertNotContains(
response, '<a class="button" href="../password/">Reset password</a>'
)
# Value in POST data is ignored.
data = self.get_user_data(u)
data["password"] = "shouldnotchange"