#!/usr/bin/python3 # # Copyright (C) 2022 Red Hat, Inc. # SPDX-License-Identifier: LGPL-2.1-or-later from anacondalib import VirtInstallMachineCase, pixel_tests_ignore from installer import Installer from password import Password from review import Review from testlib import nondestructive, test_main # pylint: disable=import-error from users import CREATE_ACCOUNT_ID_PREFIX, Users, create_user @nondestructive class TestUsers(VirtInstallMachineCase): def testBasic(self): """ Description: Test the basic functionality of the user creation screen Expected results: - A new user can be created - The root account can be enabled and a root password set - The user can skip creating a user account - The user can skip enabling the root account - The user can't skip both """ b = self.browser i = Installer(b, self.machine) u = Users(b, self.machine) r = Review(b, self.machine) i.open() i.reach(i.steps.ACCOUNTS) # Check skipping root account enablement create_user(b, self.machine) # Wait for the form to be ready before taking a screenshot i.check_next_disabled(False) b.assert_pixels( "#app", "users-step-basic", ignore=pixel_tests_ignore, ) i.reach(i.steps.REVIEW) users = u.dbus_get_users() self.assertIn('"groups" as 1 "wheel"', users) self.assertIn('"is-crypted" b true', users) self.assertIn("tester", users) assert u.dbus_get_root_locked() assert not u.dbus_get_is_root_password_set() r.check_account("tester") # Check skipping user account creation i.reach_on_sidebar(i.steps.ACCOUNTS) u.enable_user_account(False) u.enable_root_account(True) u.set_valid_root_password() i.next() r.check_account("Root account is enabled, but no user account has been configured") assert not u.dbus_get_root_locked() assert u.dbus_get_is_root_password_set() users = u.dbus_get_users() assert "tester" not in users # Check skipping both user and root account creation i.reach_on_sidebar(i.steps.ACCOUNTS) u.enable_user_account(False) u.enable_root_account(False) i.check_next_disabled() @staticmethod def _test_user_name(user, installer, valid, invalid): installer.check_next_disabled(disabled=False) n_valid = len(valid) - 1 n_invalid = len(invalid) - 1 # Set valid and invalid value in turns and check the next button for i in range(max(n_valid, n_invalid)): i_valid = min(i, n_valid) i_invalid = min(i, n_invalid) user.set_user_name(invalid[i_invalid]) installer.check_next_disabled() user.set_user_name(valid[i_valid]) installer.check_next_disabled(disabled=False) def testAccessAndValidation(self): """ Description: Test the access and validation of the user creation screen Expected results: - The forward / back navigation keeps the values inserted - Invalid values for user name, password and full name are detected - The next button is disabled when the values are invalid - Password strength is shown - The username is autogenerated from the full name """ b = self.browser i = Installer(b, self.machine) p = Password(b, CREATE_ACCOUNT_ID_PREFIX) u = Users(b, self.machine) i.open() i.reach(i.steps.ACCOUNTS) # Fill in valid values password = "password" full_name = "Full Tester" p.set_password(password) p.set_password_confirm(password) u.set_full_name(full_name) # Check auto-generated user name u.check_user_name("ftester") user_name = "tester" u.set_user_name(user_name) p.check_password(password) p.check_password_confirm(password) u.check_full_name(full_name) u.check_user_name(user_name) i.check_next_disabled(disabled=False) # Test that you can move forward and going back keeps values i.next() i.back() p.check_password(password) p.check_password_confirm(password) u.check_full_name(full_name) u.check_user_name(user_name) # Test that moving back and forward keeps values i.back() i.next() p.check_password(password) p.check_password_confirm(password) u.check_full_name(full_name) u.check_user_name(user_name) # Test full name validation u.set_full_name("") i.check_next_disabled(disabled=False) u.set_full_name("colon:isforbidden") i.check_next_disabled() u.set_full_name(full_name) i.check_next_disabled(disabled=False) # Test root password validation u.enable_root_account(True) i.check_next_disabled() u.set_valid_root_password() i.check_next_disabled(disabled=False) u.set_valid_root_password(valid=False) i.check_next_disabled() u.enable_root_account(False) i.check_next_disabled(disabled=False) # Test user name validation # FIXME this should be tested by unit tests? invalid_user_names = [ "", # reserved "root", "system", "daemon", "home", "33333", ".", "..", "-tester", "123", "$", "$tester", "tester?", "longer_than_32_characteeeeeeeeeeeeeeeeeeers", ] valid_user_names = [ "tester-", "...", "12.3", "tester1", "tester$", "test-er", "test_er", "test.er", "_tester", ".tester", "_", ] self._test_user_name(u, i, valid_user_names, invalid_user_names) u.set_user_name(user_name) # Test password validation # No password set - allowed in the default policy p.set_password("") p.set_password_confirm("") p.check_pw_rule("length", "indeterminate") p.check_pw_rule("match", "success") i.check_next_disabled(disabled=False) # Start which pw which is too short p.set_password("abcd") p.check_pw_strength(None) i.check_next_disabled() p.check_pw_rule("length", "error") p.check_pw_rule("match", "error") # Default non-strict policy: length is advisory; confirmation must match p.set_password_confirm("abcd") p.check_pw_rule("match", "success") p.check_pw_rule("length", "error") i.check_next_disabled(disabled=False) # Make the pw 6 chars long p.set_password("ef", append=True, value_check=False) i.check_next_disabled() p.check_password("abcdef") p.check_pw_rule("length", "success") p.check_pw_rule("match", "error") p.check_pw_strength("weak") # Set the password confirm p.set_password_confirm("abcde") p.check_pw_rule("match", "error") p.set_password_confirm("abcdef") p.check_pw_rule("match", "success") p.check_pw_rule("length", "success") p.check_pw_strength("weak") i.check_next_disabled(disabled=False) # Test password strength p.set_password("Rwce82ybF7dXtCzFumanchu!!!!!!!!") p.check_pw_strength("strong") # Test review values p.set_password(password) p.set_password_confirm(password) u.set_full_name(full_name) u.set_user_name(user_name) r = Review(b, self.machine) i.reach(i.steps.REVIEW) r.check_account(f"{full_name} ({user_name})") if __name__ == '__main__': test_main()