diff --git a/babybuddy/mixins.py b/babybuddy/mixins.py new file mode 100644 index 00000000..6fadb5dd --- /dev/null +++ b/babybuddy/mixins.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.contrib.auth.mixins import AccessMixin + + +class StaffOnlyMixin(AccessMixin): + """ + Verify the current user is staff. + """ + def dispatch(self, request, *args, **kwargs): + if not request.user.is_staff: + return self.handle_no_permission() + return super().dispatch(request, *args, **kwargs) diff --git a/babybuddy/templates/babybuddy/nav-dropdown.html b/babybuddy/templates/babybuddy/nav-dropdown.html index f466313a..0ca8961f 100644 --- a/babybuddy/templates/babybuddy/nav-dropdown.html +++ b/babybuddy/templates/babybuddy/nav-dropdown.html @@ -184,10 +184,8 @@ API Browser - {% if perms.admin.add_user %} - Users - {% endif %} {% if request.user.is_staff %} + Users Backend Admin diff --git a/babybuddy/tests/tests_forms.py b/babybuddy/tests/tests_forms.py index d7a7ebb9..a6855ef8 100644 --- a/babybuddy/tests/tests_forms.py +++ b/babybuddy/tests/tests_forms.py @@ -56,6 +56,8 @@ class FormsTestCase(TestCase): self.assertEqual(page.status_code, 200) def test_user_forms(self): + self.user.is_staff = True + self.user.save() self.c.login(**self.credentials) params = { diff --git a/babybuddy/tests/tests_views.py b/babybuddy/tests/tests_views.py index 2d1839c1..b4224d9a 100644 --- a/babybuddy/tests/tests_views.py +++ b/babybuddy/tests/tests_views.py @@ -62,6 +62,12 @@ class ViewsTestCase(TestCase): self.assertEqual(page.status_code, 200) def test_user_views(self): + # Staff setting is required to access user management. + page = self.c.get('/users/') + self.assertEqual(page.status_code, 302) + self.user.is_staff = True + self.user.save() + page = self.c.get('/users/') self.assertEqual(page.status_code, 200) page = self.c.get('/users/add/') diff --git a/babybuddy/views.py b/babybuddy/views.py index c200d721..cce016a4 100644 --- a/babybuddy/views.py +++ b/babybuddy/views.py @@ -17,6 +17,7 @@ from django.views.generic.edit import CreateView, UpdateView, DeleteView from django_filters.views import FilterView from babybuddy import forms +from babybuddy.mixins import StaffOnlyMixin from core import models @@ -40,16 +41,16 @@ class RootRouter(LoginRequiredMixin, RedirectView): return super(RootRouter, self).get_redirect_url(self, *args, **kwargs) -class UserList(PermissionRequiredMixin, FilterView): +class UserList(StaffOnlyMixin, FilterView): model = User template_name = 'babybuddy/user_list.html' ordering = 'username' - permission_required = ('admin.add_user',) paginate_by = 10 filter_fields = ('username', 'first_name', 'last_name', 'email') -class UserAdd(PermissionRequiredMixin, SuccessMessageMixin, CreateView): +class UserAdd(StaffOnlyMixin, PermissionRequiredMixin, SuccessMessageMixin, + CreateView): model = User template_name = 'babybuddy/user_form.html' permission_required = ('admin.add_user',) @@ -58,7 +59,8 @@ class UserAdd(PermissionRequiredMixin, SuccessMessageMixin, CreateView): success_message = 'User %(username)s added!' -class UserUpdate(PermissionRequiredMixin, SuccessMessageMixin, UpdateView): +class UserUpdate(StaffOnlyMixin, PermissionRequiredMixin, SuccessMessageMixin, + UpdateView): model = User template_name = 'babybuddy/user_form.html' permission_required = ('admin.change_user',) @@ -67,7 +69,8 @@ class UserUpdate(PermissionRequiredMixin, SuccessMessageMixin, UpdateView): success_message = 'User %(username)s updated.' -class UserDelete(PermissionRequiredMixin, DeleteView): +class UserDelete(StaffOnlyMixin, PermissionRequiredMixin, + DeleteView): model = User template_name = 'babybuddy/user_confirm_delete.html' permission_required = ('admin.delete_user',)