// The user making the request.
$datarequest->set('requestedby', $requestinguser);
// Set status.
- $datarequest->set('status', self::DATAREQUEST_STATUS_AWAITING_APPROVAL);
+ $status = self::DATAREQUEST_STATUS_AWAITING_APPROVAL;
+ if (self::is_automatic_request_approval_on($type)) {
+ // Set status to approved if automatic data request approval is enabled.
+ $status = self::DATAREQUEST_STATUS_APPROVED;
+ // Set the privacy officer field if the one making the data request is a privacy officer.
+ if (self::is_site_dpo($requestinguser)) {
+ $datarequest->set('dpo', $requestinguser);
+ }
+ // Mark this request as system approved.
+ $datarequest->set('systemapproved', true);
+ // No need to notify privacy officer(s) about automatically approved data requests.
+ $notify = false;
+ }
+ $datarequest->set('status', $status);
// Set request type.
$datarequest->set('type', $type);
// Set request comments.
// Store subject access request.
$datarequest->create();
+ // Queue the ad-hoc task for automatically approved data requests.
+ if ($status == self::DATAREQUEST_STATUS_APPROVED) {
+ $userid = null;
+ if ($type == self::DATAREQUEST_TYPE_EXPORT) {
+ $userid = $foruser;
+ }
+ self::queue_data_request_task($datarequest->get('id'), $userid);
+ }
+
if ($notify) {
// Get the list of the site Data Protection Officers.
- $dpos = api::get_site_dpos();
+ $dpos = self::get_site_dpos();
// Email the data request to the Data Protection Officer(s)/Admin(s).
foreach ($dpos as $dpo) {
- api::notify_dpo($dpo, $datarequest);
+ self::notify_dpo($dpo, $datarequest);
}
}
$result = self::update_request_status($requestid, self::DATAREQUEST_STATUS_APPROVED, $USER->id);
// Fire an ad hoc task to initiate the data request process.
- $task = new process_data_request_task();
- $task->set_custom_data(['requestid' => $requestid]);
+ $userid = null;
if ($request->get('type') == self::DATAREQUEST_TYPE_EXPORT) {
- $task->set_userid($request->get('userid'));
+ $userid = $request->get('userid');
}
- manager::queue_adhoc_task($task, true);
+ self::queue_data_request_task($requestid, $userid);
return $result;
}
return $formattedtime;
}
+
+ /**
+ * Whether automatic data request approval is turned on or not for the given request type.
+ *
+ * @param int $type The request type.
+ * @return bool
+ */
+ public static function is_automatic_request_approval_on(int $type): bool {
+ switch ($type) {
+ case self::DATAREQUEST_TYPE_EXPORT:
+ return !empty(get_config('tool_dataprivacy', 'automaticdataexportapproval'));
+ case self::DATAREQUEST_TYPE_DELETE:
+ return !empty(get_config('tool_dataprivacy', 'automaticdatadeletionapproval'));
+ }
+ return false;
+ }
+
+ /**
+ * Creates an ad-hoc task for the data request.
+ *
+ * @param int $requestid The data request ID.
+ * @param int $userid Optional. The user ID to run the task as, if necessary.
+ */
+ public static function queue_data_request_task(int $requestid, int $userid = null): void {
+ $task = new process_data_request_task();
+ $task->set_custom_data(['requestid' => $requestid]);
+ if ($userid) {
+ $task->set_userid($userid);
+ }
+ manager::queue_adhoc_task($task, true);
+ }
}
}
/**
- * Test for api::create_data_request()
+ * Data provider for data request creation tests.
+ *
+ * @return array
*/
- public function test_create_data_request() {
- $this->resetAfterTest();
-
- $generator = new testing_data_generator();
- $user = $generator->create_user();
- $comment = 'sample comment';
-
- // Login as user.
- $this->setUser($user->id);
-
- // Test data request creation.
- $datarequest = api::create_data_request($user->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
- $this->assertEquals($user->id, $datarequest->get('userid'));
- $this->assertEquals($user->id, $datarequest->get('requestedby'));
- $this->assertEquals(0, $datarequest->get('dpo'));
- $this->assertEquals(api::DATAREQUEST_TYPE_EXPORT, $datarequest->get('type'));
- $this->assertEquals(api::DATAREQUEST_STATUS_AWAITING_APPROVAL, $datarequest->get('status'));
- $this->assertEquals($comment, $datarequest->get('comments'));
+ public function data_request_creation_provider() {
+ return [
+ 'Export request by user, automatic approval off' => [
+ false, api::DATAREQUEST_TYPE_EXPORT, 'automaticdataexportapproval', false, 0,
+ api::DATAREQUEST_STATUS_AWAITING_APPROVAL, 0
+ ],
+ 'Export request by user, automatic approval on' => [
+ false, api::DATAREQUEST_TYPE_EXPORT, 'automaticdataexportapproval', true, 0,
+ api::DATAREQUEST_STATUS_APPROVED, 1
+ ],
+ 'Export request by PO, automatic approval off' => [
+ true, api::DATAREQUEST_TYPE_EXPORT, 'automaticdataexportapproval', false, 0,
+ api::DATAREQUEST_STATUS_AWAITING_APPROVAL, 0
+ ],
+ 'Export request by PO, automatic approval on' => [
+ true, api::DATAREQUEST_TYPE_EXPORT, 'automaticdataexportapproval', true, 'dpo',
+ api::DATAREQUEST_STATUS_APPROVED, 1
+ ],
+ 'Delete request by user, automatic approval off' => [
+ false, api::DATAREQUEST_TYPE_DELETE, 'automaticdatadeletionapproval', false, 0,
+ api::DATAREQUEST_STATUS_AWAITING_APPROVAL, 0
+ ],
+ 'Delete request by user, automatic approval on' => [
+ false, api::DATAREQUEST_TYPE_DELETE, 'automaticdatadeletionapproval', true, 0,
+ api::DATAREQUEST_STATUS_APPROVED, 1
+ ],
+ 'Delete request by PO, automatic approval off' => [
+ true, api::DATAREQUEST_TYPE_DELETE, 'automaticdatadeletionapproval', false, 0,
+ api::DATAREQUEST_STATUS_AWAITING_APPROVAL, 0
+ ],
+ 'Delete request by PO, automatic approval on' => [
+ true, api::DATAREQUEST_TYPE_DELETE, 'automaticdatadeletionapproval', true, 'dpo',
+ api::DATAREQUEST_STATUS_APPROVED, 1
+ ],
+ ];
}
/**
- * Test for api::create_data_request() made by DPO.
+ * Test for api::create_data_request()
+ *
+ * @dataProvider data_request_creation_provider
+ * @param bool $asprivacyofficer Whether the request is made as the Privacy Officer or the user itself.
+ * @param string $type The data request type.
+ * @param string $setting The automatic approval setting.
+ * @param bool $automaticapproval Whether automatic data request approval is turned on or not.
+ * @param int|string $expecteddpoval The expected value for the 'dpo' field. 'dpo' means we'd the expected value would be the
+ * user ID of the privacy officer which happens in the case where a PO requests on behalf of
+ * someone else and automatic data request approval is turned on.
+ * @param int $expectedstatus The expected status of the data request.
+ * @param int $expectedtaskcount The number of expected queued data requests tasks.
+ * @throws coding_exception
+ * @throws invalid_persistent_exception
*/
- public function test_create_data_request_by_dpo() {
+ public function test_create_data_request($asprivacyofficer, $type, $setting, $automaticapproval, $expecteddpoval,
+ $expectedstatus, $expectedtaskcount) {
global $USER;
$this->resetAfterTest();
$user = $generator->create_user();
$comment = 'sample comment';
- // Login as DPO (Admin is DPO by default).
- $this->setAdminUser();
+ // Login.
+ if ($asprivacyofficer) {
+ $this->setAdminUser();
+ } else {
+ $this->setUser($user->id);
+ }
+
+ // Set the automatic data request approval setting value.
+ set_config($setting, $automaticapproval, 'tool_dataprivacy');
+
+ // If set to 'dpo' use the currently logged-in user's ID (which should be the admin user's ID).
+ if ($expecteddpoval === 'dpo') {
+ $expecteddpoval = $USER->id;
+ }
// Test data request creation.
- $datarequest = api::create_data_request($user->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+ $datarequest = api::create_data_request($user->id, $type, $comment);
$this->assertEquals($user->id, $datarequest->get('userid'));
$this->assertEquals($USER->id, $datarequest->get('requestedby'));
- $this->assertEquals(api::DATAREQUEST_TYPE_EXPORT, $datarequest->get('type'));
- $this->assertEquals(api::DATAREQUEST_STATUS_AWAITING_APPROVAL, $datarequest->get('status'));
+ $this->assertEquals($expecteddpoval, $datarequest->get('dpo'));
+ $this->assertEquals($type, $datarequest->get('type'));
+ $this->assertEquals($expectedstatus, $datarequest->get('status'));
$this->assertEquals($comment, $datarequest->get('comments'));
+ $this->assertEquals($automaticapproval, $datarequest->get('systemapproved'));
+
+ // Test number of queued data request tasks.
+ $datarequesttasks = manager::get_adhoc_tasks(process_data_request_task::class);
+ $this->assertCount($expectedtaskcount, $datarequesttasks);
}
/**
set_config('siteadmins', $child->id);
$this->assertFalse(api::can_create_data_deletion_request_for_children($child->id));
}
+
+ /**
+ * Data provider function for testing \tool_dataprivacy\api::queue_data_request_task().
+ *
+ * @return array
+ */
+ public function queue_data_request_task_provider() {
+ return [
+ 'With user ID provided' => [true],
+ 'Without user ID provided' => [false],
+ ];
+ }
+
+ /**
+ * Test for \tool_dataprivacy\api::queue_data_request_task().
+ *
+ * @dataProvider queue_data_request_task_provider
+ * @param bool $withuserid
+ */
+ public function test_queue_data_request_task(bool $withuserid) {
+ $this->resetAfterTest();
+
+ $this->setAdminUser();
+
+ if ($withuserid) {
+ $user = $this->getDataGenerator()->create_user();
+ api::queue_data_request_task(1, $user->id);
+ $expecteduserid = $user->id;
+ } else {
+ api::queue_data_request_task(1);
+ $expecteduserid = null;
+ }
+
+ // Test number of queued data request tasks.
+ $datarequesttasks = manager::get_adhoc_tasks(process_data_request_task::class);
+ $this->assertCount(1, $datarequesttasks);
+ $requesttask = reset($datarequesttasks);
+ $this->assertEquals($expecteduserid, $requesttask->get_userid());
+ }
+
+ /**
+ * Data provider for test_is_automatic_request_approval_on().
+ */
+ public function automatic_request_approval_setting_provider() {
+ return [
+ 'Data export, not set' => [
+ 'automaticdataexportapproval', api::DATAREQUEST_TYPE_EXPORT, null, false
+ ],
+ 'Data export, turned on' => [
+ 'automaticdataexportapproval', api::DATAREQUEST_TYPE_EXPORT, true, true
+ ],
+ 'Data export, turned off' => [
+ 'automaticdataexportapproval', api::DATAREQUEST_TYPE_EXPORT, false, false
+ ],
+ 'Data deletion, not set' => [
+ 'automaticdatadeletionapproval', api::DATAREQUEST_TYPE_DELETE, null, false
+ ],
+ 'Data deletion, turned on' => [
+ 'automaticdatadeletionapproval', api::DATAREQUEST_TYPE_DELETE, true, true
+ ],
+ 'Data deletion, turned off' => [
+ 'automaticdatadeletionapproval', api::DATAREQUEST_TYPE_DELETE, false, false
+ ],
+ ];
+ }
+
+ /**
+ * Test for \tool_dataprivacy\api::is_automatic_request_approval_on().
+ *
+ * @dataProvider automatic_request_approval_setting_provider
+ * @param string $setting The automatic approval setting.
+ * @param int $type The data request type.
+ * @param bool $value The setting's value.
+ * @param bool $expected The expected result.
+ */
+ public function test_is_automatic_request_approval_on($setting, $type, $value, $expected) {
+ $this->resetAfterTest();
+
+ if ($value !== null) {
+ set_config($setting, $value, 'tool_dataprivacy');
+ }
+
+ $this->assertEquals($expected, api::is_automatic_request_approval_on($type));
+ }
}