Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]

   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   * Unit tests for sessionlib.php file.
  19   *
  20   * @package   core
  21   * @category  phpunit
  22   * @author    Petr Skoda <petr.skoda@totaralms.com>
  23   * @copyright 2014 Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
  24   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  /**
  30   * Unit tests for sessionlib.php file.
  31   *
  32   * @package   core
  33   * @category  phpunit
  34   * @author    Petr Skoda <petr.skoda@totaralms.com>
  35   * @copyright 2014 Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
  36   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  37   */
  38  class core_sessionlib_testcase extends advanced_testcase {
  39      public function test_cron_setup_user() {
  40          global $PAGE, $USER, $SESSION, $SITE, $CFG;
  41          $this->resetAfterTest();
  42  
  43          // NOTE: this function contains some static caches, let's reset first.
  44          cron_setup_user('reset');
  45  
  46          $admin = get_admin();
  47          $user1 = $this->getDataGenerator()->create_user();
  48          $user2 = $this->getDataGenerator()->create_user();
  49          $course = $this->getDataGenerator()->create_course();
  50  
  51          cron_setup_user();
  52          $this->assertSame($admin->id, $USER->id);
  53          $this->assertSame($PAGE->context, context_course::instance($SITE->id));
  54          $this->assertSame($CFG->timezone, $USER->timezone);
  55          $this->assertSame('', $USER->lang);
  56          $this->assertSame('', $USER->theme);
  57          $SESSION->test1 = true;
  58          $adminsession = $SESSION;
  59          $adminuser = $USER;
  60          $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
  61          $this->assertSame($GLOBALS['SESSION'], $SESSION);
  62          $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
  63          $this->assertSame($GLOBALS['USER'], $USER);
  64  
  65          cron_setup_user(null, $course);
  66          $this->assertSame($admin->id, $USER->id);
  67          $this->assertSame($PAGE->context, context_course::instance($course->id));
  68          $this->assertSame($adminsession, $SESSION);
  69          $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
  70          $this->assertSame($GLOBALS['SESSION'], $SESSION);
  71          $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
  72          $this->assertSame($GLOBALS['USER'], $USER);
  73  
  74          cron_setup_user($user1);
  75          $this->assertSame($user1->id, $USER->id);
  76          $this->assertSame($PAGE->context, context_course::instance($SITE->id));
  77          $this->assertNotSame($adminsession, $SESSION);
  78          $this->assertObjectNotHasAttribute('test1', $SESSION);
  79          $this->assertEmpty((array)$SESSION);
  80          $usersession1 = $SESSION;
  81          $SESSION->test2 = true;
  82          $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
  83          $this->assertSame($GLOBALS['SESSION'], $SESSION);
  84          $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
  85          $this->assertSame($GLOBALS['USER'], $USER);
  86  
  87          cron_setup_user($user1);
  88          $this->assertSame($user1->id, $USER->id);
  89          $this->assertSame($PAGE->context, context_course::instance($SITE->id));
  90          $this->assertNotSame($adminsession, $SESSION);
  91          $this->assertSame($usersession1, $SESSION);
  92          $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
  93          $this->assertSame($GLOBALS['SESSION'], $SESSION);
  94          $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
  95          $this->assertSame($GLOBALS['USER'], $USER);
  96  
  97          cron_setup_user($user2);
  98          $this->assertSame($user2->id, $USER->id);
  99          $this->assertSame($PAGE->context, context_course::instance($SITE->id));
 100          $this->assertNotSame($adminsession, $SESSION);
 101          $this->assertNotSame($usersession1, $SESSION);
 102          $this->assertEmpty((array)$SESSION);
 103          $usersession2 = $SESSION;
 104          $usersession2->test3 = true;
 105          $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
 106          $this->assertSame($GLOBALS['SESSION'], $SESSION);
 107          $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
 108          $this->assertSame($GLOBALS['USER'], $USER);
 109  
 110          cron_setup_user($user2, $course);
 111          $this->assertSame($user2->id, $USER->id);
 112          $this->assertSame($PAGE->context, context_course::instance($course->id));
 113          $this->assertNotSame($adminsession, $SESSION);
 114          $this->assertNotSame($usersession1, $SESSION);
 115          $this->assertSame($usersession2, $SESSION);
 116          $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
 117          $this->assertSame($GLOBALS['SESSION'], $SESSION);
 118          $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
 119          $this->assertSame($GLOBALS['USER'], $USER);
 120  
 121          cron_setup_user($user1);
 122          $this->assertSame($user1->id, $USER->id);
 123          $this->assertSame($PAGE->context, context_course::instance($SITE->id));
 124          $this->assertNotSame($adminsession, $SESSION);
 125          $this->assertNotSame($usersession1, $SESSION);
 126          $this->assertEmpty((array)$SESSION);
 127          $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
 128          $this->assertSame($GLOBALS['SESSION'], $SESSION);
 129          $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
 130          $this->assertSame($GLOBALS['USER'], $USER);
 131  
 132          cron_setup_user();
 133          $this->assertSame($admin->id, $USER->id);
 134          $this->assertSame($PAGE->context, context_course::instance($SITE->id));
 135          $this->assertSame($adminsession, $SESSION);
 136          $this->assertSame($adminuser, $USER);
 137          $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
 138          $this->assertSame($GLOBALS['SESSION'], $SESSION);
 139          $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
 140          $this->assertSame($GLOBALS['USER'], $USER);
 141  
 142          cron_setup_user('reset');
 143          $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
 144          $this->assertSame($GLOBALS['SESSION'], $SESSION);
 145          $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
 146          $this->assertSame($GLOBALS['USER'], $USER);
 147  
 148          cron_setup_user();
 149          $this->assertNotSame($adminsession, $SESSION);
 150          $this->assertNotSame($adminuser, $USER);
 151          $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
 152          $this->assertSame($GLOBALS['SESSION'], $SESSION);
 153          $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
 154          $this->assertSame($GLOBALS['USER'], $USER);
 155      }
 156  
 157      /**
 158       * Test provided for secure cookie
 159       *
 160       * @return array of config and secure result
 161       */
 162      public function moodle_cookie_secure_provider() {
 163          return array(
 164              array(
 165                  // Non ssl, not set.
 166                  'config' => array(
 167                      'wwwroot'       => 'http://example.com',
 168                      'sslproxy'      => null,
 169                      'cookiesecure'  => null,
 170                  ),
 171                  'secure' => false,
 172              ),
 173              array(
 174                  // Non ssl, off and ignored.
 175                  'config' => array(
 176                      'wwwroot'       => 'http://example.com',
 177                      'sslproxy'      => null,
 178                      'cookiesecure'  => false,
 179                  ),
 180                  'secure' => false,
 181              ),
 182              array(
 183                  // Non ssl, on and ignored.
 184                  'config' => array(
 185                      'wwwroot'       => 'http://example.com',
 186                      'sslproxy'      => null,
 187                      'cookiesecure'  => true,
 188                  ),
 189                  'secure' => false,
 190              ),
 191              array(
 192                  // SSL via proxy, off.
 193                  'config' => array(
 194                      'wwwroot'       => 'http://example.com',
 195                      'sslproxy'      => true,
 196                      'cookiesecure'  => false,
 197                  ),
 198                  'secure' => false,
 199              ),
 200              array(
 201                  // SSL via proxy, on.
 202                  'config' => array(
 203                      'wwwroot'       => 'http://example.com',
 204                      'sslproxy'      => true,
 205                      'cookiesecure'  => true,
 206                  ),
 207                  'secure' => true,
 208              ),
 209              array(
 210                  // SSL and off.
 211                  'config' => array(
 212                      'wwwroot'       => 'https://example.com',
 213                      'sslproxy'      => null,
 214                      'cookiesecure'  => false,
 215                  ),
 216                  'secure' => false,
 217              ),
 218              array(
 219                  // SSL and on.
 220                  'config' => array(
 221                      'wwwroot'       => 'https://example.com',
 222                      'sslproxy'      => null,
 223                      'cookiesecure'  => true,
 224                  ),
 225                  'secure' => true,
 226              ),
 227          );
 228      }
 229  
 230      /**
 231       * Test for secure cookie
 232       *
 233       * @dataProvider moodle_cookie_secure_provider
 234       *
 235       * @param array $config Array of key value config settings
 236       * @param bool $secure Wether cookies should be secure or not
 237       */
 238      public function test_is_moodle_cookie_secure($config, $secure) {
 239          global $CFG;
 240          $this->resetAfterTest();
 241          foreach ($config as $key => $value) {
 242              $CFG->$key = $value;
 243          }
 244          $this->assertEquals($secure, is_moodle_cookie_secure());
 245      }
 246  
 247      public function test_sesskey() {
 248          global $USER;
 249          $this->resetAfterTest();
 250  
 251          $user = $this->getDataGenerator()->create_user();
 252  
 253          \core\session\manager::init_empty_session();
 254          $this->assertObjectNotHasAttribute('sesskey', $USER);
 255  
 256          $sesskey = sesskey();
 257          $this->assertNotEmpty($sesskey);
 258          $this->assertSame($sesskey, $USER->sesskey);
 259          $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
 260          $this->assertSame($GLOBALS['USER'], $USER);
 261  
 262          $this->assertSame($sesskey, sesskey());
 263  
 264          // Test incomplete session init - the sesskeys should return random values.
 265          $_SESSION = array();
 266          unset($GLOBALS['USER']);
 267          unset($GLOBALS['SESSION']);
 268  
 269          $this->assertFalse(sesskey());
 270          $this->assertArrayNotHasKey('USER', $GLOBALS);
 271          $this->assertFalse(sesskey());
 272      }
 273  
 274      public function test_confirm_sesskey() {
 275          $this->resetAfterTest();
 276  
 277          $sesskey = sesskey();
 278  
 279          try {
 280              confirm_sesskey();
 281              $this->fail('Exception expected when sesskey not present');
 282          } catch (moodle_exception $e) {
 283              $this->assertSame('missingparam', $e->errorcode);
 284          }
 285  
 286          $this->assertTrue(confirm_sesskey($sesskey));
 287          $this->assertFalse(confirm_sesskey('blahblah'));
 288  
 289          $_GET['sesskey'] = $sesskey;
 290          $this->assertTrue(confirm_sesskey());
 291  
 292          $_GET['sesskey'] = 'blah';
 293          $this->assertFalse(confirm_sesskey());
 294      }
 295  
 296      public function test_require_sesskey() {
 297          $this->resetAfterTest();
 298  
 299          $sesskey = sesskey();
 300  
 301          try {
 302              require_sesskey();
 303              $this->fail('Exception expected when sesskey not present');
 304          } catch (moodle_exception $e) {
 305              $this->assertSame('missingparam', $e->errorcode);
 306          }
 307  
 308          $_GET['sesskey'] = $sesskey;
 309          require_sesskey();
 310  
 311          $_GET['sesskey'] = 'blah';
 312          try {
 313              require_sesskey();
 314              $this->fail('Exception expected when sesskey not incorrect');
 315          } catch (moodle_exception $e) {
 316              $this->assertSame('invalidsesskey', $e->errorcode);
 317          }
 318      }
 319  }