/
githubmirror
/
salt
Обзор
Документация
Войти
/
githubmirror
/
salt
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
tests/pytests/unit/modules/test_mac_user.py
443 строки
12 KB
pjcreath
Move the mac_user._kcpassword unit test into the pytests directory.
15 май 2023, 23:46
15 май 2023, 23:46
7fc547f
Код
Авторство
О чём код?
""" :codeauthor: Nicole Thomas <nicole@saltstack.com> """ import pytest import salt.modules.mac_user as mac_user from salt.exceptions import CommandExecutionError, SaltInvocationError from tests.support.mock import MagicMock, patch pwd = pytest.importorskip("pwd") @pytest.fixture def configure_loader_modules(): return {mac_user: {}} @pytest.fixture def mock_pwall(): return [ pwd.struct_passwd( ( "_amavisd", "*", 83, 83, "AMaViS Daemon", "/var/virusmails", "/usr/bin/false", ) ), pwd.struct_passwd( ( "_appleevents", "*", 55, 55, "AppleEvents Daemon", "/var/empty", "/usr/bin/false", ) ), pwd.struct_passwd( ( "_appowner", "*", 87, 87, "Application Owner", "/var/empty", "/usr/bin/false", ) ), ] @pytest.fixture def mock_info_ret(): return { "shell": "/bin/bash", "name": "test", "gid": 4376, "groups": ["TEST_GROUP"], "home": "/Users/foo", "fullname": "TEST USER", "uid": 4376, } @pytest.mark.skip(reason="Waiting on some clarifications from bug report #10594") def _test_flush_dscl_cache(): # TODO: Implement tests after clarifications come in pass def test_dscl(): """ Tests the creation of a dscl node """ mac_mock = MagicMock( return_value={"pid": 4948, "retcode": 0, "stderr": "", "stdout": ""} ) with patch.dict(mac_user.__salt__, {"cmd.run_all": mac_mock}): with patch.dict( mac_user.__grains__, {"kernel": "Darwin", "osrelease": "10.9.1", "osrelease_info": (10, 9, 1)}, ): assert mac_user._dscl(["username", "UniqueID", 501]) == { "pid": 4948, "retcode": 0, "stderr": "", "stdout": "", } def test_first_avail_uid(mock_pwall): """ Tests the availability of the next uid """ with patch("pwd.getpwall", MagicMock(return_value=mock_pwall)): assert mac_user._first_avail_uid() == 501 # 'add' function tests: 4 # Only tested error handling # Full functionality tests covered in integration testing def test_add_user_exists(mock_info_ret): """ Tests if the user exists or not """ with patch("salt.modules.mac_user.info", MagicMock(return_value=mock_info_ret)): pytest.raises(CommandExecutionError, mac_user.add, "test") def test_add_whitespace(): """ Tests if there is whitespace in the user name """ with patch("salt.modules.mac_user.info", MagicMock(return_value={})): pytest.raises(SaltInvocationError, mac_user.add, "foo bar") def test_add_uid_int(): """ Tests if the uid is an int """ with patch("salt.modules.mac_user.info", MagicMock(return_value={})): pytest.raises(SaltInvocationError, mac_user.add, "foo", "foo") def test_add_gid_int(): """ Tests if the gid is an int """ with patch("salt.modules.mac_user.info", MagicMock(return_value={})): pytest.raises(SaltInvocationError, mac_user.add, "foo", 20, "foo") # 'delete' function tests: 2 # Only tested pure logic of function # Full functionality tests covered in integration testing def test_delete_whitespace(): """ Tests if there is whitespace in the user name """ pytest.raises(SaltInvocationError, mac_user.delete, "foo bar") def test_delete_user_exists(): """ Tests if the user exists or not """ with patch("salt.modules.mac_user.info", MagicMock(return_value={})): assert mac_user.delete("foo") def test_getent(mock_pwall): """ Tests the list of information for all users """ with patch("pwd.getpwall", MagicMock(return_value=mock_pwall)), patch( "salt.modules.mac_user.list_groups", MagicMock(return_value=["TEST_GROUP"]) ): ret = [ { "shell": "/usr/bin/false", "name": "_amavisd", "gid": 83, "groups": ["TEST_GROUP"], "home": "/var/virusmails", "fullname": "AMaViS Daemon", "uid": 83, }, { "shell": "/usr/bin/false", "name": "_appleevents", "gid": 55, "groups": ["TEST_GROUP"], "home": "/var/empty", "fullname": "AppleEvents Daemon", "uid": 55, }, { "shell": "/usr/bin/false", "name": "_appowner", "gid": 87, "groups": ["TEST_GROUP"], "home": "/var/empty", "fullname": "Application Owner", "uid": 87, }, ] assert mac_user.getent() == ret # 'chuid' function tests: 3 # Only tested pure logic of function # Full functionality tests covered in integration testing def test_chuid_int(): """ Tests if the uid is an int """ pytest.raises(SaltInvocationError, mac_user.chuid, "foo", "foo") def test_chuid_user_exists(): """ Tests if the user exists or not """ with patch("salt.modules.mac_user.info", MagicMock(return_value={})): pytest.raises(CommandExecutionError, mac_user.chuid, "foo", 4376) def test_chuid_same_uid(mock_info_ret): """ Tests if the user's uid is the same as as the argument """ with patch("salt.modules.mac_user.info", MagicMock(return_value=mock_info_ret)): assert mac_user.chuid("foo", 4376) # 'chgid' function tests: 3 # Only tested pure logic of function # Full functionality tests covered in integration testing def test_chgid_int(): """ Tests if the gid is an int """ pytest.raises(SaltInvocationError, mac_user.chgid, "foo", "foo") def test_chgid_user_exists(): """ Tests if the user exists or not """ with patch("salt.modules.mac_user.info", MagicMock(return_value={})): pytest.raises(CommandExecutionError, mac_user.chgid, "foo", 4376) def test_chgid_same_gid(mock_info_ret): """ Tests if the user's gid is the same as as the argument """ with patch("salt.modules.mac_user.info", MagicMock(return_value=mock_info_ret)): assert mac_user.chgid("foo", 4376) # 'chshell' function tests: 2 # Only tested pure logic of function # Full functionality tests covered in integration testing def test_chshell_user_exists(): """ Tests if the user exists or not """ with patch("salt.modules.mac_user.info", MagicMock(return_value={})): pytest.raises(CommandExecutionError, mac_user.chshell, "foo", "/bin/bash") def test_chshell_same_shell(mock_info_ret): """ Tests if the user's shell is the same as the argument """ with patch("salt.modules.mac_user.info", MagicMock(return_value=mock_info_ret)): assert mac_user.chshell("foo", "/bin/bash") # 'chhome' function tests: 2 # Only tested pure logic of function # Full functionality tests covered in integration testing def test_chhome_user_exists(): """ Test if the user exists or not """ with patch("salt.modules.mac_user.info", MagicMock(return_value={})): pytest.raises(CommandExecutionError, mac_user.chhome, "foo", "/Users/foo") def test_chhome_same_home(mock_info_ret): """ Tests if the user's home is the same as the argument """ with patch("salt.modules.mac_user.info", MagicMock(return_value=mock_info_ret)): assert mac_user.chhome("foo", "/Users/foo") # 'chfullname' function tests: 2 # Only tested pure logic of function # Full functionality tests covered in integration testing def test_chfullname_user_exists(): """ Tests if the user exists or not """ with patch("salt.modules.mac_user.info", MagicMock(return_value={})): pytest.raises(CommandExecutionError, mac_user.chfullname, "test", "TEST USER") def test_chfullname_same_name(mock_info_ret): """ Tests if the user's full name is the same as the argument """ with patch("salt.modules.mac_user.info", MagicMock(return_value=mock_info_ret)): assert mac_user.chfullname("test", "TEST USER") # 'chgroups' function tests: 3 # Only tested pure logic of function # Full functionality tests covered in integration testing def test_chgroups_user_exists(): """ Tests if the user exists or not """ with patch("salt.modules.mac_user.info", MagicMock(return_value={})): pytest.raises(CommandExecutionError, mac_user.chgroups, "foo", "wheel,root") def test_chgroups_bad_groups(mock_info_ret): """ Test if there is white space in groups argument """ with patch("salt.modules.mac_user.info", MagicMock(return_value=mock_info_ret)): pytest.raises(SaltInvocationError, mac_user.chgroups, "test", "bad group") def test_chgroups_same_desired(mock_info_ret): """ Tests if the user's list of groups is the same as the arguments """ mock_primary = MagicMock(return_value="wheel") with patch.dict(mac_user.__salt__, {"file.gid_to_group": mock_primary}), patch( "salt.modules.mac_user.info", MagicMock(return_value=mock_info_ret) ), patch( "salt.modules.mac_user.list_groups", MagicMock(return_value=("wheel", "root")) ): assert mac_user.chgroups("test", "wheel,root") def test_info(): """ Tests the return of user information """ mock_pwnam = pwd.struct_passwd( ("root", "*", 0, 0, "TEST USER", "/var/test", "/bin/bash") ) ret = { "shell": "/bin/bash", "name": "root", "gid": 0, "groups": ["_TEST_GROUP"], "home": "/var/test", "fullname": "TEST USER", "uid": 0, } with patch("pwd.getpwall", MagicMock(return_value=[mock_pwnam])), patch( "salt.modules.mac_user.list_groups", MagicMock(return_value=["_TEST_GROUP"]) ): assert mac_user.info("root") == ret def test_format_info(): """ Tests the formatting of returned user information """ data = pwd.struct_passwd( ( "_TEST_GROUP", "*", 83, 83, "AMaViS Daemon", "/var/virusmails", "/usr/bin/false", ) ) ret = { "shell": "/usr/bin/false", "name": "_TEST_GROUP", "gid": 83, "groups": ["_TEST_GROUP"], "home": "/var/virusmails", "fullname": "AMaViS Daemon", "uid": 83, } with patch( "salt.modules.mac_user.list_groups", MagicMock(return_value=["_TEST_GROUP"]) ): assert mac_user._format_info(data) == ret def test_list_users(): """ Tests the list of all users """ expected = ["spongebob", "patrick", "squidward"] mock_run = MagicMock( return_value={ "pid": 4948, "retcode": 0, "stderr": "", "stdout": "\n".join(expected), } ) with patch.dict(mac_user.__grains__, {"osrelease_info": (10, 9, 1)}), patch.dict( mac_user.__salt__, {"cmd.run_all": mock_run} ): assert mac_user.list_users() == expected def test_kcpassword(): hashes = { # Actual hashes from macOS, since reference implementation didn't account for trailing null "0": "4d 89 f9 91 1f 7a 46 5e f7 a8 11 ff", "password": "0d e8 21 50 a5 d3 af 8e a3 de d9 14", "shorterpwd": "0e e1 3d 51 a6 d9 af 9a d4 dd 1f 27", "Squarepants": "2e f8 27 42 a0 d9 ad 8b cd cd 6c 7d", "longerpasswd": "11 e6 3c 44 b7 ce ad 8b d0 ca 68 19 89 b1 65 ae 7e 89 12 b8 51 f8 f0 ff", "ridiculouslyextendedpass": "0f e0 36 4a b1 c9 b1 85 d6 ca 73 04 ec 2a 57 b7 d2 b9 8f c7 c9 7e 0e fa 52 7b 71 e6 f8 b7 a6 ae 47 94 d7 86", } for password, hash in hashes.items(): kcpass = mac_user._kcpassword(password) hash = bytes.fromhex(hash) # macOS adds a trailing null and pads the rest with random data length = len(password) + 1 assert kcpass[:length] == hash[:length] assert len(kcpass) == len(hash)