1  __all__ = [ 
  2      'split', 
  3      'mkNonce', 
  4      'checkTimestamp', 
  5      ] 
  6   
  7  from openid import cryptutil 
  8  from time import strptime, strftime, gmtime, time 
  9  from calendar import timegm 
 10  import string 
 11   
 12  NONCE_CHARS = string.ascii_letters + string.digits 
 13   
 14   
 15   
 16   
 17  SKEW = 60 * 60 * 5 
 18   
 19  time_fmt = '%Y-%m-%dT%H:%M:%SZ' 
 20  time_str_len = len('0000-00-00T00:00:00Z') 
 21   
 23      """Extract a timestamp from the given nonce string 
 24   
 25      @param nonce_string: the nonce from which to extract the timestamp 
 26      @type nonce_string: str 
 27   
 28      @returns: A pair of a Unix timestamp and the salt characters 
 29      @returntype: (int, str) 
 30   
 31      @raises ValueError: if the nonce does not start with a correctly 
 32          formatted time string 
 33      """ 
 34      timestamp_str = nonce_string[:time_str_len] 
 35      try: 
 36          timestamp = timegm(strptime(timestamp_str, time_fmt)) 
 37      except AssertionError:  
 38          timestamp = -1 
 39      if timestamp < 0: 
 40          raise ValueError('time out of range') 
 41      return timestamp, nonce_string[time_str_len:] 
  42   
 44      """Is the timestamp that is part of the specified nonce string 
 45      within the allowed clock-skew of the current time? 
 46   
 47      @param nonce_string: The nonce that is being checked 
 48      @type nonce_string: str 
 49   
 50      @param allowed_skew: How many seconds should be allowed for 
 51          completing the request, allowing for clock skew. 
 52      @type allowed_skew: int 
 53   
 54      @param now: The current time, as a Unix timestamp 
 55      @type now: int 
 56   
 57      @returntype: bool 
 58      @returns: Whether the timestamp is correctly formatted and within 
 59          the allowed skew of the current time. 
 60      """ 
 61      try: 
 62          stamp, _ = split(nonce_string) 
 63      except ValueError: 
 64          return False 
 65      else: 
 66          if now is None: 
 67              now = time() 
 68   
 69           
 70          past = now - allowed_skew 
 71   
 72           
 73          future = now + allowed_skew 
 74   
 75           
 76           
 77          return past <= stamp <= future 
  78   
 80      """Generate a nonce with the current timestamp 
 81   
 82      @param when: Unix timestamp representing the issue time of the 
 83          nonce. Defaults to the current time. 
 84      @type when: int 
 85   
 86      @returntype: str 
 87      @returns: A string that should be usable as a one-way nonce 
 88   
 89      @see: time 
 90      """ 
 91      salt = cryptutil.randomString(6, NONCE_CHARS) 
 92      if when is None: 
 93          t = gmtime() 
 94      else: 
 95          t = gmtime(when) 
 96   
 97      time_str = strftime(time_fmt, t) 
 98      return time_str + salt 
  99