VirtualMailManager/password.py
branchv0.6.x
changeset 287 1e77dd639fa3
parent 284 ec1966828246
child 289 142f188f7552
--- a/VirtualMailManager/password.py	Mon May 03 20:38:36 2010 +0000
+++ b/VirtualMailManager/password.py	Tue May 04 00:01:35 2010 +0000
@@ -6,10 +6,12 @@
     VirtualMailManager.password
 
     VirtualMailManager's password module to generate password hashes from
-    passwords or random passwords. There are two functions:
+    passwords or random passwords. This module provides following
+    functions:
 
         hashed_password = pwhash(password[, scheme][, user])
         random_password = randompw()
+        scheme, encoding = verify_scheme(scheme)
 """
 
 from crypt import crypt
@@ -343,6 +345,47 @@
 }
 
 
+def verify_scheme(scheme):
+    """Checks if the password scheme *scheme* is known and supported by the
+    configured `misc.dovecot_version`.
+
+    The *scheme* maybe a password scheme's name (e.g.: 'PLAIN') or a scheme
+    name with a encoding suffix (e.g. 'PLAIN.BASE64').  If the scheme is
+    known and supported by the used Dovecot version,
+    a tuple ``(scheme, encoding)`` will be returned.
+    The `encoding` in the tuple may be `None`.
+
+    Raises a `VMMError` if the password scheme:
+      * is unknown
+      * depends on a newer Dovecot version
+      * has a unknown encoding suffix
+    """
+    assert isinstance(scheme, basestring), 'Not a str/unicode: %r' % scheme
+    scheme_encoding = scheme.upper().split('.')
+    scheme = scheme_encoding[0]
+    if not scheme in _scheme_info:
+        raise VMMError(_(u"Unsupported password scheme: '%s'") % scheme,
+                       VMM_ERROR)
+    if cfg_dget('misc.dovecot_version') < _scheme_info[scheme][1]:
+        raise VMMError(_(u"The password scheme '%(scheme)s' requires Dovecot \
+>= v%(version)s") %
+                       {'scheme': scheme,
+                        'version': version_str(_scheme_info[scheme][1])},
+                       VMM_ERROR)
+    if len(scheme_encoding) > 1:
+        if cfg_dget('misc.dovecot_version') < 0x10100a01:
+            raise VMMError(_(u'Encoding suffixes for password schemes require \
+Dovecot >= v1.1.alpha1'),
+                           VMM_ERROR)
+        if scheme_encoding[1] not in ('B64', 'BASE64', 'HEX'):
+            raise VMMError(_(u"Unsupported password encoding: '%s'") %
+                           scheme_encoding[1], VMM_ERROR)
+        encoding = scheme_encoding[1]
+    else:
+        encoding = None
+    return scheme, encoding
+
+
 def pwhash(password, scheme=None, user=None):
     """Generates a password hash from the plain text *password* string.
 
@@ -359,25 +402,7 @@
         raise ValueError("Couldn't accept empty password.")
     if scheme is None:
         scheme = cfg_dget('misc.password_scheme')
-    scheme_encoding = scheme.split('.')
-    scheme = scheme_encoding[0].upper()
-    if not scheme in _scheme_info:
-        raise VMMError(_(u"Unsupported password scheme: '%s'") % scheme,
-                       VMM_ERROR)
-    if cfg_dget('misc.dovecot_version') < _scheme_info[scheme][1]:
-        raise VMMError(_(u"The scheme '%s' requires Dovecot >= v%s") %
-                       (scheme, version_str(_scheme_info[scheme][1])),
-                       VMM_ERROR)
-    if len(scheme_encoding) > 1:
-        if cfg_dget('misc.dovecot_version') < 0x10100a01:
-            raise VMMError(_(u'Encoding suffixes for password schemes require \
-Dovecot >= v1.1.alpha1'),
-                           VMM_ERROR)
-        if scheme_encoding[1].upper() not in ('B64', 'BASE64', 'HEX'):
-            raise ValueError('Unsupported encoding: %r' % scheme_encoding[1])
-        encoding = scheme_encoding[1].upper()
-    else:
-        encoding = None
+    scheme, encoding = verify_scheme(scheme)
     if scheme == 'DIGEST-MD5':
         assert isinstance(user, EmailAddress)
         return _md5_hash(password, scheme, encoding, user)