class NetworkInterfaceTestCase(unittest.TestCase):
    """Test DBus interface for the Network module."""
    def setUp(self):
        """Set up the network module."""
        # Set up the network module.
        self.network_module = NetworkService()
        self.network_interface = NetworkInterface(self.network_module)

        # Connect to the properties changed signal.
        self.callback = PropertiesChangedCallback()
        self.network_interface.PropertiesChanged.connect(self.callback)

    def kickstart_properties_test(self):
        """Test kickstart properties."""
        self.assertEqual(self.network_interface.KickstartCommands,
                         ["network", "firewall"])
        self.assertEqual(self.network_interface.KickstartSections, [])
        self.assertEqual(self.network_interface.KickstartAddons, [])

    def _test_dbus_property(self, *args, **kwargs):
        check_dbus_property(self, NETWORK, self.network_interface, *args,
                            **kwargs)

    @patch("pyanaconda.modules.common.base.base.setlocale")
    @patch("pyanaconda.modules.common.base.base.os")
    def set_locale_test(self, mocked_os, setlocale):
        """Test setting locale of the module."""
        from locale import LC_ALL
        import pyanaconda.core.util
        locale = "en_US.UTF-8"
        mocked_os.environ = {}
        self.network_interface.SetLocale(locale)
        self.assertEqual(mocked_os.environ["LANG"], locale)
        setlocale.assert_called_once_with(LC_ALL, locale)
        self.assertEqual(pyanaconda.core.util._child_env['LANG'], locale)

    def hostname_property_test(self):
        """Test the hostname property."""
        self._test_dbus_property(
            "Hostname",
            "dot.dot",
        )

    def get_current_hostname_test(self):
        """Test getting current hostname does not fail."""
        self.network_interface.GetCurrentHostname()

    def connected_test(self):
        """Test getting connectivity status does not fail."""
        connected = self.network_interface.Connected
        self.assertIn(connected, (True, False))

    def connecting_test(self):
        """Test checking connecting status does not fail."""
        self.network_interface.IsConnecting()

    def mocked_client_connectivity_test(self):
        """Test connectivity properties with mocked NMClient."""
        nm_client = MockedNMClient()
        nm_client._connect_state_changed(self.network_module._nm_state_changed)
        self.network_module.nm_client = nm_client

        nm_client._set_state(NM.State.CONNECTED_LOCAL)
        self.assertTrue(self.network_interface.Connected)

        nm_client._set_state(NM.State.DISCONNECTED)
        self.assertFalse(self.network_interface.Connected)
        self.callback.assert_called_with(NETWORK.interface_name,
                                         {'Connected': False}, [])
        self.assertFalse(self.network_interface.IsConnecting())

        nm_client._set_state(NM.State.CONNECTED_SITE)
        self.assertTrue(self.network_interface.Connected)
        self.callback.assert_called_with(NETWORK.interface_name,
                                         {'Connected': True}, [])
        self.assertFalse(self.network_interface.IsConnecting())

        nm_client._set_state(NM.State.CONNECTED_GLOBAL)
        self.assertTrue(self.network_interface.Connected)
        self.callback.assert_called_with(NETWORK.interface_name,
                                         {'Connected': True}, [])
        self.assertFalse(self.network_interface.IsConnecting())

        nm_client._set_state(NM.State.CONNECTING)
        self.assertFalse(self.network_interface.Connected)
        self.callback.assert_called_with(NETWORK.interface_name,
                                         {'Connected': False}, [])
        self.assertTrue(self.network_interface.IsConnecting())

        nm_client._set_state(NM.State.CONNECTED_LOCAL)
        self.assertTrue(self.network_interface.Connected)
        self.callback.assert_called_with(NETWORK.interface_name,
                                         {'Connected': True}, [])
        self.assertFalse(self.network_interface.IsConnecting())

    def nm_availability_test(self):
        self.network_module.nm_client = None
        self.assertTrue(self.network_interface.Connected)
        self.assertFalse(self.network_interface.IsConnecting())

    def create_device_configurations_test(self):
        """Test creating device configurations does not fail."""
        self.network_interface.CreateDeviceConfigurations()

    def get_device_configurations_test(self):
        """Test GetDeviceConfigurations."""
        self.assertListEqual(self.network_interface.GetDeviceConfigurations(),
                             [])

    def network_device_configuration_changed_test(self):
        """Test NetworkDeviceConfigurationChanged."""
        self.network_interface.NetworkDeviceConfigurationChanged()

    def get_dracut_arguments_test(self):
        """Test GetDracutArguments."""
        self.assertListEqual(
            self.network_interface.GetDracutArguments("ens3", "10.10.10.10",
                                                      "", False), [])

    def log_configuration_state_test(self):
        """Test LogConfigurationState."""
        self.network_interface.LogConfigurationState("message")

    @patch_dbus_publish_object
    @patch('pyanaconda.modules.network.network.devices_ignore_ipv6',
           return_value=True)
    def install_network_with_task_test(self, devices_ignore_ipv6, publisher):
        """Test InstallNetworkWithTask."""
        self.network_module._disable_ipv6 = True
        self.network_module.nm_client = Mock()
        self.__mock_nm_client_devices([
            ("ens3", "33:33:33:33:33:33", "33:33:33:33:33:33",
             NM.DeviceType.ETHERNET),
            ("ens4", "44:44:44:44:44:44", "44:44:44:44:44:44",
             NM.DeviceType.ETHERNET),
            ("ens5", "55:55:55:55:55:55", "55:55:55:55:55:55",
             NM.DeviceType.ETHERNET)
        ])

        task_path = self.network_interface.InstallNetworkWithTask(False)

        obj = check_task_creation(self, task_path, publisher,
                                  NetworkInstallationTask)

        self.assertEqual(obj.implementation._disable_ipv6, True)
        self.assertEqual(obj.implementation._overwrite, False)
        self.assertEqual(obj.implementation._network_ifaces,
                         ["ens3", "ens4", "ens5"])

        self.network_module.log_task_result = Mock()

        obj.implementation.succeeded_signal.emit()
        self.network_module.log_task_result.assert_called_once()

    @patch_dbus_publish_object
    def configure_hostname_with_task_test(self, publisher):
        """Test ConfigureHostnameWithTask."""
        self.network_module._hostname = "my_hostname"

        task_path = self.network_interface.ConfigureHostnameWithTask(False)

        obj = check_task_creation(self, task_path, publisher,
                                  HostnameConfigurationTask)

        self.assertEqual(obj.implementation._overwrite, False)
        self.assertEqual(obj.implementation._hostname, "my_hostname")

    @patch_dbus_publish_object
    @patch('pyanaconda.modules.network.installation.update_connection_values')
    @patch('pyanaconda.modules.network.installation.find_ifcfg_uuid_of_device')
    def configure_activation_on_boot_with_task_test(self,
                                                    find_ifcfg_uuid_of_device,
                                                    update_connection_values,
                                                    publisher):
        """Test ConfigureActivationOnBootWithTask."""
        self.network_module.nm_client = Mock()
        self.network_module._should_apply_onboot_policy = Mock(
            return_value=True)
        self.network_module._has_any_onboot_yes_device = Mock(
            return_value=False)
        self.network_module._get_onboot_ifaces_by_policy = Mock(
            return_value=["ens4"])

        task_path = self.network_interface.ConfigureActivationOnBootWithTask(
            ["ens3"], )

        obj = check_task_creation(self, task_path, publisher,
                                  ConfigureActivationOnBootTask)

        self.assertEqual(set(obj.implementation._onboot_ifaces),
                         set(["ens3", "ens4"]))

        self.network_module.log_task_result = Mock()

        obj.implementation.succeeded_signal.emit()
        self.network_module.log_task_result.assert_called_once()

    def _mock_supported_devices(self, devices_attributes):
        ret_val = []
        for dev_name, dev_hwaddr, dev_type in devices_attributes:
            dev = Mock()
            dev.device_name = dev_name
            dev.device_hwaddress = dev_hwaddr
            dev.device_type = dev_type
            ret_val.append(dev)
        self.network_module.get_supported_devices = Mock(return_value=ret_val)

    @patch_dbus_publish_object
    def consolidate_initramfs_connections_with_task_test(self, publisher):
        """Test ConsolidateInitramfsConnectionsWithTask."""
        task_path = self.network_interface.ConsolidateInitramfsConnectionsWithTask(
        )

        obj = check_task_creation(self, task_path, publisher,
                                  ConsolidateInitramfsConnectionsTask)

        self.network_module.log_task_result = Mock()

        obj.implementation.succeeded_signal.emit()
        self.network_module.log_task_result.assert_called_once()

    @patch_dbus_publish_object
    def apply_kickstart_with_task_test(self, publisher):
        """Test ApplyKickstartWithTask."""
        self._mock_supported_devices([("ens3", "", 0)])
        task_path = self.network_interface.ApplyKickstartWithTask()

        obj = check_task_creation(self, task_path, publisher,
                                  ApplyKickstartTask)

        self.network_module.log_task_result = Mock()

        obj.implementation.succeeded_signal.emit()
        self.network_module.log_task_result.assert_called_once()

    @patch_dbus_publish_object
    def set_real_onboot_values_from_kickstart_with_task_test(self, publisher):
        """Test SetRealOnbootValuesFromKickstartWithTask."""
        self._mock_supported_devices([("ens3", "", 0)])
        task_path = self.network_interface.SetRealOnbootValuesFromKickstartWithTask(
        )

        obj = check_task_creation(self, task_path, publisher,
                                  SetRealOnbootValuesFromKickstartTask)

        self.network_module.log_task_result = Mock()

        obj.implementation.succeeded_signal.emit()
        self.network_module.log_task_result.assert_called_once()

    @patch_dbus_publish_object
    def dump_missing_ifcfg_files_with_task_test(self, publisher):
        """Test DumpMissingIfcfgFilesWithTask."""
        task_path = self.network_interface.DumpMissingIfcfgFilesWithTask()

        obj = check_task_creation(self, task_path, publisher,
                                  DumpMissingIfcfgFilesTask)

        self.network_module.log_task_result = Mock()

        obj.implementation.succeeded_signal.emit()
        self.network_module.log_task_result.assert_called_once()

    def __mock_nm_client_devices(self, device_specs):
        """Mock NM Client devices obtained by get_devices() method.
        :param device_specs: list of specifications of devices which are tuples
                             (DEVICE_NAME, PERMANENT_HWADDRESS, HWADDRESS, DEVICE_TYPE)
                             None value of PERMANENT_HWADDRESS means raising Attribute exception
        :type device_specs: list(tuple(str, str, str, int))
        """
        ret_val = []
        for name, perm_hw, hw, dtype in device_specs:
            dev = Mock()
            dev.get_iface.return_value = name
            dev.get_device_type.return_value = dtype
            dev.get_hw_address.return_value = hw
            if perm_hw:
                dev.get_permanent_hw_address.return_value = perm_hw
            else:
                dev.get_permanent_hw_address = Mock(side_effect=AttributeError(
                    'mocking no permanent hw address'))
            ret_val.append(dev)
        self.network_module.nm_client.get_devices.return_value = ret_val

    def get_supported_devices_test(self):
        """Test GetSupportedDevices."""
        # No NM available
        self.network_module.nm_client = None
        self.assertEqual(self.network_interface.GetSupportedDevices(), [])

        # Mocked NM
        self.network_module.nm_client = Mock()
        self.__mock_nm_client_devices([
            ("ens3", "33:33:33:33:33:33", "33:33:33:33:33:33",
             NM.DeviceType.ETHERNET),
            ("ens4", "44:44:44:44:44:44", "44:44:44:44:44:44",
             NM.DeviceType.ETHERNET),
            # Permanent address is preferred
            ("ens5", "55:55:55:55:55:55", "FF:FF:FF:FF:FF:FF",
             NM.DeviceType.ETHERNET),
            # Virtual devices don't have permanent hw address
            ("team0", None, "33:33:33:33:33:33", NM.DeviceType.TEAM)
        ])

        devs_infos = self.network_interface.GetSupportedDevices()
        self.assertDictEqual(
            devs_infos[0], {
                'device-name': get_variant(Str, "ens3"),
                'hw-address': get_variant(Str, "33:33:33:33:33:33"),
                'device-type': get_variant(Int, NM.DeviceType.ETHERNET)
            })
        self.assertDictEqual(
            devs_infos[1], {
                'device-name': get_variant(Str, "ens4"),
                'hw-address': get_variant(Str, "44:44:44:44:44:44"),
                'device-type': get_variant(Int, NM.DeviceType.ETHERNET)
            })
        self.assertDictEqual(
            devs_infos[2], {
                'device-name': get_variant(Str, "ens5"),
                'hw-address': get_variant(Str, "55:55:55:55:55:55"),
                'device-type': get_variant(Int, NM.DeviceType.ETHERNET)
            })
        self.assertDictEqual(
            devs_infos[3], {
                'device-name': get_variant(Str, "team0"),
                'hw-address': get_variant(Str, "33:33:33:33:33:33"),
                'device-type': get_variant(Int, NM.DeviceType.TEAM)
            })

    def _mock_nm_active_connections(self, connection_specs):
        active_connections = []
        for activated, ifaces in connection_specs:
            con = Mock()
            if activated:
                con.get_state.return_value = NM.ActiveConnectionState.ACTIVATED
            devs = []
            for iface in ifaces:
                dev = Mock()
                dev.get_ip_iface.return_value = iface
                dev.get_iface.return_value = iface
                devs.append(dev)
            con.get_devices.return_value = devs
            active_connections.append(con)
        self.network_module.nm_client.get_active_connections.return_value = active_connections

    def get_activated_interfaces_test(self):
        """Test GetActivatedInterfaces."""
        # No NM available
        self.network_module.nm_client = None
        self.assertEqual(self.network_interface.GetActivatedInterfaces(), [])

        # Mocked NM
        self.network_module.nm_client = Mock()
        self._mock_nm_active_connections([
            (True, ["ens3"]),
            # Slave of bond0
            (True, ["ens5"]),
            # Slave of bond0
            (True, ["ens7"]),
            (True, ["bond0"]),
            (False, ["ens11"]),
            # Not sure if/when this can happen, but we have been supporting it
            (True, ["devA", "devB"]),
            (True, [])
        ])
        self.assertListEqual(self.network_interface.GetActivatedInterfaces(),
                             ["ens3", "ens5", "ens7", "bond0", "devA", "devB"])

    def _test_kickstart(self, ks_in, ks_out):
        check_kickstart_interface(self, self.network_interface, ks_in, ks_out)

    def no_kickstart_test(self):
        """Test with no kickstart."""
        ks_in = None
        ks_out = """
        # Network information
        network  --hostname=localhost.localdomain
        """
        self._test_kickstart(ks_in, ks_out)

    def kickstart_empty_test(self):
        """Test with empty string."""
        ks_in = ""
        ks_out = """
        # Network information
        network  --hostname=localhost.localdomain
        """
        self._test_kickstart(ks_in, ks_out)

    def network_kickstart_test(self):
        """Test the network command.

        In case of kickstart-only network configuration the original commands are
        preserved instead of generating the commands from ifcfg files which happens
        if there has been any non-kickstart (UI) configuration.
        """
        ks_in = """
        network --device ens7 --bootproto static --ip 192.168.124.200 --netmask 255.255.255.0 --gateway 192.168.124.255 --nameserver 10.34.39.2 --activate --onboot=no --hostname=dot.dot
        """
        ks_out = """
        # Network information
        network  --bootproto=static --device=ens7 --gateway=192.168.124.255 --hostname=dot.dot --ip=192.168.124.200 --nameserver=10.34.39.2 --netmask=255.255.255.0 --onboot=off --activate
        """
        self._test_kickstart(ks_in, ks_out)

    def kickstart_firewall_basic_test(self):
        """Test basic firewall command usage."""
        ks_in = "firewall --enable --port=imap:tcp,1234:udp,47 --trust=eth0,eth1 --service=ptp,syslog,ssh --remove-service=tftp,ssh"
        ks_out = """
        # Firewall configuration
        firewall --enabled --port=imap:tcp,1234:udp,47:tcp --trust=eth0,eth1 --service=ptp,syslog,ssh --remove-service=tftp,ssh
        # Network information
        network  --hostname=localhost.localdomain
        """
        self._test_kickstart(ks_in, ks_out)

    def kickstart_firewall_disable_test(self):
        """Test firewall --disabled."""
        ks_in = "firewall --disabled"
        ks_out = """
        # Firewall configuration
        firewall --disabled
        # Network information
        network  --hostname=localhost.localdomain
        """
        self._test_kickstart(ks_in, ks_out)

    def kickstart_firewall_disable_with_options_test(self):
        """Test firewall --disabled with options."""
        # apparently Pykickstart dumps any additional options if --disabled is used
        ks_in = "firewall --disable --port=imap:tcp,1234:udp,47 --trust=eth0,eth1 --service=ptp,syslog,ssh --remove-service=tftp,ssh"
        ks_out = """
        # Firewall configuration
        firewall --disabled
        # Network information
        network  --hostname=localhost.localdomain
        """
        self._test_kickstart(ks_in, ks_out)

    def kickstart_firewall_use_system_defaults_test(self):
        """Test firewall --use-system-defaults."""
        ks_in = "firewall --use-system-defaults"
        ks_out = """
        # Firewall configuration
        firewall --use-system-defaults
        # Network information
        network  --hostname=localhost.localdomain
        """
        self._test_kickstart(ks_in, ks_out)

    def kickstart_firewall_use_system_defaults_with_options_test(self):
        """Test firewall --use-system-defaults."""
        # looks like --use-system-defaults also eats any additional options
        ks_in = "firewall --use-system-defaults --port=imap:tcp,1234:udp,47 --trust=eth0,eth1 --service=ptp,syslog,ssh --remove-service=tftp,ssh"
        ks_out = """
        # Firewall configuration
        firewall --use-system-defaults
        # Network information
        network  --hostname=localhost.localdomain
        """
        self._test_kickstart(ks_in, ks_out)

    def kickstart_firewall_service_options_test(self):
        """Test firewall with individual service options.

        The firewall command supports enabling some well known services, such as ssh or smtp, via dedicated
        options. The services should then end up in the --service list in the output.
        """
        ks_in = "firewall --ftp --http --smtp --ssh"
        ks_out = """
        # Firewall configuration
        firewall --enabled --service=ftp,http,smtp,ssh
        # Network information
        network  --hostname=localhost.localdomain
        """
        self._test_kickstart(ks_in, ks_out)

    def default_requirements_test(self):
        """Test that by default no packages are required by the network module."""
        self.assertEqual(self.network_interface.CollectRequirements(), [])

    def kickstart_firewall_package_requirements_test(self):
        """Test that firewall command in kickstart results in request for firewalld package."""

        ks_in = "firewall --ftp --http --smtp --ssh"
        ks_out = """
        # Firewall configuration
        firewall --enabled --service=ftp,http,smtp,ssh
        # Network information
        network  --hostname=localhost.localdomain
        """
        self._test_kickstart(ks_in, ks_out)
        self.assertEqual(self.network_interface.CollectRequirements(), [{
            "type":
            get_variant(Str, "package"),
            "name":
            get_variant(Str, "firewalld"),
            "reason":
            get_variant(Str, "Requested by the firewall kickstart command.")
        }])

    def teamd_requirements_test(self):
        """Test that mocked team devices result in request for teamd package."""

        # mock a team device
        self.network_module.nm_client = Mock()
        self.__mock_nm_client_devices([("team0", None, "33:33:33:33:33:33",
                                        NM.DeviceType.TEAM)])

        # check that the teamd package is requested
        self.assertEqual(self.network_interface.CollectRequirements(), [{
            "type":
            get_variant(Str, "package"),
            "name":
            get_variant(Str, "teamd"),
            "reason":
            get_variant(Str,
                        "Necessary for network team device configuration.")
        }])
