Mercurial > p > roundup > code
diff roundup/password.py @ 4483:22bc0426e348
Second patch from issue2550688 -- with some changes:
- password.py now has a second class JournalPassword used for journal
storage. We have some backends that directly store serialized python
objects. Also when reading from the journal some backends expected the
string read to be usable as a parameter to a Password constructor.
This now calls a JournalPassword constructor in all these cases.
The new JournalPassword just keeps the scheme and has an empty
password.
- some factoring, move redundant implementation of "history" from
rdbms_common and back_anydbm to hyperdb.
| author | Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net> |
|---|---|
| date | Thu, 14 Apr 2011 15:42:41 +0000 |
| parents | 1613754d2646 |
| children | 52e13bf0bb40 |
line wrap: on
line diff
--- a/roundup/password.py Thu Apr 14 12:54:52 2011 +0000 +++ b/roundup/password.py Thu Apr 14 15:42:41 2011 +0000 @@ -168,7 +168,49 @@ chars = string.letters+string.digits return ''.join([random.choice(chars) for x in range(length)]) -class Password: +class JournalPassword: + """ Password dummy instance intended for journal operation. + We do not store passwords in the journal any longer. The dummy + version only reads the encryption scheme from the given + encrypted password. + """ + default_scheme = 'PBKDF2' # new encryptions use this scheme + pwre = re.compile(r'{(\w+)}(.+)') + + def __init__ (self, encrypted=''): + if isinstance(encrypted, self.__class__): + self.scheme = encrypted.scheme or self.default_scheme + else: + m = self.pwre.match(encrypted) + if m: + self.scheme = m.group(1) + else: + self.scheme = self.default_scheme + self.password = '' + + def dummystr(self): + """ return dummy string to store in journal + - reports scheme, but nothing else + """ + return "{%s}*encrypted*" % (self.scheme,) + + __str__ = dummystr + + def __cmp__(self, other): + """Compare this password against another password.""" + # check to see if we're comparing instances + if isinstance(other, self.__class__): + if self.scheme != other.scheme: + return cmp(self.scheme, other.scheme) + return cmp(self.password, other.password) + + # assume password is plaintext + if self.password is None: + raise ValueError, 'Password not set' + return cmp(self.password, encodePassword(other, self.scheme, + self.password or None)) + +class Password(JournalPassword): """The class encapsulates a Password property type value in the database. The encoding of the password is one if None, 'SHA', 'MD5' or 'plaintext'. @@ -192,9 +234,7 @@ """ #TODO: code to migrate from old password schemes. - default_scheme = 'PBKDF2' # new encryptions use this scheme known_schemes = [ "PBKDF2", "SHA", "MD5", "crypt", "plaintext" ] - pwre = re.compile(r'{(\w+)}(.+)') def __init__(self, plaintext=None, scheme=None, encrypted=None, strict=False): """Call setPassword if plaintext is not None.""" @@ -232,20 +272,6 @@ self.password = encodePassword(plaintext, scheme) self.plaintext = plaintext - def __cmp__(self, other): - """Compare this password against another password.""" - # check to see if we're comparing instances - if isinstance(other, Password): - if self.scheme != other.scheme: - return cmp(self.scheme, other.scheme) - return cmp(self.password, other.password) - - # assume password is plaintext - if self.password is None: - raise ValueError, 'Password not set' - return cmp(self.password, encodePassword(other, self.scheme, - self.password)) - def __str__(self): """Stringify the encrypted password for database storage.""" if self.password is None:
