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-10-14 13:17:11 +01:00
parent 8256d18453
commit 8b2c91e627
3 changed files with 89 additions and 9 deletions
+10 -2
View File
@@ -42,10 +42,18 @@ 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) {
public function i_log_in_as(string $username, moodle_url $wantsurl = null) {
$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)));
+67 -6
View File
@@ -590,14 +590,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()));
}
/**
@@ -643,13 +671,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()));
}
/**
+12 -1
View File
@@ -30,7 +30,18 @@ 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.
// 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");