Esempio n. 2
0
class UsersInterfaceTestCase(unittest.TestCase):
    """Test DBus interface for the users module."""
    def setUp(self):
        """Set up the user module."""
        # Set up the users module.
        self.users_module = UsersService()
        self.users_interface = UsersInterface(self.users_module)

        # Connect to the properties changed signal.
        self.callback = PropertiesChangedCallback()
        self.users_interface.PropertiesChanged.connect(self.callback)

    def kickstart_properties_test(self):
        """Test kickstart properties."""
        self.assertEqual(self.users_interface.KickstartCommands,
                         ["rootpw", "user", "group", "sshkey"])
        self.assertEqual(self.users_interface.KickstartSections, [])
        self.assertEqual(self.users_interface.KickstartAddons, [])
        self.callback.assert_not_called()

    def _check_dbus_property(self, *args, **kwargs):
        check_dbus_property(self, USERS, self.users_interface, *args, **kwargs)

    def default_property_values_test(self):
        """Test the default user module values are as expected."""
        self.assertEqual(self.users_interface.Users, [])
        self.assertEqual(self.users_interface.Groups, [])
        self.assertEqual(self.users_interface.SshKeys, [])
        self.assertEqual(self.users_interface.RootPassword, "")
        self.assertEqual(self.users_interface.IsRootPasswordSet, False)
        self.assertEqual(self.users_interface.IsRootAccountLocked, True)
        self.assertEqual(self.users_interface.IsRootPasswordCrypted, False)
        self.assertEqual(self.users_interface.RootPasswordSSHLoginAllowed,
                         False)
        self.assertEqual(self.users_interface.CanChangeRootPassword, True)

    def users_property_test(self):
        """Test the Users property."""
        user_1 = {
            "name": get_variant(Str, "user1"),
            "uid-mode": get_variant(Str, ID_MODE_USE_VALUE),
            "uid": get_variant(UInt32, 123),
            "groups": get_variant(List[Str], ["foo", "bar"]),
            "gid-mode": get_variant(Str, ID_MODE_USE_VALUE),
            "gid": get_variant(UInt32, 321),
            "homedir": get_variant(Str, "user1_home"),
            "password": get_variant(Str, "swordfish"),
            "is-crypted": get_variant(Bool, False),
            "lock": get_variant(Bool, False),
            "shell": get_variant(Str, "zsh"),
            "gecos": get_variant(Str, "some stuff"),
        }
        user_2 = {
            "name": get_variant(Str, "user2"),
            "uid-mode": get_variant(Str, ID_MODE_USE_DEFAULT),
            "uid": get_variant(UInt32, 456),
            "groups": get_variant(List[Str], ["baz", "bar"]),
            "gid-mode": get_variant(Str, ID_MODE_USE_DEFAULT),
            "gid": get_variant(UInt32, 654),
            "homedir": get_variant(Str, "user2_home"),
            "password": get_variant(Str, "laksdjaskldjhasjhd"),
            "is-crypted": get_variant(Bool, True),
            "lock": get_variant(Bool, False),
            "shell": get_variant(Str, "csh"),
            "gecos": get_variant(Str, "some other stuff"),
        }
        self._check_dbus_property("Users", [user_1, user_2])

    def groups_property_test(self):
        """Test the Groups property."""
        group_1 = {
            "name": get_variant(Str, "group1"),
            "gid-mode": get_variant(Str, ID_MODE_USE_VALUE),
            "gid": get_variant(UInt32, 321),
        }
        group_2 = {
            "name": get_variant(Str, "group2"),
            "gid-mode": get_variant(Str, ID_MODE_USE_DEFAULT),
            "gid": get_variant(UInt32, 654),
        }
        self._check_dbus_property("Groups", [group_1, group_2])

    def ssh_keys_property_test(self):
        """Test the SshKeys property."""
        key_1 = {
            "key": get_variant(Str, "aaa"),
            "username": get_variant(Str, "user1"),
        }
        key_2 = {
            "key": get_variant(Str, "bbb"),
            "username": get_variant(Str, "user2"),
        }
        self._check_dbus_property("SshKeys", [key_1, key_2])

    def set_crypted_roopw_test(self):
        """Test if setting crypted root password works correctly."""
        self.users_interface.SetCryptedRootPassword("abcef")

        self.assertEqual(self.users_interface.RootPassword, "abcef")
        self.assertEqual(self.users_interface.IsRootPasswordCrypted, True)
        self.assertEqual(self.users_interface.IsRootPasswordSet, True)
        self.assertEqual(self.users_interface.IsRootAccountLocked, True)
        self.callback.assert_called_once_with(USERS.interface_name,
                                              {'IsRootPasswordSet': True}, [])

    def set_crypted_roopw_and_unlock_test(self):
        """Test if setting crypted root password & unlocking it from kickstart works correctly."""
        self.users_interface.SetCryptedRootPassword("abcef")

        self.assertEqual(self.users_interface.IsRootPasswordSet, True)
        self.assertEqual(self.users_interface.IsRootAccountLocked, True)
        self.assertEqual(self.users_interface.CanChangeRootPassword, True)
        self.callback.assert_called_once_with(USERS.interface_name,
                                              {'IsRootPasswordSet': True}, [])

        # this should not be a valid admin user for interactive install
        self.assertFalse(self.users_interface.CheckAdminUserExists())

        # root password is locked by default and remains locked even after a password is set
        # and needs to be unlocked via another DBus API call
        self.users_interface.SetRootAccountLocked(False)

        self.assertEqual(self.users_interface.IsRootPasswordSet, True)
        self.assertEqual(self.users_interface.IsRootAccountLocked, False)
        self.callback.assert_called_with(USERS.interface_name,
                                         {'IsRootAccountLocked': False}, [])

    def lock_root_account_test(self):
        """Test if root account can be locked via DBus correctly."""
        self.users_interface.SetRootAccountLocked(True)

        self.assertEqual(self.users_interface.IsRootPasswordSet, False)
        self.assertEqual(self.users_interface.IsRootAccountLocked, True)
        self.callback.assert_called_once_with(USERS.interface_name,
                                              {'IsRootAccountLocked': True},
                                              [])

    def clear_rootpw_test(self):
        """Test clearing of the root password."""
        # set the password to something
        self.users_interface.SetCryptedRootPassword("abcef")

        self.assertEqual(self.users_interface.IsRootPasswordSet, True)
        self.assertEqual(self.users_interface.IsRootAccountLocked, True)
        self.callback.assert_called_once_with(USERS.interface_name,
                                              {'IsRootPasswordSet': True}, [])

        # clear it
        self.users_interface.ClearRootPassword()

        # check if it looks cleared
        self.assertEqual(self.users_interface.IsRootPasswordSet, False)
        self.assertEqual(self.users_interface.IsRootAccountLocked, True)
        self.callback.assert_called_with(USERS.interface_name, {
            'IsRootPasswordSet': False,
            'IsRootAccountLocked': True
        }, [])

    def clear_unlocked_rootpw_test(self):
        """Test clearing of unlocked root password."""
        # set the password to something
        self.users_interface.SetCryptedRootPassword("abcef")
        self.callback.assert_called_once_with(USERS.interface_name,
                                              {'IsRootPasswordSet': True}, [])

        self.users_interface.SetRootAccountLocked(False)
        self.callback.assert_called_with(USERS.interface_name,
                                         {'IsRootAccountLocked': False}, [])

        self.assertEqual(self.users_interface.IsRootPasswordSet, True)
        self.assertEqual(self.users_interface.IsRootAccountLocked, False)

        # clear it
        self.users_interface.ClearRootPassword()

        # check if it looks cleared
        self.assertEqual(self.users_interface.IsRootPasswordSet, False)
        self.assertEqual(self.users_interface.IsRootAccountLocked, True)
        self.callback.assert_called_with(USERS.interface_name, {
            'IsRootPasswordSet': False,
            'IsRootAccountLocked': True
        }, [])

    def allow_root_password_ssh_login_test(self):
        """Test if root password SSH login can be allowed."""
        self.users_interface.SetRootPasswordSSHLoginAllowed(True)
        self.assertEqual(self.users_interface.RootPasswordSSHLoginAllowed,
                         True)
        self.callback.assert_called_once_with(
            USERS.interface_name, {'RootPasswordSSHLoginAllowed': True}, [])

        self.callback.reset_mock()
        self.users_interface.SetRootPasswordSSHLoginAllowed(False)
        self.assertEqual(self.users_interface.RootPasswordSSHLoginAllowed,
                         False)
        self.callback.assert_called_once_with(
            USERS.interface_name, {'RootPasswordSSHLoginAllowed': False}, [])

    def admin_user_detection_1_test(self):
        """Test that admin user detection works correctly - 3 admins."""
        # 2 admin users, unlocked root
        user1 = UserData()
        user1.name = "user1"
        user1.groups = ["foo", "wheel", "bar"]
        user1.lock = False

        user2 = UserData()
        user2.name = "user2"
        user2.groups = ["baz", "bar", "wheel"]
        user2.lock = False

        self.users_interface.SetUsers(
            UserData.to_structure_list([user1, user2]))
        self.users_interface.SetCryptedRootPassword("abc")
        self.users_interface.SetRootAccountLocked(False)
        self.assertTrue(self.users_interface.CheckAdminUserExists())

    def admin_user_detection_2_test(self):
        """Test that admin user detection works correctly - 0 admins (case 1)."""
        # 2 locked admin users, locked root
        user1 = UserData()
        user1.name = "user1"
        user1.groups = ["foo", "wheel", "bar"]
        user1.lock = True

        user2 = UserData()
        user2.name = "user2"
        user2.groups = ["baz", "bar", "wheel"]
        user2.lock = True

        self.users_interface.SetUsers(
            UserData.to_structure_list([user1, user2]))
        self.users_interface.SetCryptedRootPassword("abc")
        self.users_interface.SetRootAccountLocked(True)
        self.assertFalse(self.users_interface.CheckAdminUserExists())

    def admin_user_detection_3_test(self):
        """Test that admin user detection works correctly - 1 admin (case 2)."""
        # 2 locked admin users, unlocked root
        user1 = UserData()
        user1.name = "user1"
        user1.groups = ["foo", "wheel", "bar"]
        user1.lock = True

        user2 = UserData()
        user2.name = "user2"
        user2.groups = ["baz", "bar", "wheel"]
        user2.lock = True

        self.users_interface.SetUsers(
            UserData.to_structure_list([user1, user2]))
        self.users_interface.SetCryptedRootPassword("abc")
        self.users_interface.SetRootAccountLocked(False)
        self.assertTrue(self.users_interface.CheckAdminUserExists())

    def admin_user_detection_4_test(self):
        """Test that admin user detection works correctly - 1 admin (case 3)."""
        # 1 locked admin user, 1 unlocked admin user, locked root
        user1 = UserData()
        user1.name = "user1"
        user1.groups = ["foo", "wheel", "bar"]
        user1.lock = False

        user2 = UserData()
        user2.name = "user2"
        user2.groups = ["baz", "bar", "wheel"]
        user2.lock = True

        self.users_interface.SetUsers(
            UserData.to_structure_list([user1, user2]))
        self.users_interface.SetCryptedRootPassword("abc")
        self.users_interface.SetRootAccountLocked(True)
        self.assertTrue(self.users_interface.CheckAdminUserExists())

    def admin_user_detection_5_test(self):
        """Test that admin user detection works correctly - 1 admin (case 4)."""
        # 1 user, 1 unlocked admin user, locked root
        user1 = UserData()
        user1.name = "user1"
        user1.groups = ["foo", "bar"]
        user1.lock = False

        user2 = UserData()
        user2.name = "user2"
        user2.groups = ["baz", "bar", "wheel"]
        user2.lock = False

        self.users_interface.SetUsers(
            UserData.to_structure_list([user1, user2]))
        self.users_interface.SetCryptedRootPassword("abc")
        self.users_interface.SetRootAccountLocked(True)
        self.assertTrue(self.users_interface.CheckAdminUserExists())

    def admin_user_detection_6_test(self):
        """Test that admin user detection works correctly - 1 admin (case 5)."""
        # 2 users, unlocked root
        user1 = UserData()
        user1.name = "user1"
        user1.groups = ["foo", "bar"]
        user1.lock = False

        user2 = UserData()
        user2.name = "user2"
        user2.groups = ["baz", "bar"]
        user2.lock = False

        self.users_interface.SetUsers(
            UserData.to_structure_list([user1, user2]))
        self.users_interface.SetCryptedRootPassword("abc")
        self.users_interface.SetRootAccountLocked(False)
        self.assertTrue(self.users_interface.CheckAdminUserExists())

    def _test_kickstart(self, ks_in, ks_out, ks_tmp=None):
        check_kickstart_interface(self,
                                  self.users_interface,
                                  ks_in,
                                  ks_out,
                                  ks_tmp=ks_tmp)

    def no_kickstart_test(self):
        """Test with no kickstart."""
        ks_in = None
        ks_out = """
        #Root password
        rootpw --lock
        """
        self._test_kickstart(ks_in, ks_out)

        # root password should be empty and locked by default, but mutable
        self.assertEqual(self.users_interface.IsRootPasswordSet, False)
        self.assertEqual(self.users_interface.IsRootAccountLocked, True)
        self.assertEqual(self.users_interface.CanChangeRootPassword, True)

        # this should not be considered a valid admin user for interactive install
        self.assertFalse(self.users_interface.CheckAdminUserExists())

    def kickstart_empty_test(self):
        """Test with empty string."""
        ks_in = ""
        ks_out = """
        #Root password
        rootpw --lock
        """
        self._test_kickstart(ks_in, ks_out)

        # password should be marked as not set, locked and mutable
        self.assertEqual(self.users_interface.IsRootPasswordSet, False)
        self.assertEqual(self.users_interface.IsRootAccountLocked, True)
        self.assertEqual(self.users_interface.CanChangeRootPassword, True)

        # not a valid admin user from kickstart PoV
        self.assertFalse(self.users_interface.CheckAdminUserExists())

    def kickstart_set_rootpw_test(self):
        """Test the setting root password via kickstart."""
        ks_in = """
        rootpw abcdef
        """
        ks_out = """
        # Root password
        rootpw --plaintext abcdef
        """
        self._test_kickstart(ks_in, ks_out)

        # if rootpw shows up in the kickstart is should be reported as immutable
        self.assertEqual(self.users_interface.IsRootPasswordSet, True)
        self.assertEqual(self.users_interface.IsRootAccountLocked, False)
        self.assertEqual(self.users_interface.CanChangeRootPassword, False)

        # but this should still be a valid admin user from kickstart PoV
        self.assertTrue(self.users_interface.CheckAdminUserExists())

    def kickstart_set_plain_rootpw_test(self):
        """Test the setting plaintext root password via kickstart."""
        ks_in = """
        rootpw --plaintext abcdef
        """
        ks_out = """
        # Root password
        rootpw --plaintext abcdef
        """
        self._test_kickstart(ks_in, ks_out)

    def kickstart_set_crypted_rootpw_test(self):
        """Test the setting crypted root password via kickstart."""
        ks_in = """
        rootpw --iscrypted abcdef
        """
        ks_out = """
        # Root password
        rootpw --iscrypted abcdef
        """
        self._test_kickstart(ks_in, ks_out)

        self.assertEqual(self.users_interface.IsRootPasswordSet, True)
        self.assertEqual(self.users_interface.IsRootAccountLocked, False)

    def kickstart_lock_root_account_test(self):
        """Test locking the root account via kickstart."""
        ks_in = """
        rootpw --lock
        """
        ks_out = """
        #Root password
        rootpw --lock
        """
        self._test_kickstart(ks_in, ks_out)

        # password should be marked as not set, locked and immutable
        self.assertEqual(self.users_interface.IsRootPasswordSet, False)
        self.assertEqual(self.users_interface.IsRootAccountLocked, True)
        self.assertEqual(self.users_interface.CanChangeRootPassword, False)

        # but this should still be a valid admin user from kickstart PoV
        self.assertTrue(self.users_interface.CheckAdminUserExists())

    def kickstart_lock_root_account_with_password_test(self):
        """Test locking the root account with a password via kickstart."""
        ks_in = """
        rootpw abcdef --lock
        """
        ks_out = """
        # Root password
        rootpw --lock --plaintext abcdef
        """
        self._test_kickstart(ks_in, ks_out)

        # password should be marked as set, locked and immutable
        self.assertEqual(self.users_interface.IsRootPasswordSet, True)
        self.assertEqual(self.users_interface.IsRootAccountLocked, True)
        self.assertEqual(self.users_interface.CanChangeRootPassword, False)

        # but this should still be a valid admin user from kickstart PoV
        self.assertTrue(self.users_interface.CheckAdminUserExists())

    def kickstart_user_test(self):
        """Test kickstart user input and output."""
        ks_in = """
        user --name=user1 --password=abcedf
        """
        ks_out = """
        #Root password
        rootpw --lock
        user --name=user1 --password=abcedf
        """
        self._test_kickstart(ks_in, ks_out)

        # password should be marked as not set, locked and mutable
        self.assertEqual(self.users_interface.IsRootPasswordSet, False)
        self.assertEqual(self.users_interface.IsRootAccountLocked, True)
        self.assertEqual(self.users_interface.CanChangeRootPassword, True)

        # no a valid admin user exists from kickstart PoV
        self.assertFalse(self.users_interface.CheckAdminUserExists())

    def kickstart_user_admin_test(self):
        """Test kickstart admin user input and output."""
        ks_in = """
        user --groups=wheel --name=user1 --password=abcedf
        """
        ks_out = """
        #Root password
        rootpw --lock
        user --groups=wheel --name=user1 --password=abcedf
        """
        self._test_kickstart(ks_in, ks_out)

        # password should be marked as not set, locked and mutable
        self.assertEqual(self.users_interface.IsRootPasswordSet, False)
        self.assertEqual(self.users_interface.IsRootAccountLocked, True)
        self.assertEqual(self.users_interface.CanChangeRootPassword, True)

        # provides a valid admin user exists from kickstart PoV
        self.assertTrue(self.users_interface.CheckAdminUserExists())

    def kickstart_users_test(self):
        """Test kickstart users input and output."""
        ks_in = """
        user --name=user1 --homedir=user1_home --password=foo --shell=ksh --uid=123 --gecos=baz --gid=345 --groups=a,b,c,d --plaintext
        user --name=user2 --homedir=user2_home --password=asasas --shell=csh --uid=321 --gecos=bar --gid=543 --groups=wheel,mockuser --iscrypted
        user --name=user3 --lock
        """
        ks_out = """
        #Root password
        rootpw --lock
        user --groups=a,b,c,d --homedir=user1_home --name=user1 --password=foo --shell=ksh --uid=123 --gecos="baz" --gid=345
        user --groups=wheel,mockuser --homedir=user2_home --name=user2 --password=asasas --iscrypted --shell=csh --uid=321 --gecos="bar" --gid=543
        user --name=user3 --lock
        """
        self._test_kickstart(ks_in, ks_out)

    def kickstart_groups_test(self):
        """Test kickstart groups input and output."""
        ks_in = """
        group --name=group1 --gid=321
        group --name=group2 --gid=654
        group --name=group3
        """
        ks_out = """
        group --name=group1 --gid=321
        group --name=group2 --gid=654
        group --name=group3
        #Root password
        rootpw --lock
        """
        self._test_kickstart(ks_in, ks_out)

    def kickstart_ssh_keys_test(self):
        """Test kickstart ssh keys input and output."""
        ks_in = """
        sshkey --username=user1 "aaa"
        sshkey --username=user2 "bbb"
        sshkey --username=user3 "ccc"
        """
        ks_out = """
        #Root password
        rootpw --lock
        sshkey --username=user1 "aaa"
        sshkey --username=user2 "bbb"
        sshkey --username=user3 "ccc"
        """
        self._test_kickstart(ks_in, ks_out)

    @patch_dbus_publish_object
    def install_with_tasks_test(self, publisher):
        """Test InstallWithTasks."""
        task_classes = [
            CreateGroupsTask, CreateUsersTask, SetRootPasswordTask,
            SetSshKeysTask, ConfigureRootPasswordSSHLoginTask
        ]
        task_paths = self.users_interface.InstallWithTasks()
        check_task_creation_list(self, task_paths, publisher, task_classes)

    @patch_dbus_publish_object
    def configure_groups_with_task_test(self, publisher):
        """Test ConfigureGroupsWithTask."""
        task_path = self.users_interface.ConfigureGroupsWithTask()
        check_task_creation(self, task_path, publisher, CreateGroupsTask)

    @patch_dbus_publish_object
    def configure_users_with_task_test(self, publisher):
        """Test ConfigureUsersWithTask."""
        task_path = self.users_interface.ConfigureUsersWithTask()
        check_task_creation(self, task_path, publisher, CreateUsersTask)

    @patch_dbus_publish_object
    def set_root_password_with_task_test(self, publisher):
        """Test SetRootPasswordWithTask."""
        task_path = self.users_interface.SetRootPasswordWithTask()
        check_task_creation(self, task_path, publisher, SetRootPasswordTask)
