From 0b28290a503075feeef1dd36730bc7b403826dcd Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Tue, 16 Oct 2018 12:39:59 +1100 Subject: [PATCH] MDL-63649 enrol_lti: support removal of multiple users in a context This issue is a part of the MDL-62560 Epic. --- enrol/lti/classes/privacy/provider.php | 51 +++++++++++- enrol/lti/tests/privacy_provider_test.php | 96 ++++++++++++++++++++++- 2 files changed, 144 insertions(+), 3 deletions(-) diff --git a/enrol/lti/classes/privacy/provider.php b/enrol/lti/classes/privacy/provider.php index a6ce277f463..83f284797a3 100644 --- a/enrol/lti/classes/privacy/provider.php +++ b/enrol/lti/classes/privacy/provider.php @@ -17,6 +17,7 @@ * Privacy Subsystem implementation for enrol_lti. * * @package enrol_lti + * @category privacy * @copyright 2018 Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -25,8 +26,10 @@ namespace enrol_lti\privacy; 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\transform; +use core_privacy\local\request\userlist; use core_privacy\local\request\writer; defined('MOODLE_INTERNAL') || die(); @@ -39,7 +42,8 @@ defined('MOODLE_INTERNAL') || die(); */ class provider implements \core_privacy\local\metadata\provider, - \core_privacy\local\request\plugin\provider { + \core_privacy\local\request\plugin\provider, + \core_privacy\local\request\core_userlist_provider { /** * Return the fields which contain personal data. @@ -84,6 +88,26 @@ class provider implements 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(); + + if (!($context instanceof \context_course || $context instanceof \context_module)) { + return; + } + + $sql = "SELECT ltiusers.userid + FROM {enrol_lti_users} ltiusers + JOIN {enrol_lti_tools} ltitools ON ltiusers.toolid = ltitools.id + WHERE ltitools.contextid = :contextid"; + $params = ['contextid' => $context->id]; + $userlist->add_from_sql('userid', $sql, $params); + } + /** * Export all user data for the specified user, in the specified contexts. * @@ -169,6 +193,31 @@ class provider implements } } + /** + * Delete multiple users within a single context. + * + * @param approved_userlist $userlist The approved context and user information to delete information for. + */ + public static function delete_data_for_users(approved_userlist $userlist) { + global $DB; + + $context = $userlist->get_context(); + + if (!($context instanceof \context_course || $context instanceof \context_module)) { + return; + } + + $enrolltitools = $DB->get_fieldset_select('enrol_lti_tools', 'id', 'contextid = :contextid', + ['contextid' => $context->id]); + if (!empty($enrolltitools)) { + list($toolsql, $toolparams) = $DB->get_in_or_equal($enrolltitools, SQL_PARAMS_NAMED); + $userids = $userlist->get_userids(); + list($usersql, $userparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED); + $params = $toolparams + $userparams; + $DB->delete_records_select('enrol_lti_users', "toolid $toolsql AND userid $usersql", $params); + } + } + /** * Loop and export from a recordset. * diff --git a/enrol/lti/tests/privacy_provider_test.php b/enrol/lti/tests/privacy_provider_test.php index 43f79325c30..984684cb1ca 100644 --- a/enrol/lti/tests/privacy_provider_test.php +++ b/enrol/lti/tests/privacy_provider_test.php @@ -40,6 +40,11 @@ class enrol_lti_privacy_provider_testcase extends \core_privacy\tests\provider_t */ protected $user = null; + /** + * @var stdClass Another user + */ + protected $anotheruser = null; + /** * @var stdClass The course */ @@ -70,8 +75,8 @@ class enrol_lti_privacy_provider_testcase extends \core_privacy\tests\provider_t $this->create_lti_users($cmcontext, $this->user->id); // Create another LTI user. - $user = $this->getDataGenerator()->create_user(); - $this->create_lti_users($coursecontext, $user->id); + $this->anotheruser = $this->getDataGenerator()->create_user(); + $this->create_lti_users($coursecontext, $this->anotheruser->id); } /** @@ -197,4 +202,91 @@ class enrol_lti_privacy_provider_testcase extends \core_privacy\tests\provider_t ]; $DB->insert_record('enrol_lti_users', $ltiuser); } + + /** + * Test for provider::get_users_in_context() when the context is a course. + */ + public function test_get_users_in_context_course() { + $coursecontext = context_course::instance($this->course->id); + $userlist = new \core_privacy\local\request\userlist($coursecontext, 'enrol_paypal'); + provider::get_users_in_context($userlist); + + $this->assertEquals( + [$this->user->id, $this->anotheruser->id], + $userlist->get_userids(), + '', 0.0, 10, true); + } + + /** + * Test for provider::get_users_in_context() when the context is an activity. + */ + public function test_get_users_in_context_activity() { + $activityctx = context_module::instance($this->activity->cmid); + $userlist = new \core_privacy\local\request\userlist($activityctx, 'enrol_paypal'); + provider::get_users_in_context($userlist); + + $this->assertEquals( + [$this->user->id], + $userlist->get_userids()); + } + + /** + * Test for provider::delete_data_for_users() when the context is a course. + */ + public function test_delete_data_for_users_course() { + global $DB; + + $coursecontext = context_course::instance($this->course->id); + + $count = $DB->count_records('enrol_lti_users'); + $this->assertEquals(4, $count); + + $approveduserlist = new \core_privacy\local\request\approved_userlist($coursecontext, 'enrol_paypal', + [$this->user->id]); + provider::delete_data_for_users($approveduserlist); + + $ltiusers = $DB->get_records('enrol_lti_users'); + $this->assertCount(2, $ltiusers); + + foreach ($ltiusers as $ltiuser) { + $leftover = false; + if ($ltiuser->userid == $this->user->id) { + $contextid = $DB->get_field('enrol_lti_tools', 'contextid', ['id' => $ltiuser->toolid]); + if ($contextid == $coursecontext->id) { + $leftover = true; + } + } + } + $this->assertFalse($leftover); + } + + /** + * Test for provider::delete_data_for_users() when the context is an activity. + */ + public function test_delete_data_for_users_activity() { + global $DB; + + $cmcontext = context_module::instance($this->activity->cmid); + + $count = $DB->count_records('enrol_lti_users'); + $this->assertEquals(4, $count); + + $approveduserlist = new \core_privacy\local\request\approved_userlist($cmcontext, 'enrol_paypal', + [$this->user->id]); + provider::delete_data_for_users($approveduserlist); + + $ltiusers = $DB->get_records('enrol_lti_users'); + $this->assertCount(3, $ltiusers); + + foreach ($ltiusers as $ltiuser) { + $leftover = false; + if ($ltiuser->userid == $this->user->id) { + $contextid = $DB->get_field('enrol_lti_tools', 'contextid', ['id' => $ltiuser->toolid]); + if ($contextid == $cmcontext->id) { + $leftover = true; + } + } + } + $this->assertFalse($leftover); + } }