def test_00_constructor_autoload(self): """test constructor autoload""" # check with existing file path = self.mktemp() set_file(path, self.sample_01) ht = apache.HtpasswdFile(path) self.assertEqual(ht.to_string(), self.sample_01) self.assertEqual(ht.path, path) self.assertTrue(ht.mtime) # check changing path ht.path = path + "x" self.assertEqual(ht.path, path + "x") self.assertFalse(ht.mtime) # check new=True ht = apache.HtpasswdFile(path, new=True) self.assertEqual(ht.to_string(), b"") self.assertEqual(ht.path, path) self.assertFalse(ht.mtime) # check autoload=False (deprecated alias for new=True) with self.assertWarningList("``autoload=False`` is deprecated"): ht = apache.HtpasswdFile(path, autoload=False) self.assertEqual(ht.to_string(), b"") self.assertEqual(ht.path, path) self.assertFalse(ht.mtime) # check missing file os.remove(path) self.assertRaises(IOError, apache.HtpasswdFile, path)
def test_05_load(self): """test load()""" # setup empty file path = self.mktemp() set_file(path, "") backdate_file_mtime(path, 5) ha = apache.HtpasswdFile(path, default_scheme="plaintext") self.assertEqual(ha.to_string(), b"") # make changes, check load_if_changed() does nothing ha.set_password("user1", "pass1") ha.load_if_changed() self.assertEqual(ha.to_string(), b"user1:pass1\n") # change file set_file(path, self.sample_01) ha.load_if_changed() self.assertEqual(ha.to_string(), self.sample_01) # make changes, check load() overwrites them ha.set_password("user5", "pass5") ha.load() self.assertEqual(ha.to_string(), self.sample_01) # test load w/ no path hb = apache.HtpasswdFile() self.assertRaises(RuntimeError, hb.load) self.assertRaises(RuntimeError, hb.load_if_changed) # test load w/ dups and explicit path set_file(path, self.sample_dup) hc = apache.HtpasswdFile() hc.load(path) self.assertTrue(hc.check_password('user1','pass1'))
def test_02_set_password_autosave(self): path = self.mktemp() sample = b'user1:pass1\n' set_file(path, sample) ht = apache.HtpasswdFile(path) ht.set_password("user1", "pass2") self.assertEqual(get_file(path), sample) ht = apache.HtpasswdFile(path, default_scheme="plaintext", autosave=True) ht.set_password("user1", "pass2") self.assertEqual(get_file(path), b"user1:pass2\n")
def test_01_delete_autosave(self): path = self.mktemp() sample = b'user1:pass1\nuser2:pass2\n' set_file(path, sample) ht = apache.HtpasswdFile(path) ht.delete("user1") self.assertEqual(get_file(path), sample) ht = apache.HtpasswdFile(path, autosave=True) ht.delete("user1") self.assertEqual(get_file(path), b"user2:pass2\n")
def test_htpasswd_cmd_verify(self): """ verify "htpasswd" command can read output """ path = self.mktemp() ht = apache.HtpasswdFile(path=path, new=True) def hash_scheme(pwd, scheme): return ht.context.handler(scheme).hash(pwd) # base scheme ht.set_hash("user1", hash_scheme("password", "apr_md5_crypt")) # 2.2-compat scheme host_no_bcrypt = apache.htpasswd_defaults["host_apache_22"] ht.set_hash("user2", hash_scheme("password", host_no_bcrypt)) # 2.4-compat scheme host_best = apache.htpasswd_defaults["host"] ht.set_hash("user3", hash_scheme("password", host_best)) # unsupported scheme -- should always fail to verify ht.set_hash("user4", "$xxx$foo$bar$baz") # make sure htpasswd properly recognizes hashes ht.save() self.assertFalse(_call_htpasswd_verify(path, "user1", "wrong")) self.assertFalse(_call_htpasswd_verify(path, "user2", "wrong")) self.assertFalse(_call_htpasswd_verify(path, "user3", "wrong")) self.assertFalse(_call_htpasswd_verify(path, "user4", "wrong")) self.assertTrue(_call_htpasswd_verify(path, "user1", "password")) self.assertTrue(_call_htpasswd_verify(path, "user2", "password")) self.assertTrue(_call_htpasswd_verify(path, "user3", "password"))
def test_09_to_string(self): """test to_string""" # check with known sample ht = apache.HtpasswdFile.from_string(self.sample_01) self.assertEqual(ht.to_string(), self.sample_01) # test blank ht = apache.HtpasswdFile() self.assertEqual(ht.to_string(), b"")
def test_00_constructor_autoload(self): "test constructor autoload" if gae_env: return self.skipTest( "GAE doesn't offer read/write filesystem access") #check with existing file path = mktemp() set_file(path, self.sample_01) ht = apache.HtpasswdFile(path) self.assertEqual(ht.to_string(), self.sample_01) #check autoload=False ht = apache.HtpasswdFile(path, autoload=False) self.assertEqual(ht.to_string(), b("")) #check missing file os.remove(path) self.assertRaises(IOError, apache.HtpasswdFile, path)
def test_06_save(self): """test save()""" # load from file path = self.mktemp() set_file(path, self.sample_01) ht = apache.HtpasswdFile(path) # make changes, check they saved ht.delete("user1") ht.delete("user2") ht.save() self.assertEqual(get_file(path), self.sample_02) # test save w/ no path hb = apache.HtpasswdFile(default_scheme="plaintext") hb.set_password("user1", "pass1") self.assertRaises(RuntimeError, hb.save) # test save w/ explicit path hb.save(path) self.assertEqual(get_file(path), b"user1:pass1\n")
def test_06_save(self): "test save()" if gae_env: return self.skipTest( "GAE doesn't offer read/write filesystem access") #load from file path = mktemp() set_file(path, self.sample_01) ht = apache.HtpasswdFile(path) #make changes, check they saved ht.delete("user1") ht.delete("user2") ht.save() self.assertEqual(get_file(path), self.sample_02) #test save w/ no path hb = apache.HtpasswdFile() hb.update("user1", "pass1") self.assertRaises(RuntimeError, hb.save)
def test_05_load(self): "test load()" if gae_env: return self.skipTest( "GAE doesn't offer read/write filesystem access") #setup empty file path = mktemp() set_file(path, "") backdate_file_mtime(path, 5) ha = apache.HtpasswdFile(path, default="plaintext") self.assertEqual(ha.to_string(), b("")) #make changes, check force=False does nothing ha.update("user1", "pass1") ha.load(force=False) self.assertEqual(ha.to_string(), b("user1:pass1\n")) #change file set_file(path, self.sample_01) ha.load(force=False) self.assertEqual(ha.to_string(), self.sample_01) #make changes, check force=True overwrites them ha.update("user5", "pass5") ha.load() self.assertEqual(ha.to_string(), self.sample_01) #test load w/ no path hb = apache.HtpasswdFile() self.assertRaises(RuntimeError, hb.load) self.assertRaises(RuntimeError, hb.load, force=False) #test load w/ dups set_file(path, self.sample_dup) hc = apache.HtpasswdFile(path) self.assertTrue(hc.verify('user1', 'pass1'))
def test_00_constructor_new(self): """constructor -- 'new' keyword""" # check with existing file path = self.mktemp() set_file(path, self.sample_01) ht = apache.HtpasswdFile(path) self.assertEqual(ht.to_string(), self.sample_01) self.assertEqual(ht.path, path) self.assertTrue(ht.mtime) # check changing path ht.path = path + "x" self.assertEqual(ht.path, path + "x") self.assertFalse(ht.mtime) # check new=True ht = apache.HtpasswdFile(path, new=True) self.assertEqual(ht.to_string(), b"") self.assertEqual(ht.path, path) self.assertFalse(ht.mtime) # check missing file os.remove(path) self.assertRaises(IOError, apache.HtpasswdFile, path)
def test_htpasswd_cmd_verify_bcrypt(self): """ verify "htpasswd" command can read bcrypt format this tests for regression of issue 95, where we output "$2b$" instead of "$2y$"; fixed in v1.7.2. """ path = self.mktemp() ht = apache.HtpasswdFile(path=path, new=True) def hash_scheme(pwd, scheme): return ht.context.handler(scheme).hash(pwd) ht.set_hash("user1", hash_scheme("password", "bcrypt")) ht.save() self.assertFalse(_call_htpasswd_verify(path, "user1", "wrong")) if HAVE_HTPASSWD_BCRYPT: self.assertTrue(_call_htpasswd_verify(path, "user1", "password")) else: # apache2.2 should fail, acting like it's an unknown hash format self.assertFalse(_call_htpasswd_verify(path, "user1", "password"))
def __init__(self, **conf): """ Construct a concrete object with a set of keyword configuration options. :param **conf: htpasswd_path: Path to the Apache htpasswd file. :raises `talons.exc.BadConfiguration` if configuration options are not valid or conflict with each other. """ htpath = conf.pop('htpasswd_path', None) if not htpath: msg = ("Missing required htpasswd_path " "configuration option.") LOG.error(msg) raise exc.BadConfiguration(msg) if not os.path.exists(htpath): msg = "htpasswd file {0} does not exist.".format(htpath) LOG.error(msg) raise exc.BadConfiguration(msg) self.htfile = apache.HtpasswdFile(htpath)
def test_10_repr(self): ht = apache.HtpasswdFile("fakepath", autosave=True, new=True, encoding="latin-1") repr(ht)
def check(scheme): ht = apache.HtpasswdFile(default_scheme=scheme) ht.set_password("user1", "pass1") return ht.context.identify(ht.get_hash("user1"))