pvl/login/pubtkt.py
author Tero Marttila <terom@paivola.fi>
Mon, 13 Jan 2014 17:44:18 +0200
changeset 356 90697e60bf28
parent 354 d46c8d3e3140
child 364 b1689d86f5ac
permissions -rw-r--r--
pvl.login.PubTkt: change grace() to return timedelta within grace period
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
import base64
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
import calendar
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
import datetime
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     4
import ipaddr
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     5
import hashlib
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
import M2Crypto
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     8
import logging; log = logging.getLogger('pvl.login.pubtkt')
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    10
def datetime2unix (dt) :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    11
    """
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
        datetime.datetime -> float
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    13
    """
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    14
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    15
    return calendar.timegm(dt.utctimetuple())
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    16
351
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
    17
def unix2datetime (unix) :
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
    18
    return datetime.datetime.utcfromtimestamp(unix)
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
    19
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    20
class Error (Exception) :
354
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    21
    def __init__ (self, error) :
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    22
        self.error = error
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    23
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    24
class ParseError (Error) :
354
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    25
    """
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    26
        Unable to load PubTkt from cookie.
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    27
    """
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    28
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    29
    def __unicode__ (self) :
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    30
        return u"Invalid login token: {self.error}".format(self=self)
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    32
class VerifyError (Error) :
354
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    33
    """
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    34
        Unable to verify PubTkt.
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    35
    """
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    36
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    37
    def __init__ (self, pubtkt, error) :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    38
        self.pubtkt = pubtkt
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    39
        self.error = error
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    40
354
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    41
    def __unicode__ (self) :
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    42
        return u"Invalid login token signature: {self.error}".format(self=self)
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    43
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    44
class ExpiredError (VerifyError) :
354
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    45
    """
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    46
        Verified PubTkt, but expired.
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    47
    """
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    48
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    49
    def __init__ (self, pubtkt, now) :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    50
        self.pubtkt = pubtkt
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    51
        self.now = now
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    52
354
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    53
    def __unicode__ (self) :
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    54
        return u"Login token has expired"
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    55
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    56
class ServerError (Error) :
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    57
    """
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    58
        Invalid server request.
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    59
    """
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    60
    
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    61
    def __unicode__ (self) :
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    62
        return u"Login request is not valid: {self.error}".format(self=self)
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
    63
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    64
class ServerKeys (object) :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    65
    @classmethod
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    66
    def config (cls, public_key, private_key) :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    67
        return cls(
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    68
                public  = M2Crypto.RSA.load_pub_key(public_key),
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    69
                private = M2Crypto.RSA.load_key(private_key),
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    70
        )
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    71
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    72
    def __init__ (self, public, private) :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    73
        self.public = public
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    74
        self.private = private
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    75
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    76
class PubTkt (object) :
351
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
    77
    @staticmethod
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
    78
    def now () :
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
    79
        return datetime.datetime.utcnow()
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
    80
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    81
    @classmethod
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    82
    def load (cls, cookie, public_key) :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83
        """
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    84
            Load and verify a pubtkt from a cookie.
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    85
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    86
            Raise ParseError, VerifyError.
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    87
        """
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    88
        
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    89
        pubtkt, hash, sig = cls.parse(cookie)
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    90
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    91
        log.debug("parsed %s hash=%s sig=%s", pubtkt, hash.encode('hex'), sig.encode('hex'))
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    92
        
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    93
        try :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    94
            if not public_key.verify(hash, sig, 'sha1') :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    95
                raise VerifyError(pubtkt, "Unable to verify signature")
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    96
        except M2Crypto.RSA.RSAError as ex :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    97
            raise VerifyError(pubtkt, str(ex))
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    98
        
351
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
    99
        now = cls.now()
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   100
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   101
        log.debug("validating %s < %s", pubtkt.validuntil, now)
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   102
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   103
        if pubtkt.validuntil < now :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   104
            raise ExpiredError(pubtkt, now)
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   105
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   106
        return pubtkt
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   107
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   108
    @classmethod
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   109
    def parse (cls, cookie) :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   110
        """
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   111
            Load a pubtkt from a cookie
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   112
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   113
            Raises ParseError.
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   114
        """
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   115
        
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   116
        if ';sig=' in cookie :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   117
            data, sig = cookie.rsplit(';sig=', 1)
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   118
        else :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   119
            raise ParseError("Missing signature")
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   120
        
