From c9714893bb3f4bdfb7b8b86f20daf04a0920d951 Mon Sep 17 00:00:00 2001 From: "Langhammer, Jens" Date: Thu, 10 Oct 2019 13:01:49 +0200 Subject: [PATCH] admin(major): rewrite all views to use guardian mixins --- passbook/admin/views/applications.py | 29 ++++++++++++---- passbook/admin/views/audit.py | 6 ++-- passbook/admin/views/debug.py | 6 ++-- passbook/admin/views/factors.py | 34 ++++++++++++++---- passbook/admin/views/groups.py | 28 +++++++++++---- passbook/admin/views/invitations.py | 29 ++++++++++++---- passbook/admin/views/policy.py | 36 +++++++++++++++---- passbook/admin/views/property_mapping.py | 32 +++++++++++++---- passbook/admin/views/providers.py | 32 +++++++++++++---- passbook/admin/views/sources.py | 32 +++++++++++++---- passbook/admin/views/users.py | 44 +++++++++++++++++------- 11 files changed, 239 insertions(+), 69 deletions(-) diff --git a/passbook/admin/views/applications.py b/passbook/admin/views/applications.py index 8e5f58b6d..6b7728572 100644 --- a/passbook/admin/views/applications.py +++ b/passbook/admin/views/applications.py @@ -1,19 +1,24 @@ """passbook Application administration""" from django.contrib import messages +from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.auth.mixins import \ + PermissionRequiredMixin as DjangoPermissionRequiredMixin from django.contrib.messages.views import SuccessMessageMixin from django.urls import reverse_lazy from django.utils.translation import ugettext as _ -from django.views.generic import CreateView, DeleteView, ListView, UpdateView +from django.views.generic import DeleteView, ListView, UpdateView +from guardian.mixins import PermissionListMixin, PermissionRequiredMixin -from passbook.admin.mixins import AdminRequiredMixin from passbook.core.forms.applications import ApplicationForm from passbook.core.models import Application +from passbook.lib.views import CreateAssignPermView -class ApplicationListView(AdminRequiredMixin, ListView): +class ApplicationListView(LoginRequiredMixin, PermissionListMixin, ListView): """Show list of all applications""" model = Application + permission_required = 'passbook_core.view_application' ordering = 'name' template_name = 'administration/application/list.html' @@ -21,10 +26,18 @@ class ApplicationListView(AdminRequiredMixin, ListView): return super().get_queryset().select_subclasses() -class ApplicationCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView): +class ApplicationCreateView(SuccessMessageMixin, LoginRequiredMixin, + DjangoPermissionRequiredMixin, CreateAssignPermView): """Create new Application""" + model = Application form_class = ApplicationForm + permission_required = 'passbook_core.add_application' + permissions = [ + 'passbook_core.view_application', + 'passbook_core.change_application', + 'passbook_core.delete_application', + ] template_name = 'generic/create.html' success_url = reverse_lazy('passbook_admin:applications') @@ -35,21 +48,25 @@ class ApplicationCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView) return super().get_context_data(**kwargs) -class ApplicationUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateView): +class ApplicationUpdateView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, UpdateView): """Update application""" model = Application form_class = ApplicationForm + permission_required = 'passbook_core.change_application' template_name = 'generic/update.html' success_url = reverse_lazy('passbook_admin:applications') success_message = _('Successfully updated Application') -class ApplicationDeleteView(SuccessMessageMixin, AdminRequiredMixin, DeleteView): +class ApplicationDeleteView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, DeleteView): """Delete application""" model = Application + permission_required = 'passbook_core.delete_application' template_name = 'generic/delete.html' success_url = reverse_lazy('passbook_admin:applications') diff --git a/passbook/admin/views/audit.py b/passbook/admin/views/audit.py index a7705550b..a24ccf87d 100644 --- a/passbook/admin/views/audit.py +++ b/passbook/admin/views/audit.py @@ -1,15 +1,17 @@ """passbook AuditEntry administration""" from django.views.generic import ListView +from guardian.mixins import PermissionListMixin -from passbook.admin.mixins import AdminRequiredMixin from passbook.audit.models import AuditEntry -class AuditEntryListView(AdminRequiredMixin, ListView): +class AuditEntryListView(PermissionListMixin, ListView): """Show list of all invitations""" model = AuditEntry template_name = 'administration/audit/list.html' + permission_required = 'passbook_audit.view_auditentry' + ordering = '-created' paginate_by = 10 def get_queryset(self): diff --git a/passbook/admin/views/debug.py b/passbook/admin/views/debug.py index 336289189..4971c15ae 100644 --- a/passbook/admin/views/debug.py +++ b/passbook/admin/views/debug.py @@ -1,11 +1,9 @@ """passbook administration debug views""" - +from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic import TemplateView -from passbook.admin.mixins import AdminRequiredMixin - -class DebugRequestView(AdminRequiredMixin, TemplateView): +class DebugRequestView(LoginRequiredMixin, TemplateView): """Show debug info about request""" template_name = 'administration/debug/request.html' diff --git a/passbook/admin/views/factors.py b/passbook/admin/views/factors.py index dd5a689cd..df245d378 100644 --- a/passbook/admin/views/factors.py +++ b/passbook/admin/views/factors.py @@ -1,14 +1,18 @@ """passbook Factor administration""" from django.contrib import messages +from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.auth.mixins import \ + PermissionRequiredMixin as DjangoPermissionRequiredMixin from django.contrib.messages.views import SuccessMessageMixin from django.http import Http404 from django.urls import reverse_lazy from django.utils.translation import ugettext as _ -from django.views.generic import CreateView, DeleteView, ListView, UpdateView +from django.views.generic import DeleteView, ListView, UpdateView +from guardian.mixins import PermissionListMixin, PermissionRequiredMixin -from passbook.admin.mixins import AdminRequiredMixin from passbook.core.models import Factor from passbook.lib.utils.reflection import path_to_class +from passbook.lib.views import CreateAssignPermView def all_subclasses(cls): @@ -16,11 +20,13 @@ def all_subclasses(cls): return set(cls.__subclasses__()).union( [s for c in cls.__subclasses__() for s in all_subclasses(c)]) -class FactorListView(AdminRequiredMixin, ListView): + +class FactorListView(LoginRequiredMixin, PermissionListMixin, ListView): """Show list of all factors""" model = Factor template_name = 'administration/factor/list.html' + permission_required = 'passbook_core.view_factor' ordering = 'order' def get_context_data(self, **kwargs): @@ -31,10 +37,20 @@ class FactorListView(AdminRequiredMixin, ListView): def get_queryset(self): return super().get_queryset().select_subclasses() -class FactorCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView): + +class FactorCreateView(SuccessMessageMixin, LoginRequiredMixin, + DjangoPermissionRequiredMixin, CreateAssignPermView): """Create new Factor""" + model = Factor template_name = 'generic/create.html' + permission_required = 'passbook_core.add_factor' + permissions = [ + 'passbook_core.view_factor', + 'passbook_core.change_factor', + 'passbook_core.delete_factor', + ] + success_url = reverse_lazy('passbook_admin:factors') success_message = _('Successfully created Factor') @@ -52,10 +68,13 @@ class FactorCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView): raise Http404 return path_to_class(model.form) -class FactorUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateView): + +class FactorUpdateView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, UpdateView): """Update factor""" model = Factor + permission_required = 'passbook_core.update_application' template_name = 'generic/update.html' success_url = reverse_lazy('passbook_admin:factors') success_message = _('Successfully updated Factor') @@ -68,11 +87,14 @@ class FactorUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateView): def get_object(self, queryset=None): return Factor.objects.filter(pk=self.kwargs.get('pk')).select_subclasses().first() -class FactorDeleteView(SuccessMessageMixin, AdminRequiredMixin, DeleteView): + +class FactorDeleteView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, DeleteView): """Delete factor""" model = Factor template_name = 'generic/delete.html' + permission_required = 'passbook_core.delete_factor' success_url = reverse_lazy('passbook_admin:factors') success_message = _('Successfully deleted Factor') diff --git a/passbook/admin/views/groups.py b/passbook/admin/views/groups.py index 1e120669d..299c67abf 100644 --- a/passbook/admin/views/groups.py +++ b/passbook/admin/views/groups.py @@ -1,28 +1,40 @@ """passbook Group administration""" from django.contrib import messages +from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.auth.mixins import \ + PermissionRequiredMixin as DjangoPermissionRequiredMixin from django.contrib.messages.views import SuccessMessageMixin from django.urls import reverse_lazy from django.utils.translation import ugettext as _ -from django.views.generic import CreateView, DeleteView, ListView, UpdateView +from django.views.generic import DeleteView, ListView, UpdateView +from guardian.mixins import PermissionListMixin, PermissionRequiredMixin -from passbook.admin.mixins import AdminRequiredMixin from passbook.core.forms.groups import GroupForm from passbook.core.models import Group +from passbook.lib.views import CreateAssignPermView -class GroupListView(AdminRequiredMixin, ListView): +class GroupListView(LoginRequiredMixin, PermissionListMixin, ListView): """Show list of all groups""" model = Group + permission_required = 'passbook_core.view_group' ordering = 'name' template_name = 'administration/group/list.html' -class GroupCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView): +class GroupCreateView(SuccessMessageMixin, LoginRequiredMixin, + DjangoPermissionRequiredMixin, CreateAssignPermView): """Create new Group""" + model = Group form_class = GroupForm - + permission_required = 'passbook_core.add_group' + permissions = [ + 'passbook_core.view_group', + 'passbook_core.change_group', + 'passbook_core.delete_group', + ] template_name = 'generic/create.html' success_url = reverse_lazy('passbook_admin:groups') success_message = _('Successfully created Group') @@ -32,18 +44,20 @@ class GroupCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView): return super().get_context_data(**kwargs) -class GroupUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateView): +class GroupUpdateView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, UpdateView): """Update group""" model = Group form_class = GroupForm + permission_required = 'passbook_core.change_group' template_name = 'generic/update.html' success_url = reverse_lazy('passbook_admin:groups') success_message = _('Successfully updated Group') -class GroupDeleteView(SuccessMessageMixin, AdminRequiredMixin, DeleteView): +class GroupDeleteView(SuccessMessageMixin, LoginRequiredMixin, DeleteView): """Delete group""" model = Group diff --git a/passbook/admin/views/invitations.py b/passbook/admin/views/invitations.py index a203e05cf..0d55ead34 100644 --- a/passbook/admin/views/invitations.py +++ b/passbook/admin/views/invitations.py @@ -1,31 +1,44 @@ """passbook Invitation administration""" from django.contrib import messages +from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.auth.mixins import \ + PermissionRequiredMixin as DjangoPermissionRequiredMixin from django.contrib.messages.views import SuccessMessageMixin from django.http import HttpResponseRedirect from django.urls import reverse_lazy from django.utils.translation import ugettext as _ -from django.views.generic import CreateView, DeleteView, ListView +from django.views.generic import DeleteView, ListView +from guardian.mixins import PermissionListMixin, PermissionRequiredMixin -from passbook.admin.mixins import AdminRequiredMixin from passbook.core.forms.invitations import InvitationForm from passbook.core.models import Invitation from passbook.core.signals import invitation_created +from passbook.lib.views import CreateAssignPermView -class InvitationListView(AdminRequiredMixin, ListView): +class InvitationListView(LoginRequiredMixin, PermissionListMixin, ListView): """Show list of all invitations""" model = Invitation + permission_required = 'passbook_core.view_invitation' template_name = 'administration/invitation/list.html' -class InvitationCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView): +class InvitationCreateView(SuccessMessageMixin, LoginRequiredMixin, + DjangoPermissionRequiredMixin, CreateAssignPermView): """Create new Invitation""" + model = Invitation + form_class = InvitationForm + permission_required = 'passbook_core.add_invitation' + permissions = [ + 'passbook_core.view_invitation', + 'passbook_core.change_invitation', + 'passbook_core.delete_invitation', + ] template_name = 'generic/create.html' success_url = reverse_lazy('passbook_admin:invitations') success_message = _('Successfully created Invitation') - form_class = InvitationForm def get_context_data(self, **kwargs): kwargs['type'] = 'Invitation' @@ -41,10 +54,14 @@ class InvitationCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView): invitation=obj) return HttpResponseRedirect(self.success_url) -class InvitationDeleteView(SuccessMessageMixin, AdminRequiredMixin, DeleteView): + +class InvitationDeleteView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, DeleteView): """Delete invitation""" model = Invitation + permission_required = 'passbook_core.delete_invitation' + template_name = 'generic/delete.html' success_url = reverse_lazy('passbook_admin:invitations') success_message = _('Successfully deleted Invitation') diff --git a/passbook/admin/views/policy.py b/passbook/admin/views/policy.py index 541d70e09..7bd6d22c5 100644 --- a/passbook/admin/views/policy.py +++ b/passbook/admin/views/policy.py @@ -1,24 +1,30 @@ """passbook Policy administration""" from django.contrib import messages +from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.auth.mixins import \ + PermissionRequiredMixin as DjangoPermissionRequiredMixin from django.contrib.messages.views import SuccessMessageMixin from django.http import Http404 from django.urls import reverse_lazy from django.utils.translation import ugettext as _ -from django.views.generic import (CreateView, DeleteView, FormView, ListView, +from django.views.generic import (DeleteView, FormView, ListView, UpdateView) from django.views.generic.detail import DetailView +from guardian.mixins import PermissionListMixin, PermissionRequiredMixin from passbook.admin.forms.policies import PolicyTestForm -from passbook.admin.mixins import AdminRequiredMixin from passbook.core.models import Policy from passbook.lib.utils.reflection import path_to_class +from passbook.lib.views import CreateAssignPermView from passbook.policies.engine import PolicyEngine -class PolicyListView(AdminRequiredMixin, ListView): +class PolicyListView(LoginRequiredMixin, PermissionListMixin, ListView): """Show list of all policies""" model = Policy + permission_required = 'passbook_core.view_policy' + template_name = 'administration/policy/list.html' def get_context_data(self, **kwargs): @@ -30,9 +36,18 @@ class PolicyListView(AdminRequiredMixin, ListView): return super().get_queryset().order_by('order').select_subclasses() -class PolicyCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView): +class PolicyCreateView(SuccessMessageMixin, LoginRequiredMixin, + DjangoPermissionRequiredMixin, CreateAssignPermView): """Create new Policy""" + model = Policy + permission_required = 'passbook_core.add_policy' + permissions = [ + 'passbook_core.view_policy', + 'passbook_core.change_policy', + 'passbook_core.delete_policy', + ] + template_name = 'generic/create.html' success_url = reverse_lazy('passbook_admin:policies') success_message = _('Successfully created Policy') @@ -46,10 +61,13 @@ class PolicyCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView): return path_to_class(model.form) -class PolicyUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateView): +class PolicyUpdateView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, UpdateView): """Update policy""" model = Policy + permission_required = 'passbook_core.change_policy' + template_name = 'generic/update.html' success_url = reverse_lazy('passbook_admin:policies') success_message = _('Successfully updated Policy') @@ -63,10 +81,13 @@ class PolicyUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateView): return Policy.objects.filter(pk=self.kwargs.get('pk')).select_subclasses().first() -class PolicyDeleteView(SuccessMessageMixin, AdminRequiredMixin, DeleteView): +class PolicyDeleteView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, DeleteView): """Delete policy""" model = Policy + permission_required = 'passbook_core.delete_policy' + template_name = 'generic/delete.html' success_url = reverse_lazy('passbook_admin:policies') success_message = _('Successfully deleted Policy') @@ -79,11 +100,12 @@ class PolicyDeleteView(SuccessMessageMixin, AdminRequiredMixin, DeleteView): return super().delete(request, *args, **kwargs) -class PolicyTestView(AdminRequiredMixin, DetailView, FormView): +class PolicyTestView(LoginRequiredMixin, DetailView, PermissionRequiredMixin, FormView): """View to test policy(s)""" model = Policy form_class = PolicyTestForm + permission_required = 'passbook_core.view_policy' template_name = 'administration/policy/test.html' object = None diff --git a/passbook/admin/views/property_mapping.py b/passbook/admin/views/property_mapping.py index c4cf7fad3..0ca1235fa 100644 --- a/passbook/admin/views/property_mapping.py +++ b/passbook/admin/views/property_mapping.py @@ -1,14 +1,18 @@ """passbook PropertyMapping administration""" from django.contrib import messages +from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.auth.mixins import \ + PermissionRequiredMixin as DjangoPermissionRequiredMixin from django.contrib.messages.views import SuccessMessageMixin from django.http import Http404 from django.urls import reverse_lazy from django.utils.translation import ugettext as _ -from django.views.generic import CreateView, DeleteView, ListView, UpdateView +from django.views.generic import DeleteView, ListView, UpdateView +from guardian.mixins import PermissionListMixin, PermissionRequiredMixin -from passbook.admin.mixins import AdminRequiredMixin from passbook.core.models import PropertyMapping from passbook.lib.utils.reflection import path_to_class +from passbook.lib.views import CreateAssignPermView def all_subclasses(cls): @@ -17,10 +21,11 @@ def all_subclasses(cls): [s for c in cls.__subclasses__() for s in all_subclasses(c)]) -class PropertyMappingListView(AdminRequiredMixin, ListView): +class PropertyMappingListView(LoginRequiredMixin, PermissionListMixin, ListView): """Show list of all property_mappings""" model = PropertyMapping + permission_required = 'passbook_core.view_propertymapping' template_name = 'administration/property_mapping/list.html' ordering = 'name' @@ -33,9 +38,18 @@ class PropertyMappingListView(AdminRequiredMixin, ListView): return super().get_queryset().select_subclasses() -class PropertyMappingCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView): +class PropertyMappingCreateView(SuccessMessageMixin, LoginRequiredMixin, + DjangoPermissionRequiredMixin, CreateAssignPermView): """Create new PropertyMapping""" + model = PropertyMapping + permission_required = 'passbook_core.add_propertymapping' + permissions = [ + 'passbook_core.view_propertymapping', + 'passbook_core.change_propertymapping', + 'passbook_core.delete_propertymapping', + ] + template_name = 'generic/create.html' success_url = reverse_lazy('passbook_admin:property-mappings') success_message = _('Successfully created Property Mapping') @@ -57,10 +71,13 @@ class PropertyMappingCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateV return path_to_class(model.form) -class PropertyMappingUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateView): +class PropertyMappingUpdateView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, UpdateView): """Update property_mapping""" model = PropertyMapping + permission_required = 'passbook_core.change_propertymapping' + template_name = 'generic/update.html' success_url = reverse_lazy('passbook_admin:property-mappings') success_message = _('Successfully updated Property Mapping') @@ -74,10 +91,13 @@ class PropertyMappingUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateV return PropertyMapping.objects.filter(pk=self.kwargs.get('pk')).select_subclasses().first() -class PropertyMappingDeleteView(SuccessMessageMixin, AdminRequiredMixin, DeleteView): +class PropertyMappingDeleteView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, DeleteView): """Delete property_mapping""" model = PropertyMapping + permission_required = 'passbook_core.delete_propertymapping' + template_name = 'generic/delete.html' success_url = reverse_lazy('passbook_admin:property-mappings') success_message = _('Successfully deleted Property Mapping') diff --git a/passbook/admin/views/providers.py b/passbook/admin/views/providers.py index 77e9f5a81..8892ade5f 100644 --- a/passbook/admin/views/providers.py +++ b/passbook/admin/views/providers.py @@ -1,20 +1,25 @@ """passbook Provider administration""" from django.contrib import messages +from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.auth.mixins import \ + PermissionRequiredMixin as DjangoPermissionRequiredMixin from django.contrib.messages.views import SuccessMessageMixin from django.http import Http404 from django.urls import reverse_lazy from django.utils.translation import ugettext as _ -from django.views.generic import CreateView, DeleteView, ListView, UpdateView +from django.views.generic import DeleteView, ListView, UpdateView +from guardian.mixins import PermissionListMixin, PermissionRequiredMixin -from passbook.admin.mixins import AdminRequiredMixin from passbook.core.models import Provider from passbook.lib.utils.reflection import path_to_class +from passbook.lib.views import CreateAssignPermView -class ProviderListView(AdminRequiredMixin, ListView): +class ProviderListView(LoginRequiredMixin, PermissionListMixin, ListView): """Show list of all providers""" model = Provider + permission_required = 'passbook_core.add_provider' template_name = 'administration/provider/list.html' def get_context_data(self, **kwargs): @@ -26,9 +31,18 @@ class ProviderListView(AdminRequiredMixin, ListView): return super().get_queryset().select_subclasses() -class ProviderCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView): +class ProviderCreateView(SuccessMessageMixin, LoginRequiredMixin, + DjangoPermissionRequiredMixin, CreateAssignPermView): """Create new Provider""" + model = Provider + permission_required = 'passbook_core.add_provider' + permissions = [ + 'passbook_core.view_provider', + 'passbook_core.change_provider', + 'passbook_core.delete_provider', + ] + template_name = 'generic/create.html' success_url = reverse_lazy('passbook_admin:providers') success_message = _('Successfully created Provider') @@ -42,10 +56,13 @@ class ProviderCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView): return path_to_class(model.form) -class ProviderUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateView): +class ProviderUpdateView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, UpdateView): """Update provider""" model = Provider + permission_required = 'passbook_core.change_provider' + template_name = 'generic/update.html' success_url = reverse_lazy('passbook_admin:providers') success_message = _('Successfully updated Provider') @@ -59,10 +76,13 @@ class ProviderUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateView): return Provider.objects.filter(pk=self.kwargs.get('pk')).select_subclasses().first() -class ProviderDeleteView(SuccessMessageMixin, AdminRequiredMixin, DeleteView): +class ProviderDeleteView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, DeleteView): """Delete provider""" model = Provider + permission_required = 'passbook_core.delete_provider' + template_name = 'generic/delete.html' success_url = reverse_lazy('passbook_admin:providers') success_message = _('Successfully deleted Provider') diff --git a/passbook/admin/views/sources.py b/passbook/admin/views/sources.py index ea74e1d78..ec4ca39ee 100644 --- a/passbook/admin/views/sources.py +++ b/passbook/admin/views/sources.py @@ -1,14 +1,18 @@ """passbook Source administration""" from django.contrib import messages +from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.auth.mixins import \ + PermissionRequiredMixin as DjangoPermissionRequiredMixin from django.contrib.messages.views import SuccessMessageMixin from django.http import Http404 from django.urls import reverse_lazy from django.utils.translation import ugettext as _ -from django.views.generic import CreateView, DeleteView, ListView, UpdateView +from django.views.generic import DeleteView, ListView, UpdateView +from guardian.mixins import PermissionListMixin, PermissionRequiredMixin -from passbook.admin.mixins import AdminRequiredMixin from passbook.core.models import Source from passbook.lib.utils.reflection import path_to_class +from passbook.lib.views import CreateAssignPermView def all_subclasses(cls): @@ -16,10 +20,11 @@ def all_subclasses(cls): return set(cls.__subclasses__()).union( [s for c in cls.__subclasses__() for s in all_subclasses(c)]) -class SourceListView(AdminRequiredMixin, ListView): +class SourceListView(LoginRequiredMixin, PermissionListMixin, ListView): """Show list of all sources""" model = Source + permission_required = 'passbook_core.view_source' template_name = 'administration/source/list.html' def get_context_data(self, **kwargs): @@ -31,9 +36,18 @@ class SourceListView(AdminRequiredMixin, ListView): return super().get_queryset().select_subclasses() -class SourceCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView): +class SourceCreateView(SuccessMessageMixin, LoginRequiredMixin, + DjangoPermissionRequiredMixin, CreateAssignPermView): """Create new Source""" + model = Source + permission_required = 'passbook_core.add_source' + permissions = [ + 'passbook_core.view_source', + 'passbook_core.change_source', + 'passbook_core.delete_source', + ] + template_name = 'generic/create.html' success_url = reverse_lazy('passbook_admin:sources') success_message = _('Successfully created Source') @@ -46,10 +60,13 @@ class SourceCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView): return path_to_class(model.form) -class SourceUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateView): +class SourceUpdateView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, UpdateView): """Update source""" model = Source + permission_required = 'passbook_core.change_source' + template_name = 'generic/update.html' success_url = reverse_lazy('passbook_admin:sources') success_message = _('Successfully updated Source') @@ -63,10 +80,13 @@ class SourceUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateView): return Source.objects.filter(pk=self.kwargs.get('pk')).select_subclasses().first() -class SourceDeleteView(SuccessMessageMixin, AdminRequiredMixin, DeleteView): +class SourceDeleteView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, DeleteView): """Delete source""" model = Source + permission_required = 'passbook_core.delete_source' + template_name = 'generic/delete.html' success_url = reverse_lazy('passbook_admin:sources') success_message = _('Successfully deleted Source') diff --git a/passbook/admin/views/users.py b/passbook/admin/views/users.py index cc99fb7a7..400873e74 100644 --- a/passbook/admin/views/users.py +++ b/passbook/admin/views/users.py @@ -1,50 +1,66 @@ """passbook User administration""" from django.contrib import messages +from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.auth.mixins import \ + PermissionRequiredMixin as DjangoPermissionRequiredMixin from django.contrib.messages.views import SuccessMessageMixin -from django.shortcuts import get_object_or_404, redirect +from django.shortcuts import redirect from django.urls import reverse, reverse_lazy from django.utils.translation import ugettext as _ -from django.views import View -from django.views.generic import CreateView, DeleteView, ListView, UpdateView +from django.views.generic import DeleteView, DetailView, ListView, UpdateView +from guardian.mixins import PermissionListMixin, PermissionRequiredMixin from passbook.admin.forms.users import UserForm -from passbook.admin.mixins import AdminRequiredMixin from passbook.core.models import Nonce, User +from passbook.lib.views import CreateAssignPermView -class UserListView(AdminRequiredMixin, ListView): +class UserListView(LoginRequiredMixin, PermissionListMixin, ListView): """Show list of all users""" model = User + permission_required = 'passbook_core.view_user' template_name = 'administration/user/list.html' -class UserCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView): +class UserCreateView(SuccessMessageMixin, LoginRequiredMixin, + DjangoPermissionRequiredMixin, CreateAssignPermView): """Create user""" model = User form_class = UserForm + permission_required = 'passbook_core.add_user' + permissions = [ + 'passbook_core.view_user', + 'passbook_core.change_user', + 'passbook_core.delete_user', + ] template_name = 'generic/create.html' success_url = reverse_lazy('passbook_admin:users') success_message = _('Successfully created User') -class UserUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateView): +class UserUpdateView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, UpdateView): """Update user""" model = User form_class = UserForm + permission_required = 'passbook_core.change_user' template_name = 'generic/update.html' success_url = reverse_lazy('passbook_admin:users') success_message = _('Successfully updated User') -class UserDeleteView(SuccessMessageMixin, AdminRequiredMixin, DeleteView): +class UserDeleteView(SuccessMessageMixin, LoginRequiredMixin, + PermissionRequiredMixin, DeleteView): """Delete user""" model = User + permission_required = 'passbook_core.delete_user' + template_name = 'generic/delete.html' success_url = reverse_lazy('passbook_admin:users') success_message = _('Successfully deleted User') @@ -54,14 +70,16 @@ class UserDeleteView(SuccessMessageMixin, AdminRequiredMixin, DeleteView): return super().delete(request, *args, **kwargs) -class UserPasswordResetView(AdminRequiredMixin, View): +class UserPasswordResetView(LoginRequiredMixin, PermissionRequiredMixin, DetailView): """Get Password reset link for user""" - # pylint: disable=invalid-name - def get(self, request, pk): + model = User + permission_required = 'passbook_core.reset_user_password' + + def get(self, request, *args, **kwargs): """Create nonce for user and return link""" - user = get_object_or_404(User, pk=pk) - nonce = Nonce.objects.create(user=user) + super().get(request, *args, **kwargs) + nonce = Nonce.objects.create(user=self.object) link = request.build_absolute_uri(reverse( 'passbook_core:auth-password-reset', kwargs={'nonce': nonce.uuid})) messages.success(request, _('Password reset link:
%(link)s
' % {'link': link}))