From 7a8eae027fe9e69b9cc4d35995a75ae4ff3f893b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Mudr=C3=A1k?= Date: Thu, 12 Aug 2021 11:49:30 +0200 Subject: [PATCH] MDL-72325 user: Introduce new core_user::awaiting_action() method The method allows to check if the user is fully ready to use the site or whether there is an action (such as filling the missing profile field, changing password or agreeing to the site policy) needed. --- lib/classes/user.php | 35 +++++++++++++++++++++++++++++ lib/tests/user_test.php | 49 +++++++++++++++++++++++++++++++++++++++++ lib/upgrade.txt | 3 +++ 3 files changed, 87 insertions(+) diff --git a/lib/classes/user.php b/lib/classes/user.php index 4e5de0f6855..774d5a807f0 100644 --- a/lib/classes/user.php +++ b/lib/classes/user.php @@ -1134,4 +1134,39 @@ class core_user { } } + /** + * Is the user expected to perform an action to start using Moodle properly? + * + * This covers cases such as filling the profile, changing password or agreeing to the site policy. + * + * @param stdClass $user User object, defaults to the current user. + * @return bool + */ + public static function awaiting_action(stdClass $user = null): bool { + global $USER; + + if ($user === null) { + $user = $USER; + } + + if (user_not_fully_set_up($user)) { + // Awaiting the user to fill all fields in the profile. + return true; + } + + if (get_user_preferences('auth_forcepasswordchange', false, $user)) { + // Awaiting the user to change their password. + return true; + } + + if (empty($user->policyagreed) && !is_siteadmin($user)) { + $manager = new \core_privacy\local\sitepolicy\manager(); + + if ($manager->is_defined(isguestuser($user))) { + return true; + } + } + + return false; + } } diff --git a/lib/tests/user_test.php b/lib/tests/user_test.php index e93eac3b6af..0b9f1d91aa2 100644 --- a/lib/tests/user_test.php +++ b/lib/tests/user_test.php @@ -770,4 +770,53 @@ class core_user_testcase extends advanced_testcase { $this->assertFalse(\core_user::is_real_user(core_user::get_support_user()->id, true)); } + /** + * Tests for the {@see \core_user::awaiting_action()} method. + */ + public function test_awaiting_action() { + global $CFG, $DB, $USER; + + $guest = \core_user::get_user($CFG->siteguest); + $student = $this->getDataGenerator()->create_user(); + $teacher = $this->getDataGenerator()->create_user(); + $manager = $this->getDataGenerator()->create_user(); + $admin = get_admin(); + + $this->getDataGenerator()->role_assign($DB->get_field('role', 'id', ['shortname' => 'manager']), + $manager->id, \context_system::instance()->id); + + // Scenario: Guests required to agree to site policy. + $this->assertFalse(\core_user::awaiting_action($guest)); + + $CFG->sitepolicyguest = 'https://example.com'; + $this->assertTrue(\core_user::awaiting_action($guest)); + + $guest->policyagreed = 1; + $this->assertFalse(\core_user::awaiting_action($guest)); + + // Scenario: Student required to fill their profile. + $this->assertFalse(\core_user::awaiting_action($student)); + + $student->firstname = ''; + $this->assertTrue(\core_user::awaiting_action($student)); + + $student->firstname = 'Alice'; + $this->assertFalse(\core_user::awaiting_action($student)); + + // Scenario: Teacher force to change their password. + $this->assertFalse(\core_user::awaiting_action($teacher)); + + set_user_preference('auth_forcepasswordchange', 1, $teacher); + $this->assertTrue(\core_user::awaiting_action($teacher)); + + unset_user_preference('auth_forcepasswordchange', $teacher); + $this->assertFalse(\core_user::awaiting_action($teacher)); + + // Scenario: Admins do not need to agree to the policy but others do. + $this->assertFalse(\core_user::awaiting_action($admin)); + $this->assertFalse(\core_user::awaiting_action($manager)); + $CFG->sitepolicy = 'https://example.com'; + $this->assertFalse(\core_user::awaiting_action($admin)); + $this->assertTrue(\core_user::awaiting_action($manager)); + } } diff --git a/lib/upgrade.txt b/lib/upgrade.txt index 2ba9d7d7497..77f88aad2f0 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -58,6 +58,9 @@ information provided here is intended especially for developers. completion_info::internal_set_data() to reaggregate completions that have been marked for instant course completion. * The following functions have been finally deprecated and can not be used anymore: - generate_uuid +* New method \core_user::awaiting_action() has been introduced to check if the user is fully ready to use the site or + whether there is an action (such as filling the missing profile field, changing password or agreeing to the site + policy) needed. === 3.11.2 === * For security reasons, filelib has been updated so all requests now use emulated redirects.