""" This module contains the Django admin classes of the :py:mod:`osusers` app. """ from django import forms from django.utils.translation import ugettext as _ from django.contrib import admin from .models import ( AdditionalGroup, Group, Shadow, User, ) PASSWORD_MISMATCH_ERROR = _("Passwords don't match") """ Error message for non matching passwords. """ class AdditionalGroupInline(admin.TabularInline): """ Inline for :py:class:`osusers.models.AdditionalGroup` instances. """ model = AdditionalGroup class ShadowInline(admin.TabularInline): """ Inline for :py:class:`osusers.models.ShadowInline` instances. """ model = Shadow readonly_fields = ['passwd'] can_delete = False class UserCreationForm(forms.ModelForm): """ A form for creating :py:class:`operating system users `. """ password1 = forms.CharField( label=_('Password'), widget=forms.PasswordInput, required=False, ) password2 = forms.CharField( label=_('Password (again)'), widget=forms.PasswordInput, required=False, ) class Meta: model = User fields = ['customer'] def clean_password2(self): """ Check that the two password entries match. :return: the validated password :rtype: str or None """ password1 = self.cleaned_data.get('password1') password2 = self.cleaned_data.get('password2') if password1 and password2 and password1 != password2: raise forms.ValidationError(PASSWORD_MISMATCH_ERROR) return password2 def save(self, commit=True): """ Save the provided password in hashed format. :param boolean commit: whether to save the created user :return: user instance :rtype: :py:class:`osusers.models.User` """ user = User.objects.create_user( customer=self.cleaned_data['customer'], password=self.cleaned_data['password1'], commit=commit) return user def save_m2m(self): """ No additional groups are created when this form is saved, so this method just does nothing. """ class UserAdmin(admin.ModelAdmin): """ Admin class for working with :py:class:`operating system users `. """ actions = ['perform_delete_selected'] add_form = UserCreationForm inlines = [AdditionalGroupInline, ShadowInline] add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': ('customer', 'password1', 'password2')}), ) def get_form(self, request, obj=None, **kwargs): """ Use special form during user creation. :param request: the current HTTP request :param obj: either a :py:class:`User ` instance or None for a new user :param kwargs: keyword arguments to be passed to :py:meth:`django.contrib.admin.ModelAdmin.get_form` :return: form instance """ defaults = {} if obj is None: defaults.update({ 'form': self.add_form, 'fields': admin.options.flatten_fieldsets(self.add_fieldsets), }) defaults.update(kwargs) return super(UserAdmin, self).get_form(request, obj, **defaults) def get_readonly_fields(self, request, obj=None): """ Make sure that uid is not editable for existing users. :param request: the current HTTP request :param obj: either a :py:class:`User ` instance or None for a new user :return: a list of fields :rtype: list """ if obj: return ['uid'] return [] def perform_delete_selected(self, request, queryset): """ Action to delete a list of selected users. This action calls the delete method of each selected user in contrast to the default `delete_selected`. :param request: the current HTTP request :param queryset: Django ORM queryset representing the selected users """ for user in queryset.all(): user.delete() perform_delete_selected.short_description = _('Delete selected users') def get_actions(self, request): """ Get the available actions for users. This overrides the default behavior to remove the default `delete_selected` action. :param request: the current HTTP request :return: list of actions :rtype: list """ actions = super(UserAdmin, self).get_actions(request) if 'delete_selected' in actions: del actions['delete_selected'] return actions class GroupAdmin(admin.ModelAdmin): """ Admin class for workint with :py:class:`operating system groups `. """ actions = ['perform_delete_selected'] def perform_delete_selected(self, request, queryset): """ Action to delete a list of selected groups. This action calls the delete method of each selected group in contrast to the default `delete_selected`. :param request: the current HTTP request :param queryset: Django ORM queryset representing the selected groups """ for group in queryset.all(): group.delete() perform_delete_selected.short_description = _('Delete selected groups') def get_actions(self, request): """ Get the available actions for groups. This overrides the default behavior to remove the default `delete_selected` action. :param request: the current HTTP request :return: list of actions :rtype: list """ actions = super(GroupAdmin, self).get_actions(request) if 'delete_selected' in actions: del actions['delete_selected'] return actions admin.site.register(Group, GroupAdmin) admin.site.register(User, UserAdmin)