Skip to content

Commit

Permalink
MDL-62078 rss: Link to core_userkey in the Privacy API implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
sarjona committed Apr 22, 2018
1 parent 7bd8cd0 commit 6165597
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 44 deletions.
7 changes: 2 additions & 5 deletions lang/en/rss.php
Expand Up @@ -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';
74 changes: 37 additions & 37 deletions rss/classes/privacy/provider.php
Expand Up @@ -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->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;
}

Expand Down Expand Up @@ -84,25 +80,20 @@ public static function get_contexts_for_userid($userid) {
* @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');
}

/**
Expand All @@ -111,7 +102,15 @@ public static function export_user_data(approved_contextlist $contextlist) {
* @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);

}

/**
Expand All @@ -120,18 +119,19 @@ public static function delete_data_for_all_users_in_context(\context $context) {
* @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.
}

/**
* 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($userid) {
global $DB;
// 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);

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);
}
}
60 changes: 58 additions & 2 deletions rss/tests/privacy_test.php
Expand Up @@ -26,6 +26,7 @@
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
Expand All @@ -46,6 +47,7 @@ public function setUp() {
* 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);
Expand All @@ -60,15 +62,69 @@ public function test_get_contexts_for_userid() {
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);
}
}

0 comments on commit 6165597

Please sign in to comment.