354
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   121
        try :
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   122
            sig = base64.b64decode(sig)
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   123
        except (ValueError, TypeError) as ex :
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   124
            raise ParseError("Invalid signature")
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   125
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   126
        hash = hashlib.sha1(data).digest()
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   127
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   128
        try :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   129
            attrs = dict(field.split('=', 1) for field in data.split(';'))
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   130
        except ValueError as ex :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   131
            raise ParseError(str(ex))
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   132
        
354
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   133
        if 'uid' not in attrs or 'validuntil' not in attrs :
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   134
            raise ParseError("Missing parameters in cookie (uid, validuntil)")
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   135
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   136
        try :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   137
            return cls.build(**attrs), hash, sig
354
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   138
        except TypeError as ex :
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   139
            raise ParseError("Invalid or missing parameters in cookie")
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   140
        except ValueError as ex :
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   141
            raise ParseError(str(ex))
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   142
    
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   143
    @classmethod
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   144
    def build (cls, uid, validuntil, cip=None, tokens=None, udata=None, graceperiod=None, bauth=None) :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   145
        """
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   146
            Build a pubtkt from items.
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   147
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   148
            Raises TypeError or ValueError..
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   149
        """
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   150
        
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   151
        return cls(uid,
351
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   152
                validuntil  = unix2datetime(int(validuntil)),
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   153
                cip         = ipaddr.IPAddress(cip) if cip else None,
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   154
                tokens      = tokens.split(',') if tokens else (),
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   155
                udata       = udata,
351
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   156
                graceperiod = unix2datetime(int(graceperiod)) if graceperiod else None,
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   157
                bauth       = bauth,
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   158
        )
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   159
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   160
    @classmethod
354
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   161
    def new (cls, uid, valid, grace=None, **opts) :
351
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   162
        now = cls.now()
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   163
354
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   164
        return cls(uid, now + valid,
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   165
            graceperiod = now + grace if grace else None,
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   166
            **opts
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   167
        )
348
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   168
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   169
    def __init__ (self, uid, validuntil, cip=None, tokens=(), udata=None, graceperiod=None, bauth=None) :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   170
        self.uid = uid
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   171
        self.validuntil = validuntil
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   172
        self.cip = cip
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   173
        self.tokens = tokens
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   174
        self.udata = udata
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   175
        self.graceperiod = graceperiod
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   176
        self.bauth = bauth
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   177
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   178
    def iteritems (self) :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   179
        yield 'uid', self.uid
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   180
        yield 'validuntil', int(datetime2unix(self.validuntil))
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   181
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   182
        if self.cip :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   183
            yield 'cip', self.cip
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   184
        
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   185
        if self.tokens :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   186
            yield 'tokens', ','.join(self.tokens)
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   187
        
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   188
        if self.udata :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   189
            yield 'udata', self.udata
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   190
        
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   191
        if self.graceperiod :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   192
            yield 'graceperiod', int(datetime2unix(self.graceperiod))
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   193
        
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   194
        if self.bauth :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   195
            yield 'bauth', self.bauth
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   196
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   197
    def __str__ (self) :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   198
        """
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   199
            The (unsigned) pubtkt
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   200
        """
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   201
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   202
        return ';'.join('%s=%s' % (key, value) for key, value in self.iteritems())
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   203
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   204
    def sign (self, private_key) :
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   205
        data = str(self)
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   206
        hash = hashlib.sha1(data).digest()
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   207
        sign = private_key.sign(hash, 'sha1')
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   208
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   209
        return '%s;sig=%s' % (self, base64.b64encode(sign))
089ec3eddc92 pvl.login: a pubtkt-based sso login server..
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   210
349
3c20473d0bdc pvl.login: pimp out form with domain, and iconized panel for ticket
Tero Marttila <terom@paivola.fi>
parents: 348
diff changeset
   211
    def valid (self) :
3c20473d0bdc pvl.login: pimp out form with domain, and iconized panel for ticket
Tero Marttila <terom@paivola.fi>
parents: 348
diff changeset
   212
        """
3c20473d0bdc pvl.login: pimp out form with domain, and iconized panel for ticket
Tero Marttila <terom@paivola.fi>
parents: 348
diff changeset
   213
            Return remaining ticket validity.
3c20473d0bdc pvl.login: pimp out form with domain, and iconized panel for ticket
Tero Marttila <terom@paivola.fi>
parents: 348
diff changeset
   214
        """
