views:

444

answers:

3

I have an app that uses django.contrib.auth but makes no use of Django's built-in permissions system. Instead, views have the @login_required decorator and then check which group the user belongs to, and follow different branches of code execution within the view depending on the group.

A user can belong to only one group.

Checking for the user's group everytime seems to be too much, so I am trying to write a Django middleware that will let me know the user's group in a session.

Looking at the code below, will my middleware work like I want it to?

class SetGroupMiddleware(object):
    def process_request(self, request):
        check_if_already_set = request.session.get('thegroup', 'notset')
        if check_if_already_set == 'notset':
            if request.user.id: # User is not AnonymousUser
                groups = request.user.groups.all()
                if groups: # actually this will always be True
                    request.session['thegroup'] = str(groups[0].name) # flowchart of the app ensures that the logged in user will only have one group, and that the user will always have a group
            else:
                request.session['thegroup'] = 'nogroup' # for completeness

I then intend to check request.session['thegroup'] where needed.

Need your suggestions and opinions. Is the session safe if handled this way? Will this work at all? I am new at Django, Python, and programming in general.

Thanks.

A: 

It looks approximately correct (not having tested it). One thing to note is that your middleware must occur after django.contrib.sessions.middleware.SessionMiddleware in the MIDDLEWARE_CLASSES list, otherwise the session won't have been setup for you at the time you try to reference it.

Peter Rowell
So if this goes after the SessioonMiddleware, do I explicitly need to mark the session dirty? Or will the session framework detect and save this information automatically?
gbsmith
Because you're modifying the session directly, you don't need to explicitly save it. See: http://docs.djangoproject.com/en/dev/topics/http/sessions/#when-sessions-are-saved
Steve Losh
A: 

In general it looks good. You can make it a bit more Pythonic though:

class SetGroupMiddleware(object):
    def process_request(self, request):
        if 'thegroup' not in request.session:
            if not request.user.is_anonymous():
                groups = request.user.groups.all()
                if groups:
                    request.session['thegroup'] = str(groups[0].name)
            else:
                request.session['thegroup'] = None # for completeness
Steve Losh
Peter Rowell's answer about the order of middleware was very important, but I'm going to mark your answer as the accepted answer because of how you have refined my (obviously newbie) code.
gbsmith
Well, if a user starts out as anonymous (which mostly is the case), then with the current code request.session['thegroup'] does not get updated upon login. I will try to debug that and if I can, I'll post it here.
gbsmith
A: 

Well, as I commented in Steve Losh's answer , that code doesn't work as intended.

I modified it as follows and it seems to be OK till now: -

class SetGroupMiddleware(object):
    def process_request(self, request):
        if not request.user.is_anonymous():
            if 'thegroup' not in request.session:
                groups = request.user.groups.all()
                if groups:
                    request.session['thegroup'] = str(groups[0].name)
gbsmith