# Copyright (C) 2010-2024 RhodeCode GmbH # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License, version 3 # (only), as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # # This program is dual-licensed. If you wish to learn more about the # RhodeCode Enterprise Edition, including its added features, Support services, # and proprietary license terms, please see https://rhodecode.com/licenses/ """ Tests checking the crypto backends which can be used by lib/auth. """ import collections import pytest from rhodecode.lib import auth # Utility functions to get or check passwords def test_get_crypt_password_accepts_unicode(password): result = auth.get_crypt_password(password.value) assert result == password.hashed def test_check_password_accepts_unicode(password): result = auth.check_password(password.value, password.hashed) assert result # API contracts from _RhodeCodeCryptoBase def test_constructor_takes_no_arguments(crypto_backend_class): instance = crypto_backend_class() assert instance def test_hash_create_returns_bytes(crypto_backend, password): hashed = crypto_backend.hash_create(password.encoded) assert isinstance(hashed, str) def test_hash_create_changes_the_value(crypto_backend, password): hashed = crypto_backend.hash_create(password.encoded) assert hashed != password.encoded def test_hash_create_enforces_bytes(crypto_backend, password): with pytest.raises(TypeError): crypto_backend.hash_create(password.value) def test_hash_check(crypto_backend, password): not_matching = 'stub-hash' with pytest.raises(TypeError): crypto_backend.hash_check(password.value, not_matching) def test_hash_check_with_update_enforces_bytes(crypto_backend, password): not_matching = 'stub-hash' with pytest.raises(TypeError): crypto_backend.hash_check_with_upgrade(password.value, not_matching) @pytest.fixture(params=[ auth._RhodeCodeCryptoTest, auth._RhodeCodeCryptoBCrypt, auth._RhodeCodeCryptoSha256, ]) def crypto_backend_class(request): """ Parameterizes per crypto backend class. """ return request.param @pytest.fixture() def crypto_backend(crypto_backend_class): return crypto_backend_class() @pytest.fixture() def password(): encoding = 'utf-8' value = u'value' value_encoded = value.encode(encoding) value_hashed = auth.crypto_backend().hash_create(value_encoded) return collections.namedtuple('Password', 'value, encoded, hashed')( value, value_encoded, value_hashed)