MDL-61882 auth_oauth2: Implement Privacy API
[moodle.git] / auth / oauth2 / classes / privacy / provider.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16 /**
17  * Privacy class for requesting user data for auth_oauth2.
18  *
19  * @package    auth_oauth2
20  * @copyright  2018 Carlos Escobedo <carlos@moodle.com>
21  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22  */
23 namespace auth_oauth2\privacy;
25 defined('MOODLE_INTERNAL') || die();
27 use \core_privacy\local\metadata\collection;
28 use \core_privacy\local\request\contextlist;
29 use \core_privacy\local\request\approved_contextlist;
30 use \core_privacy\local\request\transform;
31 use \core_privacy\local\request\writer;
33 /**
34  * Privacy provider for auth_oauth2
35  *
36  * @package    auth_oauth2
37  * @copyright  2018 Carlos Escobedo <carlos@moodle.com>
38  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39  */
40 class provider implements
41     \core_privacy\local\metadata\provider,
42     \core_privacy\local\request\plugin\provider {
44     /**
45      * Get information about the user data stored by this plugin.
46      *
47      * @param  collection $collection An object for storing metadata.
48      * @return collection The metadata.
49      */
50     public static function get_metadata(collection $collection) : collection {
51         $authfields = [
52             'timecreated' => 'privacy:metadata:auth_oauth2:timecreated',
53             'timemodified' => 'privacy:metadata:auth_oauth2:timemodified',
54             'usermodified' => 'privacy:metadata:auth_oauth2:usermodified',
55             'userid' => 'privacy:metadata:auth_oauth2:userid',
56             'issuerid' => 'privacy:metadata:auth_oauth2:issuerid',
57             'username' => 'privacy:metadata:auth_oauth2:username',
58             'email' => 'privacy:metadata:auth_oauth2:email',
59             'confirmtoken' => 'privacy:metadata:auth_oauth2:confirmtoken',
60             'confirmtokenexpires' => 'privacy:metadata:auth_oauth2:confirmtokenexpires'
61         ];
63         $collection->add_database_table('auth_oauth2_linked_login', $authfields, 'privacy:metadata:auth_oauth2:tableexplanation');
64         $collection->link_subsystem('core_auth', 'privacy:metadata:auth_oauth2:authsubsystem');
66         return $collection;
67     }
69     /**
70      * Return all contexts for this userid. In this situation the user context.
71      *
72      * @param  int $userid The user ID.
73      * @return contextlist The list of context IDs.
74      */
75     public static function get_contexts_for_userid(int $userid) : contextlist {
76         $sql = "SELECT ctx.id
77                   FROM {auth_oauth2_linked_login} ao
78                   JOIN {user} u ON ao.userid = u.id
79                   JOIN {context} ctx ON ctx.instanceid = u.id AND ctx.contextlevel = :contextlevel
80                  WHERE ao.userid = :userid";
81         $params = ['userid' => $userid, 'contextlevel' => CONTEXT_USER];
82         $contextlist = new contextlist();
83         $contextlist->add_from_sql($sql, $params);
85         return $contextlist;
86     }
88     /**
89      * Export all oauth2 information for the list of contexts and this user.
90      *
91      * @param  approved_contextlist $contextlist The list of approved contexts for a user.
92      */
93     public static function export_user_data(approved_contextlist $contextlist) {
94         global $DB;
96         // Export oauth2 linked accounts.
97         $context = \context_user::instance($contextlist->get_user()->id);
98         $sql = "SELECT ll.id, ll.username, ll.email, ll.timecreated, ll.timemodified, oi.name as issuername
99                 FROM {auth_oauth2_linked_login} ll JOIN {oauth2_issuer} oi ON oi.id = ll.issuerid
100                 WHERE ll.userid = :userid";
101         if ($oauth2accounts = $DB->get_records_sql($sql, ['userid' => $contextlist->get_user()->id])) {
102             foreach ($oauth2accounts as $oauth2account) {
103                 $data = (object)[
104                     'timecreated' => transform::datetime($oauth2account->timecreated),
105                     'timemodified' => transform::datetime($oauth2account->timemodified),
106                     'issuerid' => $oauth2account->issuername,
107                     'username' => $oauth2account->username,
108                     'email' => $oauth2account->email
109                 ];
110                 writer::with_context($context)->export_data([
111                         get_string('privacy:metadata:auth_oauth2', 'auth_oauth2'),
112                         $oauth2account->issuername
113                     ], $data);
114             }
115         }
116     }
118     /**
119      * Delete all user data for this context.
120      *
121      * @param  \context $context The context to delete data for.
122      */
123     public static function delete_data_for_all_users_in_context(\context $context) {
124         if (empty($context)) {
125             return;
126         }
128         if ($context->contextlevel != CONTEXT_USER) {
129             return;
130         }
131         static::delete_user_data($context->instanceid);
132     }
134     /**
135      * Delete all user data for this user only.
136      *
137      * @param  approved_contextlist $contextlist The list of approved contexts for a user.
138      */
139     public static function delete_data_for_user(approved_contextlist $contextlist) {
140         if (empty($contextlist->count())) {
141             return;
142         }
143         foreach ($contextlist->get_contexts() as $context) {
144             if ($context->contextlevel != CONTEXT_USER) {
145                 return;
146             }
147             // Because we only use user contexts the instance ID is the user ID.
148             static::delete_user_data($context->instanceid);
149         }
150     }
152     /**
153      * This does the deletion of user data for the auth_oauth2.
154      *
155      * @param  int $userid The user ID
156      */
157     protected static function delete_user_data(int $userid) {
158         global $DB;
160         // Because we only use user contexts the instance ID is the user ID.
161         $DB->delete_records('auth_oauth2_linked_login', ['userid' => $userid]);
162     }