#NEWLINE# def parse_ticket( secret , ticket , ip , digest_algo = DEFAULT_DIGEST ) : #NEWLINE# #INDENT# '\n    Parse the ticket, returning (timestamp, userid, tokens, user_data).\n\n    If the ticket cannot be parsed, ``BadTicket`` will be raised with\n    an explanation.\n    ' #NEWLINE# if isinstance ( digest_algo , str ) : #NEWLINE# #INDENT# digest_algo = getattr ( hashlib , digest_algo ) #NEWLINE# #UNINDENT# digest_hexa_size = ( digest_algo ( ) . digest_size * 2 ) #NEWLINE# ticket = ticket . strip ( '"' ) #NEWLINE# digest = ticket [ : digest_hexa_size ] #NEWLINE# try : #NEWLINE# #INDENT# timestamp = int ( ticket [ digest_hexa_size : ( digest_hexa_size + 8 ) ] , 16 ) #NEWLINE# #UNINDENT# except ValueError as e : #NEWLINE# #INDENT# raise BadTicket ( ( 'Timestamp is not a hex integer: %s' % e ) ) #NEWLINE# #UNINDENT# try : #NEWLINE# #INDENT# ( userid , data ) = ticket [ ( digest_hexa_size + 8 ) : ] . split ( '!' , 1 ) #NEWLINE# #UNINDENT# except ValueError : #NEWLINE# #INDENT# raise BadTicket ( 'userid is not followed by !' ) #NEWLINE# #UNINDENT# userid = url_unquote ( user_data ) #NEWLINE# if ( '!' in data ) : #NEWLINE# #INDENT# ( tokens , user_data ) = data . split ( '!' , 1 ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# tokens = '' #NEWLINE# user_data = data #NEWLINE# #UNINDENT# expected = calculate_digest ( ip , timestamp , secret , userid , tokens , user_data , digest_algo ) #NEWLINE# if ( expected != digest ) : #NEWLINE# #INDENT# raise BadTicket ( 'Digest signature is not correct' , expected = ( expected , digest ) ) #NEWLINE# #UNINDENT# tokens = tokens . split ( ',' ) #NEWLINE# return ( timestamp , userid , tokens , user_data )