Esempio n. 3
0
class ServicesInterfaceTestCase(unittest.TestCase):
    """Test DBus interface for the services module."""
    def setUp(self):
        """Set up the services module."""
        # Set up the services module.
        self.services_module = ServicesService()
        self.services_interface = ServicesInterface(self.services_module)

        # Connect to the properties changed signal.
        self.callback = PropertiesChangedCallback()
        self.services_interface.PropertiesChanged.connect(self.callback)

    def kickstart_properties_test(self):
        """Test kickstart properties."""
        self.assertEqual(self.services_interface.KickstartCommands,
                         ["firstboot", "services", "skipx", "xconfig"])
        self.assertEqual(self.services_interface.KickstartSections, [])
        self.assertEqual(self.services_interface.KickstartAddons, [])
        self.callback.assert_not_called()

    def enabled_services_property_test(self):
        """Test the enabled services property."""
        self.services_interface.SetEnabledServices(["a", "b", "c"])
        self.assertEqual(self.services_interface.EnabledServices,
                         ["a", "b", "c"])
        self.callback.assert_called_once_with(
            SERVICES.interface_name, {'EnabledServices': ["a", "b", "c"]}, [])

    def disabled_services_property_test(self):
        """Test the disabled services property."""
        self.services_interface.SetDisabledServices(["a", "b", "c"])
        self.assertEqual(self.services_interface.DisabledServices,
                         ["a", "b", "c"])
        self.callback.assert_called_once_with(
            SERVICES.interface_name, {'DisabledServices': ["a", "b", "c"]}, [])

    def default_target_property_default_graphical_test(self):
        """Test the default target property - default value."""
        self.callback.assert_not_called()
        self.assertEqual(self.services_interface.DefaultTarget, "")

    def default_target_property_graphical_test(self):
        """Test the default target property - set graphical target."""
        self.services_interface.SetDefaultTarget(GRAPHICAL_TARGET)
        self.assertEqual(self.services_interface.DefaultTarget,
                         GRAPHICAL_TARGET)
        self.callback.assert_called_once_with(
            SERVICES.interface_name, {'DefaultTarget': GRAPHICAL_TARGET}, [])

    def default_target_property_text_test(self):
        """Test the default target property - set text target."""
        self.services_interface.SetDefaultTarget(TEXT_ONLY_TARGET)
        self.assertEqual(self.services_interface.DefaultTarget,
                         TEXT_ONLY_TARGET)
        self.callback.assert_called_once_with(
            SERVICES.interface_name, {'DefaultTarget': TEXT_ONLY_TARGET}, [])

    def default_desktop_property_test(self):
        """Test the default desktop property."""
        self.services_interface.SetDefaultDesktop("KDE")
        self.assertEqual(self.services_interface.DefaultDesktop, "KDE")
        self.callback.assert_called_once_with(SERVICES.interface_name,
                                              {'DefaultDesktop': "KDE"}, [])

    def setup_on_boot_property_test(self):
        """Test the setup on boot property."""
        self.services_interface.SetSetupOnBoot(SETUP_ON_BOOT_DISABLED)
        self.assertEqual(self.services_interface.SetupOnBoot,
                         SETUP_ON_BOOT_DISABLED)
        self.callback.assert_called_once_with(
            SERVICES.interface_name, {'SetupOnBoot': SETUP_ON_BOOT_DISABLED},
            [])

    def post_install_tools_disabled_test(self):
        """Test the post-install-tools-enabled property."""
        # should not be marked as disabled by default
        self.assertEqual(self.services_interface.PostInstallToolsEnabled, True)
        # mark as disabled
        self.services_interface.SetPostInstallToolsEnabled(False)
        self.assertEqual(self.services_interface.PostInstallToolsEnabled,
                         False)
        self.callback.assert_called_once_with(
            SERVICES.interface_name, {'PostInstallToolsEnabled': False}, [])
        # mark as not disabled again
        self.services_interface.SetPostInstallToolsEnabled(True)
        self.assertEqual(self.services_interface.PostInstallToolsEnabled, True)
        self.callback.assert_called_with(SERVICES.interface_name,
                                         {'PostInstallToolsEnabled': True}, [])

    def _test_kickstart(self, ks_in, ks_out):
        check_kickstart_interface(self, self.services_interface, ks_in, ks_out)

    def no_kickstart_test(self):
        """Test with no kickstart."""
        ks_in = None
        ks_out = ""
        self._test_kickstart(ks_in, ks_out)
        self.assertEqual(self.services_interface.SetupOnBoot,
                         SETUP_ON_BOOT_DEFAULT)
        self.assertEqual(self.services_interface.PostInstallToolsEnabled, True)

    def kickstart_empty_test(self):
        """Test with empty string."""
        ks_in = ""
        ks_out = ""
        self._test_kickstart(ks_in, ks_out)
        self.assertEqual(self.services_interface.SetupOnBoot,
                         SETUP_ON_BOOT_DEFAULT)
        self.assertEqual(self.services_interface.PostInstallToolsEnabled, True)

    def services_kickstart_test(self):
        """Test the services command."""
        ks_in = """
        services --disabled=a,b,c --enabled=d,e,f
        """
        ks_out = """
        # System services
        services --disabled="a,b,c" --enabled="d,e,f"
        """
        self._test_kickstart(ks_in, ks_out)

    def skipx_kickstart_test(self):
        """Test the skipx command."""
        ks_in = """
        skipx
        """
        ks_out = """
        # Do not configure the X Window System
        skipx
        """
        self._test_kickstart(ks_in, ks_out)

    def xconfig_kickstart_test(self):
        """Test the xconfig command."""
        ks_in = """
        xconfig --defaultdesktop GNOME --startxonboot
        """
        ks_out = """
        # X Window System configuration information
        xconfig  --defaultdesktop=GNOME --startxonboot
        """
        self._test_kickstart(ks_in, ks_out)

    def firstboot_disabled_kickstart_test(self):
        """Test the firstboot command - disabled."""
        ks_in = """
        firstboot --disable
        """
        ks_out = """
        firstboot --disable
        """
        self._test_kickstart(ks_in, ks_out)
        self.assertEqual(self.services_interface.SetupOnBoot,
                         SETUP_ON_BOOT_DISABLED)
        self.assertEqual(self.services_interface.PostInstallToolsEnabled,
                         False)

    def firstboot_enabled_kickstart_test(self):
        """Test the firstboot command - enabled."""
        ks_in = """
        firstboot --enable
        """
        ks_out = """
        # Run the Setup Agent on first boot
        firstboot --enable
        """
        self._test_kickstart(ks_in, ks_out)
        self.assertEqual(self.services_interface.SetupOnBoot,
                         SETUP_ON_BOOT_ENABLED)
        self.assertEqual(self.services_interface.PostInstallToolsEnabled, True)

    def firstboot_reconfig_kickstart_test(self):
        """Test the firstboot command - reconfig."""
        ks_in = """
        firstboot --reconfig
        """
        ks_out = """
        # Run the Setup Agent on first boot
        firstboot --reconfig
        """
        self._test_kickstart(ks_in, ks_out)
        self.assertEqual(self.services_interface.SetupOnBoot,
                         SETUP_ON_BOOT_RECONFIG)
        self.assertEqual(self.services_interface.PostInstallToolsEnabled, True)