3c20473d0bdc pvl.login: pimp out form with domain, and iconized panel for ticket
Tero Marttila <terom@paivola.fi>
parents: 348
diff changeset
   215
351
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   216
        now = self.now()
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   217
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   218
        if self.validuntil > now :
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   219
            return self.validuntil - now
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   220
        else :
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   221
            return False
349
3c20473d0bdc pvl.login: pimp out form with domain, and iconized panel for ticket
Tero Marttila <terom@paivola.fi>
parents: 348
diff changeset
   222
3c20473d0bdc pvl.login: pimp out form with domain, and iconized panel for ticket
Tero Marttila <terom@paivola.fi>
parents: 348
diff changeset
   223
    def grace (self) :
3c20473d0bdc pvl.login: pimp out form with domain, and iconized panel for ticket
Tero Marttila <terom@paivola.fi>
parents: 348
diff changeset
   224
        """
356
90697e60bf28 pvl.login.PubTkt: change grace() to return timedelta within grace period
Tero Marttila <terom@paivola.fi>
parents: 354
diff changeset
   225
            Return remaining grace period.
349
3c20473d0bdc pvl.login: pimp out form with domain, and iconized panel for ticket
Tero Marttila <terom@paivola.fi>
parents: 348
diff changeset
   226
        """
351
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   227
        
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   228
        now = self.now()
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   229
        
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   230
        if not self.graceperiod :
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   231
            return None
349
3c20473d0bdc pvl.login: pimp out form with domain, and iconized panel for ticket
Tero Marttila <terom@paivola.fi>
parents: 348
diff changeset
   232
356
90697e60bf28 pvl.login.PubTkt: change grace() to return timedelta within grace period
Tero Marttila <terom@paivola.fi>
parents: 354
diff changeset
   233
        elif now < self.graceperiod :
90697e60bf28 pvl.login.PubTkt: change grace() to return timedelta within grace period
Tero Marttila <terom@paivola.fi>
parents: 354
diff changeset
   234
            # still valid
90697e60bf28 pvl.login.PubTkt: change grace() to return timedelta within grace period
Tero Marttila <terom@paivola.fi>
parents: 354
diff changeset
   235
            return None
90697e60bf28 pvl.login.PubTkt: change grace() to return timedelta within grace period
Tero Marttila <terom@paivola.fi>
parents: 354
diff changeset
   236
90697e60bf28 pvl.login.PubTkt: change grace() to return timedelta within grace period
Tero Marttila <terom@paivola.fi>
parents: 354
diff changeset
   237
        elif now < self.validuntil :
90697e60bf28 pvl.login.PubTkt: change grace() to return timedelta within grace period
Tero Marttila <terom@paivola.fi>
parents: 354
diff changeset
   238
            # positive
90697e60bf28 pvl.login.PubTkt: change grace() to return timedelta within grace period
Tero Marttila <terom@paivola.fi>
parents: 354
diff changeset
   239
            return self.validuntil - now
90697e60bf28 pvl.login.PubTkt: change grace() to return timedelta within grace period
Tero Marttila <terom@paivola.fi>
parents: 354
diff changeset
   240
351
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   241
        else :
356
90697e60bf28 pvl.login.PubTkt: change grace() to return timedelta within grace period
Tero Marttila <terom@paivola.fi>
parents: 354
diff changeset
   242
            # expired
351
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   243
            return False
349
3c20473d0bdc pvl.login: pimp out form with domain, and iconized panel for ticket
Tero Marttila <terom@paivola.fi>
parents: 348
diff changeset
   244
354
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   245
    def renew (self, valid, grace=None) :
351
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   246
        if not self.valid() :
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   247
            raise ExpiredError(self, "Unable to renew expired pubtkt")
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   248
354
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   249
        now = self.now()
351
147f5e86b139 pvl.login: fix validity logic, implement renew
Tero Marttila <terom@paivola.fi>
parents: 349
diff changeset
   250
354
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   251
        self.validuntil = now + valid
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   252
        self.graceperiod = now + grace if grace else None
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   253
d46c8d3e3140 pvl.login: ui tweaks, alerts, back support
Tero Marttila <terom@paivola.fi>
parents: 351
diff changeset
   254