diff --git a/roundup/password.py b/roundup/password.py
index a2f01f52c4c71e569f5b877f3f419c46a3272a03..201a6a979edd837918fdb5c6dd8e16c8039994c4 100644 (file)
--- a/roundup/password.py
+++ b/roundup/password.py
# FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-#
-# $Id: password.py,v 1.9 2003-04-10 05:12:41 richard Exp $
+#
+# $Id: password.py,v 1.15 2005-12-25 15:38:40 a1s Exp $
-__doc__ = """
-Password handling (encoding, decoding).
+"""Password handling (encoding, decoding).
"""
+__docformat__ = 'restructuredtext'
-import sha, re, string, random
+import re, string, random
+from roundup.anypy.hashlib_ import md5, sha1
try:
import crypt
-except:
+except ImportError:
crypt = None
+
+class PasswordValueError(ValueError):
+ """ The password value is not valid """
pass
def encodePassword(plaintext, scheme, other=None):
- '''Encrypt the plaintext password.
- '''
+ """Encrypt the plaintext password.
+ """
if plaintext is None:
plaintext = ""
if scheme == 'SHA':
- s = sha.sha(plaintext).hexdigest()
+ s = sha1(plaintext).hexdigest()
+ elif scheme == 'MD5':
+ s = md5(plaintext).hexdigest()
elif scheme == 'crypt' and crypt is not None:
if other is not None:
- salt = other[:2]
+ salt = other
else:
saltchars = './0123456789'+string.letters
salt = random.choice(saltchars) + random.choice(saltchars)
elif scheme == 'plaintext':
s = plaintext
else:
- raise ValueError, 'Unknown encryption scheme "%s"'%scheme
+ raise PasswordValueError, 'unknown encryption scheme %r'%scheme
return s
def generatePassword(length=8):
return ''.join([random.choice(chars) for x in range(length)])
class Password:
- '''The class encapsulates a Password property type value in the database.
+ """The class encapsulates a Password property type value in the database.
- The encoding of the password is one if None, 'SHA' or 'plaintext'. The
- encodePassword function is used to actually encode the password from
+ The encoding of the password is one if None, 'SHA', 'MD5' or 'plaintext'.
+ The encodePassword function is used to actually encode the password from
plaintext. The None encoding is used in legacy databases where no
encoding scheme is identified.
1
>>> 'not sekrit' != p
1
- '''
+ """
default_scheme = 'SHA' # new encryptions use this scheme
pwre = re.compile(r'{(\w+)}(.+)')
- def __init__(self, plaintext=None, scheme=None):
- '''Call setPassword if plaintext is not None.'''
+ def __init__(self, plaintext=None, scheme=None, encrypted=None):
+ """Call setPassword if plaintext is not None."""
if scheme is None:
scheme = self.default_scheme
if plaintext is not None:
- self.password = encodePassword(plaintext, self.default_scheme)
- self.scheme = self.default_scheme
+ self.setPassword (plaintext, scheme)
+ elif encrypted is not None:
+ self.unpack(encrypted, scheme)
else:
- self.password = None
self.scheme = self.default_scheme
+ self.password = None
+ self.plaintext = None
- def unpack(self, encrypted):
- '''Set the password info from the scheme:<encryted info> string
+ def unpack(self, encrypted, scheme=None):
+ """Set the password info from the scheme:<encryted info> string
(the inverse of __str__)
- '''
+ """
m = self.pwre.match(encrypted)
if m:
self.scheme = m.group(1)
self.password = m.group(2)
+ self.plaintext = None
else:
# currently plaintext - encrypt
- self.password = encodePassword(encrypted, self.default_scheme)
- self.scheme = self.default_scheme
+ self.setPassword(encrypted, scheme)
def setPassword(self, plaintext, scheme=None):
- '''Sets encrypts plaintext.'''
+ """Sets encrypts plaintext."""
if scheme is None:
scheme = self.default_scheme
+ self.scheme = scheme
self.password = encodePassword(plaintext, scheme)
+ self.plaintext = plaintext
def __cmp__(self, other):
- '''Compare this password against another password.'''
+ """Compare this password against another password."""
# check to see if we're comparing instances
if isinstance(other, Password):
if self.scheme != other.scheme:
self.password))
def __str__(self):
- '''Stringify the encrypted password for database storage.'''
+ """Stringify the encrypted password for database storage."""
if self.password is None:
raise ValueError, 'Password not set'
return '{%s}%s'%(self.scheme, self.password)
assert 'sekrit' == p
assert 'not sekrit' != p
+ # MD5
+ p = Password('sekrit', 'MD5')
+ assert p == 'sekrit'
+ assert p != 'not sekrit'
+ assert 'sekrit' == p
+ assert 'not sekrit' != p
+
# crypt
p = Password('sekrit', 'crypt')
assert p == 'sekrit'
if __name__ == '__main__':
test()
-# vim: set filetype=python ts=4 sw=4 et si
+# vim: set filetype=python sts=4 sw=4 et si :