Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Privacy API: Difference between revisions

From MoodleDocs
No edit summary
Line 174: Line 174:


You can indicate this by calling the '''link_external_location()''' method on the collection.
You can indicate this by calling the '''link_external_location()''' method on the collection.
====Example===
====Example====
''mod/lti/classes/privacy/provider.php''
''mod/lti/classes/privacy/provider.php''
<code php>
<code php>

Revision as of 13:04, 22 March 2018

Note: This page is a work-in-progress. Feedback and suggested improvements are welcome. Please join the discussion on moodle.org or use the page comments.


Overview

The Privacy API has been implemented to help report the use of data within Moodle Plugins as part of General Data Protection Regulations, and will help admins comply with key user rights such as:

  • request information on the types of personal data held, instances of such data and retention policy for each
  • their right to access their data ("Right of Access") *and* to have their data in a machine readable format ("Right to data portability")
  • deletion of personal data ("Right to erasure" / "right to be forgotten")

It shall be expected that *all* plugins will require to report their use of and storing of personal data as part of their inclusion in the Moodle Plugins Database.

Architecture

The Privacy API comprises 3 components within the core_privacy subsystem:

Metadata providers
A set of PHP interfaces to be implemented by components for that component to describe the kind of data that it stores, and the purpose for its storage
Request providers
A set of PHP interfaces to be implemented by components to allow that component to act upon user requests such as the Right to be Forgotten, and a Subject Access Request
Manager
A concrete class used to bridge components which implement the providers with tools which request their data.

All plugins will be expected to implement a privacy provider class. This class will provide details on personal data being held by the plugin and where it is held, and may implement methods to allow the export or deletion of user data.

Plugins that do not hold personal data

If a plugin does not hold any personal data it should implement a provider class that implements the core_privacy\local\metadata\null_provider.

Some examples of plugin types which might fit this criteria include themes, blocks, filters, editor plugins, etc, however plugins which cause data to be stored elsewhere in Moodle (e.g. via a subsystem call) are considered to store data.

get_reason(): string

This function should return a string that explains why the plugin is asserting that it holds no personal data.

Example

One examples of a plugin which does not store any data would be the Calendar month block which just displays a view of the user’s calendar. It does not store any data itself.

block/calendar_month/classes/privacy/provider.php // …

namespace block_calendar_month\privacy;

class provider implements

   # This plugin does not store any personal user data.
   \core_privacy\local\metadata\null_provider

{

   /**
    * Get the language string identifier with the component's language
    * file to explain why this plugin stores no data.
    *
    * @return  string
    */
   public static function get_reason() : string {
       return 'privacy:null_reason';
   }

}

block/calendar_month/lang/en/block_calendar_month,php $string['privacy:null_reason'] = 'The calendar month block displays information from the Calendar, but does not effect or store any data itself. All changes are made via the Calendar.';

Using Privacy API

Every plugin should define a privacy provider class. At minimum this will describe the data held in the plugin, and implement means for servicing Subject Access Requests (SARs) and Deletion of User Data.

Data is described via a metadata provider, and it is both exported and deleted via an implementation of a request provider.

This must:

  • be named provider,
  • be in a <plugin>\classes\privacy\provider.php file.
  • be in the "<pluginname>\privacy" namespace
  • implement core_privacy\local\metadata\provider or core_privacy\local\metadata\null_provider
  • implement core_privacy\local\request\plugin\provider

namespace mod_peerassessment\privacy;

class provider implements

   \core_privacy\local\metadata\provider,
   \core_privacy\local\request\plugin\provider

{ ... }

Reporting Meta Data

Moodle currently has 6 areas where data can be held:

  • database tables
  • user preferences
  • subsystems
  • external locations
  • other Moodle plugins

A description for user data held in these areas is added to a metadata collection via add_<type>() or link_<type>() methods. $collection->add_database_table($name, $fields, $summary); $collection->add_user_preference($name, $summary); $collection->link_subsystem($name, $summary); $collection->link_external_location($name, $fields, $summary) $collection->link_plugintype($name, $summary);

get_metadata(collection $collection): collection

This function allows you describe the personal data that is held and where it is held in Moodle.

Database tables

Most plugins will hold data in database tables. You should describe each database table and each field within that table that holds user data.

