Source code for shuup.admin.modules.users.views.permissions

# -*- coding: utf-8 -*-
# This file is part of Shuup.
#
# Copyright (c) 2012-2021, Shuup Commerce Inc. All rights reserved.
#
# This source code is licensed under the OSL-3.0 license found in the
# LICENSE file in the root directory of this source tree.
from __future__ import unicode_literals

from django import forms
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 as PermissionGroup
from django.forms.models import modelform_factory
from django.http.response import HttpResponseRedirect
from django.utils.translation import ugettext_lazy as _
from django.views.generic.edit import UpdateView

from shuup.admin.forms.fields import Select2MultipleField
from shuup.admin.toolbar import get_default_edit_toolbar
from shuup.admin.utils.urls import get_model_url
from shuup.utils.django_compat import force_text


[docs]class PermissionChangeFormBase(forms.ModelForm): old_password = forms.CharField( label=_("Your Password"), widget=forms.PasswordInput, help_text=_( "In order to allow making significant changes to accounts, we need " "to confirm that you know the password for the account you are using." ), ) def __init__(self, changing_user, *args, **kwargs): super(PermissionChangeFormBase, self).__init__(*args, **kwargs) self.changing_user = changing_user if not getattr(self.changing_user, "is_superuser", False): self.fields.pop("is_superuser") if not (self.changing_user == self.instance or getattr(self.instance, "is_superuser", False)): # Only require old password when editing self.fields.pop("old_password") if "is_superuser" in self.fields: self.fields["is_superuser"].label = _("Superuser (Full rights) status") self.fields["is_superuser"].help_text = _( "Designates whether this user has all permissions without explicitly " "assigning them. Assigning Granular Permission Groups to a Superuser " "will not have any effect because Granular Permission Groups are only " " able to give more rights, but Superuser already has them all." ) self.fields["is_staff"].label = _("Access to Admin Panel status") self.fields["is_staff"].help_text = _( "Designates whether this user can log into this admin site. Even " "Superusers should have this status enabled, otherwise they won't " "be able to access the Admin Panel." ) permission_groups_field = Select2MultipleField( model=PermissionGroup, required=False, label=_("Granular Permission Groups"), help_text=_( "Use Permission Groups to granularly give more permissions. User " "can belong to many groups and their permissions add and stack together. " "Search for `Permission Groups` to change these and add them to " "multiple users. Go to user account -> `Actions` -> `Edit Main " "Permissions` to add them to a specific user. Will not influence " "Superusers as they already have all the rights and can't be " "stripped of them without removing Superuser status first." ), ) initial_groups = self._get_initial_groups() permission_groups_field.initial = [group.pk for group in initial_groups] permission_groups_field.widget.choices = [(group.pk, force_text(group)) for group in initial_groups] self.fields["permission_groups"] = permission_groups_field def _get_initial_groups(self): if self.instance.pk and hasattr(self.instance, "groups"): return self.instance.groups.all() else: return []
[docs] def clean_old_password(self): """ Validates that the `old_password` field is correct. """ old_password = self.cleaned_data["old_password"] if not self.changing_user.check_password(old_password): raise forms.ValidationError( _("Your old password was entered incorrectly. Please enter it again."), code="password_incorrect", ) return old_password
[docs] def clean_members(self): members = self.cleaned_data.get("members", []) return get_user_model().objects.filter(pk__in=members).all()
[docs] def clean_permission_groups(self): permission_groups = self.cleaned_data.get("permission_groups", []) return PermissionGroup.objects.filter(pk__in=permission_groups)
[docs] def clean(self): for field in ("is_staff", "is_superuser"): if field not in self.cleaned_data: continue flag = self.cleaned_data[field] if self.changing_user == self.instance and not flag: self.add_error( field, _( "You can't unset this status for yourself " "due to security reasons. Use another account if you want to " "remove permissions for this particular account." ), ) return self.cleaned_data
[docs] def save(self): obj = super(PermissionChangeFormBase, self).save() obj.groups.clear() obj.groups.set(self.cleaned_data["permission_groups"])
[docs]class UserChangePermissionsView(UpdateView): template_name = "shuup/admin/users/change_permissions.jinja" model = settings.AUTH_USER_MODEL title = _("Change User Permissions")
[docs] def get_form_class(self): return modelform_factory( model=get_user_model(), form=PermissionChangeFormBase, fields=("is_staff", "is_superuser") )
[docs] def get_queryset(self): return get_user_model().objects.all()
[docs] def get_toolbar(self): toolbar = get_default_edit_toolbar( self, "permissions_form", discard_url=get_model_url(self.object), with_split_save=False, ) return toolbar
[docs] def get_form_kwargs(self): kwargs = super(UserChangePermissionsView, self).get_form_kwargs() kwargs["changing_user"] = self.request.user return kwargs
[docs] def get_context_data(self, **kwargs): context = super(UserChangePermissionsView, self).get_context_data(**kwargs) context["toolbar"] = self.get_toolbar() context["title"] = _("Change Main Permissions: %s") % self.object return context
[docs] def form_valid(self, form): form.save() messages.success(self.request, _("Permissions changed for %s.") % self.object) return HttpResponseRedirect(self.get_success_url())
[docs] def get_success_url(self): return get_model_url(self.object)