pvl.login: update access on renew
authorTero Marttila <terom@paivola.fi>
Mon, 13 Jan 2014 22:21:42 +0200
changeset 370 184917c7d4d4
parent 369 e6d0e8a967ac
child 371 8c17eb11858f
pvl.login: update access on renew
pvl/login/auth.py
pvl/login/pubtkt.py
pvl/login/server.py
--- a/pvl/login/auth.py	Mon Jan 13 21:14:52 2014 +0200
+++ b/pvl/login/auth.py	Mon Jan 13 22:21:42 2014 +0200
@@ -76,7 +76,7 @@
 
     def access (self, user) :
         """
-            Yield a list of access control tokens for the given auth state.
+            Yield a list of access control tokens for the given auth username.
         """
         
         yield pvl.users.group.Group.fromldap(self.ldap.users.group(user))
@@ -91,3 +91,13 @@
 
         return user.get('cn')
 
+    def renew (self, username) :
+        """
+            Re-lookup auth state for given username.
+        """
+
+        try :
+            return self.ldap.users.get(username)
+        except KeyError :
+            return None
+        
--- a/pvl/login/pubtkt.py	Mon Jan 13 21:14:52 2014 +0200
+++ b/pvl/login/pubtkt.py	Mon Jan 13 22:21:42 2014 +0200
@@ -18,49 +18,49 @@
     return datetime.datetime.utcfromtimestamp(unix)
 
 class Error (Exception) :
+    """
+        Error
+    """
+
     def __init__ (self, error) :
         self.error = error
 
+    def __unicode__ (self) :
+        return u"{doc}: {self.error}".format(self=self, doc=self.__doc__.strip())
+
 class ParseError (Error) :
     """
-        Unable to load PubTkt from cookie.
+        Unable to parse PubTkt from cookie
     """
 
-    def __unicode__ (self) :
-        return u"Invalid login token: {self.error}".format(self=self)
-
 class VerifyError (Error) :
     """
-        Unable to verify PubTkt.
+        Invalid login token sigunature
     """
 
     def __init__ (self, pubtkt, error) :
         self.pubtkt = pubtkt
         self.error = error
 
-    def __unicode__ (self) :
-        return u"Invalid login token signature: {self.error}".format(self=self)
-
 class ExpiredError (VerifyError) :
     """
-        Verified PubTkt, but expired.
+        Login token has expired
     """
 
-    def __init__ (self, pubtkt, now) :
+    def __init__ (self, pubtkt, expire) :
         self.pubtkt = pubtkt
-        self.now = now
+        self.error = expire
 
-    def __unicode__ (self) :
-        return u"Login token has expired"
+class RenewError (Error) :
+    """
+        Unable to renew login token
+    """
 
 class ServerError (Error) :
     """
-        Invalid server request.
+        Login request from invalid server
     """
     
-    def __unicode__ (self) :
-        return u"Login request is not valid: {self.error}".format(self=self)
-
 class ServerKeys (object) :
     @classmethod
     def config (cls, public_key, private_key) :
@@ -101,7 +101,7 @@
         log.debug("validating %s < %s", pubtkt.validuntil, now)
 
         if pubtkt.validuntil < now :
-            raise ExpiredError(pubtkt, now)
+            raise ExpiredError(pubtkt, pubtkt.validuntil)
 
         return pubtkt
 
@@ -166,6 +166,17 @@
             **opts
         )
 
+    def update (self, valid, grace, cip=None, tokens=None, udata=None, bauth=None) :
+        now = self.now()
+
+        return type(self)(self.uid, now + valid,
+            graceperiod = now + grace if grace else None,
+            cip         = self.cip if cip is None else cip,
+            tokens      = self.tokens if tokens is None else tokens,
+            udata       = self.udata if udata is None else udata,
+            bauth       = self.bauth if bauth is None else bauth,
+        )
+
     def __init__ (self, uid, validuntil, cip=None, tokens=(), udata=None, graceperiod=None, bauth=None) :
         self.uid = uid
         self.validuntil = validuntil
--- a/pvl/login/server.py	Mon Jan 13 21:14:52 2014 +0200
+++ b/pvl/login/server.py	Mon Jan 13 22:21:42 2014 +0200
@@ -235,7 +235,7 @@
             yield 'cloud', None, "Network address", pubtkt.cip
 
         if pubtkt.udata :
-            yield 'comment', None, "Associated data", pubtkt.udata
+            yield 'comment', None, "User data", pubtkt.udata
 
         for token in pubtkt.tokens :
             yield 'flag', None, "Access token", token
@@ -476,8 +476,8 @@
     
     login_domain = 'test.paivola.fi'
     login_server = 'login.test.paivola.fi'
-    login_valid = datetime.timedelta(seconds=60)
-    login_grace = datetime.timedelta(seconds=30)
+    login_valid = datetime.timedelta(minutes=60)
+    login_grace = datetime.timedelta(minutes=15)
     login_scheme = 'https'
 
     cookie_name = 'auth_pubtkt'
@@ -515,7 +515,7 @@
 
     def auth (self, username, password) :
         """
-            Perform authentication, returning a PubTkt, signed, or None.
+            Perform authentication, returning a PubTkt (unsiigned) or None.
 
             Raises auth.AuthError.
         """
@@ -525,14 +525,11 @@
         if not auth :
             return None
 
-        tokens = list(self._auth.access(auth))
-        udata = self._auth.userdata(auth)
-
         return pubtkt.PubTkt.new(username,
                 valid   = self.login_valid,
                 grace   = self.login_grace,
-                tokens  = tokens,
-                udata   = udata,
+                tokens  = list(self._auth.access(auth)),
+                udata   = self._auth.userdata(auth),
         )
 
     def sign (self, pubtkt) :
@@ -546,8 +543,15 @@
         """
             Renew and re-sign the given pubtkt.
         """
+
+        auth = self._auth.renew(pubtkt.uid)
+
+        if not auth :
+            raise pubtkt.RenewError("Unable to re-authenticate")
     
-        # XXX: inplace
-        pubtkt.renew(self.login_valid, self.login_grace)
-
-        return pubtkt
+        return pubtkt.update(
+                valid   = self.login_valid,
+                grace   = self.login_grace,
+                tokens  = list(self._auth.access(auth)),
+                udata   = self._auth.userdata(auth),
+        )