diff --git a/cas_server/tests.py b/cas_server/tests.py index 3f53a04..7d355cb 100644 --- a/cas_server/tests.py +++ b/cas_server/tests.py @@ -61,8 +61,10 @@ def get_pgt(): class CheckPasswordCase(TestCase): + """Tests for the utils function `utils.check_password`""" def setUp(self): + """Generate random bytes string that will be used ass passwords""" self.password1 = utils.gen_saml_id() self.password2 = utils.gen_saml_id() if not isinstance(self.password1, bytes): @@ -70,14 +72,17 @@ class CheckPasswordCase(TestCase): self.password2 = self.password2.encode("utf8") def test_setup(self): + """check that generated password are bytes""" self.assertIsInstance(self.password1, bytes) self.assertIsInstance(self.password2, bytes) def test_plain(self): + """test the plain auth method""" self.assertTrue(utils.check_password("plain", self.password1, self.password1, "utf8")) self.assertFalse(utils.check_password("plain", self.password1, self.password2, "utf8")) def test_crypt(self): + """test the crypt auth method""" if six.PY3: hashed_password1 = utils.crypt.crypt( self.password1.decode("utf8"), @@ -90,6 +95,7 @@ class CheckPasswordCase(TestCase): self.assertFalse(utils.check_password("crypt", self.password2, hashed_password1, "utf8")) def test_ldap_ssha(self): + """test the ldap auth method with a {SSHA} scheme""" salt = b"UVVAQvrMyXMF3FF3" hashed_password1 = utils.LdapHashUserPassword.hash(b'{SSHA}', self.password1, salt, "utf8") @@ -98,12 +104,14 @@ class CheckPasswordCase(TestCase): self.assertFalse(utils.check_password("ldap", self.password2, hashed_password1, "utf8")) def test_hex_md5(self): + """test the hex_md5 auth method""" hashed_password1 = utils.hashlib.md5(self.password1).hexdigest() self.assertTrue(utils.check_password("hex_md5", self.password1, hashed_password1, "utf8")) self.assertFalse(utils.check_password("hex_md5", self.password2, hashed_password1, "utf8")) def test_hox_sha512(self): + """test the hex_sha512 auth method""" hashed_password1 = utils.hashlib.sha512(self.password1).hexdigest() self.assertTrue( diff --git a/cas_server/utils.py b/cas_server/utils.py index 68325eb..c8b345b 100644 --- a/cas_server/utils.py +++ b/cas_server/utils.py @@ -206,22 +206,30 @@ class LdapHashUserPassword(object): } class BadScheme(ValueError): + """Error raised then the hash scheme is not in schemes_salt + schemes_nosalt""" pass class BadHash(ValueError): + """Error raised then the hash is too short""" pass class BadSalt(ValueError): + """Error raised then with the scheme {CRYPT} the salt is invalid""" pass @classmethod def _raise_bad_scheme(cls, scheme, valid, msg): + """ + Raise BadScheme error for `scheme`, possible valid scheme are + in `valid`, the error message is `msg` + """ valid_schemes = [s.decode() for s in valid] valid_schemes.sort() raise cls.BadScheme(msg % (scheme, u", ".join(valid_schemes))) @classmethod def _test_scheme(cls, scheme): + """Test if a scheme is valide or raise BadScheme""" if scheme not in cls.schemes_salt and scheme not in cls.schemes_nosalt: cls._raise_bad_scheme( scheme, @@ -231,6 +239,7 @@ class LdapHashUserPassword(object): @classmethod def _test_scheme_salt(cls, scheme): + """Test if the scheme need a salt or raise BadScheme""" if scheme not in cls.schemes_salt: cls._raise_bad_scheme( scheme, @@ -240,6 +249,7 @@ class LdapHashUserPassword(object): @classmethod def _test_scheme_nosalt(cls, scheme): + """Test if the scheme need no salt or raise BadScheme""" if scheme not in cls.schemes_nosalt: cls._raise_bad_scheme( scheme, @@ -249,6 +259,10 @@ class LdapHashUserPassword(object): @classmethod def hash(cls, scheme, password, salt=None, charset="utf8"): + """ + Hash `password` with `scheme` using `salt`. + This three variable beeing encoded in `charset`. + """ scheme = scheme.upper() cls._test_scheme(scheme) if salt is None or salt == b"": @@ -273,6 +287,7 @@ class LdapHashUserPassword(object): @classmethod def get_scheme(cls, hashed_passord): + """Return the scheme of `hashed_passord` or raise BadHash""" if not hashed_passord[0] == b'{'[0] or b'}' not in hashed_passord: raise cls.BadHash("%r should start with the scheme enclosed with { }" % hashed_passord) scheme = hashed_passord.split(b'}', 1)[0] @@ -281,6 +296,7 @@ class LdapHashUserPassword(object): @classmethod def get_salt(cls, hashed_passord): + """Return the salt of `hashed_passord` possibly empty""" scheme = cls.get_scheme(hashed_passord) cls._test_scheme(scheme) if scheme in cls.schemes_nosalt: @@ -295,6 +311,10 @@ class LdapHashUserPassword(object): def check_password(method, password, hashed_password, charset): + """ + Check that `password` match `hashed_password` using `method`, + assuming the encoding is `charset`. + """ if not isinstance(password, six.binary_type): password = password.encode(charset) if not isinstance(hashed_password, six.binary_type):