It is up to you to determine which fields constitute the "user data".

Example

mod/forum/classes/privacy/provider.php public static function get_metadata(collection $collection) : collection {

   $collection->add_database_table(
       'forum_discussion_subs',
        [
           'userid' => 'privacy:metadata:forum_discussion_subs:userid',
           'discussionid' => 'privacy:metadata:forum_discussion_subs:discussionid',
           'preference' => 'privacy:metadata:forum_discussion_subs:preference',
        ],
       'privacy:metadata:forum_discussion_subs'
   );
   return $collection;

}

mod/forum/lang/en/forum.php

$string['privacy:metadata:forum_discussion_subs'] = 'Information about the subscriptions to individual forum discussions. This includes when a user has chosen to subscribe to a discussion, or to unsubscribe from one where they would otherwise be subscribed.'; $string['privacy:metadata:forum_discussion_subs:userid'] = 'The ID of the user with this subscription preference.'; $string['privacy:metadata:forum_discussion_subs:discussionid'] = 'The ID of the discussion that was subscribed to.'; $string['privacy:metadata:forum_discussion_subs:preference'] = 'The start time of the subscription.';

Site-Wide User Preferences

Each plugin should be aware of how it handles its own preferences.

Where there are multiple instances of a user-preference (e.g. tool_usertours_tour_completion_time_2) only the general name needs to be indicated.

Any plugin providing user preferences must also implement the core_privacy\local\request\user_preference_provider interface, and the export_user_preferences(int $userid) function.

Moodle Sub System

Your plugin may use one of Moodle's sub-systems to store data (tk Link to list of sub-systems).

You do not have to describe the sub-system in detail, only the how your plugin uses it.

Example

mod/forum/classes/privacy/provider.php public static function get_metadata(collection $collection) : collection {

   $collection->link_subsystem(
       'core_files',
       'privacy:metadata:core_files'
   );
   return $collection;

}

mod/forum/lang/en/forum.php $string['privacy:metadata:core_files'] = 'The forum stores files which have been uploaded by the user to form part of a forum post.';

External Locations

Many plugins will interact with external systems - for example cloud-based services. Often this external location is configurable within the plugin either at the site or the instance level.

You will need to describe each type of target destination, alongside a list of each exported field which includes user data.

The actual destination does not need to be described as this can change based on configuration.

You can indicate this by calling the link_external_location() method on the collection.

Example

mod/lti/classes/privacy/provider.php public static function get_metadata(collection $collection) : collection {

   $collection->link_external_location('lti_client', [
           'userid' => 'privacy:metadata:lti_client:userid',
           'fullname' => 'privacy:metadata:lti_client:fullname',
       ], 'privacy:metadata:lti_client');
   return $collection;

}

admin/tool/usertours/lang/en/tool_usertours.php $string['privacy:metadata:lti_client'] = 'In order to integrate with a remote LTI service, user data needs to be exchanged with that service.'; $string['privacy:metadata:lti_client:userid'] = 'The userid is sent from Moodle to allow you to access your data on the remote system.'; $string['privacy:metadata:lti_client:fullname'] = 'Your full name is sent to the remote system to allow a better user experience.';

Other Moodle plugins

Exporting User Data

To support the export of user data for Subject Access Requests, the plugin provider class should implement \core_privacy\local\request\plugin\provider

There are 3 cases to be considered:

  • Plugins that store user-preferences
  • Plugins that 'define sub-plugins
  • Plugins that are sub-plugins

Plugins that store user-preferences

Plugins that 'define sub-plugins

If your plugin defines sub-plugins you must define a contract between your plugin and any sub-plugins.

For each sub-plugin you define you must create a new interface that extends the \core_privacy\local'request\plugin\subplugin_provider interface.

For example, the Assignment plugin defines the assignsubmission_provider and assignfeedback_provider interfaces, which must be implemented by any Assignment Submission or Feedback plugins.

Plugins that are sub-plugins

If your plugin is a 'sub-plugin' you will need to look at the parent plugin to identify what interface you need to implement.

Deleting User Data

Helpers

Pointers

  • If a field supports Moodle files it must be re-written:

use \core_privacy\local\request\writer; writer::with_context($context)

   ->rewrite_pluginfile_urls($postarea, 'mod_forum', 'post', $post->id, $post->message);