Skip to content

Commit

Permalink
Merge branch 'MDL-62560-master'
Browse files Browse the repository at this point in the history
  • Loading branch information
David Monllao committed Oct 22, 2018
2 parents 53f14ee + 9e217d8 commit f7642be
Show file tree
Hide file tree
Showing 128 changed files with 11,906 additions and 335 deletions.
37 changes: 36 additions & 1 deletion admin/tool/dataprivacy/classes/api.php
Expand Up @@ -988,6 +988,7 @@ public static function set_expired_context_status(expired_context $expiredctx, $
*/ */
public static function add_request_contexts_with_status(contextlist_collection $clcollection, int $requestid, int $status) { public static function add_request_contexts_with_status(contextlist_collection $clcollection, int $requestid, int $status) {
$request = new data_request($requestid); $request = new data_request($requestid);
$user = \core_user::get_user($request->get('userid'));
foreach ($clcollection as $contextlist) { foreach ($clcollection as $contextlist) {
// Convert the \core_privacy\local\request\contextlist into a contextlist persistent and store it. // Convert the \core_privacy\local\request\contextlist into a contextlist persistent and store it.
$clp = \tool_dataprivacy\contextlist::from_contextlist($contextlist); $clp = \tool_dataprivacy\contextlist::from_contextlist($contextlist);
Expand All @@ -998,10 +999,14 @@ public static function add_request_contexts_with_status(contextlist_collection $
foreach ($contextlist->get_contextids() as $contextid) { foreach ($contextlist->get_contextids() as $contextid) {
if ($request->get('type') == static::DATAREQUEST_TYPE_DELETE) { if ($request->get('type') == static::DATAREQUEST_TYPE_DELETE) {
$context = \context::instance_by_id($contextid); $context = \context::instance_by_id($contextid);
if (($purpose = static::get_effective_context_purpose($context)) && !empty($purpose->get('protected'))) { $purpose = static::get_effective_context_purpose($context);

// Data can only be deleted from it if the context is either expired, or unprotected.
if (!expired_contexts_manager::is_context_expired_or_unprotected_for_user($context, $user)) {
continue; continue;
} }
} }

$context = new contextlist_context(); $context = new contextlist_context();
$context->set('contextid', $contextid) $context->set('contextid', $contextid)
->set('contextlistid', $contextlistid) ->set('contextlistid', $contextlistid)
Expand Down Expand Up @@ -1099,6 +1104,15 @@ public static function get_approved_contextlist_collection_for_request(data_requ
$contexts = []; $contexts = [];
} }


if ($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.
if (!expired_contexts_manager::is_context_expired_or_unprotected_for_user($context, $foruser)) {
continue;
}
}

$contexts[] = $record->contextid; $contexts[] = $record->contextid;
$lastcomponent = $record->component; $lastcomponent = $record->component;
} }
Expand Down Expand Up @@ -1196,4 +1210,25 @@ public static function set_context_defaults($contextlevel, $categoryid, $purpose


return true; return true;
} }

/**
* Format the supplied date interval as a retention period.
*
* @param \DateInterval $interval
* @return string
*/
public static function format_retention_period(\DateInterval $interval) : string {
// It is one or another.
if ($interval->y) {
$formattedtime = get_string('numyears', 'moodle', $interval->format('%y'));
} else if ($interval->m) {
$formattedtime = get_string('nummonths', 'moodle', $interval->format('%m'));
} else if ($interval->d) {
$formattedtime = get_string('numdays', 'moodle', $interval->format('%d'));
} else {
$formattedtime = get_string('retentionperiodzero', 'tool_dataprivacy');
}

return $formattedtime;
}
} }
185 changes: 177 additions & 8 deletions admin/tool/dataprivacy/classes/expired_context.php
Expand Up @@ -60,21 +60,36 @@ class expired_context extends \core\persistent {
* @return array * @return array
*/ */
protected static function define_properties() { protected static function define_properties() {
return array( return [
'contextid' => array( 'contextid' => [
'type' => PARAM_INT, 'type' => PARAM_INT,
'description' => 'The context id.', 'description' => 'The context id.',
), ],
'status' => array( 'defaultexpired' => [
'type' => PARAM_INT,
'description' => 'Whether to default retention period for the purpose has been reached',
'default' => 1,
],
'expiredroles' => [
'type' => PARAM_TEXT,
'description' => 'This list of roles to include during deletion',
'default' => '',
],
'unexpiredroles' => [
'type' => PARAM_TEXT,
'description' => 'This list of roles to exclude during deletion',
'default' => '',
],
'status' => [
'choices' => [ 'choices' => [
self::STATUS_EXPIRED, self::STATUS_EXPIRED,
self::STATUS_APPROVED, self::STATUS_APPROVED,
self::STATUS_CLEANED, self::STATUS_CLEANED,
], ],
'type' => PARAM_INT, 'type' => PARAM_INT,
'description' => 'The deletion status of the context.', 'description' => 'The deletion status of the context.',
), ],
); ];
} }


/** /**
Expand Down Expand Up @@ -160,21 +175,130 @@ public static function get_record_count_by_contextlevel($contextlevel = null, $s
return $DB->count_records_sql($sql, $params); return $DB->count_records_sql($sql, $params);
} }


/**
* Set the list of role IDs for either expiredroles, or unexpiredroles.
*
* @param string $field
* @param int[] $roleids
* @return expired_context
*/
protected function set_roleids_for(string $field, array $roleids) : expired_context {
$roledata = json_encode($roleids);

$this->raw_set($field, $roledata);

return $this;
}

/**
* Get the list of role IDs for either expiredroles, or unexpiredroles.
*
* @param string $field
* @return int[]
*/
protected function get_roleids_for(string $field) {
$value = $this->raw_get($field);
if (empty($value)) {
return [];
}

return json_decode($value);
}

/**
* Set the list of unexpired role IDs.
*
* @param int[] $roleids
* @return expired_context
*/
protected function set_unexpiredroles(array $roleids) : expired_context {
$this->set_roleids_for('unexpiredroles', $roleids);

return $this;
}

/**
* Add a set of role IDs to the list of expired role IDs.
*
* @param int[] $roleids
* @return expired_context
*/
public function add_expiredroles(array $roleids) : expired_context {
$existing = $this->get('expiredroles');
$newvalue = array_merge($existing, $roleids);

$this->set('expiredroles', $newvalue);

return $this;
}

/**
* Add a set of role IDs to the list of unexpired role IDs.
*
* @param int[] $roleids
* @return unexpired_context
*/
public function add_unexpiredroles(array $roleids) : expired_context {
$existing = $this->get('unexpiredroles');
$newvalue = array_merge($existing, $roleids);

$this->set('unexpiredroles', $newvalue);

return $this;
}

/**
* Set the list of expired role IDs.
*
* @param int[] $roleids
* @return expired_context
*/
protected function set_expiredroles(array $roleids) : expired_context {
$this->set_roleids_for('expiredroles', $roleids);

return $this;
}

/**
* Get the list of expired role IDs.
*
* @return int[]
*/
protected function get_expiredroles() {
return $this->get_roleids_for('expiredroles');
}

/**
* Get the list of unexpired role IDs.
*
* @return int[]
*/
protected function get_unexpiredroles() {
return $this->get_roleids_for('unexpiredroles');
}

/** /**
* Create a new expired_context based on the context, and expiry_info object. * Create a new expired_context based on the context, and expiry_info object.
* *
* @param \context $context * @param \context $context
* @param expiry_info $info * @param expiry_info $info
* @param boolean $save
* @return expired_context * @return expired_context
*/ */
public static function create_from_expiry_info(\context $context, expiry_info $info) : expired_context { public static function create_from_expiry_info(\context $context, expiry_info $info, bool $save = true) : expired_context {
$record = (object) [ $record = (object) [
'contextid' => $context->id, 'contextid' => $context->id,
'status' => self::STATUS_EXPIRED, 'status' => self::STATUS_EXPIRED,
'defaultexpired' => (int) $info->is_default_expired(),
]; ];


$expiredcontext = new static(0, $record); $expiredcontext = new static(0, $record);
$expiredcontext->save(); $expiredcontext->set('expiredroles', $info->get_expired_roles());
$expiredcontext->set('unexpiredroles', $info->get_unexpired_roles());

if ($save) {
$expiredcontext->save();
}


return $expiredcontext; return $expiredcontext;
} }
Expand All @@ -186,7 +310,42 @@ public static function create_from_expiry_info(\context $context, expiry_info $i
* @return $this * @return $this
*/ */
public function update_from_expiry_info(expiry_info $info) : expired_context { public function update_from_expiry_info(expiry_info $info) : expired_context {
$save = false;

// Compare the expiredroles.
$thisexpired = $this->get('expiredroles');
$infoexpired = $info->get_expired_roles();

sort($thisexpired);
sort($infoexpired);
if ($infoexpired != $thisexpired) {
$this->set('expiredroles', $infoexpired);
$save = true;
}

// Compare the unexpiredroles.
$thisunexpired = $this->get('unexpiredroles');
$infounexpired = $info->get_unexpired_roles();

sort($thisunexpired);
sort($infounexpired);
if ($infounexpired != $thisunexpired) {
$this->set('unexpiredroles', $infounexpired);
$save = true;
}

if (empty($this->get('defaultexpired')) == $info->is_default_expired()) {
$this->set('defaultexpired', (int) $info->is_default_expired());
$save = true;
}

if ($save) {
$this->set('status', self::STATUS_EXPIRED);
$this->save();
}

return $this; return $this;

} }


/** /**
Expand All @@ -206,4 +365,14 @@ public function can_process_deletion() : bool {
public function is_complete() : bool { public function is_complete() : bool {
return ($this->get('status') == self::STATUS_CLEANED); return ($this->get('status') == self::STATUS_CLEANED);
} }

/**
* Whether this context has 'fully' expired.
* That is to say that the default retention period has been reached, and that there are no unexpired roles.
*
* @return bool
*/
public function is_fully_expired() : bool {
return $this->get('defaultexpired') && empty($this->get('unexpiredroles'));
}
} }

0 comments on commit f7642be

Please sign in to comment.