Merge branch 'MDL-64030-34' of git://github.com/andrewnicols/moodle into MOODLE_34_STABLE
This commit is contained in:
@@ -1075,6 +1075,7 @@ class api {
|
||||
public static function add_request_contexts_with_status(contextlist_collection $clcollection, int $requestid, int $status) {
|
||||
$request = new data_request($requestid);
|
||||
$user = \core_user::get_user($request->get('userid'));
|
||||
$isconfigured = data_registry::defaults_set();
|
||||
foreach ($clcollection as $contextlist) {
|
||||
// Convert the \core_privacy\local\request\contextlist into a contextlist persistent and store it.
|
||||
$clp = \tool_dataprivacy\contextlist::from_contextlist($contextlist);
|
||||
@@ -1083,7 +1084,11 @@ class api {
|
||||
|
||||
// Store the associated contexts in the contextlist.
|
||||
foreach ($contextlist->get_contextids() as $contextid) {
|
||||
if ($request->get('type') == static::DATAREQUEST_TYPE_DELETE) {
|
||||
if ($isconfigured && self::DATAREQUEST_TYPE_DELETE == $request->get('type')) {
|
||||
// Data can only be deleted from it if the context is either expired, or unprotected.
|
||||
// Note: We can only check whether a context is expired or unprotected if the site is configured and
|
||||
// defaults are set appropriately. If they are not, we treat all contexts as though they are
|
||||
// unprotected.
|
||||
$context = \context::instance_by_id($contextid);
|
||||
$purpose = static::get_effective_context_purpose($context);
|
||||
|
||||
@@ -1163,10 +1168,11 @@ class api {
|
||||
* @return contextlist_collection the collection of approved_contextlist objects.
|
||||
*/
|
||||
public static function get_approved_contextlist_collection_for_request(data_request $request) : contextlist_collection {
|
||||
global $DB;
|
||||
$foruser = core_user::get_user($request->get('userid'));
|
||||
$isconfigured = data_registry::defaults_set();
|
||||
|
||||
// Fetch all approved contextlists and create the core_privacy\local\request\contextlist objects here.
|
||||
global $DB;
|
||||
$sql = "SELECT cl.component, ctx.contextid
|
||||
FROM {" . request_contextlist::TABLE . "} rcl
|
||||
JOIN {" . contextlist::TABLE . "} cl ON rcl.contextlistid = cl.id
|
||||
@@ -1190,10 +1196,13 @@ class api {
|
||||
$contexts = [];
|
||||
}
|
||||
|
||||
if ($request->get('type') == static::DATAREQUEST_TYPE_DELETE) {
|
||||
if ($isconfigured && $request->get('type') == static::DATAREQUEST_TYPE_DELETE) {
|
||||
$context = \context::instance_by_id($record->contextid);
|
||||
$purpose = static::get_effective_context_purpose($context);
|
||||
// Data can only be deleted from it if the context is either expired, or unprotected.
|
||||
// Note: We can only check whether a context is expired or unprotected if the site is configured and
|
||||
// defaults are set appropriately. If they are not, we treat all contexts as though they are
|
||||
// unprotected.
|
||||
if (!expired_contexts_manager::is_context_expired_or_unprotected_for_user($context, $foruser)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -74,11 +74,9 @@ class process_data_request_task extends adhoc_task {
|
||||
return;
|
||||
}
|
||||
|
||||
// If no site purpose is defined, reject requests since they cannot be processed.
|
||||
if (!\tool_dataprivacy\data_registry::defaults_set()) {
|
||||
api::update_request_status($requestid, api::DATAREQUEST_STATUS_REJECTED);
|
||||
mtrace('No site purpose defined. Request ' . $requestid . ' rejected.');
|
||||
return;
|
||||
// Warn if no site purpose is defined.
|
||||
mtrace('Warning: No purpose is defined at the system level. Deletion will delete all.');
|
||||
}
|
||||
|
||||
// Get the user details now. We might not be able to retrieve it later if it's a deletion processing.
|
||||
|
||||
@@ -38,6 +38,10 @@ $title = get_string('datarequests', 'tool_dataprivacy');
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading($title);
|
||||
|
||||
if (!\tool_dataprivacy\data_registry::defaults_set()) {
|
||||
\core\notification::error(get_string('systemconfignotsetwarning', 'tool_dataprivacy'));
|
||||
}
|
||||
|
||||
if (\tool_dataprivacy\api::is_site_dpo($USER->id)) {
|
||||
$filtersapplied = optional_param_array('request-filters', [-1], PARAM_NOTAGS);
|
||||
$filterscleared = optional_param('filters-cleared', 0, PARAM_INT);
|
||||
|
||||
@@ -308,6 +308,7 @@ $string['statusrejected'] = 'Rejected';
|
||||
$string['subjectscope'] = 'Subject scope';
|
||||
$string['subjectscope_help'] = 'The subject scope lists the roles which may be assigned in this context.';
|
||||
$string['summary'] = 'Registry configuration summary';
|
||||
$string['systemconfignotsetwarning'] = 'A site purpose and category have not been defined. When these are not defined, all data will be removed when processing deletion requests.';
|
||||
$string['user'] = 'User';
|
||||
$string['userlistnoncompliant'] = 'Userlist provider missing';
|
||||
$string['userlistexplanation'] = 'This plugin has the base provider but should also implement the userlist provider for full support of privacy functionality.';
|
||||
|
||||
@@ -1711,6 +1711,48 @@ class tool_dataprivacy_api_testcase extends advanced_testcase {
|
||||
$this->assertEquals($data->contexts->used, $contextids, '', 0.0, 10, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that delete requests do not filter out protected purpose contexts if the the site is properly configured.
|
||||
*/
|
||||
public function test_add_request_contexts_with_status_delete_course_no_site_config() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course(['startdate' => time() - YEARSECS, 'enddate' => time() - YEARSECS]);
|
||||
$coursecontext = \context_course::instance($course->id);
|
||||
|
||||
$forum = $this->getDataGenerator()->create_module('forum', ['course' => $course->id]);
|
||||
list(, $forumcm) = get_course_and_cm_from_instance($forum->id, 'forum');
|
||||
$contextforum = \context_module::instance($forumcm->id);
|
||||
|
||||
$this->getDataGenerator()->enrol_user($user->id, $course->id, 'student');
|
||||
|
||||
// Create the initial contextlist.
|
||||
$initialcollection = new \core_privacy\local\request\contextlist_collection($user->id);
|
||||
|
||||
$contextlist = new \core_privacy\local\request\contextlist();
|
||||
$contextlist->add_from_sql('SELECT id FROM {context} WHERE id = :contextid', ['contextid' => $coursecontext->id]);
|
||||
$contextlist->set_component('tool_dataprivacy');
|
||||
$initialcollection->add_contextlist($contextlist);
|
||||
|
||||
$contextlist = new \core_privacy\local\request\contextlist();
|
||||
$contextlist->add_from_sql('SELECT id FROM {context} WHERE id = :contextid', ['contextid' => $contextforum->id]);
|
||||
$contextlist->set_component('mod_forum');
|
||||
$initialcollection->add_contextlist($contextlist);
|
||||
|
||||
$request = api::create_data_request($user->id, api::DATAREQUEST_TYPE_DELETE);
|
||||
api::add_request_contexts_with_status(
|
||||
$initialcollection, $request->get('id'), contextlist_context::STATUS_APPROVED);
|
||||
|
||||
$newcollection = \tool_dataprivacy\request_contextlist::get_records();
|
||||
$this->assertCount(2, $newcollection);
|
||||
foreach ($newcollection as $contextlist) {
|
||||
$requests = contextlist_context::get_records(['contextlistid' => $contextlist->get('contextlistid')]);
|
||||
$this->assertCount(1, $requests);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that delete requests do not filter out protected purpose contexts if they are already expired.
|
||||
*/
|
||||
@@ -1807,6 +1849,64 @@ class tool_dataprivacy_api_testcase extends advanced_testcase {
|
||||
$this->assertCount(1, $requests);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that delete requests do not filter out protected purpose contexts if the the site is properly configured.
|
||||
*/
|
||||
public function test_get_approved_contextlist_collection_for_request_delete_course_no_config() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$course = $this->getDataGenerator()->create_course(['startdate' => time() - YEARSECS, 'enddate' => time() - YEARSECS]);
|
||||
$coursecontext = \context_course::instance($course->id);
|
||||
|
||||
$forum = $this->getDataGenerator()->create_module('forum', ['course' => $course->id]);
|
||||
list(, $forumcm) = get_course_and_cm_from_instance($forum->id, 'forum');
|
||||
$contextforum = \context_module::instance($forumcm->id);
|
||||
|
||||
$this->getDataGenerator()->enrol_user($user->id, $course->id, 'student');
|
||||
|
||||
// Create the initial contextlist.
|
||||
$request = api::create_data_request($user->id, api::DATAREQUEST_TYPE_DELETE);
|
||||
$initialcollection = new \core_privacy\local\request\contextlist_collection($user->id);
|
||||
|
||||
$contextlist = new \tool_dataprivacy\contextlist(0, (object) ['component' => 'tool_dataprivacy']);
|
||||
$contextlist->save();
|
||||
$clcontext = new \tool_dataprivacy\contextlist_context(0, (object) [
|
||||
'contextid' => $coursecontext->id,
|
||||
'status' => contextlist_context::STATUS_APPROVED,
|
||||
'contextlistid' => $contextlist->get('id'),
|
||||
]);
|
||||
$clcontext->save();
|
||||
$rcl = new \tool_dataprivacy\request_contextlist(0, (object) [
|
||||
'requestid' => $request->get('id'),
|
||||
'contextlistid' => $contextlist->get('id'),
|
||||
]);
|
||||
$rcl->save();
|
||||
|
||||
$contextlist = new \tool_dataprivacy\contextlist(0, (object) ['component' => 'mod_forum']);
|
||||
$contextlist->save();
|
||||
$clcontext = new \tool_dataprivacy\contextlist_context(0, (object) [
|
||||
'contextid' => $contextforum->id,
|
||||
'status' => contextlist_context::STATUS_APPROVED,
|
||||
'contextlistid' => $contextlist->get('id'),
|
||||
]);
|
||||
$clcontext->save();
|
||||
$rcl = new \tool_dataprivacy\request_contextlist(0, (object) [
|
||||
'requestid' => $request->get('id'),
|
||||
'contextlistid' => $contextlist->get('id'),
|
||||
]);
|
||||
$rcl->save();
|
||||
|
||||
$collection = api::get_approved_contextlist_collection_for_request($request);
|
||||
$this->assertCount(2, $collection);
|
||||
|
||||
$list = $collection->get_contextlist_for_component('tool_dataprivacy');
|
||||
$this->assertCount(1, $list);
|
||||
|
||||
$list = $collection->get_contextlist_for_component('mod_forum');
|
||||
$this->assertCount(1, $list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that delete requests do not filter out protected purpose contexts if they are already expired.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user