| 1 | efrain | 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 | /**
 | 
        
           |  |  | 18 |  * Class for loading/storing oauth2 linked logins from the DB.
 | 
        
           |  |  | 19 |  *
 | 
        
           |  |  | 20 |  * @package    auth_oauth2
 | 
        
           |  |  | 21 |  * @copyright  2017 Damyon Wiese
 | 
        
           |  |  | 22 |  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 23 |  */
 | 
        
           |  |  | 24 | namespace auth_oauth2;
 | 
        
           |  |  | 25 |   | 
        
           |  |  | 26 | use context_user;
 | 
        
           |  |  | 27 | use stdClass;
 | 
        
           |  |  | 28 | use moodle_exception;
 | 
        
           |  |  | 29 | use moodle_url;
 | 
        
           |  |  | 30 |   | 
        
           |  |  | 31 | defined('MOODLE_INTERNAL') || die();
 | 
        
           |  |  | 32 |   | 
        
           |  |  | 33 | /**
 | 
        
           |  |  | 34 |  * Static list of api methods for auth oauth2 configuration.
 | 
        
           |  |  | 35 |  *
 | 
        
           |  |  | 36 |  * @package    auth_oauth2
 | 
        
           |  |  | 37 |  * @copyright  2017 Damyon Wiese
 | 
        
           |  |  | 38 |  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 39 |  */
 | 
        
           |  |  | 40 | class api {
 | 
        
           |  |  | 41 |   | 
        
           |  |  | 42 |     /**
 | 
        
           |  |  | 43 |      * Remove all linked logins that are using issuers that have been deleted.
 | 
        
           |  |  | 44 |      *
 | 
        
           |  |  | 45 |      * @param int $issuerid The issuer id of the issuer to check, or false to check all (defaults to all)
 | 
        
           |  |  | 46 |      * @return boolean
 | 
        
           |  |  | 47 |      */
 | 
        
           |  |  | 48 |     public static function clean_orphaned_linked_logins($issuerid = false) {
 | 
        
           |  |  | 49 |         return linked_login::delete_orphaned($issuerid);
 | 
        
           |  |  | 50 |     }
 | 
        
           |  |  | 51 |   | 
        
           |  |  | 52 |     /**
 | 
        
           |  |  | 53 |      * List linked logins
 | 
        
           |  |  | 54 |      *
 | 
        
           |  |  | 55 |      * Requires auth/oauth2:managelinkedlogins capability at the user context.
 | 
        
           |  |  | 56 |      *
 | 
        
           |  |  | 57 |      * @param int $userid (defaults to $USER->id)
 | 
        
           | 1441 | ariadna | 58 |      * @return linked_login[]
 | 
        
           | 1 | efrain | 59 |      */
 | 
        
           |  |  | 60 |     public static function get_linked_logins($userid = false) {
 | 
        
           |  |  | 61 |         global $USER;
 | 
        
           |  |  | 62 |   | 
        
           |  |  | 63 |         if ($userid === false) {
 | 
        
           |  |  | 64 |             $userid = $USER->id;
 | 
        
           |  |  | 65 |         }
 | 
        
           |  |  | 66 |   | 
        
           |  |  | 67 |         if (\core\session\manager::is_loggedinas()) {
 | 
        
           |  |  | 68 |             throw new moodle_exception('notwhileloggedinas', 'auth_oauth2');
 | 
        
           |  |  | 69 |         }
 | 
        
           |  |  | 70 |   | 
        
           |  |  | 71 |         $context = context_user::instance($userid);
 | 
        
           |  |  | 72 |         require_capability('auth/oauth2:managelinkedlogins', $context);
 | 
        
           |  |  | 73 |   | 
        
           |  |  | 74 |         return linked_login::get_records(['userid' => $userid, 'confirmtoken' => '']);
 | 
        
           |  |  | 75 |     }
 | 
        
           |  |  | 76 |   | 
        
           |  |  | 77 |     /**
 | 
        
           |  |  | 78 |      * See if there is a match for this username and issuer in the linked_login table.
 | 
        
           |  |  | 79 |      *
 | 
        
           |  |  | 80 |      * @param string $username as returned from an oauth client.
 | 
        
           |  |  | 81 |      * @param \core\oauth2\issuer $issuer
 | 
        
           | 1441 | ariadna | 82 |      * @return linked_login|false record if found and user exists, false otherwise.
 | 
        
           | 1 | efrain | 83 |      */
 | 
        
           |  |  | 84 |     public static function match_username_to_user($username, $issuer) {
 | 
        
           |  |  | 85 |         $params = [
 | 
        
           |  |  | 86 |             'issuerid' => $issuer->get('id'),
 | 
        
           |  |  | 87 |             'username' => $username
 | 
        
           |  |  | 88 |         ];
 | 
        
           |  |  | 89 |         $result = linked_login::get_record($params);
 | 
        
           |  |  | 90 |   | 
        
           |  |  | 91 |         if ($result) {
 | 
        
           |  |  | 92 |             $user = \core_user::get_user($result->get('userid'));
 | 
        
           |  |  | 93 |             if (!empty($user) && !$user->deleted) {
 | 
        
           |  |  | 94 |                 return $result;
 | 
        
           |  |  | 95 |             }
 | 
        
           |  |  | 96 |         }
 | 
        
           |  |  | 97 |         return false;
 | 
        
           |  |  | 98 |     }
 | 
        
           |  |  | 99 |   | 
        
           |  |  | 100 |     /**
 | 
        
           |  |  | 101 |      * Link a login to this account.
 | 
        
           |  |  | 102 |      *
 | 
        
           |  |  | 103 |      * Requires auth/oauth2:managelinkedlogins capability at the user context.
 | 
        
           |  |  | 104 |      *
 | 
        
           |  |  | 105 |      * @param array $userinfo as returned from an oauth client.
 | 
        
           |  |  | 106 |      * @param \core\oauth2\issuer $issuer
 | 
        
           |  |  | 107 |      * @param int $userid (defaults to $USER->id)
 | 
        
           |  |  | 108 |      * @param bool $skippermissions During signup we need to set this before the user is setup for capability checks.
 | 
        
           | 1441 | ariadna | 109 |      * @return linked_login
 | 
        
           | 1 | efrain | 110 |      */
 | 
        
           |  |  | 111 |     public static function link_login($userinfo, $issuer, $userid = false, $skippermissions = false) {
 | 
        
           |  |  | 112 |         global $USER;
 | 
        
           |  |  | 113 |   | 
        
           |  |  | 114 |         if ($userid === false) {
 | 
        
           |  |  | 115 |             $userid = $USER->id;
 | 
        
           |  |  | 116 |         }
 | 
        
           |  |  | 117 |   | 
        
           |  |  | 118 |         if (linked_login::has_existing_issuer_match($issuer, $userinfo['username'])) {
 | 
        
           |  |  | 119 |             throw new moodle_exception('alreadylinked', 'auth_oauth2');
 | 
        
           |  |  | 120 |         }
 | 
        
           |  |  | 121 |   | 
        
           |  |  | 122 |         if (\core\session\manager::is_loggedinas()) {
 | 
        
           |  |  | 123 |             throw new moodle_exception('notwhileloggedinas', 'auth_oauth2');
 | 
        
           |  |  | 124 |         }
 | 
        
           |  |  | 125 |   | 
        
           |  |  | 126 |         $context = context_user::instance($userid);
 | 
        
           |  |  | 127 |         if (!$skippermissions) {
 | 
        
           |  |  | 128 |             require_capability('auth/oauth2:managelinkedlogins', $context);
 | 
        
           |  |  | 129 |         }
 | 
        
           |  |  | 130 |   | 
        
           |  |  | 131 |         $record = new stdClass();
 | 
        
           |  |  | 132 |         $record->issuerid = $issuer->get('id');
 | 
        
           |  |  | 133 |         $record->username = $userinfo['username'];
 | 
        
           |  |  | 134 |         $record->userid = $userid;
 | 
        
           |  |  | 135 |         $existing = linked_login::get_record((array)$record);
 | 
        
           |  |  | 136 |         if ($existing) {
 | 
        
           |  |  | 137 |             $existing->set('confirmtoken', '');
 | 
        
           |  |  | 138 |             $existing->update();
 | 
        
           |  |  | 139 |             return $existing;
 | 
        
           |  |  | 140 |         }
 | 
        
           |  |  | 141 |         $record->email = $userinfo['email'];
 | 
        
           |  |  | 142 |         $record->confirmtoken = '';
 | 
        
           |  |  | 143 |         $record->confirmtokenexpires = 0;
 | 
        
           |  |  | 144 |         $linkedlogin = new linked_login(0, $record);
 | 
        
           |  |  | 145 |         return $linkedlogin->create();
 | 
        
           |  |  | 146 |     }
 | 
        
           |  |  | 147 |   | 
        
           |  |  | 148 |     /**
 | 
        
           |  |  | 149 |      * Send an email with a link to confirm linking this account.
 | 
        
           |  |  | 150 |      *
 | 
        
           |  |  | 151 |      * @param array $userinfo as returned from an oauth client.
 | 
        
           |  |  | 152 |      * @param \core\oauth2\issuer $issuer
 | 
        
           |  |  | 153 |      * @param int $userid (defaults to $USER->id)
 | 
        
           |  |  | 154 |      * @return bool
 | 
        
           |  |  | 155 |      */
 | 
        
           |  |  | 156 |     public static function send_confirm_link_login_email($userinfo, $issuer, $userid) {
 | 
        
           |  |  | 157 |         $record = new stdClass();
 | 
        
           |  |  | 158 |         $record->issuerid = $issuer->get('id');
 | 
        
           |  |  | 159 |         $record->username = $userinfo['username'];
 | 
        
           |  |  | 160 |         $record->userid = $userid;
 | 
        
           |  |  | 161 |         if (linked_login::has_existing_issuer_match($issuer, $userinfo['username'])) {
 | 
        
           |  |  | 162 |             throw new moodle_exception('alreadylinked', 'auth_oauth2');
 | 
        
           |  |  | 163 |         }
 | 
        
           |  |  | 164 |         $record->email = $userinfo['email'];
 | 
        
           |  |  | 165 |         $record->confirmtoken = random_string(32);
 | 
        
           |  |  | 166 |         $expires = new \DateTime('NOW');
 | 
        
           |  |  | 167 |         $expires->add(new \DateInterval('PT30M'));
 | 
        
           |  |  | 168 |         $record->confirmtokenexpires = $expires->getTimestamp();
 | 
        
           |  |  | 169 |   | 
        
           |  |  | 170 |         $linkedlogin = new linked_login(0, $record);
 | 
        
           |  |  | 171 |         $linkedlogin->create();
 | 
        
           |  |  | 172 |   | 
        
           |  |  | 173 |         // Construct the email.
 | 
        
           |  |  | 174 |         $site = get_site();
 | 
        
           |  |  | 175 |         $supportuser = \core_user::get_support_user();
 | 
        
           |  |  | 176 |         $user = get_complete_user_data('id', $userid);
 | 
        
           |  |  | 177 |   | 
        
           |  |  | 178 |         $data = new stdClass();
 | 
        
           | 1441 | ariadna | 179 |         $placeholders = \core_user::get_name_placeholders($user);
 | 
        
           |  |  | 180 |         foreach ($placeholders as $field => $value) {
 | 
        
           |  |  | 181 |             $data->{$field} = $value;
 | 
        
           |  |  | 182 |         }
 | 
        
           | 1 | efrain | 183 |         $data->sitename  = format_string($site->fullname);
 | 
        
           |  |  | 184 |         $data->admin     = generate_email_signoff();
 | 
        
           |  |  | 185 |         $data->issuername = format_string($issuer->get('name'));
 | 
        
           |  |  | 186 |         $data->linkedemail = format_string($linkedlogin->get('email'));
 | 
        
           |  |  | 187 |   | 
        
           |  |  | 188 |         $subject = get_string('confirmlinkedloginemailsubject', 'auth_oauth2', format_string($site->fullname));
 | 
        
           |  |  | 189 |   | 
        
           |  |  | 190 |         $params = [
 | 
        
           |  |  | 191 |             'token' => $linkedlogin->get('confirmtoken'),
 | 
        
           |  |  | 192 |             'userid' => $userid,
 | 
        
           |  |  | 193 |             'username' => $userinfo['username'],
 | 
        
           |  |  | 194 |             'issuerid' => $issuer->get('id'),
 | 
        
           |  |  | 195 |         ];
 | 
        
           |  |  | 196 |         $confirmationurl = new moodle_url('/auth/oauth2/confirm-linkedlogin.php', $params);
 | 
        
           |  |  | 197 |   | 
        
           |  |  | 198 |         $data->link = $confirmationurl->out(false);
 | 
        
           |  |  | 199 |         $message = get_string('confirmlinkedloginemail', 'auth_oauth2', $data);
 | 
        
           |  |  | 200 |   | 
        
           |  |  | 201 |         $data->link = $confirmationurl->out();
 | 
        
           |  |  | 202 |         $messagehtml = text_to_html(get_string('confirmlinkedloginemail', 'auth_oauth2', $data), false, false, true);
 | 
        
           |  |  | 203 |   | 
        
           |  |  | 204 |         $user->mailformat = 1;  // Always send HTML version as well.
 | 
        
           |  |  | 205 |   | 
        
           |  |  | 206 |         // Directly email rather than using the messaging system to ensure its not routed to a popup or jabber.
 | 
        
           |  |  | 207 |         return email_to_user($user, $supportuser, $subject, $message, $messagehtml);
 | 
        
           |  |  | 208 |     }
 | 
        
           |  |  | 209 |   | 
        
           |  |  | 210 |     /**
 | 
        
           |  |  | 211 |      * Look for a waiting confirmation token, and if we find a match - confirm it.
 | 
        
           |  |  | 212 |      *
 | 
        
           |  |  | 213 |      * @param int $userid
 | 
        
           |  |  | 214 |      * @param string $username
 | 
        
           |  |  | 215 |      * @param int $issuerid
 | 
        
           |  |  | 216 |      * @param string $token
 | 
        
           |  |  | 217 |      * @return boolean True if we linked.
 | 
        
           |  |  | 218 |      */
 | 
        
           |  |  | 219 |     public static function confirm_link_login($userid, $username, $issuerid, $token) {
 | 
        
           |  |  | 220 |         if (empty($token) || empty($userid) || empty($issuerid) || empty($username)) {
 | 
        
           |  |  | 221 |             return false;
 | 
        
           |  |  | 222 |         }
 | 
        
           |  |  | 223 |         $params = [
 | 
        
           |  |  | 224 |             'userid' => $userid,
 | 
        
           |  |  | 225 |             'username' => $username,
 | 
        
           |  |  | 226 |             'issuerid' => $issuerid,
 | 
        
           |  |  | 227 |             'confirmtoken' => $token,
 | 
        
           |  |  | 228 |         ];
 | 
        
           |  |  | 229 |   | 
        
           |  |  | 230 |         $login = linked_login::get_record($params);
 | 
        
           |  |  | 231 |         if (empty($login)) {
 | 
        
           |  |  | 232 |             return false;
 | 
        
           |  |  | 233 |         }
 | 
        
           |  |  | 234 |         $expires = $login->get('confirmtokenexpires');
 | 
        
           |  |  | 235 |         if (time() > $expires) {
 | 
        
           |  |  | 236 |             $login->delete();
 | 
        
           | 1441 | ariadna | 237 |             return false;
 | 
        
           | 1 | efrain | 238 |         }
 | 
        
           |  |  | 239 |         $login->set('confirmtokenexpires', 0);
 | 
        
           |  |  | 240 |         $login->set('confirmtoken', '');
 | 
        
           |  |  | 241 |         $login->update();
 | 
        
           |  |  | 242 |         return true;
 | 
        
           |  |  | 243 |     }
 | 
        
           |  |  | 244 |   | 
        
           |  |  | 245 |     /**
 | 
        
           |  |  | 246 |      * Create an account with a linked login that is already confirmed.
 | 
        
           |  |  | 247 |      *
 | 
        
           |  |  | 248 |      * @param array $userinfo as returned from an oauth client.
 | 
        
           |  |  | 249 |      * @param \core\oauth2\issuer $issuer
 | 
        
           | 1441 | ariadna | 250 |      * @return stdClass
 | 
        
           | 1 | efrain | 251 |      */
 | 
        
           |  |  | 252 |     public static function create_new_confirmed_account($userinfo, $issuer) {
 | 
        
           |  |  | 253 |         global $CFG, $DB;
 | 
        
           |  |  | 254 |         require_once($CFG->dirroot.'/user/profile/lib.php');
 | 
        
           |  |  | 255 |         require_once($CFG->dirroot.'/user/lib.php');
 | 
        
           |  |  | 256 |   | 
        
           |  |  | 257 |         $user = new stdClass();
 | 
        
           |  |  | 258 |         $user->auth = 'oauth2';
 | 
        
           |  |  | 259 |         $user->mnethostid = $CFG->mnet_localhost_id;
 | 
        
           |  |  | 260 |         $user->secret = random_string(15);
 | 
        
           |  |  | 261 |         $user->password = '';
 | 
        
           |  |  | 262 |         $user->confirmed = 1;  // Set the user to confirmed.
 | 
        
           |  |  | 263 |   | 
        
           |  |  | 264 |         $user = self::save_user($userinfo, $user);
 | 
        
           |  |  | 265 |   | 
        
           |  |  | 266 |         // The linked account is pre-confirmed.
 | 
        
           |  |  | 267 |         $record = new stdClass();
 | 
        
           |  |  | 268 |         $record->issuerid = $issuer->get('id');
 | 
        
           |  |  | 269 |         $record->username = $userinfo['username'];
 | 
        
           |  |  | 270 |         $record->userid = $user->id;
 | 
        
           |  |  | 271 |         $record->email = $userinfo['email'];
 | 
        
           |  |  | 272 |         $record->confirmtoken = '';
 | 
        
           |  |  | 273 |         $record->confirmtokenexpires = 0;
 | 
        
           |  |  | 274 |   | 
        
           |  |  | 275 |         $linkedlogin = new linked_login(0, $record);
 | 
        
           |  |  | 276 |         $linkedlogin->create();
 | 
        
           |  |  | 277 |   | 
        
           |  |  | 278 |         return $user;
 | 
        
           |  |  | 279 |     }
 | 
        
           |  |  | 280 |   | 
        
           |  |  | 281 |     /**
 | 
        
           |  |  | 282 |      * Send an email with a link to confirm creating this account.
 | 
        
           |  |  | 283 |      *
 | 
        
           |  |  | 284 |      * @param array $userinfo as returned from an oauth client.
 | 
        
           |  |  | 285 |      * @param \core\oauth2\issuer $issuer
 | 
        
           |  |  | 286 |      * @param int $userid (defaults to $USER->id)
 | 
        
           | 1441 | ariadna | 287 |      * @return stdClass
 | 
        
           | 1 | efrain | 288 |      */
 | 
        
           |  |  | 289 |     public static function send_confirm_account_email($userinfo, $issuer) {
 | 
        
           |  |  | 290 |         global $CFG, $DB;
 | 
        
           |  |  | 291 |         require_once($CFG->dirroot.'/user/profile/lib.php');
 | 
        
           |  |  | 292 |         require_once($CFG->dirroot.'/user/lib.php');
 | 
        
           |  |  | 293 |   | 
        
           |  |  | 294 |         if (linked_login::has_existing_issuer_match($issuer, $userinfo['username'])) {
 | 
        
           |  |  | 295 |             throw new moodle_exception('alreadylinked', 'auth_oauth2');
 | 
        
           |  |  | 296 |         }
 | 
        
           |  |  | 297 |   | 
        
           |  |  | 298 |         $user = new stdClass();
 | 
        
           |  |  | 299 |         $user->auth = 'oauth2';
 | 
        
           |  |  | 300 |         $user->mnethostid = $CFG->mnet_localhost_id;
 | 
        
           |  |  | 301 |         $user->secret = random_string(15);
 | 
        
           |  |  | 302 |         $user->password = '';
 | 
        
           |  |  | 303 |         $user->confirmed = 0;  // The user is not yet confirmed.
 | 
        
           |  |  | 304 |   | 
        
           |  |  | 305 |         $user = self::save_user($userinfo, $user);
 | 
        
           |  |  | 306 |   | 
        
           |  |  | 307 |         // The linked account is pre-confirmed.
 | 
        
           |  |  | 308 |         $record = new stdClass();
 | 
        
           |  |  | 309 |         $record->issuerid = $issuer->get('id');
 | 
        
           |  |  | 310 |         $record->username = $userinfo['username'];
 | 
        
           |  |  | 311 |         $record->userid = $user->id;
 | 
        
           |  |  | 312 |         $record->email = $userinfo['email'];
 | 
        
           |  |  | 313 |         $record->confirmtoken = '';
 | 
        
           |  |  | 314 |         $record->confirmtokenexpires = 0;
 | 
        
           |  |  | 315 |   | 
        
           |  |  | 316 |         $linkedlogin = new linked_login(0, $record);
 | 
        
           |  |  | 317 |         $linkedlogin->create();
 | 
        
           |  |  | 318 |   | 
        
           |  |  | 319 |         // Construct the email.
 | 
        
           |  |  | 320 |         $site = get_site();
 | 
        
           |  |  | 321 |         $supportuser = \core_user::get_support_user();
 | 
        
           |  |  | 322 |         $user = get_complete_user_data('id', $user->id);
 | 
        
           |  |  | 323 |   | 
        
           |  |  | 324 |         $data = new stdClass();
 | 
        
           | 1441 | ariadna | 325 |         $placeholders = \core_user::get_name_placeholders($user);
 | 
        
           |  |  | 326 |         foreach ($placeholders as $field => $value) {
 | 
        
           |  |  | 327 |             $data->{$field} = $value;
 | 
        
           |  |  | 328 |         }
 | 
        
           | 1 | efrain | 329 |         $data->sitename  = format_string($site->fullname);
 | 
        
           |  |  | 330 |         $data->admin     = generate_email_signoff();
 | 
        
           |  |  | 331 |   | 
        
           |  |  | 332 |         $subject = get_string('confirmaccountemailsubject', 'auth_oauth2', format_string($site->fullname));
 | 
        
           |  |  | 333 |   | 
        
           |  |  | 334 |         $params = [
 | 
        
           |  |  | 335 |             'token' => $user->secret,
 | 
        
           |  |  | 336 |             'username' => $userinfo['username']
 | 
        
           |  |  | 337 |         ];
 | 
        
           |  |  | 338 |         $confirmationurl = new moodle_url('/auth/oauth2/confirm-account.php', $params);
 | 
        
           |  |  | 339 |   | 
        
           |  |  | 340 |         $data->link = $confirmationurl->out(false);
 | 
        
           |  |  | 341 |         $message = get_string('confirmaccountemail', 'auth_oauth2', $data);
 | 
        
           |  |  | 342 |   | 
        
           |  |  | 343 |         $data->link = $confirmationurl->out();
 | 
        
           |  |  | 344 |         $messagehtml = text_to_html(get_string('confirmaccountemail', 'auth_oauth2', $data), false, false, true);
 | 
        
           |  |  | 345 |   | 
        
           |  |  | 346 |         $user->mailformat = 1;  // Always send HTML version as well.
 | 
        
           |  |  | 347 |   | 
        
           |  |  | 348 |         // Directly email rather than using the messaging system to ensure its not routed to a popup or jabber.
 | 
        
           |  |  | 349 |         email_to_user($user, $supportuser, $subject, $message, $messagehtml);
 | 
        
           |  |  | 350 |         return $user;
 | 
        
           |  |  | 351 |     }
 | 
        
           |  |  | 352 |   | 
        
           |  |  | 353 |     /**
 | 
        
           | 1441 | ariadna | 354 |      * Delete a users own linked login
 | 
        
           | 1 | efrain | 355 |      *
 | 
        
           |  |  | 356 |      * Requires auth/oauth2:managelinkedlogins capability at the user context.
 | 
        
           |  |  | 357 |      *
 | 
        
           |  |  | 358 |      * @param int $linkedloginid
 | 
        
           |  |  | 359 |      */
 | 
        
           |  |  | 360 |     public static function delete_linked_login($linkedloginid) {
 | 
        
           | 1441 | ariadna | 361 |         global $USER;
 | 
        
           | 1 | efrain | 362 |   | 
        
           |  |  | 363 |         if (\core\session\manager::is_loggedinas()) {
 | 
        
           |  |  | 364 |             throw new moodle_exception('notwhileloggedinas', 'auth_oauth2');
 | 
        
           |  |  | 365 |         }
 | 
        
           |  |  | 366 |   | 
        
           | 1441 | ariadna | 367 |         $login = linked_login::get_record([
 | 
        
           |  |  | 368 |             'id' => $linkedloginid,
 | 
        
           |  |  | 369 |             'userid' => $USER->id,
 | 
        
           |  |  | 370 |             'confirmtoken' => '',
 | 
        
           |  |  | 371 |         ], MUST_EXIST);
 | 
        
           |  |  | 372 |   | 
        
           |  |  | 373 |         $context = context_user::instance($login->get('userid'));
 | 
        
           | 1 | efrain | 374 |         require_capability('auth/oauth2:managelinkedlogins', $context);
 | 
        
           |  |  | 375 |   | 
        
           |  |  | 376 |         $login->delete();
 | 
        
           |  |  | 377 |     }
 | 
        
           |  |  | 378 |   | 
        
           |  |  | 379 |     /**
 | 
        
           |  |  | 380 |      * Delete linked logins for a user.
 | 
        
           |  |  | 381 |      *
 | 
        
           |  |  | 382 |      * @param \core\event\user_deleted $event
 | 
        
           |  |  | 383 |      * @return boolean
 | 
        
           |  |  | 384 |      */
 | 
        
           |  |  | 385 |     public static function user_deleted(\core\event\user_deleted $event) {
 | 
        
           |  |  | 386 |         global $DB;
 | 
        
           |  |  | 387 |   | 
        
           |  |  | 388 |         $userid = $event->objectid;
 | 
        
           |  |  | 389 |   | 
        
           |  |  | 390 |         return $DB->delete_records(linked_login::TABLE, ['userid' => $userid]);
 | 
        
           |  |  | 391 |     }
 | 
        
           |  |  | 392 |   | 
        
           |  |  | 393 |     /**
 | 
        
           |  |  | 394 |      * Is the plugin enabled.
 | 
        
           |  |  | 395 |      *
 | 
        
           |  |  | 396 |      * @return bool
 | 
        
           |  |  | 397 |      */
 | 
        
           |  |  | 398 |     public static function is_enabled() {
 | 
        
           |  |  | 399 |         return is_enabled_auth('oauth2');
 | 
        
           |  |  | 400 |     }
 | 
        
           |  |  | 401 |   | 
        
           |  |  | 402 |     /**
 | 
        
           |  |  | 403 |      * Create a new user & update the profile fields
 | 
        
           |  |  | 404 |      *
 | 
        
           |  |  | 405 |      * @param array $userinfo
 | 
        
           |  |  | 406 |      * @param object $user
 | 
        
           | 1441 | ariadna | 407 |      * @return stdClass
 | 
        
           | 1 | efrain | 408 |      */
 | 
        
           |  |  | 409 |     private static function save_user(array $userinfo, object $user): object {
 | 
        
           |  |  | 410 |         // Map supplied issuer user info to Moodle user fields.
 | 
        
           |  |  | 411 |         $userfieldmapping = new \core\oauth2\user_field_mapping();
 | 
        
           |  |  | 412 |         $userfieldlist = $userfieldmapping->get_internalfields();
 | 
        
           |  |  | 413 |         $hasprofilefield = false;
 | 
        
           |  |  | 414 |         foreach ($userfieldlist as $field) {
 | 
        
           |  |  | 415 |             if (isset($userinfo[$field]) && $userinfo[$field]) {
 | 
        
           |  |  | 416 |                 $user->$field = $userinfo[$field];
 | 
        
           |  |  | 417 |   | 
        
           |  |  | 418 |                 // Check whether the profile fields exist or not.
 | 
        
           |  |  | 419 |                 $hasprofilefield = $hasprofilefield || strpos($field, \core_user\fields::PROFILE_FIELD_PREFIX) === 0;
 | 
        
           |  |  | 420 |             }
 | 
        
           |  |  | 421 |         }
 | 
        
           |  |  | 422 |   | 
        
           |  |  | 423 |         // Create a new user.
 | 
        
           |  |  | 424 |         $user->id = user_create_user($user, false, true);
 | 
        
           |  |  | 425 |   | 
        
           |  |  | 426 |         // If profile fields exist then save custom profile fields data.
 | 
        
           |  |  | 427 |         if ($hasprofilefield) {
 | 
        
           |  |  | 428 |             profile_save_data($user);
 | 
        
           |  |  | 429 |         }
 | 
        
           |  |  | 430 |   | 
        
           |  |  | 431 |         return $user;
 | 
        
           |  |  | 432 |     }
 | 
        
           |  |  | 433 | }
 |