webfaction and repo.or.cz deployment done
[worddb.git] / libs / openid / store / nonce.py
blobe9337a8a41303551f871ac49e5f1f9c75041c5e5
1 __all__ = [
2 'split',
3 'mkNonce',
4 'checkTimestamp',
7 from openid import cryptutil
8 from time import strptime, strftime, gmtime, time
9 from calendar import timegm
10 import string
12 NONCE_CHARS = string.ascii_letters + string.digits
14 # Keep nonces for five hours (allow five hours for the combination of
15 # request time and clock skew). This is probably way more than is
16 # necessary, but there is not much overhead in storing nonces.
17 SKEW = 60 * 60 * 5
19 time_fmt = '%Y-%m-%dT%H:%M:%SZ'
20 time_str_len = len('0000-00-00T00:00:00Z')
22 def split(nonce_string):
23 """Extract a timestamp from the given nonce string
25 @param nonce_string: the nonce from which to extract the timestamp
26 @type nonce_string: str
28 @returns: A pair of a Unix timestamp and the salt characters
29 @returntype: (int, str)
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: # Python 2.2
38 timestamp = -1
39 if timestamp < 0:
40 raise ValueError('time out of range')
41 return timestamp, nonce_string[time_str_len:]
43 def checkTimestamp(nonce_string, allowed_skew=SKEW, now=None):
44 """Is the timestamp that is part of the specified nonce string
45 within the allowed clock-skew of the current time?
47 @param nonce_string: The nonce that is being checked
48 @type nonce_string: str
50 @param allowed_skew: How many seconds should be allowed for
51 completing the request, allowing for clock skew.
52 @type allowed_skew: int
54 @param now: The current time, as a Unix timestamp
55 @type now: int
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()
69 # Time after which we should not use the nonce
70 past = now - allowed_skew
72 # Time that is too far in the future for us to allow
73 future = now + allowed_skew
75 # the stamp is not too far in the future and is not too far in
76 # the past
77 return past <= stamp <= future
79 def mkNonce(when=None):
80 """Generate a nonce with the current timestamp
82 @param when: Unix timestamp representing the issue time of the
83 nonce. Defaults to the current time.
84 @type when: int
86 @returntype: str
87 @returns: A string that should be usable as a one-way nonce
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)
97 time_str = strftime(time_fmt, t)
98 return time_str + salt