See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401]
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 Subsystem implementation for auth_mnet. 18 * 19 * @package auth_mnet 20 * @copyright 2018 Carlos Escobedo <carlos@moodle.com> 21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 22 */ 23 24 namespace auth_mnet\privacy; 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 use core_privacy\local\metadata\collection; 29 use core_privacy\local\request\contextlist; 30 use core_privacy\local\request\approved_contextlist; 31 use core_privacy\local\request\transform; 32 use core_privacy\local\request\writer; 33 use core_privacy\local\request\userlist; 34 use core_privacy\local\request\approved_userlist; 35 36 /** 37 * Privacy provider for the mnet authentication 38 * 39 * @copyright 2018 Carlos Escobedo <carlos@moodle.com> 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 */ 42 class provider implements 43 \core_privacy\local\metadata\provider, 44 \core_privacy\local\request\core_userlist_provider, 45 \core_privacy\local\request\plugin\provider { 46 /** 47 * Returns meta data about this system. 48 * 49 * @param collection $collection The initialised item collection to add items to. 50 * @return collection A listing of user data stored through this system. 51 */ 52 public static function get_metadata(collection $collection) : collection { 53 54 $sessionfields = [ 55 'userid' => 'privacy:metadata:mnet_session:userid', 56 'username' => 'privacy:metadata:mnet_session:username', 57 'token' => 'privacy:metadata:mnet_session:token', 58 'mnethostid' => 'privacy:metadata:mnet_session:mnethostid', 59 'useragent' => 'privacy:metadata:mnet_session:useragent', 60 'expires' => 'privacy:metadata:mnet_session:expires' 61 ]; 62 63 $collection->add_database_table('mnet_session', $sessionfields, 'privacy:metadata:mnet_session'); 64 65 $logfields = [ 66 'hostid' => 'privacy:metadata:mnet_log:hostid', 67 'remoteid' => 'privacy:metadata:mnet_log:remoteid', 68 'time' => 'privacy:metadata:mnet_log:time', 69 'userid' => 'privacy:metadata:mnet_log:userid', 70 'ip' => 'privacy:metadata:mnet_log:ip', 71 'course' => 'privacy:metadata:mnet_log:course', 72 'coursename' => 'privacy:metadata:mnet_log:coursename', 73 'module' => 'privacy:metadata:mnet_log:module', 74 'cmid' => 'privacy:metadata:mnet_log:cmid', 75 'action' => 'privacy:metadata:mnet_log:action', 76 'url' => 'privacy:metadata:mnet_log:url', 77 'info' => 'privacy:metadata:mnet_log:info' 78 ]; 79 80 $collection->add_database_table('mnet_log', $logfields, 'privacy:metadata:mnet_log'); 81 82 $externalfields = [ 83 'address' => 'privacy:metadata:mnet_external:address', 84 'alternatename' => 'privacy:metadata:mnet_external:alternatename', 85 'autosubscribe' => 'privacy:metadata:mnet_external:autosubscribe', 86 'calendartype' => 'privacy:metadata:mnet_external:calendartype', 87 'city' => 'privacy:metadata:mnet_external:city', 88 'country' => 'privacy:metadata:mnet_external:country', 89 'currentlogin' => 'privacy:metadata:mnet_external:currentlogin', 90 'department' => 'privacy:metadata:mnet_external:department', 91 'description' => 'privacy:metadata:mnet_external:description', 92 'email' => 'privacy:metadata:mnet_external:email', 93 'emailstop' => 'privacy:metadata:mnet_external:emailstop', 94 'firstaccess' => 'privacy:metadata:mnet_external:firstaccess', 95 'firstname' => 'privacy:metadata:mnet_external:firstname', 96 'firstnamephonetic' => 'privacy:metadata:mnet_external:firstnamephonetic', 97 'id' => 'privacy:metadata:mnet_external:id', 98 'idnumber' => 'privacy:metadata:mnet_external:idnumber', 99 'imagealt' => 'privacy:metadata:mnet_external:imagealt', 100 'institution' => 'privacy:metadata:mnet_external:institution', 101 'lang' => 'privacy:metadata:mnet_external:lang', 102 'lastaccess' => 'privacy:metadata:mnet_external:lastaccess', 103 'lastlogin' => 'privacy:metadata:mnet_external:lastlogin', 104 'lastname' => 'privacy:metadata:mnet_external:lastname', 105 'lastnamephonetic' => 'privacy:metadata:mnet_external:lastnamephonetic', 106 'maildigest' => 'privacy:metadata:mnet_external:maildigest', 107 'maildisplay' => 'privacy:metadata:mnet_external:maildisplay', 108 'middlename' => 'privacy:metadata:mnet_external:middlename', 109 'phone1' => 'privacy:metadata:mnet_external:phone1', 110 'pnone2' => 'privacy:metadata:mnet_external:phone2', 111 'picture' => 'privacy:metadata:mnet_external:picture', 112 'policyagreed' => 'privacy:metadata:mnet_external:policyagreed', 113 'suspended' => 'privacy:metadata:mnet_external:suspended', 114 'timezone' => 'privacy:metadata:mnet_external:timezone', 115 'trackforums' => 'privacy:metadata:mnet_external:trackforums', 116 'trustbitmask' => 'privacy:metadata:mnet_external:trustbitmask', 117 'username' => 'privacy:metadata:mnet_external:username', 118 ]; 119 120 $collection->add_external_location_link('moodle', $externalfields, 'privacy:metadata:external:moodle'); 121 122 $collection->add_external_location_link('mahara', $externalfields, 'privacy:metadata:external:mahara'); 123 124 return $collection; 125 } 126 127 /** 128 * Get the list of contexts that contain user information for the specified user. 129 * 130 * @param int $userid The user to search. 131 * @return contextlist $contextlist The list of contexts used in this plugin. 132 */ 133 public static function get_contexts_for_userid(int $userid) : contextlist { 134 $sql = "SELECT ctx.id 135 FROM {mnet_log} ml 136 JOIN {context} ctx ON ctx.instanceid = ml.userid AND ctx.contextlevel = :contextlevel 137 WHERE ml.userid = :userid"; 138 $params = ['userid' => $userid, 'contextlevel' => CONTEXT_USER]; 139 140 $contextlist = new contextlist(); 141 $contextlist->add_from_sql($sql, $params); 142 143 return $contextlist; 144 } 145 146 /** 147 * Get the list of users within a specific context. 148 * 149 * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination. 150 */ 151 public static function get_users_in_context(userlist $userlist) { 152 $context = $userlist->get_context(); 153 154 if (!$context instanceof \context_user) { 155 return; 156 } 157 158 $sql = "SELECT userid 159 FROM {mnet_log} 160 WHERE userid = ?"; 161 $params = [$context->instanceid]; 162 $userlist->add_from_sql('userid', $sql, $params); 163 } 164 165 /** 166 * Export all user data for the specified user, in the specified contexts, using the supplied exporter instance. 167 * 168 * @param approved_contextlist $contextlist The approved contexts to export information for. 169 */ 170 public static function export_user_data(approved_contextlist $contextlist) { 171 global $DB; 172 173 $context = \context_user::instance($contextlist->get_user()->id); 174 175 $sql = "SELECT ml.id, mh.wwwroot, mh.name, ml.remoteid, ml.time, ml.userid, ml.ip, ml.course, 176 ml.coursename, ml.module, ml.cmid, ml.action, ml.url, ml.info 177 FROM {mnet_log} ml 178 JOIN {mnet_host} mh ON mh.id = ml.hostid 179 WHERE ml.userid = :userid 180 ORDER BY mh.name, ml.coursename"; 181 $params = ['userid' => $contextlist->get_user()->id]; 182 183 $data = []; 184 $lastcourseid = null; 185 186 $logentries = $DB->get_recordset_sql($sql, $params); 187 foreach ($logentries as $logentry) { 188 $item = (object) [ 189 'time' => transform::datetime($logentry->time), 190 'remoteid' => $logentry->remoteid, 191 'ip' => $logentry->ip, 192 'course' => $logentry->course, 193 'coursename' => format_string($logentry->coursename), 194 'module' => $logentry->module, 195 'cmid' => $logentry->cmid, 196 'action' => $logentry->action, 197 'url' => $logentry->url, 198 'info' => format_string($logentry->info) 199 ]; 200 201 $item->externalhost = 202 ($logentry->name == '') ? preg_replace('#^https?://#', '', $logentry->wwwroot) : 203 preg_replace('#^https?://#', '', $logentry->name); 204 205 if ($lastcourseid && $lastcourseid != $logentry->course) { 206 $path = [get_string('pluginname', 'auth_mnet'), $data[0]->externalhost, $data[0]->coursename]; 207 writer::with_context($context)->export_data($path, (object) $data); 208 $data = []; 209 } 210 211 $data[] = $item; 212 $lastcourseid = $logentry->course; 213 } 214 $logentries->close(); 215 216 $path = [get_string('pluginname', 'auth_mnet'), $item->externalhost, $item->coursename]; 217 writer::with_context($context)->export_data($path, (object) $data); 218 } 219 220 /** 221 * Delete all personal data for all users in the specified context. 222 * 223 * @param context $context Context to delete data from. 224 */ 225 public static function delete_data_for_all_users_in_context(\context $context) { 226 global $DB; 227 228 if ($context->contextlevel != CONTEXT_USER) { 229 return; 230 } 231 232 $DB->delete_records('mnet_log', ['userid' => $context->instanceid]); 233 } 234 235 /** 236 * Delete multiple users within a single context. 237 * 238 * @param approved_userlist $userlist The approved context and user information to delete information for. 239 */ 240 public static function delete_data_for_users(approved_userlist $userlist) { 241 global $DB; 242 243 $context = $userlist->get_context(); 244 245 if ($context instanceof \context_user) { 246 $DB->delete_records('mnet_log', ['userid' => $context->instanceid]); 247 } 248 } 249 250 /** 251 * Delete all user data for the specified user, in the specified contexts. 252 * 253 * @param approved_contextlist $contextlist The approved contexts and user information to delete information for. 254 */ 255 public static function delete_data_for_user(approved_contextlist $contextlist) { 256 global $DB; 257 258 if (empty($contextlist->count())) { 259 return; 260 } 261 262 $userid = $contextlist->get_user()->id; 263 foreach ($contextlist->get_contexts() as $context) { 264 if ($context->contextlevel != CONTEXT_USER) { 265 continue; 266 } 267 if ($context->instanceid == $userid) { 268 // Because we only use user contexts the instance ID is the user ID. 269 $DB->delete_records('mnet_log', ['userid' => $context->instanceid]); 270 } 271 } 272 } 273 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body