Skip to content

Commit

Permalink
Merge 5af3717 into 84de104
Browse files Browse the repository at this point in the history
  • Loading branch information
dyve committed Sep 24, 2018
2 parents 84de104 + 5af3717 commit 42d9543
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 11 deletions.
13 changes: 8 additions & 5 deletions rules/contrib/views.py
Expand Up @@ -13,6 +13,8 @@

# These are made available for convenience, as well as for use in Django
# versions before 1.9. For usage help see Django's docs for 1.9 or later.
from django.views.generic.edit import BaseCreateView

LoginRequiredMixin = mixins.LoginRequiredMixin
UserPassesTestMixin = mixins.UserPassesTestMixin

Expand All @@ -34,11 +36,12 @@ def get_permission_object(self):
``SingleObjectMixin``. Returns None if there's no ``get_object``
method.
"""
if hasattr(self, 'get_object') and callable(self.get_object):
# Requires SingleObjectMixin or equivalent ``get_object`` method
return self.get_object()
else: # pragma: no cover
return None
if not isinstance(self, BaseCreateView):
# We do NOT want to call get_object in a BaseCreateView, see issue #85
if hasattr(self, 'get_object') and callable(self.get_object):
# Requires SingleObjectMixin or equivalent ``get_object`` method
return self.get_object()
return None

def has_permission(self):
obj = self.get_permission_object()
Expand Down
8 changes: 6 additions & 2 deletions tests/testapp/rules.py
Expand Up @@ -12,14 +12,18 @@ def is_book_author(user, book):
return book.author == user


is_editor = rules.is_group_member('editors')
@rules.predicate
def is_boss(user):
return user.is_superuser


is_editor = rules.is_group_member('editors')

# Rules

rules.add_rule('change_book', is_book_author | is_editor)
rules.add_rule('delete_book', is_book_author)

rules.add_rule('create_book', is_boss)

# Permissions

Expand Down
7 changes: 4 additions & 3 deletions tests/testapp/urls.py
Expand Up @@ -2,9 +2,9 @@
from django.contrib import admin

from .views import (change_book, delete_book,
view_that_raises, view_with_object, view_with_permission_list,
BookUpdateView, BookDeleteView, ViewThatRaises, ViewWithPermissionList,
BookUpdateErrorView)
view_that_raises, view_with_object, view_with_permission_list,
BookUpdateView, BookDeleteView, ViewThatRaises, ViewWithPermissionList,
BookUpdateErrorView, BookCreateView)

admin.autodiscover()

Expand All @@ -19,6 +19,7 @@
url(r'^(?P<book_id>\d+)/list/$', view_with_permission_list, name='view_with_permission_list'),

# Class-based views
url(r'^cbv/create/$', BookCreateView.as_view(), name='cbv.create_book'),
url(r'^cbv/(?P<book_id>\d+)/change/$', BookUpdateView.as_view(), name='cbv.change_book'),
url(r'^cbv/(?P<book_id>\d+)/delete/$', BookDeleteView.as_view(), name='cbv.delete_book'),
url(r'^cbv/(?P<book_id>\d+)/raise/$', ViewThatRaises.as_view(), name='cbv.view_that_raises'),
Expand Down
9 changes: 8 additions & 1 deletion tests/testapp/views.py
@@ -1,7 +1,7 @@
from __future__ import absolute_import

from django.http import HttpResponse
from django.views.generic.edit import UpdateView, DeleteView
from django.views.generic.edit import UpdateView, DeleteView, CreateView

from rules.contrib.views import permission_required, objectgetter
from rules.contrib.views import LoginRequiredMixin, PermissionRequiredMixin
Expand All @@ -24,6 +24,13 @@ def change_book(request, book_id):
return HttpResponse('OK')



class BookCreateView(LoginRequiredMixin, PermissionRequiredMixin, BookMixin, CreateView):
fields = ['title']
template_name = 'empty.html'
permission_required = 'testapp.create_book'


class BookUpdateView(LoginRequiredMixin, PermissionRequiredMixin, BookMixin, UpdateView):
fields = ['title']
template_name = 'empty.html'
Expand Down
5 changes: 5 additions & 0 deletions tests/testsuite/contrib/test_views.py
Expand Up @@ -53,6 +53,11 @@ def test_permission_required(self):
self.assertEqual(response.status_code, 200)
self.assertEqual(force_str(response.content), 'OK')

# Martin can *not* create a book
self.assertTrue(self.client.login(username='martin', password='secr3t'))
response = self.client.get(reverse('cbv.create_book'))
self.assertEqual(response.status_code, 302)

# Martin can *not* delete Adrian's book and is redirected to login
self.assertTrue(self.client.login(username='martin', password='secr3t'))
response = self.client.get(reverse('delete_book', args=(1,)))
Expand Down

0 comments on commit 42d9543

Please sign in to comment.