From b720d9dae83b23a0d01d5da31382cf56ffa8e044 Mon Sep 17 00:00:00 2001 From: sarjona Date: Sat, 21 Apr 2018 10:49:26 +0200 Subject: [PATCH] MDL-62078 rss: Link to core_userkey in the Privacy API implementation --- lang/en/rss.php | 7 +-- rss/classes/privacy/provider.php | 74 ++++++++++++++++---------------- rss/tests/privacy_test.php | 60 +++++++++++++++++++++++++- 3 files changed, 97 insertions(+), 44 deletions(-) diff --git a/lang/en/rss.php b/lang/en/rss.php index 3ed277a7776..809e938beed 100644 --- a/lang/en/rss.php +++ b/lang/en/rss.php @@ -24,9 +24,6 @@ defined('MOODLE_INTERNAL') || die(); -$string['privacy:metadata:user_private_key'] = 'Information about the user\'s access keys used in cookieless scripts, such as RSS.'; -$string['privacy:metadata:user_private_key:timecreated'] = 'The timestamp indicating when the key was created'; -$string['privacy:metadata:user_private_key:userid'] = 'The ID of the user which is associated to this key'; -$string['privacy:metadata:user_private_key:validuntil'] = 'The timestamp indicating when the key will expire'; -$string['privacy:metadata:user_private_key:value'] = 'The token used for getting the ID of the user'; + +$string['privacy:metadata:core_userkey'] = 'User\'s keys used to access RSS from a URL'; $string['rss'] = 'RSS'; diff --git a/rss/classes/privacy/provider.php b/rss/classes/privacy/provider.php index b405647c0a8..6d569cf2a90 100644 --- a/rss/classes/privacy/provider.php +++ b/rss/classes/privacy/provider.php @@ -49,12 +49,8 @@ class provider implements * @return collection A listing of user data stored through this system. */ public static function get_metadata(collection $collection) : collection { - $collection->add_database_table('user_private_key', [ - 'value' => 'privacy:metadata:user_private_key:value', - 'userid' => 'privacy:metadata:user_private_key:userid', - 'validuntil' => 'privacy:metadata:user_private_key:validuntil', - 'timecreated' => 'privacy:metadata:user_private_key:timecreated' - ], 'privacy:metadata:user_private_key'); + $collection->add_subsystem_link('core_userkey', [], 'privacy:metadata:core_userkey'); + return $collection; } @@ -84,25 +80,20 @@ class provider implements * @param approved_contextlist $contextlist The approved contexts to export information for. */ public static function export_user_data(approved_contextlist $contextlist) { - $results = static::get_records($contextlist->get_user()->id); - $context = $contextlist->current(); - if ($context->contextlevel == CONTEXT_USER) { - foreach ($results as $result) { - $context = \context_user::instance($result->userid); - $subcontext = [ - get_string('rss', 'rss'), - transform::user($result->userid) - ]; - $name = 'user_private_key-' . $result->id; - $data = (object)[ - 'value' => $result->value, - 'iprestriction' => $result->iprestriction, - 'validuntil' => $result->validuntil, - 'timecreated' => transform::datetime($result->timecreated), - ]; - writer::with_context($context)->export_related_data($subcontext, $name, $data); - } + // If the user has data, then only the CONTEXT_USER should be present so get the first context. + $contexts = $contextlist->get_contexts(); + if (count($contexts) == 0) { + return; } + $context = reset($contexts); + + // Sanity check that context is at the user context level, then get the userid. + if ($context->contextlevel !== CONTEXT_USER) { + return; + } + + // Export associated userkeys. + \core_userkey\privacy\provider::export_userkeys($context, [], 'rss'); } /** @@ -111,7 +102,15 @@ class provider implements * @param context $context A user context. */ public static function delete_data_for_all_users_in_context(\context $context) { - // The information in user_private_key table is removed automaticaly when a user is deteled. + // Sanity check that context is at the user context level, then get the userid. + if ($context->contextlevel !== CONTEXT_USER) { + return; + } + $userid = $context->instanceid; + + // Delete all the userkeys. + \core_userkey\privacy\provider::delete_userkeys('rss', $userid); + } /** @@ -120,18 +119,19 @@ class provider implements * @param approved_contextlist $contextlist The approved contexts and user information to delete information for. */ public static function delete_data_for_user(approved_contextlist $contextlist) { - // The information in user_private_key table is removed automaticaly when a user is deteled. - } + // If the user has data, then only the user context should be present so get the first context. + $contexts = $contextlist->get_contexts(); + if (count($contexts) == 0) { + return; + } + $context = reset($contexts); - /** - * Get records related to this plugin and user. - * - * @param int $userid The user ID - * @return array An array of records. - */ - protected static function get_records(int $userid) : array { - global $DB; - - return $DB->get_records('user_private_key', ['userid' => $userid, 'script' => 'rss']); + // Sanity check that context is at the user context level, then get the userid. + if ($context->contextlevel !== CONTEXT_USER) { + return; + } + $userid = $context->instanceid; + // Delete all the userkeys. + \core_userkey\privacy\provider::delete_userkeys('rss', $userid); } } diff --git a/rss/tests/privacy_test.php b/rss/tests/privacy_test.php index c3cc70303f9..1fc46d4fded 100644 --- a/rss/tests/privacy_test.php +++ b/rss/tests/privacy_test.php @@ -26,6 +26,7 @@ defined('MOODLE_INTERNAL') || die(); use \core_privacy\tests\provider_testcase; use \core_rss\privacy\provider; use \core_privacy\local\request\writer; +use \core_privacy\local\request\approved_contextlist; /** * Unit tests for rss\classes\privacy\provider.php @@ -46,6 +47,7 @@ class core_rss_testcase extends provider_testcase { * Test getting the context for the user ID related to this plugin. */ public function test_get_contexts_for_userid() { + // Create user and RSS user keys. $user = $this->getDataGenerator()->create_user(); $context = \context_user::instance($user->id); $key = get_user_key('rss', $user->id); @@ -60,15 +62,69 @@ class core_rss_testcase extends provider_testcase { public function test_export_user_data() { global $DB; + // Create user and RSS user keys. $user = $this->getDataGenerator()->create_user(); $context = \context_user::instance($user->id); $keyvalue = get_user_key('rss', $user->id); $key = $DB->get_record('user_private_key', ['value' => $keyvalue]); + // Validate exported data. + $this->setUser($user); $writer = writer::with_context($context); $this->assertFalse($writer->has_any_data()); $this->export_context_data_for_user($user->id, $context, 'core_rss'); - $data = $writer->get_related_data([get_string('rss', 'rss'), $user->id], 'user_private_key-' . $key->id); - $this->assertEquals($key->value, $data->value); + $userkeydata = $writer->get_related_data([], 'userkeys'); + $this->assertCount(1, $userkeydata->keys); + $this->assertEquals($key->script, reset($userkeydata->keys)->script); + } + + /** + * Test for provider::delete_data_for_all_users_in_context(). + */ + public function test_delete_data_for_all_users_in_context() { + global $DB; + + // Create user and RSS user keys. + $user = $this->getDataGenerator()->create_user(); + $context = \context_user::instance($user->id); + $keyvalue = get_user_key('rss', $user->id); + $key = $DB->get_record('user_private_key', ['value' => $keyvalue]); + + // Before deletion, we should have 1 user_private_key. + $count = $DB->count_records('user_private_key', ['script' => 'rss']); + $this->assertEquals(1, $count); + + // Delete data. + provider::delete_data_for_all_users_in_context($context); + + // After deletion, the user_private_key entries should have been deleted. + $count = $DB->count_records('user_private_key', ['script' => 'rss']); + $this->assertEquals(0, $count); + } + + /** + * Test for provider::delete_data_for_user(). + */ + public function test_delete_data_for_user() { + global $DB; + + // Create user and RSS user keys. + $user = $this->getDataGenerator()->create_user(); + $context = \context_user::instance($user->id); + $keyvalue = get_user_key('rss', $user->id); + $key = $DB->get_record('user_private_key', ['value' => $keyvalue]); + + // Before deletion, we should have 1 user_private_key. + $count = $DB->count_records('user_private_key', ['script' => 'rss']); + $this->assertEquals(1, $count); + + // Delete data. + $contextlist = provider::get_contexts_for_userid($user->id); + $approvedcontextlist = new approved_contextlist($user, 'rss', $contextlist->get_contextids()); + provider::delete_data_for_user($approvedcontextlist); + + // After deletion, the user_private_key entries should have been deleted. + $count = $DB->count_records('user_private_key', ['script' => 'rss']); + $this->assertEquals(0, $count); } }