#!/usr/bin/python3## Copyright (C) 2022 Red Hat, Inc.# SPDX-License-Identifier: LGPL-2.1-or-laterfrom anacondalib import VirtInstallMachineCase, pixel_tests_ignorefrom installer import Installerfrom password import Passwordfrom review import Reviewfrom testlib import nondestructive, test_main # pylint: disable=import-errorfrom users import CREATE_ACCOUNT_ID_PREFIX, Users, create_user@nondestructiveclass TestUsers(VirtInstallMachineCase):def testBasic(self):"""Description:Test the basic functionality of the user creation screenExpected 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.browseri = 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 enablementcreate_user(b, self.machine)# Wait for the form to be ready before taking a screenshoti.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 creationi.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 creationi.reach_on_sidebar(i.steps.ACCOUNTS)u.enable_user_account(False)u.enable_root_account(False)i.check_next_disabled()@staticmethoddef _test_user_name(user, installer, valid, invalid):installer.check_next_disabled(disabled=False)n_valid = len(valid) - 1n_invalid = len(invalid) - 1# Set valid and invalid value in turns and check the next buttonfor 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 screenExpected 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.browseri = 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 valuespassword = "password"full_name = "Full Tester"p.set_password(password)p.set_password_confirm(password)u.set_full_name(full_name)# Check auto-generated user nameu.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 valuesi.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 valuesi.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 validationu.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 validationu.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 policyp.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 shortp.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 matchp.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 longp.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 confirmp.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 strengthp.set_password("Rwce82ybF7dXtCzFumanchu!!!!!!!!")p.check_pw_strength("strong")# Test review valuesp.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()