from __future__ import absolute_import, unicode_literals from django.conf import settings from django.contrib import messages from django.contrib.auth import get_user_model from django.contrib.auth.models import Group, User from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404, render_to_response from django.template import RequestContext from django.utils.translation import ugettext_lazy as _ from common.utils import encapsulate from common.views import AssignRemoveView, SingleObjectListView from common.widgets import two_state_template from permissions import Permission from .forms import GroupForm, PasswordForm, UserForm from .permissions import ( permission_group_create, permission_group_delete, permission_group_edit, permission_group_view, permission_user_create, permission_user_delete, permission_user_edit, permission_user_view ) class UserListView(SingleObjectListView): view_permission = permission_user_view def get_queryset(self): return get_user_model().objects.exclude(is_superuser=True).exclude(is_staff=True).order_by('last_name', 'first_name') def get_context_data(self, **kwargs): context = super(UserListView, self).get_context_data(**kwargs) context.update( { 'title': _('Users'), 'hide_link': True, 'extra_columns': [ { 'name': _('Full name'), 'attribute': 'get_full_name' }, { 'name': _('Email'), 'attribute': 'email' }, { 'name': _('Active'), 'attribute': encapsulate(lambda x: two_state_template(x.is_active)), }, { 'name': _('Has usable password?'), 'attribute': encapsulate(lambda x: two_state_template(x.has_usable_password())), }, ], } ) return context def user_edit(request, user_id): Permission.check_permissions(request.user, [permission_user_edit]) user = get_object_or_404(User, pk=user_id) if user.is_superuser or user.is_staff: messages.error(request, _('Super user and staff user editing is not allowed, use the admin interface for these cases.')) return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL))) if request.method == 'POST': form = UserForm(instance=user, data=request.POST) if form.is_valid(): form.save() messages.success(request, _('User "%s" updated successfully.') % user) return HttpResponseRedirect(reverse('user_management:user_list')) else: form = UserForm(instance=user) return render_to_response('appearance/generic_form.html', { 'title': _('Edit user: %s') % user, 'form': form, 'object': user, }, context_instance=RequestContext(request)) def user_add(request): Permission.check_permissions(request.user, [permission_user_create]) if request.method == 'POST': form = UserForm(request.POST) if form.is_valid(): user = form.save(commit=False) user.set_unusable_password() user.save() messages.success(request, _('User "%s" created successfully.') % user) return HttpResponseRedirect(reverse('user_management:user_set_password', args=[user.pk])) else: form = UserForm() return render_to_response('appearance/generic_form.html', { 'title': _('Create new user'), 'form': form, }, context_instance=RequestContext(request)) def user_delete(request, user_id=None, user_id_list=None): Permission.check_permissions(request.user, [permission_user_delete]) post_action_redirect = None if user_id: users = [get_object_or_404(User, pk=user_id)] post_action_redirect = reverse('user_management:user_list') elif user_id_list: users = [get_object_or_404(User, pk=user_id) for user_id in user_id_list.split(',')] else: messages.error(request, _('Must provide at least one user.')) return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL))) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))) next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))) if request.method == 'POST': for user in users: try: if user.is_superuser or user.is_staff: messages.error(request, _('Super user and staff user deleting is not allowed, use the admin interface for these cases.')) else: user.delete() messages.success(request, _('User "%s" deleted successfully.') % user) except Exception as exception: messages.error(request, _('Error deleting user "%(user)s": %(error)s') % { 'user': user, 'error': exception }) return HttpResponseRedirect(next) context = { 'delete_view': True, 'previous': previous, 'next': next, } if len(users) == 1: context['object'] = users[0] context['title'] = _('Are you sure you wish to delete the user: %s?') % ', '.join([unicode(d) for d in users]) elif len(users) > 1: context['title'] = _('Are you sure you wish to delete the users: %s?') % ', '.join([unicode(d) for d in users]) return render_to_response('appearance/generic_confirm.html', context, context_instance=RequestContext(request)) def user_multiple_delete(request): return user_delete( request, user_id_list=request.GET.get('id_list', []) ) def user_set_password(request, user_id=None, user_id_list=None): Permission.check_permissions(request.user, [permission_user_edit]) post_action_redirect = None if user_id: users = [get_object_or_404(User, pk=user_id)] post_action_redirect = reverse('user_management:user_list') elif user_id_list: users = [get_object_or_404(User, pk=user_id) for user_id in user_id_list.split(',')] else: messages.error(request, _('Must provide at least one user.')) return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL))) next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))) if request.method == 'POST': form = PasswordForm(request.POST) if form.is_valid(): password_1 = form.cleaned_data['new_password_1'] password_2 = form.cleaned_data['new_password_2'] if password_1 != password_2: messages.error(request, _('Passwords do not match, try again.')) else: for user in users: try: if user.is_superuser or user.is_staff: messages.error(request, _('Super user and staff user password reseting is not allowed, use the admin interface for these cases.')) else: user.set_password(password_1) user.save() messages.success(request, _('Successfull password reset for user: %s.') % user) except Exception as exception: messages.error(request, _('Error reseting password for user "%(user)s": %(error)s') % { 'user': user, 'error': exception }) return HttpResponseRedirect(next) else: form = PasswordForm() context = { 'next': next, 'form': form, } if len(users) == 1: context['object'] = users[0] context['title'] = _('Reseting password for user: %s') % ', '.join([unicode(d) for d in users]) elif len(users) > 1: context['title'] = _('Reseting password for users: %s') % ', '.join([unicode(d) for d in users]) return render_to_response('appearance/generic_form.html', context, context_instance=RequestContext(request)) def user_multiple_set_password(request): return user_set_password( request, user_id_list=request.GET.get('id_list', []) ) def get_user_groups(user): return Group.objects.filter(user=user) def get_user_non_groups(user): return Group.objects.exclude(user=user) class UserGroupsView(AssignRemoveView): decode_content_type = True left_list_title = _('Available groups') right_list_title = _('Groups joined') view_permission = permission_user_edit def add(self, item): item.user_set.add(self.get_object()) def get_object(self): return get_object_or_404(User, pk=self.kwargs['pk']) def left_list(self): return AssignRemoveView.generate_choices(get_user_non_groups(self.get_object())) def right_list(self): return AssignRemoveView.generate_choices(get_user_groups(self.get_object())) def remove(self, item): item.user_set.remove(self.get_object()) def get_context_data(self, **kwargs): data = super(UserGroupsView, self).get_context_data(**kwargs) data.update({ 'object': self.get_object(), 'title': _('Groups of user: %s') % self.get_object() }) return data # Group views class GroupListView(SingleObjectListView): view_permission = permission_group_view def get_queryset(self): return Group.objects.all() def get_context_data(self, **kwargs): context = super(GroupListView, self).get_context_data(**kwargs) context.update( { 'title': _('Groups'), 'hide_link': True, 'extra_columns': [ { 'name': _('Members'), 'attribute': 'user_set.count' }, ], } ) return context def group_edit(request, group_id): Permission.check_permissions(request.user, [permission_group_edit]) group = get_object_or_404(Group, pk=group_id) if request.method == 'POST': form = GroupForm(instance=group, data=request.POST) if form.is_valid(): form.save() messages.success(request, _('Group "%s" updated successfully.') % group) return HttpResponseRedirect(reverse('user_management:group_list')) else: form = GroupForm(instance=group) return render_to_response('appearance/generic_form.html', { 'title': _('Edit group: %s') % group, 'form': form, 'object': group, }, context_instance=RequestContext(request)) def group_add(request): Permission.check_permissions(request.user, [permission_group_create]) if request.method == 'POST': form = GroupForm(request.POST) if form.is_valid(): group = form.save() messages.success(request, _('Group "%s" created successfully.') % group) return HttpResponseRedirect(reverse('user_management:group_list')) else: form = GroupForm() return render_to_response('appearance/generic_form.html', { 'title': _('Create new group'), 'form': form, }, context_instance=RequestContext(request)) def group_delete(request, group_id=None, group_id_list=None): Permission.check_permissions(request.user, [permission_group_delete]) post_action_redirect = None if group_id: groups = [get_object_or_404(Group, pk=group_id)] post_action_redirect = reverse('user_management:group_list') elif group_id_list: groups = [get_object_or_404(Group, pk=group_id) for group_id in group_id_list.split(',')] else: messages.error(request, _('Must provide at least one group.')) return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL))) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))) next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))) if request.method == 'POST': for group in groups: try: group.delete() messages.success(request, _('Group "%s" deleted successfully.') % group) except Exception as exception: messages.error(request, _('Error deleting group "%(group)s": %(error)s') % { 'group': group, 'error': exception }) return HttpResponseRedirect(next) context = { 'delete_view': True, 'previous': previous, 'next': next, } if len(groups) == 1: context['object'] = groups[0] context['title'] = _('Are you sure you wish to delete the group: %s?') % ', '.join([unicode(d) for d in groups]) elif len(groups) > 1: context['title'] = _('Are you sure you wish to delete the groups: %s?') % ', '.join([unicode(d) for d in groups]) return render_to_response('appearance/generic_confirm.html', context, context_instance=RequestContext(request)) def group_multiple_delete(request): return group_delete( request, group_id_list=request.GET.get('id_list', []) ) class GroupMembersView(AssignRemoveView): decode_content_type = True left_list_title = _('Available groups') right_list_title = _('Members of groups') view_permission = permission_group_edit def add(self, item): self.get_object().user_set.add(item) def get_object(self): return get_object_or_404(Group, pk=self.kwargs['pk']) def left_list(self): return AssignRemoveView.generate_choices(User.objects.exclude(groups=self.get_object()).exclude(is_staff=True).exclude(is_superuser=True)) def right_list(self): return AssignRemoveView.generate_choices(self.get_object().user_set.all()) def remove(self, item): self.get_object().user_set.remove(item) def get_context_data(self, **kwargs): data = super(GroupMembersView, self).get_context_data(**kwargs) data.update({ 'object': self.get_object(), 'title': _('Members of group: %s') % self.get_object() }) return data