| 1 | Sometimes it is useful to only allow users from a certain group to login. |
| 2 | |
| 3 | The main problem with that idea is that you can't actually check if the user is in the required group before he logs in. This is a kind of chicken and egg problem in django because as the anonymous user you don't have enough rights to look the necessary information up. |
| 4 | |
| 5 | The solution/workaround to the problem is: |
| 6 | |
| 7 | a) modified decorator for ''user_passes_test'' from ''django.contrib.auth.decorator'': |
| 8 | {{{ |
| 9 | from django.contrib.auth import LOGIN_URL, REDIRECT_FIELD_NAME |
| 10 | from django.http import HttpResponseRedirect, Http404 |
| 11 | |
| 12 | def user_passes_mytest(test_func, login_url=LOGIN_URL): |
| 13 | def _dec(view_func): |
| 14 | def _checklogin(request, *args, **kwargs): |
| 15 | try: |
| 16 | if test_func(request.user): |
| 17 | return view_func(request, *args, **kwargs) |
| 18 | return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, quote(request.get_full_path |
| 19 | ()))) |
| 20 | except: |
| 21 | raise Http404 |
| 22 | return _checklogin |
| 23 | return _dec |
| 24 | }}} |
| 25 | |
| 26 | b) one central login view (and template) for every (django) application: |
| 27 | {{{ |
| 28 | from django.contrib.auth.decorators import login_required |
| 29 | from django.contrib.auth.models import Group, SESSION_KEY |
| 30 | from django.shortcuts import render_to_response |
| 31 | |
| 32 | @login_required |
| 33 | def index(request): |
| 34 | custgroup = Group.objects.get(name="thegroupyouneed") # Replace group name here! |
| 35 | if custgroup in request.user.groups.all(): |
| 36 | return render_to_response('myapp/templates/index.html') # This is the welcome screen after a successful login |
| 37 | else: |
| 38 | try: |
| 39 | del request.session[SESSION_KEY] |
| 40 | except: |
| 41 | pass |
| 42 | return render_to_response('registration/notallowed.html') # This is the 'not allowed' screen wich |
| 43 | # should be shown if the user is not in the correct group |
| 44 | }}} |
| 45 | |
| 46 | and finally c) the other views using our new decorator: |
| 47 | {{{ |
| 48 | REQUIRED_GROUP = Group.objects.get(name="thegroupyouneed") # Replace group name here! |
| 49 | |
| 50 | @user_passes_mytest(lambda u: REQUIRED_GROUP in u.groups.all()) |
| 51 | def someviewhere(request): |
| 52 | return render_to_response('myapp/templates/someviewhere.html') |
| 53 | }}} |
| 54 | |
| 55 | That's it. Enjoy! |