jezdez / django-authority (http://packages.python.org/django-authority/)
A Django app that provides generic per-object-permissions for Django's auth app and helpers to create custom permission checks.
Clone this repository (size: 338.3 KB): HTTPS / SSH
$ hg clone http://bitbucket.org/jezdez/django-authority/
| commit 28: | 00f8b83e5397 |
| parent 27: | 8cd5342dd03b |
| branch: | default |
Fixed decorator to only check for permissions if user is logged in. Added permission_denied view to be used when permission check unsuccessful, e.g. with the new permission_required_or_403 decorator. The permission_required decorator will redirect to the login form by default.
- View jezdez's profile
-
jezdez's public repos »
- django-adminfiles-de
- pip-standalone
- djangologging
- django-endless-pagination-de
- django-endless-pagination-fixes
- creole
- pip-wininst
- transifex-buildout
- hgstuff
- akismet
- django-dbtemplates
- Sphinx-PyPI-upload
- django-robots
- django-authority
- pip-config
- jezdez.bitbucket.org
- ports
- virtualenv-packaging
- pip
- django-registration-de
- pycompletion
- django-piston
- django-piston-python-oauth2
- django-licenses
- jzdz
- django-vcstorage
- textmate-missingdrawer
- virtualenv
- pip-uninstall
- setuptools_hg
- djangolocales
- django-staticfiles
- Send message
9 months ago
Changed (Δ1.3 KB):
raw changeset »
example/exampleapp/views.py (2 lines added, 1 lines removed)
src/authority/decorators.py (35 lines added, 24 lines removed)
src/authority/views.py (19 lines added, 0 lines removed)
Up to file-list example/exampleapp/views.py:
1 |
1 |
from django.contrib.flatpages.views import flatpage |
2 |
2 |
from django.contrib.flatpages.models import FlatPage |
3 |
3 |
|
4 |
from authority.decorators import permission_required |
|
4 |
from authority.decorators import permission_required, permission_required_or_403 |
|
5 |
5 |
|
6 |
#@permission_required_or_403('flatpage_permission.top_secret', (FlatPage, 'url__contains')) # use this to return a 403 page |
|
6 |
7 |
@permission_required('flatpage_permission.top_secret', (FlatPage, 'url__contains')) |
7 |
8 |
def top_secret(request, url): |
8 |
9 |
""" |
| … | … | @@ -10,38 +10,49 @@ from django.contrib.auth.decorators impo |
10 |
10 |
from django.contrib.auth import REDIRECT_FIELD_NAME |
11 |
11 |
|
12 |
12 |
from authority import permissions |
13 |
from authority.views import permission_denied |
|
13 |
14 |
|
14 |
15 |
def permission_required(perm, *args, **kwargs): |
15 |
16 |
""" |
16 |
17 |
Decorator for views that checks whether a user has a particular permission |
17 |
18 |
enabled, redirecting to the log-in page if necessary. |
18 |
19 |
""" |
19 |
login_url = kwargs.pop('login_url', None) |
|
20 |
if not login_url: |
|
21 |
|
|
20 |
login_url = kwargs.pop('login_url', settings.LOGIN_URL) |
|
22 |
21 |
redirect_field_name = kwargs.pop('redirect_field_name', REDIRECT_FIELD_NAME) |
22 |
redirect_to_login = kwargs.pop('redirect_to_login', True) |
|
23 |
23 |
model_lookups = args |
24 |
24 |
def _permission_required(view_func, request, *args, **kwargs): |
25 |
25 |
objs = [] |
26 |
# model_lookups = [('flatpages.flatpage', 'url__contains')] |
|
27 |
for i, arguments in enumerate(model_lookups): |
|
28 |
model, lookup = arguments |
|
29 |
if isinstance(model, basestring): |
|
30 |
model_class = get_model(*model.split(".")) |
|
31 |
else: |
|
32 |
model_class = model |
|
33 |
if model_class is None: |
|
34 |
raise ValueError( |
|
35 |
"The given argument '%s' is not a valid model." % model) |
|
36 |
if inspect.isclass(model_class) and \ |
|
37 |
not issubclass(model_class, Model): |
|
38 |
raise ValueError( |
|
39 |
'The argument %s needs to be a model.' % model) |
|
40 |
objs.append(get_object_or_404(model_class, **{lookup: args[i]})) |
|
41 |
check = permissions.registry.get_check(request.user, perm) |
|
42 |
if check is not None: |
|
43 |
if check(*objs): |
|
44 |
return view_func(request, *args, **kwargs) |
|
45 |
#return HttpResponseForbidden("Permission") |
|
46 |
|
|
26 |
if request.user.is_authenticated(): |
|
27 |
for i, arguments in enumerate(model_lookups): |
|
28 |
model, lookup = arguments |
|
29 |
if isinstance(model, basestring): |
|
30 |
model_class = get_model(*model.split(".")) |
|
31 |
else: |
|
32 |
model_class = model |
|
33 |
if model_class is None: |
|
34 |
raise ValueError( |
|
35 |
"The given argument '%s' is not a valid model." % model) |
|
36 |
if inspect.isclass(model_class) and \ |
|
37 |
not issubclass(model_class, Model): |
|
38 |
raise ValueError( |
|
39 |
'The argument %s needs to be a model.' % model) |
|
40 |
objs.append(get_object_or_404(model_class, **{lookup: args[i]})) |
|
41 |
check = permissions.registry.get_check(request.user, perm) |
|
42 |
if check is not None: |
|
43 |
if check(*objs): |
|
44 |
return view_func(request, *args, **kwargs) |
|
45 |
if redirect_to_login: |
|
46 |
path = urlquote(request.get_full_path()) |
|
47 |
tup = login_url, redirect_field_name, path |
|
48 |
return HttpResponseRedirect('%s?%s=%s' % tup) |
|
49 |
return permission_denied(request) |
|
47 |
50 |
return decorator(_permission_required) |
51 |
||
52 |
def permission_required_or_403(perm, *args, **kwargs): |
|
53 |
""" |
|
54 |
Decorator that wraps the permission_required decorator and returns a |
|
55 |
permission denied (403) page instead of redirecting to the login URL. |
|
56 |
""" |
|
57 |
kwargs['redirect_to_login'] = False |
|
58 |
return permission_required(perm, *args, **kwargs) |
| … | … | @@ -5,6 +5,7 @@ from django.db.models.loading import get |
5 |
5 |
from django.core.urlresolvers import reverse |
6 |
6 |
from django.utils.translation import ugettext, ugettext_lazy as _ |
7 |
7 |
from django.template.context import RequestContext |
8 |
from django.template import loader |
|
8 |
9 |
from django.contrib.auth.decorators import login_required |
9 |
10 |
|
10 |
11 |
from authority.models import Permission |
| … | … | @@ -56,3 +57,21 @@ def delete_permission(request, permissio |
56 |
57 |
message=ugettext('You removed the permission.')) |
57 |
58 |
next = request.REQUEST.get('next') or '/' |
58 |
59 |
return HttpResponseRedirect(next) |
60 |
||
61 |
def permission_denied(request, template_name=None, extra_context={}): |
|
62 |
""" |
|
63 |
Default 403 handler. |
|
64 |
||
65 |
Templates: `403.html` |
|
66 |
Context: |
|
67 |
request_path |
|
68 |
The path of the requested URL (e.g., '/app/pages/bad_page/') |
|
69 |
""" |
|
70 |
if template_name is None: |
|
71 |
template_name = ('authority/403.html', '403.html') |
|
72 |
context = { |
|
73 |
'request_path': request.path, |
|
74 |
} |
|
75 |
context.update(extra_context) |
|
76 |
return HttpResponseForbidden(loader.render_to_string(template_name, context, |
|
77 |
context_instance=RequestContext(request))) |
