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