src/egonomy/auth/middleware.py
author ymh <ymh.work@gmail.com>
Fri, 21 Mar 2014 17:30:29 +0100
changeset 273 a8dcacb29110
parent 271 4e7178ce5688
permissions -rw-r--r--
Add basic auth.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
271
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
# -*- coding: utf-8 -*-
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
'''
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
Created on Mar 19, 2014
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
@author: ymh
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
'''
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
import logging
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
from django.conf import settings
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
from django.contrib import auth
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
from django.contrib.auth import get_user_model
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
from django.core.exceptions import ImproperlyConfigured
273
a8dcacb29110 Add basic auth.
ymh <ymh.work@gmail.com>
parents: 271
diff changeset
    13
from django.http.response import HttpResponseBadRequest
271
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
273
a8dcacb29110 Add basic auth.
ymh <ymh.work@gmail.com>
parents: 271
diff changeset
    15
from egonomy.auth import clean_egonomy_username, get_http_session
271
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
logger = logging.getLogger(__name__) 
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
class EgonomyUserTokenMiddleware(object):
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
    parameter = (getattr(settings, "EGONOMY_TOKEN_NAME", None) or "egonomytoken")
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
    def process_request(self, request):
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
        if not hasattr(request, 'user'):
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
            raise ImproperlyConfigured(
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
                "The Egonomy user token auth middleware requires the"
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
                " authentication middleware to be installed.  Edit your"
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
                " MIDDLEWARE_CLASSES setting to insert"
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
                " 'django.contrib.auth.middleware.AuthenticationMiddleware'"
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
                " before the EgonomyUserTokenMiddleware class.")
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
        logger.debug("EgonomyUserTokenMiddleware called")
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
        token = request.POST.get(self.parameter,request.GET.get(self.parameter,None))
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
        if not token:
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
            return
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
        logger.debug("EgonomyUserTokenMiddleware token found %s" % token)
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
        
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
        token_check_url = getattr(settings, "EGONOMY_TOKEN_CHECK_URL", None)
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
        if not token_check_url:
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
            return
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
        
273
a8dcacb29110 Add basic auth.
ymh <ymh.work@gmail.com>
parents: 271
diff changeset
    44
        res_check = get_http_session().get(token_check_url, params={self.parameter:token})
271
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
        logger.debug("EgonomyUserTokenMiddleware json raw %s" % res_check.text)
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
        res_json = res_check.json()
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
        
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
        logger.debug("EgonomyUserTokenMiddleware json %s" % res_json )
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
        if not res_json.get('success', False):
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
            return
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
        
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
        username = res_json.get('username', None)
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
        if not username :
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
            return HttpResponseBadRequest("Empty username")
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
        #"namespace" username
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
        username = clean_egonomy_username(username, res_json.get('external', True))
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
        # If the user is already authenticated and that user is the user we are
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
        # getting passed in the headers, then the correct user is already
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
        # persisted in the session and we don't need to continue.
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
        if request.user.is_authenticated() and request.user.get_username() == username:
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
                return
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
        else:
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
            auth.logout(request)
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
        
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
        # create user if not known
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
        # login user
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
        UserModel = get_user_model()
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
        # Note that this could be accomplished in one try-except clause, but
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
        # instead we use get_or_create when creating unknown users since it has
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
        # built-in safeguards for multiple threads.
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
        user, _ = UserModel.objects.get_or_create(**{
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
                UserModel.USERNAME_FIELD: username
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
        })
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
        
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
        if user:
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
            user.backend = 'django.contrib.auth.backends.ModelBackend'
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
            # User is valid.  Set request.user and persist user in the session
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
            # by logging the user in.
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
            request.user = user
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
            
4e7178ce5688 Implement single sign on with egonomy - mobenfact
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
            auth.login(request, user)