Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   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 test for the authentication oauth2
  18   *
  19   * @package    auth_oauth2
  20   * @category   test
  21   * @copyright  2018 Carlos Escobedo <carlos@moodle.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  namespace auth_oauth2\privacy;
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  use auth_oauth2\privacy\provider;
  29  use core_privacy\local\request\approved_contextlist;
  30  use core_privacy\local\request\writer;
  31  use core_privacy\tests\provider_testcase;
  32  use core_privacy\local\request\approved_userlist;
  33  
  34  /**
  35   * Privacy test for the authentication oauth2
  36   *
  37   * @package    auth_oauth2
  38   * @category   test
  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_test extends provider_testcase {
  43      /**
  44       * Set up method.
  45       */
  46      public function setUp(): void {
  47          $this->resetAfterTest();
  48          $this->setAdminUser();
  49      }
  50  
  51      /**
  52       * Check that a user context is returned if there is any user data for this user.
  53       */
  54      public function test_get_contexts_for_userid() {
  55          $user = $this->getDataGenerator()->create_user();
  56          $this->assertEmpty(provider::get_contexts_for_userid($user->id));
  57  
  58          $issuer = \core\oauth2\api::create_standard_issuer('google');
  59          $info = [];
  60          $info['username'] = 'gina';
  61          $info['email'] = 'gina@example.com';
  62          \auth_oauth2\api::link_login($info, $issuer, $user->id, false);
  63  
  64          $contextlist = provider::get_contexts_for_userid($user->id);
  65          // Check that we only get back one context.
  66          $this->assertCount(1, $contextlist);
  67  
  68          // Check that a context is returned is the expected.
  69          $usercontext = \context_user::instance($user->id);
  70          $this->assertEquals($usercontext->id, $contextlist->get_contextids()[0]);
  71      }
  72  
  73      /**
  74       * Test that user data is exported correctly.
  75       */
  76      public function test_export_user_data() {
  77          $user = $this->getDataGenerator()->create_user();
  78          $issuer = \core\oauth2\api::create_standard_issuer('google');
  79          $info = [];
  80          $info['username'] = 'gina';
  81          $info['email'] = 'gina@example.com';
  82          \auth_oauth2\api::link_login($info, $issuer, $user->id, false);
  83          $usercontext = \context_user::instance($user->id);
  84  
  85          $writer = writer::with_context($usercontext);
  86          $this->assertFalse($writer->has_any_data());
  87          $approvedlist = new approved_contextlist($user, 'auth_oauth2', [$usercontext->id]);
  88          provider::export_user_data($approvedlist);
  89          $data = $writer->get_data([get_string('privacy:metadata:auth_oauth2', 'auth_oauth2'), $issuer->get('name')]);
  90          $this->assertEquals($info['username'], $data->username);
  91          $this->assertEquals($info['email'], $data->email);
  92      }
  93  
  94      /**
  95       * Test deleting all user data for a specific context.
  96       */
  97      public function test_delete_data_for_all_users_in_context() {
  98          global $DB;
  99  
 100          $user1 = $this->getDataGenerator()->create_user();
 101          $issuer1 = \core\oauth2\api::create_standard_issuer('google');
 102          $info = [];
 103          $info['username'] = 'gina';
 104          $info['email'] = 'gina@example.com';
 105          \auth_oauth2\api::link_login($info, $issuer1, $user1->id, false);
 106          $user1context = \context_user::instance($user1->id);
 107  
 108          $user2 = $this->getDataGenerator()->create_user();
 109          $issuer2 = \core\oauth2\api::create_standard_issuer('microsoft');
 110          $info = [];
 111          $info['username'] = 'jerry';
 112          $info['email'] = 'jerry@example.com';
 113          \auth_oauth2\api::link_login($info, $issuer2, $user2->id, false);
 114          $user2context = \context_user::instance($user2->id);
 115  
 116          // Get all oauth2 accounts.
 117          $oauth2accounts = $DB->get_records('auth_oauth2_linked_login', array());
 118          // There should be two.
 119          $this->assertCount(2, $oauth2accounts);
 120  
 121          // Delete everything for the first user context.
 122          provider::delete_data_for_all_users_in_context($user1context);
 123  
 124          // Get all oauth2 accounts match with user1.
 125          $oauth2accounts = $DB->get_records('auth_oauth2_linked_login', ['userid' => $user1->id]);
 126          $this->assertCount(0, $oauth2accounts);
 127  
 128          // Get all oauth2 accounts.
 129          $oauth2accounts = $DB->get_records('auth_oauth2_linked_login', array());
 130          // There should be one.
 131          $this->assertCount(1, $oauth2accounts);
 132      }
 133  
 134      /**
 135       * This should work identical to the above test.
 136       */
 137      public function test_delete_data_for_user() {
 138          global $DB;
 139  
 140          $user1 = $this->getDataGenerator()->create_user();
 141          $issuer1 = \core\oauth2\api::create_standard_issuer('google');
 142          $info = [];
 143          $info['username'] = 'gina';
 144          $info['email'] = 'gina@example.com';
 145          \auth_oauth2\api::link_login($info, $issuer1, $user1->id, false);
 146          $user1context = \context_user::instance($user1->id);
 147  
 148          $user2 = $this->getDataGenerator()->create_user();
 149          $issuer2 = \core\oauth2\api::create_standard_issuer('microsoft');
 150          $info = [];
 151          $info['username'] = 'jerry';
 152          $info['email'] = 'jerry@example.com';
 153          \auth_oauth2\api::link_login($info, $issuer2, $user2->id, false);
 154          $user2context = \context_user::instance($user2->id);
 155  
 156          // Get all oauth2 accounts.
 157          $oauth2accounts = $DB->get_records('auth_oauth2_linked_login', array());
 158          // There should be two.
 159          $this->assertCount(2, $oauth2accounts);
 160  
 161          // Delete everything for the first user.
 162          $approvedlist = new approved_contextlist($user1, 'auth_oauth2', [$user1context->id]);
 163          provider::delete_data_for_user($approvedlist);
 164  
 165          // Get all oauth2 accounts match with user1.
 166          $oauth2accounts = $DB->get_records('auth_oauth2_linked_login', ['userid' => $user1->id]);
 167          $this->assertCount(0, $oauth2accounts);
 168  
 169          // Get all oauth2 accounts.
 170          $oauth2accounts = $DB->get_records('auth_oauth2_linked_login', array());
 171          // There should be one user.
 172          $this->assertCount(1, $oauth2accounts);
 173      }
 174  
 175      /**
 176       * Test that only users with a user context are fetched.
 177       */
 178      public function test_get_users_in_context() {
 179          $this->resetAfterTest();
 180  
 181          $component = 'auth_oauth2';
 182          // Create a user.
 183          $user = $this->getDataGenerator()->create_user();
 184          $usercontext = \context_user::instance($user->id);
 185  
 186          // The list of users should not return anything yet (related data still haven't been created).
 187          $userlist = new \core_privacy\local\request\userlist($usercontext, $component);
 188          provider::get_users_in_context($userlist);
 189          $this->assertCount(0, $userlist);
 190  
 191          $issuer = \core\oauth2\api::create_standard_issuer('google');
 192          $info = [];
 193          $info['username'] = 'gina';
 194          $info['email'] = 'gina@example.com';
 195          \auth_oauth2\api::link_login($info, $issuer, $user->id, false);
 196  
 197          // The list of users for user context should return the user.
 198          provider::get_users_in_context($userlist);
 199          $this->assertCount(1, $userlist);
 200          $expected = [$user->id];
 201          $actual = $userlist->get_userids();
 202          $this->assertEquals($expected, $actual);
 203  
 204          // The list of users for system context should not return any users.
 205          $systemcontext = \context_system::instance();
 206          $userlist = new \core_privacy\local\request\userlist($systemcontext, $component);
 207          provider::get_users_in_context($userlist);
 208          $this->assertCount(0, $userlist);
 209      }
 210  
 211      /**
 212       * Test that data for users in approved userlist is deleted.
 213       */
 214      public function test_delete_data_for_users() {
 215          $this->resetAfterTest();
 216  
 217          $component = 'auth_oauth2';
 218          // Create user1.
 219          $user1 = $this->getDataGenerator()->create_user();
 220          $usercontext1 = \context_user::instance($user1->id);
 221          // Create user2.
 222          $user2 = $this->getDataGenerator()->create_user();
 223          $usercontext2 = \context_user::instance($user2->id);
 224  
 225          $issuer1 = \core\oauth2\api::create_standard_issuer('google');
 226          $info1 = [];
 227          $info1['username'] = 'gina1';
 228          $info1['email'] = 'gina@example1.com';
 229          \auth_oauth2\api::link_login($info1, $issuer1, $user1->id, false);
 230  
 231          $issuer2 = \core\oauth2\api::create_standard_issuer('google');
 232          $info2 = [];
 233          $info2['username'] = 'gina2';
 234          $info2['email'] = 'gina@example2.com';
 235          \auth_oauth2\api::link_login($info2, $issuer2, $user2->id, false);
 236  
 237          // The list of users for usercontext1 should return user1.
 238          $userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component);
 239          provider::get_users_in_context($userlist1);
 240          $this->assertCount(1, $userlist1);
 241          $expected = [$user1->id];
 242          $actual = $userlist1->get_userids();
 243          $this->assertEquals($expected, $actual);
 244  
 245          // The list of users for usercontext2 should return user2.
 246          $userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component);
 247          provider::get_users_in_context($userlist2);
 248          $this->assertCount(1, $userlist2);
 249          $expected = [$user2->id];
 250          $actual = $userlist2->get_userids();
 251          $this->assertEquals($expected, $actual);
 252  
 253          // Add userlist1 to the approved user list.
 254          $approvedlist = new approved_userlist($usercontext1, $component, $userlist1->get_userids());
 255  
 256          // Delete user data using delete_data_for_user for usercontext1.
 257          provider::delete_data_for_users($approvedlist);
 258  
 259          // Re-fetch users in usercontext1 - The user list should now be empty.
 260          $userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component);
 261          provider::get_users_in_context($userlist1);
 262          $this->assertCount(0, $userlist1);
 263          // Re-fetch users in usercontext2 - The user list should not be empty (user2).
 264          $userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component);
 265          provider::get_users_in_context($userlist2);
 266          $this->assertCount(1, $userlist2);
 267  
 268          // User data should be only removed in the user context.
 269          $systemcontext = \context_system::instance();
 270          // Add userlist2 to the approved user list in the system context.
 271          $approvedlist = new approved_userlist($systemcontext, $component, $userlist2->get_userids());
 272          // Delete user1 data using delete_data_for_user.
 273          provider::delete_data_for_users($approvedlist);
 274          // Re-fetch users in usercontext2 - The user list should not be empty (user2).
 275          $userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component);
 276          provider::get_users_in_context($userlist2);
 277          $this->assertCount(1, $userlist2);
 278      }
 279  }