public function test_set_user() { global $USER, $DB; $this->assertEquals(0, $USER->id); $this->assertSame($_SESSION['USER'], $USER); $user = $DB->get_record('user', array('id' => 2)); $this->assertNotEmpty($user); $this->setUser($user); $this->assertEquals(2, $USER->id); $this->assertEquals(2, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); $USER->id = 3; $this->assertEquals(3, $USER->id); $this->assertEquals(3, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); \core\session\manager::set_user($user); $this->assertEquals(2, $USER->id); $this->assertEquals(2, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); $USER = $DB->get_record('user', array('id' => 1)); $this->assertNotEmpty($USER); $this->assertEquals(1, $USER->id); $this->assertEquals(1, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); $this->setUser(null); $this->assertEquals(0, $USER->id); $this->assertSame($_SESSION['USER'], $USER); }
public function test_set_user() { global $USER; $this->resetAfterTest(); $user = $this->getDataGenerator()->create_user(); $this->setUser(0); $this->assertEquals(0, $USER->id); \core\session\manager::set_user($user); $this->assertEquals($user->id, $USER->id); }
public function execute() { global $CFG, $DB; require_once $CFG->dirroot . "/mod/turnitintooltwo/lib.php"; require_once $CFG->dirroot . "/mod/turnitintooltwo/turnitintooltwo_view.class.php"; $data = (array) $this->get_custom_data(); // Make sure we are still wanted. $submission = $DB->get_record('turnitintooltwo_submissions', array('id' => $data['submissionid'])); if (!$submission) { return true; } cli_writeln("Processing Turnitintooltwo submission: " . $data['submissionid']); $user = $DB->get_record('user', array('id' => $data['userid'])); \core\session\manager::set_user($user); $turnitintooltwo = $DB->get_record('turnitintooltwo', array('id' => $data['tiiid'])); list($course, $cm) = get_course_and_cm_from_instance($turnitintooltwo, 'turnitintooltwo'); try { $turnitintooltwoassignment = new \turnitintooltwo_assignment($turnitintooltwo->id, $turnitintooltwo); $turnitintooltwosubmission = new \turnitintooltwo_submission($data['submissionid'], "moodle", $turnitintooltwoassignment); $parts = $turnitintooltwoassignment->get_parts(); $tiisubmission = $turnitintooltwosubmission->do_tii_submission($cm, $turnitintooltwoassignment); // Update submission. $DB->update_record('turnitintooltwo_submissions', array('id' => $data['submissionid'], 'submission_modified' => $data['subtime'])); } catch (\Exception $e) { $tiisubmission = array('success' => false, 'message' => $e->getMessage()); cli_writeln($e->getMessage()); } $digitalreceipt = $tiisubmission; $digitalreceipt['is_manual'] = 0; $digitalreceipt = json_encode($digitalreceipt); $this->update_sub_status($data['submissionid'], $tiisubmission['success'], $digitalreceipt); if ($tiisubmission['success'] === true) { $lockedassignment = new \stdClass(); $lockedassignment->id = $turnitintooltwoassignment->turnitintooltwo->id; $lockedassignment->submitted = 1; $DB->update_record('turnitintooltwo', $lockedassignment); $lockedpart = new \stdClass(); $lockedpart->id = $data['submissionpart']; $lockedpart->submitted = 1; // Disable anonymous marking if post date has passed. if ($parts[$data['submissionpart']]->dtpost <= time()) { $lockedpart->unanon = 1; } $DB->update_record('turnitintooltwo_parts', $lockedpart); cli_writeln("Finished processing successful submission: " . $data['submissionid']); } else { turnitintooltwo_add_to_log($course->id, "errored submission", 'view.php?id=' . $cm->id, "Failed to submit '" . $turnitintooltwosubmission->submission_title . "'", $cm->id, $user->id, array('submissionid' => $data['submissionid'])); cli_writeln("Finished processing unsuccessful submission: " . $data['submissionid']); } \core\session\manager::set_user(get_admin()); return $tiisubmission['success']; }
public function test_set_user() { global $USER, $DB, $SESSION; $this->resetAfterTest(); $this->assertEquals(0, $USER->id); $this->assertSame($_SESSION['USER'], $USER); $this->assertSame($GLOBALS['USER'], $USER); $user = $DB->get_record('user', array('id' => 2)); $this->assertNotEmpty($user); $this->setUser($user); $this->assertEquals(2, $USER->id); $this->assertEquals(2, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); $this->assertSame($GLOBALS['USER'], $USER); $USER->id = 3; $this->assertEquals(3, $USER->id); $this->assertEquals(3, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); $this->assertSame($GLOBALS['USER'], $USER); \core\session\manager::set_user($user); $this->assertEquals(2, $USER->id); $this->assertEquals(2, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); $this->assertSame($GLOBALS['USER'], $USER); $USER = $DB->get_record('user', array('id' => 1)); $this->assertNotEmpty($USER); $this->assertEquals(1, $USER->id); $this->assertEquals(1, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); $this->assertSame($GLOBALS['USER'], $USER); $this->setUser(null); $this->assertEquals(0, $USER->id); $this->assertSame($_SESSION['USER'], $USER); $this->assertSame($GLOBALS['USER'], $USER); // Ensure session is reset after setUser, as it may contain extra info. $SESSION->sometestvalue = true; $this->setUser($user); $this->assertObjectNotHasAttribute('sometestvalue', $SESSION); }
/** * Sets up current user and course environment (lang, etc.) in cron. * Do not use outside of cron script! * * @param stdClass $user full user object, null means default cron user (admin), * value 'reset' means reset internal static caches. * @param stdClass $course full course record, null means $SITE * @return void */ function cron_setup_user($user = NULL, $course = NULL) { global $CFG, $SITE, $PAGE; if (!CLI_SCRIPT) { throw new coding_exception('Function cron_setup_user() cannot be used in normal requests!'); } static $cronuser = NULL; static $cronsession = NULL; if ($user === 'reset') { $cronuser = null; $cronsession = null; \core\session\manager::init_empty_session(); return; } if (empty($cronuser)) { /// ignore admins timezone, language and locale - use site default instead! $cronuser = get_admin(); $cronuser->timezone = $CFG->timezone; $cronuser->lang = ''; $cronuser->theme = ''; unset($cronuser->description); $cronsession = new stdClass(); } if (!$user) { // Cached default cron user (==modified admin for now). \core\session\manager::init_empty_session(); \core\session\manager::set_user($cronuser); $GLOBALS['SESSION'] = $cronsession; } else { // Emulate real user session - needed for caps in cron. if ($GLOBALS['USER']->id != $user->id) { \core\session\manager::init_empty_session(); \core\session\manager::set_user($user); } } // TODO MDL-19774 relying on global $PAGE in cron is a bad idea. // Temporary hack so that cron does not give fatal errors. $PAGE = new moodle_page(); if ($course) { $PAGE->set_course($course); } else { $PAGE->set_course($SITE); } // TODO: it should be possible to improve perf by caching some limited number of users here ;-) }
/** * Authenticate user using username+password or token. * This function sets up $USER global. * It is safe to use has_capability() after this. * This method also verifies user is allowed to use this * server. */ protected function authenticate_user() { global $CFG, $DB; if (!NO_MOODLE_COOKIES) { throw new coding_exception('Cookies must be disabled in WS servers!'); } $loginfaileddefaultparams = array('context' => context_system::instance(), 'other' => array('method' => $this->authmethod, 'reason' => null)); if ($this->authmethod == WEBSERVICE_AUTHMETHOD_USERNAME) { //we check that authentication plugin is enabled //it is only required by simple authentication if (!is_enabled_auth('webservice')) { throw new webservice_access_exception('The web service authentication plugin is disabled.'); } if (!($auth = get_auth_plugin('webservice'))) { throw new webservice_access_exception('The web service authentication plugin is missing.'); } $this->restricted_context = context_system::instance(); if (!$this->username) { throw new moodle_exception('missingusername', 'webservice'); } if (!$this->password) { throw new moodle_exception('missingpassword', 'webservice'); } if (!$auth->user_login_webservice($this->username, $this->password)) { // Log failed login attempts. $params = $loginfaileddefaultparams; $params['other']['reason'] = 'password'; $params['other']['username'] = $this->username; $event = \core\event\webservice_login_failed::create($params); $event->set_legacy_logdata(array(SITEID, 'webservice', get_string('simpleauthlog', 'webservice'), '', get_string('failedtolog', 'webservice') . ": " . $this->username . "/" . $this->password . " - " . getremoteaddr(), 0)); $event->trigger(); throw new moodle_exception('wrongusernamepassword', 'webservice'); } $user = $DB->get_record('user', array('username' => $this->username, 'mnethostid' => $CFG->mnet_localhost_id), '*', MUST_EXIST); } else { if ($this->authmethod == WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN) { $user = $this->authenticate_by_token(EXTERNAL_TOKEN_PERMANENT); } else { $user = $this->authenticate_by_token(EXTERNAL_TOKEN_EMBEDDED); } } //Non admin can not authenticate if maintenance mode $hassiteconfig = has_capability('moodle/site:config', context_system::instance(), $user); if (!empty($CFG->maintenance_enabled) and !$hassiteconfig) { throw new moodle_exception('sitemaintenance', 'admin'); } //only confirmed user should be able to call web service if (!empty($user->deleted)) { $params = $loginfaileddefaultparams; $params['other']['reason'] = 'user_deleted'; $params['other']['username'] = $user->username; $event = \core\event\webservice_login_failed::create($params); $event->set_legacy_logdata(array(SITEID, '', '', '', get_string('wsaccessuserdeleted', 'webservice', $user->username) . " - " . getremoteaddr(), 0, $user->id)); $event->trigger(); throw new webservice_access_exception('Refused web service access for deleted username: '******'other']['reason'] = 'user_unconfirmed'; $params['other']['username'] = $user->username; $event = \core\event\webservice_login_failed::create($params); $event->set_legacy_logdata(array(SITEID, '', '', '', get_string('wsaccessuserunconfirmed', 'webservice', $user->username) . " - " . getremoteaddr(), 0, $user->id)); $event->trigger(); throw new moodle_exception('wsaccessuserunconfirmed', 'webservice', '', $user->username); } //check the user is suspended if (!empty($user->suspended)) { $params = $loginfaileddefaultparams; $params['other']['reason'] = 'user_unconfirmed'; $params['other']['username'] = $user->username; $event = \core\event\webservice_login_failed::create($params); $event->set_legacy_logdata(array(SITEID, '', '', '', get_string('wsaccessusersuspended', 'webservice', $user->username) . " - " . getremoteaddr(), 0, $user->id)); $event->trigger(); throw new webservice_access_exception('Refused web service access for suspended username: '******'other']['reason'] = 'password_expired'; $params['other']['username'] = $user->username; $event = \core\event\webservice_login_failed::create($params); $event->set_legacy_logdata(array(SITEID, '', '', '', get_string('wsaccessuserexpired', 'webservice', $user->username) . " - " . getremoteaddr(), 0, $user->id)); $event->trigger(); throw new webservice_access_exception('Refused web service access for password expired username: '******'nologin') { $params = $loginfaileddefaultparams; $params['other']['reason'] = 'login'; $params['other']['username'] = $user->username; $event = \core\event\webservice_login_failed::create($params); $event->set_legacy_logdata(array(SITEID, '', '', '', get_string('wsaccessusernologin', 'webservice', $user->username) . " - " . getremoteaddr(), 0, $user->id)); $event->trigger(); throw new webservice_access_exception('Refused web service access for nologin authentication username: '******'You are not allowed to use the {$a} protocol (missing capability: webservice/' . $this->wsname . ':use)'); } external_api::set_context_restriction($this->restricted_context); }
/** * See if the request contains a proper username/password for login * * @param Zend_Controller_Request_Http $request The request to check * @return boolean */ public function isValid($request) { // No cookies ! if (!PHPUNIT_TEST) { if (!defined('NO_MOODLE_COOKIES') or !NO_MOODLE_COOKIES) { $this->_error(self::LOGIN_COOKIE); return false; } } $wsusername = $request->getParam($this->_paramusername, ''); $wsusername = clean_param($wsusername, PARAM_RAW); $wspassword = $request->getParam($this->_parampassword, ''); $wspassword = clean_param($wspassword, PARAM_RAW); // Are they empty ? if (empty($wsusername) or empty($wspassword)) { $this->_error(self::LOGIN_MISSING); return false; } // Can we login ? if (!($user = authenticate_user_login($wsusername, $wspassword))) { $this->_error(self::LOGIN_FAIL); return false; } // Set the user to the session enrol_check_plugins($user); \core\session\manager::set_user($user); return true; }
/** * Set the calendar type for this user. * * @param string $type the calendar type we want to set */ private function set_calendar_type($type) { $this->user->calendartype = $type; \core\session\manager::set_user($this->user); }
/** * Require key login. Function terminates with error if key not found or incorrect. * * @uses NO_MOODLE_COOKIES * @uses PARAM_ALPHANUM * @param string $script unique script identifier * @param int $instance optional instance id * @return int Instance ID */ function require_user_key_login($script, $instance = null) { global $DB; if (!NO_MOODLE_COOKIES) { print_error('sessioncookiesdisable'); } // Extra safety. \core\session\manager::write_close(); $keyvalue = required_param('key', PARAM_ALPHANUM); if (!($key = $DB->get_record('user_private_key', array('script' => $script, 'value' => $keyvalue, 'instance' => $instance)))) { print_error('invalidkey'); } if (!empty($key->validuntil) and $key->validuntil < time()) { print_error('expiredkey'); } if ($key->iprestriction) { $remoteaddr = getremoteaddr(null); if (empty($remoteaddr) or !address_in_subnet($remoteaddr, $key->iprestriction)) { print_error('ipmismatch'); } } if (!($user = $DB->get_record('user', array('id' => $key->userid)))) { print_error('invaliduserid'); } // Emulate normal session. enrol_check_plugins($user); \core\session\manager::set_user($user); // Note we are not using normal login. if (!defined('USER_KEY_LOGIN')) { define('USER_KEY_LOGIN', true); } // Return instance id - it might be empty. return $key->instance; }
define('NO_OUTPUT_BUFFERING', true); require __DIR__ . '/../../../../config.php'; require_once $CFG->libdir . '/clilib.php'; // CLI options. list($options, $unrecognized) = cli_get_params(array('help' => false, 'size' => false, 'fixeddataset' => false, 'filesizelimit' => false, 'bypasscheck' => false, 'quiet' => false), array('h' => 'help')); $sitesizes = '* ' . implode(PHP_EOL . '* ', tool_generator_site_backend::get_size_choices()); // Display help. if (!empty($options['help']) || empty($options['size'])) { echo "\nUtility to generate a standard test site data set.\n\nNot for use on live sites; only normally works if debugging is set to DEVELOPER\nlevel.\n\nConsider that, depending on the size you select, this CLI tool can really generate a lot of data, aproximated sizes:\n\n{$sitesizes}\n\nOptions:\n--size Size of the generated site, this value affects the number of courses and their size. Accepted values: XS, S, M, L, XL, or XXL (required)\n--fixeddataset Use a fixed data set instead of randomly generated data\n--filesizelimit Limits the size of the generated files to the specified bytes\n--bypasscheck Bypasses the developer-mode check (be careful!)\n--quiet Do not show any output\n\n-h, --help Print out this help\n\nExample from Moodle root directory:\n\$ php admin/tool/generator/cli/maketestsite.php --size=S\n"; // Exit with error unless we're showing this because they asked for it. exit(empty($options['help']) ? 1 : 0); } // Check debugging is set to developer level. if (empty($options['bypasscheck']) && !$CFG->debugdeveloper) { cli_error(get_string('error_notdebugging', 'tool_generator')); } // Get options. $sizename = $options['size']; $fixeddataset = $options['fixeddataset']; $filesizelimit = $options['filesizelimit']; // Check size. try { $size = tool_generator_site_backend::size_for_name($sizename); } catch (coding_exception $e) { cli_error("Invalid size ({$sizename}). Use --help for help."); } // Switch to admin user account. \core\session\manager::set_user(get_admin()); // Do backend code to generate site. $backend = new tool_generator_site_backend($size, $options['bypasscheck'], $fixeddataset, $filesizelimit, empty($options['quiet'])); $backend->make();
public function test_set_user() { global $USER; $this->resetAfterTest(); $this->assertEquals(0, $USER->id); $user = $this->getDataGenerator()->create_user(); $this->assertObjectHasAttribute('description', $user); $this->assertObjectHasAttribute('password', $user); \core\session\manager::set_user($user); $this->assertEquals($user->id, $USER->id); $this->assertObjectNotHasAttribute('description', $user); $this->assertObjectNotHasAttribute('password', $user); $this->assertObjectHasAttribute('sesskey', $user); $this->assertSame($user, $GLOBALS['USER']); $this->assertSame($GLOBALS['USER'], $_SESSION['USER']); $this->assertSame($GLOBALS['USER'], $USER); }
/** * Sets up current user and course environment (lang, etc.) in cron. * Do not use outside of cron script! * * @param stdClass $user full user object, null means default cron user (admin) * @param $course full course record, null means $SITE * @return void */ function cron_setup_user($user = NULL, $course = NULL) { global $CFG, $SITE, $PAGE; static $cronuser = NULL; static $cronsession = NULL; if (empty($cronuser)) { /// ignore admins timezone, language and locale - use site default instead! $cronuser = get_admin(); $cronuser->timezone = $CFG->timezone; $cronuser->lang = ''; $cronuser->theme = ''; unset($cronuser->description); $cronsession = new stdClass(); } if (!$user) { // cached default cron user (==modified admin for now) \core\session\manager::set_user($cronuser); $_SESSION['SESSION'] = $cronsession; } else { // emulate real user session - needed for caps in cron if ($_SESSION['USER']->id != $user->id) { \core\session\manager::set_user($user); $_SESSION['SESSION'] = new stdClass(); } } // TODO MDL-19774 relying on global $PAGE in cron is a bad idea. // Temporary hack so that cron does not give fatal errors. $PAGE = new moodle_page(); if ($course) { $PAGE->set_course($course); } else { $PAGE->set_course($SITE); } // TODO: it should be possible to improve perf by caching some limited number of users here ;-) }
/** * Set current $USER, reset access cache. * @static * @param null|int|stdClass $user user record, null or 0 means non-logged-in, positive integer means userid * @return void */ public static function setUser($user = null) { global $CFG, $DB; if (is_object($user)) { $user = clone $user; } else { if (!$user) { $user = new stdClass(); $user->id = 0; $user->mnethostid = $CFG->mnet_localhost_id; } else { $user = $DB->get_record('user', array('id' => $user)); } } unset($user->description); unset($user->access); unset($user->preference); // Enusre session is empty, as it may contain caches and user specific info. \core\session\manager::init_empty_session(); \core\session\manager::set_user($user); }
/** * Set the passed user ID to the session user. * * @param int $userid */ function lti_set_session_user($userid) { global $DB; if ($user = $DB->get_record('user', array('id' => $userid))) { \core\session\manager::set_user($user); } }
/** * Resets the test environment. * * @param OutlineExampleEvent|ScenarioEvent $event event fired before scenario. * @throws coding_exception If here we are not using the test database it should be because of a coding error * @BeforeScenario */ public function before_scenario($event) { global $DB, $CFG; // TODO: check config value to ensure site is set for performance data. $moreinfo = 'More info in ' . behat_command::DOCS_URL . '#Running_tests'; $driverexceptionmsg = 'Selenium server is not running, you need to start it to run tests that involve Javascript. ' . $moreinfo; try { $session = $this->getSession(); } catch (CurlExec $e) { // Exception thrown by WebDriver, so only @javascript tests will be caugth; in // behat_util::is_server_running() we already checked that the server is running. throw new Exception($driverexceptionmsg); } catch (DriverException $e) { throw new Exception($driverexceptionmsg); } catch (UnknownError $e) { // Generic 'I have no idea' Selenium error. Custom exception to provide more feedback about possible solutions. $this->throw_unknown_exception($e); } // We need the Mink session to do it and we do it only before the first scenario. if (self::is_first_scenario()) { behat_selectors::register_moodle_selectors($session); behat_context_helper::set_session($session); } // Reset mink session between the scenarios. $session->reset(); // Assign valid data to admin user (some generator-related code needs a valid user). $user = $DB->get_record('user', array('username' => 'admin')); \core\session\manager::set_user($user); // Start always in the the homepage. try { // Let's be conservative as we never know when new upstream issues will affect us. $session->visit($this->locate_path('/')); } catch (UnknownError $e) { $this->throw_unknown_exception($e); } }
/** * Install Moodle DB, * config.php must exist, there must not be any tables in db yet. * * @param array $options adminpass is mandatory * @param bool $interactive * @return void */ function install_cli_database(array $options, $interactive) { global $CFG, $DB; require_once $CFG->libdir . '/environmentlib.php'; require_once $CFG->libdir . '/upgradelib.php'; // show as much debug as possible @error_reporting(E_ALL | E_STRICT); @ini_set('display_errors', '1'); $CFG->debug = E_ALL | E_STRICT; $CFG->debugdisplay = true; $CFG->debugdeveloper = true; $CFG->version = ''; $CFG->release = ''; $CFG->branch = ''; $version = null; $release = null; $branch = null; // read $version and $release require $CFG->dirroot . '/version.php'; if ($DB->get_tables()) { cli_error(get_string('clitablesexist', 'install')); } if (empty($options['adminpass'])) { cli_error('Missing required admin password'); } // test environment first list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE); if (!$envstatus) { $errors = environment_get_errors($environment_results); cli_heading(get_string('environment', 'admin')); foreach ($errors as $error) { list($info, $report) = $error; echo "!! {$info} !!\n{$report}\n\n"; } exit(1); } if (!$DB->setup_is_unicodedb()) { if (!$DB->change_db_encoding()) { // If could not convert successfully, throw error, and prevent installation cli_error(get_string('unicoderequired', 'admin')); } } if ($interactive) { cli_separator(); cli_heading(get_string('databasesetup')); } // install core install_core($version, true); set_config('release', $release); set_config('branch', $branch); if (PHPUNIT_TEST) { // mark as test database as soon as possible set_config('phpunittest', 'na'); } // install all plugins types, local, etc. upgrade_noncore(true); // set up admin user password $DB->set_field('user', 'password', hash_internal_user_password($options['adminpass']), array('username' => 'admin')); // rename admin username if needed if (isset($options['adminuser']) and $options['adminuser'] !== 'admin' and $options['adminuser'] !== 'guest') { $DB->set_field('user', 'username', $options['adminuser'], array('username' => 'admin')); } // indicate that this site is fully configured set_config('rolesactive', 1); upgrade_finished(); // log in as admin - we need do anything when applying defaults \core\session\manager::set_user(get_admin()); // apply all default settings, do it twice to fill all defaults - some settings depend on other setting admin_apply_default_settings(NULL, true); admin_apply_default_settings(NULL, true); set_config('registerauth', ''); // set the site name if (isset($options['shortname']) and $options['shortname'] !== '') { $DB->set_field('course', 'shortname', $options['shortname'], array('format' => 'site')); } if (isset($options['fullname']) and $options['fullname'] !== '') { $DB->set_field('course', 'fullname', $options['fullname'], array('format' => 'site')); } }
/** * Setup $USER object - called during login, loginas, etc. * * Call sync_user_enrolments() manually after log-in, or log-in-as. * * @deprecated since 2.6 * @param stdClass $user full user record object * @return void */ function session_set_user($user) { debugging('session_set_user() is deprecated, use \\core\\session\\manager::set_user() instead', DEBUG_DEVELOPER); \core\session\manager::set_user($user); }
/** * Resets the test environment. * * @throws coding_exception If here we are not using the test database it should be because of a coding error * @BeforeScenario */ public function before_scenario($event) { global $DB, $SESSION, $CFG; // As many checks as we can. if (!defined('BEHAT_TEST') || !defined('BEHAT_SITE_RUNNING') || php_sapi_name() != 'cli' || !behat_util::is_test_mode_enabled() || !behat_util::is_test_site()) { throw new coding_exception('Behat only can modify the test database and the test dataroot!'); } $moreinfo = 'More info in ' . behat_command::DOCS_URL . '#Running_tests'; $driverexceptionmsg = 'Selenium server is not running, you need to start it to run tests that involve Javascript. ' . $moreinfo; try { $session = $this->getSession(); } catch (CurlExec $e) { // Exception thrown by WebDriver, so only @javascript tests will be caugth; in // behat_util::is_server_running() we already checked that the server is running. throw new Exception($driverexceptionmsg); } catch (DriverException $e) { throw new Exception($driverexceptionmsg); } catch (UnknownError $e) { // Generic 'I have no idea' Selenium error. Custom exception to provide more feedback about possible solutions. $this->throw_unknown_exception($e); } // We need the Mink session to do it and we do it only before the first scenario. if (self::is_first_scenario()) { behat_selectors::register_moodle_selectors($session); behat_context_helper::set_session($session); } // Reset $SESSION. \core\session\manager::init_empty_session(); behat_util::reset_database(); behat_util::reset_dataroot(); accesslib_clear_all_caches(true); // Reset the nasty strings list used during the last test. nasty_strings::reset_used_strings(); // Assign valid data to admin user (some generator-related code needs a valid user). $user = $DB->get_record('user', array('username' => 'admin')); \core\session\manager::set_user($user); // Reset the browser if specified in config.php. if (!empty($CFG->behat_restart_browser_after) && $this->running_javascript()) { $now = time(); if (self::$lastbrowsersessionstart + $CFG->behat_restart_browser_after < $now) { $session->restart(); self::$lastbrowsersessionstart = $now; } } // Start always in the the homepage. try { // Let's be conservative as we never know when new upstream issues will affect us. $session->visit($this->locate_path('/')); } catch (UnknownError $e) { $this->throw_unknown_exception($e); } // Checking that the root path is a Moodle test site. if (self::is_first_scenario()) { $notestsiteexception = new Exception('The base URL (' . $CFG->wwwroot . ') is not a behat test site, ' . 'ensure you started the built-in web server in the correct directory or your web server is correctly started and set up'); $this->find("xpath", "//head/child::title[normalize-space(.)='" . behat_util::BEHATSITENAME . "']", $notestsiteexception); self::$initprocessesfinished = true; } // Run all test with medium (1024x768) screen size, to avoid responsive problems. $this->resize_window('medium'); }
/** * Set current $USER, reset access cache. * @static * @param null|int|stdClass $user user record, null or 0 means non-logged-in, positive integer means userid * @return void */ public static function setUser($user = null) { global $CFG, $DB; if (is_object($user)) { $user = clone($user); } else if (!$user) { $user = new stdClass(); $user->id = 0; $user->mnethostid = $CFG->mnet_localhost_id; } else { $user = $DB->get_record('user', array('id'=>$user)); } unset($user->description); unset($user->access); unset($user->preference); \core\session\manager::set_user($user); }
/** * Resets the test environment. * * @param OutlineExampleEvent|ScenarioEvent $event event fired before scenario. * @throws coding_exception If here we are not using the test database it should be because of a coding error * @BeforeScenario */ public function before_scenario($event) { global $DB, $CFG; // TODO: check config value to ensure site is set for performance data. $moreinfo = 'More info in ' . behat_command::DOCS_URL . '#Running_tests'; $driverexceptionmsg = 'Selenium server is not running, you need to start it to run tests that involve Javascript. ' . $moreinfo; try { $session = $this->getSession(); } catch (CurlExec $e) { // Exception thrown by WebDriver, so only @javascript tests will be caugth; in // behat_util::is_server_running() we already checked that the server is running. throw new Exception($driverexceptionmsg); } catch (DriverException $e) { throw new Exception($driverexceptionmsg); } catch (UnknownError $e) { // Generic 'I have no idea' Selenium error. Custom exception to provide more feedback about possible solutions. $this->throw_unknown_exception($e); } // We need the Mink session to do it and we do it only before the first scenario. if (self::is_first_scenario()) { behat_selectors::register_moodle_selectors($session); behat_context_helper::set_session($session); } // Reset mink session between the scenarios. $session->reset(); // Assign valid data to admin user (some generator-related code needs a valid user). $user = $DB->get_record('user', array('username' => 'admin')); \core\session\manager::set_user($user); // Start always in the the homepage. try { // Let's be conservative as we never know when new upstream issues will affect us. $session->visit($this->locate_path('/')); } catch (UnknownError $e) { $this->throw_unknown_exception($e); } // Checking that the root path is a Moodle test site. /*if (self::is_first_scenario()) { $notestsiteexception = new Exception('The base URL (' . $CFG->wwwroot . ') is not a behat test site, ' . 'ensure you started the built-in web server in the correct directory or your web server is correctly started and set up'); $this->find("xpath", "//head/child::title[normalize-space(.)='" . behat_util::BEHATSITENAME . "']", $notestsiteexception); self::$initprocessesfinished = true; }*/ }
/** * Require key login. Function terminates with error if key not found or incorrect. * * @uses NO_MOODLE_COOKIES * @uses PARAM_ALPHANUM * @param string $script unique script identifier * @param int $instance optional instance id * @return int Instance ID */ function require_user_key_login($script, $instance = null) { global $DB; if (!NO_MOODLE_COOKIES) { print_error('sessioncookiesdisable'); } // Extra safety. \core\session\manager::write_close(); $keyvalue = required_param('key', PARAM_ALPHANUM); $key = validate_user_key($keyvalue, $script, $instance); if (!($user = $DB->get_record('user', array('id' => $key->userid)))) { print_error('invaliduserid'); } // Emulate normal session. enrol_check_plugins($user); \core\session\manager::set_user($user); // Note we are not using normal login. if (!defined('USER_KEY_LOGIN')) { define('USER_KEY_LOGIN', true); } // Return instance id - it might be empty. return $key->instance; }
/** * Resets the test environment. * * @param BeforeScenarioScope $scope scope passed by event fired before scenario. * @throws behat_stop_exception If here we are not using the test database it should be because of a coding error */ public function before_scenario(BeforeScenarioScope $scope) { global $DB, $CFG; // As many checks as we can. if (!defined('BEHAT_TEST') || !defined('BEHAT_SITE_RUNNING') || php_sapi_name() != 'cli' || !behat_util::is_test_mode_enabled() || !behat_util::is_test_site()) { throw new behat_stop_exception('Behat only can modify the test database and the test dataroot!'); } $moreinfo = 'More info in ' . behat_command::DOCS_URL . '#Running_tests'; $driverexceptionmsg = 'Selenium server is not running, you need to start it to run tests that involve Javascript. ' . $moreinfo; try { $session = $this->getSession(); } catch (CurlExec $e) { // Exception thrown by WebDriver, so only @javascript tests will be caugth; in // behat_util::check_server_status() we already checked that the server is running. throw new behat_stop_exception($driverexceptionmsg); } catch (DriverException $e) { throw new behat_stop_exception($driverexceptionmsg); } catch (UnknownError $e) { // Generic 'I have no idea' Selenium error. Custom exception to provide more feedback about possible solutions. throw new behat_stop_exception($e->getMessage()); } $suitename = $scope->getSuite()->getName(); // Register behat selectors for theme, if suite is changed. We do it for every suite change. if ($suitename !== self::$runningsuite) { behat_context_helper::set_environment($scope->getEnvironment()); // We need the Mink session to do it and we do it only before the first scenario. $namedpartialclass = 'behat_partial_named_selector'; $namedexactclass = 'behat_exact_named_selector'; if ($suitename !== 'default') { // If override selector exist, then set it as default behat selectors class. $overrideclass = behat_config_util::get_behat_theme_selector_override_classname($suitename, 'named_partial', true); if (class_exists($overrideclass)) { $namedpartialclass = $overrideclass; } // If override selector exist, then set it as default behat selectors class. $overrideclass = behat_config_util::get_behat_theme_selector_override_classname($suitename, 'named_exact', true); if (class_exists($overrideclass)) { $namedexactclass = $overrideclass; } } $this->getSession()->getSelectorsHandler()->registerSelector('named_partial', new $namedpartialclass()); $this->getSession()->getSelectorsHandler()->registerSelector('named_exact', new $namedexactclass()); } // Reset mink session between the scenarios. $session->reset(); // Reset $SESSION. \core\session\manager::init_empty_session(); behat_util::reset_all_data(); // Assign valid data to admin user (some generator-related code needs a valid user). $user = $DB->get_record('user', array('username' => 'admin')); \core\session\manager::set_user($user); // Reset the browser if specified in config.php. if (!empty($CFG->behat_restart_browser_after) && $this->running_javascript()) { $now = time(); if (self::$lastbrowsersessionstart + $CFG->behat_restart_browser_after < $now) { $session->restart(); self::$lastbrowsersessionstart = $now; } } // Set the theme if not default. if ($suitename !== "default") { set_config('theme', $suitename); self::$runningsuite = $suitename; } // Start always in the the homepage. try { // Let's be conservative as we never know when new upstream issues will affect us. $session->visit($this->locate_path('/')); } catch (UnknownError $e) { throw new behat_stop_exception($e->getMessage()); } // Checking that the root path is a Moodle test site. if (self::is_first_scenario()) { $notestsiteexception = new behat_stop_exception('The base URL (' . $CFG->wwwroot . ') is not a behat test site, ' . 'ensure you started the built-in web server in the correct directory or your web server is correctly started and set up'); $this->find("xpath", "//head/child::title[normalize-space(.)='" . behat_util::BEHATSITENAME . "']", $notestsiteexception); self::$initprocessesfinished = true; } // Run all test with medium (1024x768) screen size, to avoid responsive problems. $this->resize_window('medium'); }
/** * Reset contents of all database tables to initial values, reset caches, etc. * * Note: this is relatively slow (cca 2 seconds for pg and 7 for mysql) - please use with care! * * @static * @param bool $detectchanges * true - changes in global state and database are reported as errors * false - no errors reported * null - only critical problems are reported as errors * @return void */ public static function reset_all_data($detectchanges = false) { global $DB, $CFG, $USER, $SITE, $COURSE, $PAGE, $OUTPUT, $SESSION; // Stop any message redirection. phpunit_util::stop_message_redirection(); // Stop any message redirection. phpunit_util::stop_phpmailer_redirection(); // Stop any message redirection. phpunit_util::stop_event_redirection(); // Release memory and indirectly call destroy() methods to release resource handles, etc. gc_collect_cycles(); // Show any unhandled debugging messages, the runbare() could already reset it. self::display_debugging_messages(); self::reset_debugging(); // reset global $DB in case somebody mocked it $DB = self::get_global_backup('DB'); if ($DB->is_transaction_started()) { // we can not reset inside transaction $DB->force_transaction_rollback(); } $resetdb = self::reset_database(); $warnings = array(); if ($detectchanges === true) { if ($resetdb) { $warnings[] = 'Warning: unexpected database modification, resetting DB state'; } $oldcfg = self::get_global_backup('CFG'); $oldsite = self::get_global_backup('SITE'); foreach ($CFG as $k => $v) { if (!property_exists($oldcfg, $k)) { $warnings[] = 'Warning: unexpected new $CFG->' . $k . ' value'; } else { if ($oldcfg->{$k} !== $CFG->{$k}) { $warnings[] = 'Warning: unexpected change of $CFG->' . $k . ' value'; } } unset($oldcfg->{$k}); } if ($oldcfg) { foreach ($oldcfg as $k => $v) { $warnings[] = 'Warning: unexpected removal of $CFG->' . $k; } } if ($USER->id != 0) { $warnings[] = 'Warning: unexpected change of $USER'; } if ($COURSE->id != $oldsite->id) { $warnings[] = 'Warning: unexpected change of $COURSE'; } } if (ini_get('max_execution_time') != 0) { // This is special warning for all resets because we do not want any // libraries to mess with timeouts unintentionally. // Our PHPUnit integration is not supposed to change it either. if ($detectchanges !== false) { $warnings[] = 'Warning: max_execution_time was changed to ' . ini_get('max_execution_time'); } set_time_limit(0); } // restore original globals $_SERVER = self::get_global_backup('_SERVER'); $CFG = self::get_global_backup('CFG'); $SITE = self::get_global_backup('SITE'); $_GET = array(); $_POST = array(); $_FILES = array(); $_REQUEST = array(); $COURSE = $SITE; // reinitialise following globals $OUTPUT = new bootstrap_renderer(); $PAGE = new moodle_page(); $FULLME = null; $ME = null; $SCRIPT = null; $SESSION = new stdClass(); $_SESSION['SESSION'] =& $SESSION; // set fresh new not-logged-in user $user = new stdClass(); $user->id = 0; $user->mnethostid = $CFG->mnet_localhost_id; \core\session\manager::set_user($user); // reset all static caches \core\event\manager::phpunit_reset(); accesslib_clear_all_caches(true); get_string_manager()->reset_caches(true); reset_text_filters_cache(true); events_get_handlers('reset'); core_text::reset_caches(); get_message_processors(false, true); filter_manager::reset_caches(); //TODO MDL-25290: add more resets here and probably refactor them to new core function // Reset course and module caches. if (class_exists('format_base')) { // If file containing class is not loaded, there is no cache there anyway. format_base::reset_course_cache(0); } get_fast_modinfo(0, 0, true); // Reset other singletons. if (class_exists('core_plugin_manager')) { core_plugin_manager::reset_caches(true); } if (class_exists('\\core\\update\\checker')) { \core\update\checker::reset_caches(true); } if (class_exists('\\core\\update\\deployer')) { \core\update\deployer::reset_caches(true); } // purge dataroot directory self::reset_dataroot(); // restore original config once more in case resetting of caches changed CFG $CFG = self::get_global_backup('CFG'); // inform data generator self::get_data_generator()->reset(); // fix PHP settings error_reporting($CFG->debug); // verify db writes just in case something goes wrong in reset if (self::$lastdbwrites != $DB->perf_get_writes()) { error_log('Unexpected DB writes in phpunit_util::reset_all_data()'); self::$lastdbwrites = $DB->perf_get_writes(); } if ($warnings) { $warnings = implode("\n", $warnings); trigger_error($warnings, E_USER_WARNING); } }
/** * Login as another user - no security checks here. * @param int $userid * @param \context $context * @return void */ public static function loginas($userid, \context $context) { global $USER; if (self::is_loggedinas()) { return; } // Switch to fresh new $_SESSION. $_SESSION = array(); $_SESSION['REALSESSION'] = clone $GLOBALS['SESSION']; $GLOBALS['SESSION'] = new \stdClass(); $_SESSION['SESSION'] =& $GLOBALS['SESSION']; // Create the new $USER object with all details and reload needed capabilities. $_SESSION['REALUSER'] = clone $GLOBALS['USER']; $user = get_complete_user_data('id', $userid); $user->realuser = $_SESSION['REALUSER']->id; $user->loginascontext = $context; // Let enrol plugins deal with new enrolments if necessary. enrol_check_plugins($user); // Create event before $USER is updated. $event = \core\event\user_loggedinas::create(array('objectid' => $USER->id, 'context' => $context, 'relateduserid' => $userid, 'other' => array('originalusername' => fullname($USER, true), 'loggedinasusername' => fullname($user, true)))); // Set up global $USER. \core\session\manager::set_user($user); $event->trigger(); }
} $PAGE->set_url($url); if (!($chatuser = $DB->get_record('chat_users', array('sid' => $chatsid)))) { print_error('notlogged', 'chat'); } // Get the minimal course. if (!($course = $DB->get_record('course', array('id' => $chatuser->course)))) { print_error('invalidcourseid'); } // Get the user theme and enough info to be used in chat_format_message() which passes it along to // chat_format_message_manually() -- and only id and timezone are used. // No optimisation here, it would break again in future! if (!($user = $DB->get_record('user', array('id' => $chatuser->userid, 'deleted' => 0, 'suspended' => 0)))) { print_error('invaliduser'); } \core\session\manager::set_user($user); // Setup course, lang and theme. $PAGE->set_course($course); // Force deleting of timed out users if there is a silence in room or just entering. if (time() - $chatlasttime > $CFG->chat_old_ping) { // Must be done before chat_get_latest_message! chat_delete_old_users(); } // Time to send headers, and lay out the basic JS updater page. header('Expires: Sun, 28 Dec 1997 09:32:45 GMT'); header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); header('Cache-Control: no-cache, must-revalidate'); header('Pragma: no-cache'); header('Content-Type: text/html; charset=utf-8'); $refreshurl = "{$CFG->wwwroot}/mod/chat/gui_header_js/jsupdated.php?" . "chat_sid={$chatsid}&chat_lasttime={$chatlasttime}&chat_lastrow={$chatnewrow}&chat_lastid={$chatlastid}"; ?>
/** * Get recent activity for course(s) * * The passed course(s) will get populated with recent activity * and returned. EG: $course->recentactivity = array(...of activity...); * * @param int $timestart Look for activity after this time * @param array|stdClass $courses An array of course objects or a single course object * @param mixed $otheruser The user who will view the list of activity. If NULL, then currently logged in user is used. * @throws Exception * @return array */ public function direct($timestart, $courses, $otheruser = NULL) { global $DB, $CFG, $USER; $recentactivity = array(); // Param checks if (is_null($timestart) or empty($courses)) { return $recentactivity; } if (!is_array($courses)) { $courses = array($courses->id => $courses); } if (!is_null($otheruser)) { $currentuser = clone $USER; enrol_check_plugins($otheruser); \core\session\manager::set_user($otheruser); } else { $currentuser = false; } $timestart = clean_param($timestart, PARAM_INT); if ($allmods = $DB->get_records('modules')) { foreach ($allmods as $mod) { if ($mod->visible) { $modnames[$mod->name] = get_string('modulename', $mod->name); } } } else { throw new Exception('No modules are installed!'); } // Gather recent activity foreach ($courses as $course) { $modinfo = get_fast_modinfo($course); $viewfullnames = has_capability('moodle/site:viewfullnames', context_course::instance($course->id)); $activities = array(); $index = 0; $recentactivity[$course->id] = $course; $recentactivity[$course->id]->recentactivity = array(); $logs = $DB->get_records_sql("SELECT l.*, u.firstname, u.lastname, u.picture\n FROM {log} l\n LEFT OUTER JOIN {user} u ON l.userid = u.id\n WHERE time > ?\n AND course = ?\n AND module = 'course'\n AND (action = 'add mod' OR action = 'update mod' OR action = 'delete mod')\n ORDER BY id ASC", array($timestart, $course->id)); if ($logs) { $changelist = array(); $newgones = array(); // added and later deleted items foreach ($logs as $key => $log) { $info = explode(' ', $log->info); // Labels are ignored in recent activity if ($info[0] == 'label') { continue; } // Check for incorrect entry if (count($info) != 2) { continue; } $modname = $info[0]; $instanceid = $info[1]; $userinfo = new stdClass(); $userinfo->id = $log->userid; $userinfo->userid = $log->userid; $userinfo->fullname = ''; $userinfo->picture = $log->picture; if (!empty($log->firstname) and !empty($log->lastname)) { $a = new stdClass(); $a->fullname = fullname($log, $viewfullnames); $a->modname = get_string('modulename', $modname); $userinfo->fullname = $a->fullname; } else { $a = false; } if ($log->action == 'delete mod') { // unfortunately we do not know if the mod was visible if (!array_key_exists($log->info, $newgones)) { if ($a) { $strdeleted = get_string('deletedactivity', 'local_mr', $a); } else { $strdeleted = get_string('deletedactivity', 'moodle', get_string('modulename', $modname)); } $changelist[$log->info] = (object) array('cmid' => $log->cmid, 'type' => $modname, 'name' => '', 'action' => 'delete', 'timestamp' => $log->time, 'description_html' => $strdeleted, 'description_text' => $strdeleted, 'user' => $userinfo); } } else { if (!isset($modinfo->instances[$modname][$instanceid])) { if ($log->action == 'add mod') { // do not display added and later deleted activities $newgones[$log->info] = true; } continue; } $cm = $modinfo->instances[$modname][$instanceid]; if (!$cm->uservisible) { continue; } if ($log->action == 'add mod') { if ($a) { $stradded = get_string('addedactivity', 'local_mr', $a); } else { $stradded = get_string('added', 'moodle', get_string('modulename', $modname)); } $changelist[$log->info] = (object) array('cmid' => $cm->id, 'type' => $modname, 'name' => $cm->name, 'action' => 'add', 'timestamp' => $log->time, 'description_html' => "{$stradded}:<br /><a href=\"{$CFG->wwwroot}/mod/{$cm->modname}/view.php?id={$cm->id}\">" . format_string($cm->name, true) . '</a>', 'description_text' => "{$stradded}: " . format_string($cm->name, true), 'user' => $userinfo); } else { if ($log->action == 'update mod' and empty($changelist[$log->info])) { if ($a) { $strupdated = get_string('updatedactivity', 'local_mr', $a); } else { $strupdated = get_string('updated', 'moodle', get_string('modulename', $modname)); } $changelist[$log->info] = (object) array('cmid' => $cm->id, 'type' => $modname, 'name' => $cm->name, 'action' => 'update', 'timestamp' => $log->time, 'description_html' => "{$strupdated}:<br /><a href=\"{$CFG->wwwroot}/mod/{$cm->modname}/view.php?id={$cm->id}\">" . format_string($cm->name, true) . '</a>', 'description_text' => "{$strupdated}: " . format_string($cm->name, true), 'user' => $userinfo); } } } } // Add to main recentactivity array $recentactivity[$course->id]->recentactivity = array_values($changelist); } foreach ($modinfo->cms as $cm) { if (!$cm->uservisible) { continue; } $lib = "{$CFG->dirroot}/mod/{$cm->modname}/lib.php"; if (file_exists($lib)) { require_once $lib; $get_recent_mod_activity = "{$cm->modname}_get_recent_mod_activity"; if (function_exists($get_recent_mod_activity)) { $get_recent_mod_activity($activities, $index, $timestart, $course->id, $cm->id, 0, 0); } } } foreach ($activities as $activity) { $print_recent_mod_activity = "{$activity->type}_print_recent_mod_activity"; if (function_exists($print_recent_mod_activity)) { ob_start(); $print_recent_mod_activity($activity, $course->id, true, $modnames, true); $description = ob_get_contents(); ob_end_clean(); $activity->description_html = $description; $activity->description_text = trim(strip_tags(str_replace(array('</td>', '</div>'), array(' </td>', ' </div>'), $description))); if (empty($activity->timestamp)) { $activity->timestamp = 0; } $recentactivity[$course->id]->recentactivity[] = $activity; } } } // Sort recent activity foreach ($recentactivity as $courseid => $course) { uasort($course->recentactivity, create_function('$a, $b', 'return ($a->timestamp == $b->timestamp) ? 0 : (($a->timestamp > $b->timestamp) ? -1 : 1);')); $recentactivity[$courseid]->recentactivity = array_values($course->recentactivity); } if ($currentuser !== false) { \core\session\manager::set_user($currentuser); } return $recentactivity; }