def test_password_parameter_change(self): """Validate hash parameter update on login works""" username = "******" password = "******" data = {"username": username, "password": password} user = models.User.objects.get(username=username) self.set_global_parameter("password_scheme", "argon2id") self.client.logout() with self.settings( MODOBOA_ARGON2_TIME_COST=4, MODOBOA_ARGON2_MEMORY_COST=10000, MODOBOA_ARGON2_PARALLELISM=4): self.client.post(reverse("core:login"), data) user.refresh_from_db() self.assertTrue(user.password.startswith("{ARGON2ID}")) parameters = argon2.extract_parameters(user.password.lstrip("{ARGON2ID}")) self.assertEqual(parameters.time_cost, 4) self.assertEqual(parameters.memory_cost, 10000) self.assertEqual(parameters.parallelism, 4) self.client.logout() with self.settings( MODOBOA_ARGON2_TIME_COST=3, MODOBOA_ARGON2_MEMORY_COST=1000, MODOBOA_ARGON2_PARALLELISM=2): self.client.post(reverse("core:login"), data) user.refresh_from_db() self.assertTrue(user.password.startswith("{ARGON2ID}")) parameters = argon2.extract_parameters( user.password.lstrip("{ARGON2ID}")) self.assertEqual(parameters.time_cost, 3) self.assertEqual(parameters.memory_cost, 1000) self.assertEqual(parameters.parallelism, 2)
def is_hashed(value: Union[bytes, str]) -> bool: """Check if a value is hashed or not.""" if not isinstance(value, str): return False try: argon2.extract_parameters(value) hashed = True except argon2.exceptions.InvalidHash: hashed = False return hashed
def test_type_is_configurable(self): """ Argon2id is default but can be changed. """ ph = PasswordHasher(time_cost=1, memory_cost=64) default_hash = ph.hash("foo") assert Type.ID is ph.type is ph._parameters.type assert Type.ID is extract_parameters(default_hash).type ph = PasswordHasher(time_cost=1, memory_cost=64, type=Type.I) assert Type.I is ph.type is ph._parameters.type assert Type.I is extract_parameters(ph.hash("foo")).type assert ph.check_needs_rehash(default_hash)
def test_valid_hash(self): """ A valid hash is parsed. """ parsed = extract_parameters(VALID_HASH) assert VALID_PARAMETERS == parsed
def test_valid_hash_v18(self): """ A valid Argon v1.2 hash is parsed. """ parsed = extract_parameters(VALID_HASH_V18) assert VALID_PARAMETERS_V18 == parsed
def verify(hash2text, password): hash_params = argon2.extract_parameters(hash2text) hash_func = argon2.PasswordHasher(hash_params.time_cost, hash_params.memory_cost, hash_params.parallelism, hash_params.hash_len, hash_params.salt_len, type=hash_params.type) logging.debug('Verificando la validez de la contraseña...') return hash_func.verify(hash2text, password)
def test_password_argon2_parameter_change(self): """Validate hash parameter update on login works with argon2.""" username = "******" password = "******" data = {"username": username, "password": password} user = models.User.objects.get(username=username) self.set_global_parameter("password_scheme", "argon2id") self.client.logout() with self.settings( MODOBOA_ARGON2_TIME_COST=4, MODOBOA_ARGON2_MEMORY_COST=10000, MODOBOA_ARGON2_PARALLELISM=4, ): self.client.post(reverse("core:login"), data) user.refresh_from_db() self.assertTrue(user.password.startswith("{ARGON2ID}")) parameters = argon2.extract_parameters( user.password.lstrip("{ARGON2ID}") ) self.assertEqual(parameters.time_cost, 4) self.assertEqual(parameters.memory_cost, 10000) self.assertEqual(parameters.parallelism, 4) self.client.logout() with self.settings( MODOBOA_ARGON2_TIME_COST=3, MODOBOA_ARGON2_MEMORY_COST=1000, MODOBOA_ARGON2_PARALLELISM=2, ): self.client.post(reverse("core:login"), data) user.refresh_from_db() self.assertTrue(user.password.startswith("{ARGON2ID}")) parameters = argon2.extract_parameters( user.password.lstrip("{ARGON2ID}")) self.assertEqual(parameters.time_cost, 3) self.assertEqual(parameters.memory_cost, 1000) self.assertEqual(parameters.parallelism, 2)
def verify(hash2text: str, password: str) -> bool: """Verifica si una contraseña es correcta Args: hash2text: El hash generado por argon2 sobre la contraseña password: La contraseña a verificar Returns: **True** si la contraseña es correcta """ hash_params = argon2.extract_parameters(hash2text) hash_func = argon2.PasswordHasher(hash_params.time_cost, hash_params.memory_cost, hash_params.parallelism, hash_params.hash_len, hash_params.salt_len, type=hash_params.type) return hash_func.verify(hash2text, password)
def test_invalid_hash(self, hash): """ Invalid hashes of various types raise an InvalidHash error. """ with pytest.raises(InvalidHash): extract_parameters(hash)
def parameters(self) -> Parameters: """Returns the Argon2 hash parameters.""" return extract_parameters(self)