Login

Global custom permissions (no model association)

Author:
miracle2k
Posted:
July 22, 2007
Language:
Python
Version:
.96
Tags:
auth permissions
Score:
7 (after 7 ratings)

Example (in project/application/models.py):

register_custom_permissions_simple((("is_editor", "User is editor"),))

In a view:

if not request.user.has_perm('application.is_editor'):
   return HttpResonseRedirect(LoginUrl)
 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
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from django.dispatch import dispatcher
from django.db.models import signals

"""
    Registers any number of custom permissions that are not related to any
    certain model (i.e. "global/app level").
    
    You must pass the models module of your app as the sender parameter. If you
    use "None" instead, the permissions will be duplicated for each application
    in your project.
    
    Permissions is a tuple:    
       (
           # codename, name
           ("can_drive", "Can drive"),
           ("can_drink", "Can drink alcohol"),
       )
       
    Examples:        
        from myapp.mysite import models as app
        register_custom_permissions(('my_perm', 'My Permission'), app)
        register_custom_permissions(('my_perm', 'My Permission'), sys.modules[__name__])  # in models.py
        register_custom_permissions(('my_perm', 'My Permission'))
"""
def register_custom_permissions(permissions, sender):
    def mk_permissions(permissions, app, verbosity):
        # retrieve actual appname string from module instance
        appname = app.__name__.lower().split('.')[-2]
        # create a content type for the app
        ct, created = ContentType.objects.get_or_create(model='', app_label=appname,
                                                        defaults={'name': appname})
        if created and verbosity >= 2: print "Adding custom content type '%s'" % ct
        # create permissions
        for codename, name in permissions:
            p, created = Permission.objects.get_or_create(codename=codename,
                            content_type__pk=ct.id,
                            defaults={'name': name, 'content_type': ct})            
            if created and verbosity >= 2:
                print "Adding custom permission '%s'" % p

    dispatcher.connect(lambda app, verbosity: mk_permissions(permissions, app, verbosity),
                       sender=sender, signal=signals.post_syncdb, weak=False)

"""
    A wrapper around register_custom_permissions() that automatically determines
    the sender paramter via the stack. This is probably overkill, but learning
    about stack inspection in python was very interesting, so here it is.
    
    The functions expects that it is called from a module within your django
    application directory (e.g. project.app.callermodule). If that is not the
    case, you can use the levels_down parameter: If __name__ is
    project.app.views.callermodule, then levels_down should be set to 2
    (because "callermodule" is two levels below the application directory).
"""
def register_custom_permissions_simple(permissions, levels_down=1):    
    # find the caller's __name__ via the stack
    import inspect, sys
    frame = inspect.stack()[1][0]
    try: caller__name__ = frame.f_locals['__name__']
    finally: del frame    
    # build the path to the app's models.py
    models_module = '.'.join(caller__name__.split('.')[0:-levels_down]+['models'])
    sender = sys.modules[models_module]
    # register the signal handler
    register_custom_permissions(permissions, sender)

More like this

  1. Templatetag for granular permissions by achimnol 6 years, 1 month ago
  2. Class based generic views that automatically check permissions by humphreymurray 4 years, 6 months ago
  3. Login with email or username by zeeg 6 years, 11 months ago
  4. Functional Filters by waterson 7 years, 10 months ago
  5. Create permissions for proxy models by charettes 3 years, 5 months ago

Comments

pigletto (on August 27, 2007):

Examples are wrong because as it is said just before, 'permissions is a tuple' so instead: register_custom_permissions(('my_perm', 'My Permission'), app) you should use: register_custom_permissions((('my_perm', 'My Permission'),), app)

#

jjlorenzo (on December 14, 2008):

pigletto your wrong is a function receives a param, and the param is passed in the form of: foo((2,3),2) the first param of foo is (2,3) that's a tuple

#

akaihola (on October 7, 2010):

For better Google hits, some keywords related to this snippet: per-app custom permissions, app-wide custom permissions, app-specific custom permissions,

#

Please login first before commenting.