decoupling authorization from calling the view

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# -*- coding: iso-8859-1 -*-
# $Id: has_perm.py 128 2008-10-02 11:28:43Z tguettler $
# $HeadURL: svn+ssh://svnserver/svn/djangotools/trunk/utils/has_perm.py $


u'''

has_perm.py: Check if a user can access a view without calling it

One of the goals:
 You can disable or hide a link if the user must not call it. 


Usage:

# file views.py
def myview(request, ...):

    return ...
myview.has_perm=STRING_BOOL_OR_METHOD

STRING_BOOL_OR_METHOD:
 - 'is_staff', 'is_superuser', 'is_authenticated'
 - True (everybody can access it), False (nobody can access it)
 - method which returns True, False or HttpResponse

If you install the HasPermMiddleware, you don't need to check access in your view method.

http://www.djangosnippets.org/snippets/1214/

'''

# Python
import logging

# Django
import django
from django.http import Http404
from django.core.urlresolvers import get_resolver
from django.contrib.auth.models import Permission

# Project
from django.conf import settings

def has_perm(request, url):
    sn=request.META['SCRIPT_NAME']
    if sn is None:
        sn=''
    else:
        assert url.startswith(sn), u'URL=%s does not start with SCRIPT_NAME=%s' % (
            url, sn)
    url_orig=url
    url=url[len(sn):]
    resolver=get_resolver(None)
    try:
        view_func, view_args, view_kwargs = resolver.resolve(url)
    except Http404, exc:
        raise Exception('could not resolve url: %r %r' % (url, url_orig))
    return not check_deny(request, view_func, view_args, view_kwargs)

def check_deny(request, view_func, view_args, view_kwargs):
    view_name='%s.%s' % (view_func.__module__, view_func.__name__)
    has_perm=getattr(view_func, 'has_perm', view_func)
    if has_perm is view_func:
        # Attribute does not exist
        raise AttributeError(u'View %s does not have attribute has_perm' % (
                view_name))
    if has_perm is True:
        return
    if has_perm is False:
        return True

    if isinstance(has_perm, basestring):
        count=has_perm.count('.')
        if count==1:
            if settings.DEBUG:
                app_label, codename = has_perm.split('.')
                perms=Permission.objects.filter(codename=codename, content_type__app_label=app_label)
                if not len(perms)==1:
                    raise Exception('permission string "%s": No or more than one permission objects found: %s' % (
                            has_perm, perms))
            if request.user.has_perm(has_perm):
                return
            else:
                return True

More like this

  1. Remember path decorator by robhudson 4 years, 4 months ago
  2. Declaring django views like web.py views by danigm 4 years, 2 months ago
  3. a template tag to invoke a method on an object with a variable by Scanner 6 years, 11 months ago
  4. My approach on class based views by henning 3 years, 10 months ago
  5. View and StatefulView classes by Digitalxero 5 years, 6 months ago

Comments

(Forgotten your password?)