MDL-66335 behat: new step to log in and go straight to a particular page

I did not think thought through if this new URL parameter would be a
potential security hole. The simple cop-out option is to make it only
work on Behat sites for now.
This commit is contained in:
Tim Hunt 2019-09-05 18:00:39 +01:00
parent 4024556b98
commit 9bcc357107
3 changed files with 89 additions and 10 deletions

View File

@ -42,16 +42,23 @@ class behat_auth extends behat_base {
* Logs in the user. There should exist a user with the same value as username and password.
*
* @Given /^I log in as "(?P<username_string>(?:[^"]|\\")*)"$/
* @param string $username the user to log in as.
* @param moodle_url|null $wantsurl optional, URL to go to after logging in.
*/
public function i_log_in_as($username) {
// In the mobile app the required tasks are different.
public function i_log_in_as(string $username, moodle_url $wantsurl = null) {
// In the mobile app the required tasks are different (does not support $wantsurl).
if ($this->is_in_app()) {
$this->execute('behat_app::login', [$username]);
return;
}
$loginurl = new moodle_url('/login/index.php');
if ($wantsurl !== null) {
$loginurl->param('wantsurl', $wantsurl->out_as_local_url());
}
// Visit login page.
$this->getSession()->visit($this->locate_path('login/index.php'));
$this->getSession()->visit($this->locate_path($loginurl->out_as_local_url()));
// Enter username and password.
$this->execute('behat_forms::i_set_the_field_to', array('Username', $this->escape($username)));

View File

@ -549,14 +549,42 @@ class behat_navigation extends behat_base {
* @throws Exception if the specified page cannot be determined.
*/
public function i_am_on_page(string $page) {
$this->getSession()->visit($this->locate_path(
$this->resolve_page_helper($page)->out_as_local_url()));
}
/**
* Open a given page logged in as a given user.
*
* This is like the combination
* When I log in as "..."
* And I am on the "..." page
* but with the advantage that you go straight to the desired page, without
* having to wait for the Dashboard to load.
*
* @When I am on the :page page logged in as :username
* @param string $page the type of page. E.g. 'Admin notifications' or 'core_user > Preferences'.
* @param string $username the name of the user to log in as. E.g. 'admin'.
* @throws Exception if the specified page cannot be determined.
*/
public function i_am_on_page_logged_in_as(string $page, string $username) {
self::execute('behat_auth::i_log_in_as', [$username, $this->resolve_page_helper($page)]);
}
/**
* Helper used by i_am_on_page() and i_am_on_page_logged_in_as().
*
* @param string $page the type of page. E.g. 'Admin notifications' or 'core_user > Preferences'.
* @return moodle_url the corresponding URL.
*/
protected function resolve_page_helper(string $page): moodle_url {
list($component, $name) = $this->parse_page_name($page);
if ($component === 'core') {
$url = $this->resolve_core_page_url($name);
return $this->resolve_core_page_url($name);
} else {
$context = behat_context_helper::get('behat_' . $component);
$url = $context->resolve_page_url($name);
return $context->resolve_page_url($name);
}
$this->getSession()->visit($this->locate_path($url->out_as_local_url()));
}
/**
@ -602,13 +630,46 @@ class behat_navigation extends behat_base {
*/
public function i_am_on_page_instance(string $identifier, string $type) {
list($component, $type) = $this->parse_page_name($type);
$this->getSession()->visit($this->locate_path(
$this->resolve_page_instance_helper($identifier, $type)->out_as_local_url()));
}
/**
* Open a given page logged in as a given user.
*
* This is like the combination
* When I log in as "..."
* And I am on the "..." "..." page
* but with the advantage that you go straight to the desired page, without
* having to wait for the Dashboard to load.
*
* @When I am on the :identifier :type page logged in as :username
* @param string $identifier identifies the particular page. E.g. 'Test quiz'.
* @param string $type the component and page type. E.g. 'mod_quiz > View'.
* @param string $username the name of the user to log in as. E.g. 'student'.
* @throws Exception if the specified page cannot be determined.
*/
public function i_am_on_page_instance_logged_in_as(string $identifier,
string $type, string $username) {
self::execute('behat_auth::i_log_in_as',
[$username, $this->resolve_page_instance_helper($identifier, $type)]);
}
/**
* Helper used by i_am_on_page() and i_am_on_page_logged_in_as().
*
* @param string $identifier identifies the particular page. E.g. 'Test quiz'.
* @param string $pagetype the component and page type. E.g. 'mod_quiz > View'.
* @return moodle_url the corresponding URL.
*/
protected function resolve_page_instance_helper(string $identifier, string $pagetype): moodle_url {
list($component, $type) = $this->parse_page_name($pagetype);
if ($component === 'core') {
$url = $this->resolve_core_page_instance_url($type, $identifier);
return $this->resolve_core_page_instance_url($type, $identifier);
} else {
$context = behat_context_helper::get('behat_' . $component);
$url = $context->resolve_page_instance_url($type, $identifier);
return $context->resolve_page_instance_url($type, $identifier);
}
$this->getSession()->visit($this->locate_path($url->out_as_local_url()));
}
/**

View File

@ -30,10 +30,21 @@ require_once('lib.php');
redirect_if_major_upgrade_required();
$testsession = optional_param('testsession', 0, PARAM_INT); // test session works properly
$anchor = optional_param('anchor', '', PARAM_RAW); // Used to restore hash anchor to wantsurl.
$anchor = optional_param('anchor', '', PARAM_RAW); // Used to restore hash anchor to wantsurl.
$resendconfirmemail = optional_param('resendconfirmemail', false, PARAM_BOOL);
// It might be safe to do this for non-Behat sites, or there might
// be a security risk. For now we only allow it on Behat sites.
// If you wants to do the analysis, you may be able to remove the
// if (BEHAT_SITE_RUNNING).
if (defined('BEHAT_SITE_RUNNING') && BEHAT_SITE_RUNNING) {
$wantsurl = optional_param('wantsurl', '', PARAM_LOCALURL); // Overrides $SESSION->wantsurl if given.
if ($wantsurl !== '') {
$SESSION->wantsurl = (new moodle_url($wantsurl))->out(false);
}
}
$context = context_system::instance();
$PAGE->set_url("$CFG->wwwroot/login/index.php");
$PAGE->set_context($context);