Source code for tcms.kiwi_auth.admin

# -*- coding: utf-8 -*-

from django import forms
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin, sensitive_post_parameters_m
from django.contrib.auth.forms import UserChangeForm
from django.contrib.auth.models import Permission
from django.http import HttpResponseForbidden
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.translation import gettext_lazy as _

from tcms.utils.user import delete_user

User = get_user_model()  # pylint: disable=invalid-name


[docs]class MyUserChangeForm(UserChangeForm): """ Enforces unique user emails. """ email = forms.EmailField(required=True)
[docs] def clean_email(self): query_set = User.objects.filter(email=self.cleaned_data['email']) if self.instance: query_set = query_set.exclude(pk=self.instance.pk) if query_set.count(): raise forms.ValidationError(_('This email address is already in use')) return self.cleaned_data['email']
def _modifying_myself(request, object_id): return request.user.pk == int(object_id)
[docs]class KiwiUserAdmin(UserAdmin): list_display = UserAdmin.list_display + ('is_active', 'is_superuser', 'date_joined', 'last_login') ordering = ['-pk'] # same as -date_joined # override standard form and make the email address unique # even when adding users via admin panel form = MyUserChangeForm
[docs] def has_change_permission(self, request, obj=None): return request.user.is_superuser or obj is not None
[docs] def has_view_permission(self, request, obj=None): if _modifying_myself(request, getattr(obj, 'pk', 0)): return True return super().has_view_permission(request, obj)
# pylint: disable=too-many-arguments
[docs] def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None): if not self.has_view_permission(request, obj): return HttpResponseForbidden() if obj and not (_modifying_myself(request, obj.pk) or request.user.is_superuser): context.update({ 'show_save': False, 'show_save_and_continue': False, }) return super().render_change_form(request, context, add=add, change=change, form_url=form_url, obj=obj)
[docs] def get_readonly_fields(self, request, obj=None): if request.user.is_superuser: return super().get_readonly_fields(request, obj) readonly_fields = ['username', 'is_staff', 'is_active', 'is_superuser', 'last_login', 'date_joined', 'groups', 'user_permissions'] if obj and not _modifying_myself(request, obj.pk): readonly_fields.extend(['first_name', 'last_name', 'email']) return readonly_fields
[docs] def get_fieldsets(self, request, obj=None): # super-user adding new account if not obj and request.user.is_superuser: return super().get_fieldsets(request, obj) first_fieldset_fields = ('username',) if obj and _modifying_myself(request, obj.pk): first_fieldset_fields = first_fieldset_fields + ('password',) remaining_fieldsets = ( (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}), (_('Permissions'), {'fields': ('is_active', 'groups')}), ) if request.user.is_superuser: field_sets = super().get_fieldsets(request, obj) if field_sets[0][0] is None and 'password' in field_sets[0][1]['fields']: remaining_fieldsets = field_sets[1:] return ((None, {'fields': first_fieldset_fields}),) + remaining_fieldsets
[docs] @sensitive_post_parameters_m def user_change_password(self, request, id, form_url=''): # pylint: disable=redefined-builtin return HttpResponseRedirect(reverse('admin:password_change'))
[docs] @admin.options.csrf_protect_m def delete_view(self, request, object_id, extra_context=None): if not _modifying_myself(request, object_id): return super().delete_view(request, object_id, extra_context) # allow deletion of the user own account permission = Permission.objects.get(content_type__app_label='auth', codename='delete_user') try: request.user.user_permissions.add(permission) return super().delete_view(request, object_id, extra_context) finally: request.user.user_permissions.remove(permission)
[docs] def response_delete(self, request, obj_display, obj_id): result = super().response_delete(request, obj_display, obj_id) if not _modifying_myself(request, obj_id): return result # user doesn't exist anymore so go to the index page # instead of returning to the user admin page return HttpResponseRedirect(reverse('core-views-index'))
[docs] def has_delete_permission(self, request, obj=None): # allow to delete yourself without having 'delete' permission # explicitly assigned if _modifying_myself(request, getattr(obj, 'pk', 0)): return True return super().has_delete_permission(request, obj)
[docs] def delete_model(self, request, obj): delete_user(obj)
# user admin extended functionality admin.site.unregister(User) admin.site.register(User, KiwiUserAdmin)