use core_privacy\local\metadata\collection;
use core_privacy\local\request\approved_contextlist;
+use core_privacy\local\request\approved_userlist;
use core_privacy\local\request\contextlist;
use core_privacy\local\request\moodle_content_writer;
+use core_privacy\local\request\userlist;
use core_privacy\local\request\transform;
use core_privacy\local\request\writer;
// This tool stores user data.
\core_privacy\local\metadata\provider,
+ // This plugin is capable of determining which users have data within it.
+ \core_privacy\local\request\core_userlist_provider,
+
// This tool may provide access to and deletion of user data.
\core_privacy\local\request\plugin\provider {
return $contextlist;
}
+ /**
+ * Get the list of users who have data within a context.
+ *
+ * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
+ */
+ public static function get_users_in_context(userlist $userlist) {
+ $context = $userlist->get_context();
+
+ // Users that have modified any policies, if fetching for system context.
+ if (is_a($context, \context_system::class)) {
+ $sql = "SELECT v.usermodified AS userid
+ FROM {tool_policy_versions} v";
+ $userlist->add_from_sql('userid', $sql, []);
+ }
+
+ // Users that have accepted any policies, if fetching for user context.
+ if (is_a($context, \context_user::class)) {
+ $sql = "SELECT a.userid, a.usermodified
+ FROM {tool_policy_acceptances} a
+ WHERE a.userid = :instanceid";
+ $params = ['instanceid' => $context->instanceid];
+
+ $userlist->add_from_sql('userid', $sql, $params);
+ $userlist->add_from_sql('usermodified', $sql, $params);
+ }
+ }
+
/**
* Export personal data for the given approved_contextlist. User and context information is contained within the contextlist.
*
public static function delete_data_for_user(approved_contextlist $contextlist) {
}
+ /**
+ * Delete multiple users within a single context.
+ *
+ * We never delete user agreements to the policies because they are part of privacy data.
+ * We never delete policy versions because they are part of privacy data.
+ *
+ * @param approved_userlist $userlist The approved context and user information to delete information for.
+ */
+ public static function delete_data_for_users(approved_userlist $userlist) {
+ }
+
/**
* Export all policy agreements relating to the specified user context.
*
/** @var stdClass The manager user object. */
protected $manager;
+/** @var context_system The system context instance. */
+ protected $syscontext;
+
/**
* Setup function. Will create a user.
*/
// Create manager user.
$this->manager = $generator->create_user();
- $syscontext = context_system::instance();
+ $this->syscontext = context_system::instance();
$rolemanagerid = create_role('Policy manager', 'policymanager', 'Can manage policy documents');
- assign_capability('tool/policy:managedocs', CAP_ALLOW, $rolemanagerid, $syscontext->id);
- assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $rolemanagerid, $syscontext->id);
- role_assign($rolemanagerid, $this->manager->id, $syscontext->id);
+ assign_capability('tool/policy:managedocs', CAP_ALLOW, $rolemanagerid, $this->syscontext->id);
+ assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $rolemanagerid, $this->syscontext->id);
+ role_assign($rolemanagerid, $this->manager->id, $this->syscontext->id);
accesslib_clear_all_caches_for_unit_testing();
}
$this->assertEquals(1, $contextlist->count());
}
+ /**
+ * Test getting the user IDs within the context related to this plugin.
+ */
+ public function test_get_users_in_context() {
+ global $CFG;
+ $component = 'tool_policy';
+
+ // System context should have nothing before a policy is added.
+ $userlist = new \core_privacy\local\request\userlist($this->syscontext, $component);
+ provider::get_users_in_context($userlist);
+ $this->assertEmpty($userlist);
+
+ // Create parent and child users.
+ $generator = $this->getDataGenerator();
+ $parentuser = $generator->create_user();
+ $childuser = $generator->create_user();
+
+ // Fetch relevant contexts.
+ $managercontext = \context_user::instance($this->manager->id);
+ $usercontext = $managercontext = \context_user::instance($this->user->id);
+ $parentcontext = $managercontext = \context_user::instance($parentuser->id);
+ $childcontext = $managercontext = \context_user::instance($childuser->id);
+
+ // Assign parent to accept on behalf of the child.
+ $roleparentid = create_role('Parent', 'parent', 'Can accept policies on behalf of their child');
+ assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $roleparentid, $this->syscontext->id);
+ role_assign($roleparentid, $parentuser->id, $childcontext->id);
+
+ // Create a policy.
+ $this->setUser($this->manager);
+ $CFG->sitepolicyhandler = 'tool_policy';
+ $policy = $this->add_policy();
+ api::make_current($policy->get('id'));
+
+ // Manager should exist in system context now they have created a policy.
+ $userlist = new \core_privacy\local\request\userlist($this->syscontext, $component);
+ provider::get_users_in_context($userlist);
+ $this->assertCount(1, $userlist);
+ $this->assertEquals([$this->manager->id], $userlist->get_userids());
+
+ // User contexts should be empty before policy acceptances.
+ $userlist = new \core_privacy\local\request\userlist($usercontext, $component);
+ provider::get_users_in_context($userlist);
+ $this->assertEmpty($userlist);
+
+ $userlist = new \core_privacy\local\request\userlist($parentcontext, $component);
+ provider::get_users_in_context($userlist);
+ $this->assertEmpty($userlist);
+
+ $userlist = new \core_privacy\local\request\userlist($childcontext, $component);
+ provider::get_users_in_context($userlist);
+ $this->assertEmpty($userlist);
+
+ // User accepts policy, parent accepts on behalf of child only.
+ $this->setUser($this->user);
+ api::accept_policies([$policy->get('id')]);
+
+ $this->setUser($parentuser);
+ api::accept_policies([$policy->get('id')], $childuser->id);
+
+ // Ensure user is fetched within its user context.
+ $userlist = new \core_privacy\local\request\userlist($usercontext, $component);
+ provider::get_users_in_context($userlist);
+ $this->assertCount(1, $userlist);
+ $this->assertEquals([$this->user->id], $userlist->get_userids());
+
+ // Ensure parent and child are both found within child's user context.
+ $userlist = new \core_privacy\local\request\userlist($childcontext, $component);
+ provider::get_users_in_context($userlist);
+ $this->assertCount(2, $userlist);
+ $expected = [$parentuser->id, $childuser->id];
+ $actual = $userlist->get_userids();
+ sort($expected);
+ sort($actual);
+ $this->assertEquals($expected, $actual);
+
+ // Parent has not accepted for itself, so should not be found within its user context.
+ $userlist = new \core_privacy\local\request\userlist($parentcontext, $component);
+ provider::get_users_in_context($userlist);
+ $this->assertCount(0, $userlist);
+ }
+
public function test_export_agreements() {
global $CFG;