mirror of
https://github.com/ansible/ansible.git
synced 2025-11-30 23:16:08 +07:00
Increase code coverage of utils/encrypt.py (#86060)
* Add encryption code coverage Co-authored-by: Matt Clay <matt@mystile.com>
This commit is contained in:
@@ -87,3 +87,53 @@
|
||||
assert:
|
||||
that:
|
||||
- yescrypt_hash_salt == '$y$j9T$V7qMYJaNbVKOeh4PhtqPk/$x7rTqZ.RpI07.dkBSxcg.jLM8ODUfx25rCN0cFsAUg0'
|
||||
|
||||
- name: Test salt with invalid character
|
||||
set_fact:
|
||||
md5_hash: "{{ 'test' | password_hash('md5_crypt', salt='123^') }}"
|
||||
ignore_errors: yes
|
||||
register: bad_salt_result
|
||||
|
||||
- name: Determine if bad salt character was recognized
|
||||
assert:
|
||||
that: bad_salt_result.msg is contains 'invalid characters in salt'
|
||||
|
||||
- name: Test supplying invalid salt size with algo needing exact size
|
||||
set_fact:
|
||||
bcrypt_hash: "{{ 'test' | password_hash('bcrypt', salt='12345', salt_size=5) }}"
|
||||
ignore_errors: yes
|
||||
register: bad_salt_result
|
||||
|
||||
- name: Determine if salt size mismatch caught
|
||||
assert:
|
||||
that: bad_salt_result.msg is contains 'invalid salt size supplied (5), expected 22'
|
||||
|
||||
- name: Test salt with exact size mismatch
|
||||
set_fact:
|
||||
bcrypt_hash: "{{ 'test' | password_hash('bcrypt', salt='123') }}"
|
||||
ignore_errors: yes
|
||||
register: bad_salt_result
|
||||
|
||||
- name: Determine if salt size mismatch caught
|
||||
assert:
|
||||
that: bad_salt_result.msg is contains 'invalid salt size supplied (3), expected 22'
|
||||
|
||||
- name: Test supplying too big salt
|
||||
set_fact:
|
||||
bcrypt_hash: "{{ 'test' | password_hash('md5_crypt', salt='1234567890') }}"
|
||||
ignore_errors: yes
|
||||
register: bad_salt_result
|
||||
|
||||
- name: Determine if too big salt caught
|
||||
assert:
|
||||
that: bad_salt_result.msg is contains 'invalid salt size supplied (10), expected at most 8'
|
||||
|
||||
- name: Test supplying too big salt size
|
||||
set_fact:
|
||||
bcrypt_hash: "{{ 'test' | password_hash('md5_crypt', salt='1234567890', salt_size=10) }}"
|
||||
ignore_errors: yes
|
||||
register: bad_salt_result
|
||||
|
||||
- name: Determine if too big salt size caught
|
||||
assert:
|
||||
that: bad_salt_result.msg is contains 'invalid salt size supplied (10), expected at most 8'
|
||||
|
||||
@@ -7,6 +7,8 @@ import warnings
|
||||
|
||||
import pytest
|
||||
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
|
||||
from ansible.plugins.filter.core import get_encrypted_password
|
||||
@@ -249,3 +251,61 @@ def test_passlib_bcrypt_salt(recwarn):
|
||||
|
||||
result = passlib_obj.hash(secret, salt=repaired_salt, ident=ident)
|
||||
assert result == expected
|
||||
|
||||
|
||||
def test_do_encrypt_no_lib(mocker: MockerFixture) -> None:
|
||||
"""Test AnsibleError is raised when no encryption library is installed."""
|
||||
mocker.patch('ansible.utils.encrypt.HAS_CRYPT', False)
|
||||
mocker.patch('ansible.utils.encrypt.PASSLIB_AVAILABLE', False)
|
||||
|
||||
with pytest.raises(AnsibleError, match=r"Unable to encrypt nor hash, either libxcrypt \(recommended\), crypt, or passlib must be installed\."):
|
||||
encrypt.do_encrypt("123", "sha256_crypt", salt="12345678")
|
||||
|
||||
|
||||
class TestCryptHash:
|
||||
"""
|
||||
Tests for the CryptHash class.
|
||||
|
||||
These tests are hitting code paths that are otherwise impossible to reach
|
||||
through integration tests, but necessary for more complete code coverage.
|
||||
"""
|
||||
|
||||
def test_invalid_instantiation(self, mocker: MockerFixture) -> None:
|
||||
"""Should not be able to instantiate a CryptHash class without libxcrypt/libcrypt."""
|
||||
mocker.patch('ansible.utils.encrypt.HAS_CRYPT', False)
|
||||
|
||||
with pytest.raises(AnsibleError, match=r"crypt cannot be used as the 'libxcrypt' library is not installed or is unusable\."):
|
||||
encrypt.CryptHash("sha256_crypt")
|
||||
|
||||
def test_ansible_unsupported_algorithm(self) -> None:
|
||||
"""Test AnsibleError is raised when Ansible does not support requested algorithm."""
|
||||
with pytest.raises(AnsibleError, match=r"crypt does not support 'foo' algorithm"):
|
||||
encrypt.CryptHash("foo")
|
||||
|
||||
def test_library_unsupported_algorithm(self, mocker: MockerFixture) -> None:
|
||||
"""Test AnsibleError is raised when crypt library does not support an Ansible supported algorithm."""
|
||||
# Pretend we have a crypt lib that doesn't like our algo
|
||||
mocker.patch('ansible.utils.encrypt.HAS_CRYPT', True)
|
||||
mocker.patch('ansible._internal._encryption._crypt.crypt', side_effect=ValueError)
|
||||
|
||||
# instantiate with an Ansible supported algo
|
||||
crypt_hash = encrypt.CryptHash("sha256_crypt")
|
||||
|
||||
with pytest.raises(AnsibleError, match=r"crypt does not support 'sha256_crypt' algorithm"):
|
||||
crypt_hash.hash("123", salt="12345678")
|
||||
|
||||
|
||||
class TestPasslibHash:
|
||||
"""
|
||||
Tests for the PasslibHash class.
|
||||
|
||||
These tests are hitting code paths that are otherwise impossible to reach
|
||||
through integration tests, but necessary for more complete code coverage.
|
||||
"""
|
||||
|
||||
def test_invalid_instantiation(self, mocker: MockerFixture) -> None:
|
||||
"""Should not be able to instantiate a PasslibHash class without passlib."""
|
||||
mocker.patch('ansible.utils.encrypt.PASSLIB_AVAILABLE', False)
|
||||
|
||||
with pytest.raises(AnsibleError, match=r"The passlib Python package must be installed to hash with the 'sha256_crypt' algorithm\."):
|
||||
encrypt.PasslibHash("sha256_crypt")
|
||||
|
||||
Reference in New Issue
Block a user