Changeset 134

Show
Ignore:
Timestamp:
11/06/07 00:35:39
Author:
thejimmyg
Message:

Added provisional support for cookies which don't store the username in plain text

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • AuthKit/trunk/authkit/authenticate/cookie.py

    r118 r134  
    112112    """ 
    113113 
    114     def __init__(self, secret, userid, ip, tokens=(), user_data='', time=None,  
    115                  cookie_name='authkit', cookie_params=None): 
     114    def __init__( 
     115        self,  
     116        secret,  
     117        userid,  
     118        ip,  
     119        tokens=(),  
     120        user_data='',  
     121        time=None,  
     122        cookie_name='authkit',  
     123        cookie_params=None, 
     124        nouserincookie=False, 
     125    ): 
     126        self.nouserincookie = nouserincookie 
    116127        secure = False 
    117128        if cookie_params is None: 
     
    142153 
    143154    def cookie_value(self): 
    144         v = '%s%08x%s!' % (self.digest(), int(self.time), self.userid) 
     155        if not self.nouserincookie: 
     156            v = '%s%08x%s!' % (self.digest(), int(self.time), self.userid) 
     157        else: 
     158            v = '%s%08x!' % (self.digest(), int(self.time)) 
     159             
    145160        if self.tokens: 
    146161            v += self.tokens + '!' 
     
    172187# are utility methods which you shouldn't need to use on their own. 
    173188 
    174 def parse_ticket(secret, ticket, ip): 
     189def parse_ticket(secret, ticket, ip, session): 
    175190    """ 
    176191    Parse the ticket, returning (timestamp, userid, tokens, user_data). 
     
    186201    except ValueError, e: 
    187202        raise BadTicket('Timestamp is not a hex integer: %s' % e) 
    188     try: 
    189         userid, data = ticket[40:].split('!', 1) 
    190     except ValueError: 
    191         raise BadTicket('userid is not followed by !') 
     203 
     204    if session is not None: 
     205        if not session.has_key('authkit.cookie.user'): 
     206            raise BadTicket('No authkit.cookie.user key exists in the session') 
     207        userid = session['authkit.cookie.user'] 
     208        data = ticket[40:] 
     209    else: 
     210        try: 
     211            userid, data = ticket[40:].split('!', 1) 
     212        except ValueError: 
     213            raise BadTicket('userid is not followed by !') 
    192214    if '!' in data: 
    193215        tokens, user_data = data.split('!', 1) 
     
    245267    """ 
    246268 
    247     def __init__(self, app, secret, name='authkit', params=None,  
    248                  includeip=True, signoutpath=None, enforce=False,  
    249                  ticket_class=AuthKitTicket): 
     269    def __init__(self,  
     270        app,  
     271        secret,  
     272        name='authkit',  
     273        params=None,    
     274        includeip=True, 
     275        signoutpath=None,  
     276        enforce=False,  
     277        ticket_class=AuthKitTicket,  
     278        nouserincookie=False, 
     279        session_middleware='beaker.session' 
     280    ): 
    250281        log.debug("Setting up the cookie middleware") 
    251282        secure = False 
    252283        if params.has_key('secure') and asbool(params['secure']) == True: 
    253284            secure = True 
    254          
    255285        # secure not needed! 
    256286        AuthTKTMiddleware.__init__(self, app, secret, cookie_name=name,  
     
    262292        self.cookie_enforce = enforce 
    263293        if self.cookie_enforce and not self.cookie_params.has_key('expires'): 
    264             raise Exception("Cannot enforce cookie expiration since no " 
    265                             "cookie_params expires' has been set") 
     294            raise AuthKitConfigError( 
     295                "Cannot enforce cookie expiration since no " 
     296                "cookie_params expires' has been set" 
     297            ) 
     298 
     299        self.nouserincookie = nouserincookie 
     300        self.session_middleware = session_middleware 
    266301 
    267302    def __call__(self, environ, start_response): 
     303        session = None 
     304        if self.nouserincookie: 
     305            session = environ[self.session_middleware] 
    268306        cookies = request.get_cookies(environ) 
    269307        log.debug("These cookies were found: %s", cookies.keys()) 
     
    292330            # 
    293331            def bad_ticket_app(environ, start_response, msg=None): 
     332                # Remove the session username 
     333                if self.nouserincookie: 
     334                    environ[self.session_middleware]['authkit.cookie.user'] = None 
     335                    del environ[self.session_middleware]['authkit.cookie.user'] 
     336                    environ[self.session_middleware].save() 
     337 
    294338                headers = self.logout_user_cookie(environ) 
    295339                headers.append(('Content-type','text/plain')) 
    296                 start_response('401 Not authenticated', headers) 
     340                start_response('200 OK', headers) 
    297341                if not msg: 
    298342                    msg = 'Bad cookie, you have been signed out.\n If this' 
     
    305349                          remote_addr) 
    306350                timestamp, userid, tokens, user_data = \ 
    307                     parse_ticket(self.secret, cookie_value, remote_addr
     351                    parse_ticket(self.secret, cookie_value, remote_addr, session
    308352            except BadTicket, e: 
    309353                if e.expected: 
    310                     log.error("BadTicket: %s Expected: %s", e, e.expected) 
     354                    log.debug("BadTicket: %s Expected: %s", e, e.expected) 
    311355                else: 
    312                     log.error("BadTicket: %s", e) 
     356                    log.debug("BadTicket: %s", e) 
    313357                return bad_ticket_app(environ, start_response) 
    314358            else: 
     
    373417                                   tokens=tokens, user_data=user_data,  
    374418                                   cookie_name=self.cookie_name,  
    375                                    cookie_params=self.cookie_params) 
     419                                   cookie_params=self.cookie_params,  
     420                                   nouserincookie=self.nouserincookie) 
    376421         
    377422        # @@: Should we set REMOTE_USER etc in the current 
     
    380425        cookies = [(parts[0].strip(), ':'.join(parts[1:]).strip())] 
    381426        log.debug(cookies) 
     427        if self.nouserincookie: 
     428            if self.cookie_name == environ[self.session_middleware].key: 
     429                raise AuthKitConfigError( 
     430                    "The session cookie name %r is the same as the " 
     431                    "AuthKit cookie name. Please change the session cookie " 
     432                    "name."%( 
     433                        environ[self.session_middleware].key 
     434                    ) 
     435                ) 
     436            environ[self.session_middleware]['authkit.cookie.user'] = userid 
     437            environ[self.session_middleware].save() 
    382438        return cookies 
    383439         
    384440    def logout_user_cookie(self, environ): 
     441        environ[self.session_middleware]['authkit.cookie.user'] = None 
     442        del environ[self.session_middleware]['authkit.cookie.user'] 
     443        environ[self.session_middleware].save() 
    385444        domain = self.cookie_params.get('domain') 
    386445        path = '/'