MDL-58774 auth_oauth2: Prevent duplicate linked logins
authorDamyon Wiese <damyon@moodle.com>
Mon, 8 May 2017 06:42:52 +0000 (14:42 +0800)
committerDamyon Wiese <damyon@moodle.com>
Wed, 10 May 2017 02:17:56 +0000 (10:17 +0800)
auth/oauth2/classes/api.php
auth/oauth2/lang/en/auth_oauth2.php
auth/oauth2/linkedlogins.php

index adf3f94..ffcb79c 100644 (file)
@@ -105,6 +105,10 @@ class api {
             $userid = $USER->id;
         }
 
+        if (linked_login::count_records(['username' => $userinfo['username']]) > 0) {
+            throw new moodle_exception('alreadylinked', 'auth_oauth2');
+        }
+
         if (\core\session\manager::is_loggedinas()) {
             throw new moodle_exception('notwhileloggedinas', 'auth_oauth2');
         }
@@ -144,9 +148,8 @@ class api {
         $record->issuerid = $issuer->get('id');
         $record->username = $userinfo['username'];
         $record->userid = $userid;
-        $existing = linked_login::get_record((array)$record);
-        if ($existing) {
-            return false;
+        if (linked_login::count_records(['username' => $userinfo['username']]) > 0) {
+            throw new moodle_exception('alreadylinked', 'auth_oauth2');
         }
         $record->email = $userinfo['email'];
         $record->confirmtoken = random_string(32);
@@ -239,6 +242,10 @@ class api {
         require_once($CFG->dirroot.'/user/profile/lib.php');
         require_once($CFG->dirroot.'/user/lib.php');
 
+        if (linked_login::count_records(['username' => $userinfo['username']]) > 0) {
+            throw new moodle_exception('alreadylinked', 'auth_oauth2');
+        }
+
         $user = new stdClass();
         $user->username = $userinfo['username'];
         $user->email = $userinfo['email'];
index f0715e0..1ba808c 100644 (file)
@@ -83,3 +83,4 @@ $string['notwhileloggedinas'] = 'Linked logins cannot be managed while logged in
 $string['oauth2:managelinkedlogins'] = 'Manage own linked login accounts';
 $string['plugindescription'] = 'This authentication plugin displays a list of the configured identity providers on the login page. Selecting an identity provider allows users to login with their credentials from an OAuth 2 provider.';
 $string['pluginname'] = 'OAuth 2';
+$string['alreadylinked'] = 'This external account is already linked to an account on this site';
index 1228530..fe18f8f 100644 (file)
@@ -58,8 +58,12 @@ if ($action == 'new') {
     $userinfo = $client->get_userinfo();
 
     if (!empty($userinfo)) {
-        \auth_oauth2\api::link_login($userinfo, $issuer);
-        redirect($PAGE->url, get_string('changessaved'), null, \core\output\notification::NOTIFY_SUCCESS);
+        try {
+            \auth_oauth2\api::link_login($userinfo, $issuer);
+            redirect($PAGE->url, get_string('changessaved'), null, \core\output\notification::NOTIFY_SUCCESS);
+        } catch (Exception $e) {
+            redirect($PAGE->url, $e->getMessage(), null, \core\output\notification::NOTIFY_ERROR);
+        }
     } else {
         redirect($PAGE->url, get_string('notloggedin', 'auth_oauth2'), null, \core\output\notification::NOTIFY_ERROR);
     }