diff options
| author | Aurélien Bompard | 2015-12-26 13:41:30 +0100 |
|---|---|---|
| committer | Aurélien Bompard | 2015-12-26 13:41:30 +0100 |
| commit | f739cda916ffdd64ed3b389c5c8b920578cc9475 (patch) | |
| tree | a551011ff301a220d26cc72084c28075f9dfa431 /src/mailman/utilities | |
| parent | a11e089cc1e0e5aff2502e584014295a414a43f9 (diff) | |
| download | mailman-f739cda916ffdd64ed3b389c5c8b920578cc9475.tar.gz mailman-f739cda916ffdd64ed3b389c5c8b920578cc9475.tar.zst mailman-f739cda916ffdd64ed3b389c5c8b920578cc9475.zip | |
Diffstat (limited to 'src/mailman/utilities')
| -rw-r--r-- | src/mailman/utilities/uid.py | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/src/mailman/utilities/uid.py b/src/mailman/utilities/uid.py index ec7948189..d20360ca0 100644 --- a/src/mailman/utilities/uid.py +++ b/src/mailman/utilities/uid.py @@ -28,8 +28,11 @@ __all__ = [ import os +import time import uuid import errno +import random +import hashlib from flufl.lock import Lock from mailman.config import config @@ -78,7 +81,7 @@ class UniqueIDFactory: # may still not be ideal due to race conditions, but I think the # tests will be serialized enough (and the ids reset between # tests) that it will not be a problem. Maybe. - return self._next_uid() + return uuid.UUID(int=self._next_uid()) while True: uid = uuid.uuid4() try: @@ -96,13 +99,13 @@ class UniqueIDFactory: next_uid = uid + 1 with open(self._uid_file, 'w') as fp: fp.write(str(next_uid)) - return uuid.UUID(int=uid) + return uid except IOError as error: if error.errno != errno.ENOENT: raise with open(self._uid_file, 'w') as fp: fp.write('2') - return uuid.UUID(int=1) + return 1 def reset(self): with self._lock: @@ -111,4 +114,25 @@ class UniqueIDFactory: -factory = UniqueIDFactory() +class TokenFactory(UniqueIDFactory): + + def __init__(self): + super(TokenFactory, self).__init__(context='token') + + def new_token(self): + """ + Calculate a unique token. Algorithm vetted by the Timbot. time() + has high resolution on Linux, clock() on Windows. random gives us + about 45 bits in Python 2.2, 53 bits on Python 2.3. The time and + clock values basically help obscure the random number generator, as + does the hash calculation. The integral parts of the time values + are discarded because they're the most predictable bits. + """ + if layers.is_testing(): + # When in testing mode we want to produce predictable tokens, see + # UniqueIDFactory for a similar use case. + return str(self._next_uid()).zfill(40) + right_now = time.time() + x = random.random() + right_now % 1.0 + time.clock() % 1.0 + # Use sha1 because it produces shorter strings. + return hashlib.sha1(repr(x).encode('utf-8')).hexdigest() |
