X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=roundup%2Fpassword.py;h=14dbcda0da9338193fbd2b128dbf0881be899778;hb=255fa1ce653b104f8e79b05c6565ceb8d0a0c185;hp=28c68a1382622a907404a1d2466895a3e970edfc;hpb=7d090d036546fee25381ecc6ddaddfd26317c9c3;p=roundup.git diff --git a/roundup/password.py b/roundup/password.py index 28c68a1..14dbcda 100644 --- a/roundup/password.py +++ b/roundup/password.py @@ -15,25 +15,47 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: password.py,v 1.4 2001-11-22 15:46:42 jhermann Exp $ +# $Id: password.py,v 1.12 2004-03-22 07:45:39 richard Exp $ -__doc__ = """ -Password handling (encoding, decoding). +"""Password handling (encoding, decoding). """ +__docformat__ = 'restructuredtext' -import sha, re +import sha, re, string, random +try: + import crypt +except: + crypt = None + pass -def encodePassword(plaintext, scheme): +class PasswordValueError(ValueError): + ''' The password value is not valid ''' + pass + +def encodePassword(plaintext, scheme, other=None): '''Encrypt the plaintext password. ''' + if plaintext is None: + plaintext = "" if scheme == 'SHA': s = sha.sha(plaintext).hexdigest() + elif scheme == 'crypt' and crypt is not None: + if other is not None: + salt = other[:2] + else: + saltchars = './0123456789'+string.letters + salt = random.choice(saltchars) + random.choice(saltchars) + s = crypt.crypt(plaintext, salt) elif scheme == 'plaintext': - pass + s = plaintext else: - raise ValueError, 'Unknown encryption scheme "%s"'%scheme + raise PasswordValueError, 'unknown encryption scheme %r'%scheme return s +def generatePassword(length=8): + chars = string.letters+string.digits + return ''.join([random.choice(chars) for x in range(length)]) + class Password: '''The class encapsulates a Password property type value in the database. @@ -60,11 +82,15 @@ class Password: default_scheme = 'SHA' # new encryptions use this scheme pwre = re.compile(r'{(\w+)}(.+)') - def __init__(self, plaintext=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 + elif encrypted is not None: + self.unpack(encrypted) else: self.password = None self.scheme = self.default_scheme @@ -82,22 +108,25 @@ class Password: self.password = encodePassword(encrypted, self.default_scheme) self.scheme = self.default_scheme - def setPassword(self, plaintext): + def setPassword(self, plaintext, scheme=None): '''Sets encrypts plaintext.''' - self.password = encodePassword(plaintext, self.scheme) + if scheme is None: + scheme = self.default_scheme + self.password = encodePassword(plaintext, scheme) 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 + 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)) + return cmp(self.password, encodePassword(other, self.scheme, + self.password)) def __str__(self): '''Stringify the encrypted password for database storage.''' @@ -106,31 +135,21 @@ class Password: return '{%s}%s'%(self.scheme, self.password) def test(): + # SHA p = Password('sekrit') assert p == 'sekrit' assert p != 'not sekrit' assert 'sekrit' == p assert 'not sekrit' != p + # crypt + p = Password('sekrit', 'crypt') + assert p == 'sekrit' + assert p != 'not sekrit' + assert 'sekrit' == p + assert 'not sekrit' != p + if __name__ == '__main__': test() -# -# $Log: not supported by cvs2svn $ -# Revision 1.3 2001/10/20 11:58:48 richard -# Catch errors in login - no username or password supplied. -# Fixed editing of password (Password property type) thanks Roch'e Compaan. -# -# Revision 1.2 2001/10/09 23:58:10 richard -# Moved the data stringification up into the hyperdb.Class class' get, set -# and create methods. This means that the data is also stringified for the -# journal call, and removes duplication of code from the backends. The -# backend code now only sees strings. -# -# Revision 1.1 2001/10/09 07:25:59 richard -# Added the Password property type. See "pydoc roundup.password" for -# implementation details. Have updated some of the documentation too. -# -# -# # vim: set filetype=python ts=4 sw=4 et si