Skip to content

Commit 722a2c3

Browse files
committed
add privacy
1 parent 9063f62 commit 722a2c3

File tree

2 files changed

+521
-0
lines changed

2 files changed

+521
-0
lines changed

classes/privacy/provider.php

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
<?php
2+
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
16+
17+
/**
18+
* Plugin privicy provider
19+
*
20+
* @package local_oauth
21+
* @copyright 2024 Rens Sikma <[email protected]>
22+
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23+
*/
24+
namespace local_oauth\privacy;
25+
use core_privacy\local\metadata\collection;
26+
use core_privacy\local\request\approved_contextlist;
27+
use core_privacy\local\request\approved_userlist;
28+
use core_privacy\local\request\userlist;
29+
use core_privacy\local\request\contextlist;
30+
use core_privacy\local\request\transform;
31+
use core_privacy\local\request\writer;
32+
33+
class provider implements
34+
\core_privacy\local\metadata\provider,
35+
\core_privacy\local\request\plugin\provider,
36+
\core_privacy\local\request\core_userlist_provider
37+
{
38+
39+
40+
public static function get_metadata(collection $collection): collection {
41+
42+
$collection->add_database_table(
43+
'local_oauth_user_auth_scopes',
44+
[
45+
'id' => 'privacy:metadata:local_oauth:auth_scopes:id',
46+
'client_id' => 'privacy:metadata:local_oauth:auth_scopes:id',
47+
'user_id' => 'privacy:metadata:local_oauth:auth_scopes:id',
48+
'scope' => 'privacy:metadata:local_oauth:auth_scopes:id',
49+
50+
],
51+
'privacy:metadata:local_oauth:auth_scopes:tableexplanation'
52+
);
53+
54+
$collection->add_database_table(
55+
'local_oauth_refresh_tokens',
56+
[
57+
'id' => 'privacy:metadata:local_oauth:refresh_tokens:id',
58+
'refresh_token' => 'privacy:metadata:local_oauth:refresh_tokens:refresh_token',
59+
'client_id' => 'privacy:metadata:local_oauth:refresh_tokens:client_id',
60+
'user_id' => 'privacy:metadata:local_oauth:refresh_tokens:user_id',
61+
'expires' => 'privacy:metadata:local_oauth:refresh_tokens:expires',
62+
'scope' => 'privacy:metadata:local_oauth:refresh_tokens:scope',
63+
],
64+
'privacy:metadata:local_oauth:refresh_tokens:tableexplanation');
65+
66+
$collection->add_database_table(
67+
'local_oauth_auth_codes',
68+
[
69+
'id' => 'privacy:metadata:local_oauth:auth_codes:id',
70+
'authorization_code' => 'privacy:metadata:local_oauth:auth_codes:authorization_code',
71+
'client_id' => 'privacy:metadata:local_oauth:auth_codes:client_id',
72+
'user_id' => 'privacy:metadata:local_oauth:auth_codes:user_id',
73+
'redirect_uri' => 'privacy:metadata:local_oauth:auth_codes:redirect_uri',
74+
'expires' => 'privacy:metadata:local_oauth:auth_codes:expires',
75+
'scope' => 'privacy:metadata:local_oauth:auth_codes:scope',
76+
'id_token' => 'privacy:metadata:local_oauth:auth_codes:id_token',
77+
],
78+
'privacy:metadata:local_oauth:auth_codes:tableexplanation');
79+
80+
$collection->add_database_table('local_oauth_access_tokens',
81+
[
82+
'id' => 'privacy:metadata:local_oauth:access_tokens:id',
83+
'access_token' => 'privacy:metadata:local_oauth:access_tokens:access_token',
84+
'client_id' => 'privacy:metadata:local_oauth:access_tokens:client_id',
85+
'user_id' => 'privacy:metadata:local_oauth:access_tokens:user_id',
86+
'expires' => 'privacy:metadata:local_oauth:access_tokens:expires',
87+
'scope' => 'privacy:metadata:local_oauth:access_tokens:scope',
88+
],
89+
'privacy:metadata:local_oauth:access_tokens:tableexplanation');
90+
91+
$collection->add_external_location_link(
92+
'oauth_client',
93+
[
94+
'family_name' => 'privacy:metadata:oauth_client:family_name',
95+
'given_name' => 'privacy:metadata:oauth_client:given_name',
96+
'middle_name' => 'privacy:metadata:oauth_client:middle_name',
97+
'nickname' => 'privacy:metadata:oauth_client:nickname',
98+
'preferred_username' => 'privacy:metadata:oauth_client:preferred_username',
99+
'profile' => 'privacy:metadata:oauth_client:profile',
100+
'picture' => 'privacy:metadata:oauth_client:picture',
101+
'zoneinfo' => 'privacy:metadata:oauth_client:zoneinfo',
102+
'updated_at' => 'privacy:metadata:oauth_client:updated_at',
103+
'email' => 'privacy:metadata:oauth_client:email',
104+
'phone_number' => 'privacy:metadata:oauth_client:phone_number',
105+
'street_address' => 'privacy:metadata:oauth_client:street_address',
106+
'locality ' => 'privacy:metadata:oauth_client:locality',
107+
'country' => 'privacy:metadata:oauth_client:country',
108+
'enrolments' => 'privacy:metadata:oauth_client:enrolments',
109+
], 'privacy:metadata:oauth_client');
110+
111+
// plugin also access user and enrolment data but does not store or modify it.
112+
// So we dont have to specify that
113+
114+
return $collection;
115+
}
116+
117+
/**
118+
* Get the list of contexts that contain user information for the specified user.
119+
*
120+
* @param int $userid The user to search.
121+
* @return contextlist $contextlist The list of contexts used in this plugin.
122+
*/
123+
public static function get_contexts_for_userid(int $userid): contextlist {
124+
125+
$contextlist = new \core_privacy\local\request\contextlist();
126+
return $contextlist->add_user_context($userid);
127+
128+
}
129+
130+
/**
131+
* Get the list of users who have data within a context.
132+
*
133+
* @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
134+
*/
135+
public static function get_users_in_context(userlist $userlist) {
136+
global $DB;
137+
$context = $userlist->get_context();
138+
139+
if (!is_a($context, \context_user::class)) {
140+
return;
141+
}
142+
$userid = $context->instanceid;
143+
144+
$hasdata = false;
145+
146+
$hasdata = $hasdata || $DB->record_exists('local_oauth_user_auth_scopes', ['user_id' => $userid]);
147+
$hasdata = $hasdata || $DB->record_exists('local_oauth_refresh_tokens', ['user_id' => $userid]);
148+
$hasdata = $hasdata || $DB->record_exists('local_oauth_auth_codes', ['user_id' => $userid]);
149+
$hasdata = $hasdata || $DB->record_exists('local_oauth_access_tokens', ['user_id' => $userid]);
150+
151+
if ($hasdata) {
152+
$userlist->add_user($userid);
153+
}
154+
}
155+
156+
/**
157+
* Export all user data for the specified user, in the specified contexts, using the supplied exporter instance.
158+
*
159+
* @param approved_contextlist $contextlist The approved contexts to export information for.
160+
*/
161+
public static function export_user_data(approved_contextlist $contextlist) {
162+
global $DB;
163+
$user = $contextlist->get_user();
164+
$context = \context_user::instance($user->id);
165+
$subcontext = [
166+
get_string('plugin', 'local_oauth'),
167+
get_string('pluginname', 'local_oauth'),
168+
];
169+
$notexportedstr = get_string('privacy:request:notexportedsecurity', 'core_external');
170+
171+
$userauthscopes = $DB->get_records('local_oauth_user_auth_scopes', ['user_id' => $user->id]);
172+
foreach ($userauthscopes as $scope) {
173+
$scope->user_id = transform::user($scope->user_id);
174+
writer::with_context($context)->export_data( array_merge($subcontext,[
175+
$scope->client_id,
176+
$scope->scope,
177+
get_string('privacy:metadata:local_oauth:auth_scopes', 'local_oauth')
178+
]), $scope);
179+
}
180+
181+
$refreshtokens = $DB->get_records('local_oauth_refresh_tokens', ['user_id' => $user->id]);
182+
foreach ($refreshtokens as $token) {
183+
$token->user_id = transform::user($token->user_id);
184+
$token->expires = transform::datetime($token->expires);
185+
$token->refresh_token = $notexportedstr;
186+
writer::with_context($context)->export_data(array_merge($subcontext,[
187+
$token->client_id,
188+
$token->scope,
189+
get_string('privacy:metadata:local_oauth:refresh_tokens', 'local_oauth')
190+
]), $token);
191+
}
192+
193+
$oauthcodes = $DB->get_records('local_oauth_auth_codes', ['user_id' => $user->id]);
194+
foreach ($oauthcodes as $code) {
195+
$code->user_id = transform::user($code->user_id);
196+
$code->expires = transform::datetime($code->expires);
197+
$code->authorization_code = $notexportedstr;
198+
writer::with_context($context)->export_data(array_merge($subcontext,[
199+
$code->client_id,
200+
$code->scope,
201+
get_string('privacy:metadata:local_oauth:auth_codes', 'local_oauth'),
202+
]), $code);
203+
}
204+
205+
$accesstokens = $DB->get_records('local_oauth_access_tokens', ['user_id' => $user->id]);
206+
foreach ($accesstokens as $token) {
207+
$token->user_id = transform::user($token->user_id);
208+
$token->expires = transform::datetime($token->expires);
209+
$token->access_token = $notexportedstr;
210+
writer::with_context($context)->export_data( array_merge($subcontext,[
211+
$token->client_id,
212+
$token->scope,
213+
get_string('privacy:metadata:local_oauth:access_tokens', 'local_oauth'),
214+
]), $token);
215+
}
216+
}
217+
218+
219+
/**
220+
* Delete all personal data for all users in the specified context.
221+
*
222+
* @param context $context Context to delete data from.
223+
*/
224+
public static function delete_data_for_all_users_in_context(\context $context) {
225+
226+
if ($context->contextlevel != CONTEXT_USER) {
227+
return;
228+
}
229+
$userid = $context->instanceid;
230+
self->delete_user(userid);
231+
}
232+
233+
/**
234+
* Delete multiple users within a single context.
235+
*
236+
* @param approved_userlist $userlist The approved context and user information to delete information for.
237+
*/
238+
public static function delete_data_for_users(approved_userlist $userlist) {
239+
240+
$context = $userlist->get_context();
241+
if ($context->contextlevel != CONTEXT_USER) {
242+
return;
243+
}
244+
245+
foreach ($userlist->get_userids() as $userid) {
246+
self::delete_user($userid);
247+
}
248+
}
249+
250+
/**
251+
* Delete user data in the list of given contexts.
252+
*
253+
* @param approved_contextlist $contextlist the list of contexts.
254+
*/
255+
public static function delete_data_for_user(approved_contextlist $contextlist) {
256+
}
257+
258+
private static function delete_user(int $userid){
259+
global $DB;
260+
$DB->delete_records('local_oauth_user_auth_scopes', ['user_id' => $userid]);
261+
$DB->delete_records('local_oauth_refresh_tokens', ['user_id' => $userid]);
262+
$DB->delete_records('local_oauth_auth_codes', ['user_id' => $userid]);
263+
$DB->delete_records('local_oauth_access_tokens', ['user_id' => $userid]);
264+
265+
}
266+
267+
}
268+

0 commit comments

Comments
 (0)