Only redirect when redirect url is an internal page.
This commit is contained in:
@@ -10,3 +10,20 @@ Feature: Sign in
|
||||
And I press the Create My Account button on the registration form
|
||||
Then I should see be on the studio home page
|
||||
And I should see the message "complete your sign up we need you to verify your email address"
|
||||
|
||||
Scenario: Login with a valid redirect
|
||||
Given I have opened a new course in Studio
|
||||
And I am not logged in
|
||||
And I visit the url "/MITx/999/course/Robot_Super_Course"
|
||||
And I should see that the path is "/signin?next=/MITx/999/course/Robot_Super_Course"
|
||||
When I fill in and submit the signin form
|
||||
And I wait for "2" seconds
|
||||
Then I should see that the path is "/MITx/999/course/Robot_Super_Course"
|
||||
|
||||
Scenario: Login with an invalid redirect
|
||||
Given I have opened a new course in Studio
|
||||
And I am not logged in
|
||||
And I visit the url "/signin?next=http://www.google.com/"
|
||||
When I fill in and submit the signin form
|
||||
And I wait for "2" seconds
|
||||
Then I should see that the path is "/"
|
||||
|
||||
@@ -30,3 +30,13 @@ def i_should_see_be_on_the_studio_home_page(step):
|
||||
@step(u'I should see the message "([^"]*)"$')
|
||||
def i_should_see_the_message(step, msg):
|
||||
assert world.browser.is_text_present(msg, 5)
|
||||
|
||||
|
||||
@step(u'I fill in and submit the signin form$')
|
||||
def i_fill_in_the_signin_form(step):
|
||||
def fill_login_form():
|
||||
login_form = world.browser.find_by_css('form#login_form')
|
||||
login_form.find_by_name('email').fill('robot+studio@edx.org')
|
||||
login_form.find_by_name('password').fill('test')
|
||||
login_form.find_by_name('submit').click()
|
||||
world.retry_on_exception(fill_login_form)
|
||||
|
||||
@@ -247,7 +247,7 @@ PIPELINE_JS = {
|
||||
'js/models/section.js', 'js/views/section.js',
|
||||
'js/models/metadata_model.js', 'js/views/metadata_editor_view.js',
|
||||
'js/models/textbook.js', 'js/views/textbook.js',
|
||||
'js/views/assets.js'],
|
||||
'js/views/assets.js', 'js/utility.js'],
|
||||
'output_filename': 'js/cms-application.js',
|
||||
'test_order': 0
|
||||
},
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
function(json) {
|
||||
if(json.success) {
|
||||
var next = /next=([^&]*)/g.exec(decodeURIComponent(window.location.search));
|
||||
if (next && next.length > 1) {
|
||||
if (next && next.length > 1 && !isExternal(next[1])) {
|
||||
location.href = next[1];
|
||||
}
|
||||
else location.href = "${reverse('homepage')}";
|
||||
|
||||
@@ -65,7 +65,7 @@ def log_in(username, password):
|
||||
|
||||
@world.absorb
|
||||
def register_by_course_id(course_id, is_staff=False):
|
||||
create_user('robot')
|
||||
create_user('robot', 'password')
|
||||
u = User.objects.get(username='robot')
|
||||
if is_staff:
|
||||
u.is_staff = True
|
||||
|
||||
@@ -168,6 +168,11 @@ def dialogs_are_closed(step):
|
||||
assert world.dialogs_closed()
|
||||
|
||||
|
||||
@step(u'visit the url "([^"]*)"')
|
||||
def visit_url(step, url):
|
||||
world.browser.visit(django_url(url))
|
||||
|
||||
|
||||
@step('I will confirm all alerts')
|
||||
def i_confirm_all_alerts(step):
|
||||
"""
|
||||
|
||||
20
common/static/js/utility.js
Normal file
20
common/static/js/utility.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// checks whether or not the url is external to the local site.
|
||||
// generously provided by StackOverflow: http://stackoverflow.com/questions/6238351/fastest-way-to-detect-external-urls
|
||||
function isExternal(url) {
|
||||
// parse the url into protocol, host, path, query, and fragment. More information can be found here: http://tools.ietf.org/html/rfc3986#appendix-B
|
||||
var match = url.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);
|
||||
// match[1] matches a protocol if one exists in the url
|
||||
// if the protocol in the url does not match the protocol in the window's location, this url is considered external
|
||||
if (typeof match[1] === "string" &&
|
||||
match[1].length > 0
|
||||
&& match[1].toLowerCase() !== location.protocol)
|
||||
return true;
|
||||
// match[2] matches the host if one exists in the url
|
||||
// if the host in the url does not match the host of the window location, this url is considered external
|
||||
if (typeof match[2] === "string" &&
|
||||
match[2].length > 0 &&
|
||||
// this regex removes the port number if it patches the current location's protocol
|
||||
match[2].replace(new RegExp(":("+{"http:":80,"https:":443}[location.protocol]+")?$"), "") !== location.host)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -25,3 +25,21 @@ Feature: Login in as a registered user
|
||||
And I click the link with the text "Log Out"
|
||||
Then I should see a link with the text "Log in"
|
||||
And I should see that the path is "/"
|
||||
|
||||
Scenario: Login with valid redirect
|
||||
Given I am an edX user
|
||||
And The course "6.002x" exists
|
||||
And I am registered for the course "6.002x"
|
||||
And I am not logged in
|
||||
And I visit the url "/courses/edx/6.002x/Test_Course/courseware"
|
||||
And I should see that the path is "/accounts/login?next=/courses/edx/6.002x/Test_Course/courseware"
|
||||
When I submit my credentials on the login form
|
||||
And I wait for "2" seconds
|
||||
Then the page title should contain "6.002x Courseware"
|
||||
|
||||
Scenario: Login with an invalid redirect
|
||||
Given I am an edX user
|
||||
And I am not logged in
|
||||
And I visit the url "/login?next=http://www.google.com/"
|
||||
When I submit my credentials on the login form
|
||||
Then I should be on the dashboard page
|
||||
|
||||
@@ -95,19 +95,19 @@ MITX_FEATURES = {
|
||||
# This flag disables the requirement of having to agree to the TOS for users registering
|
||||
# with Shib. Feature was requested by Stanford's office of general counsel
|
||||
'SHIB_DISABLE_TOS': False,
|
||||
|
||||
|
||||
# Enables ability to restrict enrollment in specific courses by the user account login method
|
||||
'RESTRICT_ENROLL_BY_REG_METHOD': False,
|
||||
|
||||
# analytics experiments
|
||||
'ENABLE_INSTRUCTOR_ANALYTICS': False,
|
||||
|
||||
# enable analytics server.
|
||||
# enable analytics server.
|
||||
# WARNING: THIS SHOULD ALWAYS BE SET TO FALSE UNDER NORMAL
|
||||
# LMS OPERATION. See analytics.py for details about what
|
||||
# this does.
|
||||
# this does.
|
||||
|
||||
'RUN_AS_ANALYTICS_SERVER_ENABLED' : False,
|
||||
'RUN_AS_ANALYTICS_SERVER_ENABLED': False,
|
||||
|
||||
# Flip to True when the YouTube iframe API breaks (again)
|
||||
'USE_YOUTUBE_OBJECT_API': False,
|
||||
@@ -571,6 +571,7 @@ PIPELINE_JS = {
|
||||
'js/toggle_login_modal.js',
|
||||
'js/sticky_filter.js',
|
||||
'js/query-params.js',
|
||||
'js/utility.js',
|
||||
],
|
||||
'output_filename': 'js/lms-application.js',
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
$("label").parent().removeClass("is-focused");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
(function() {
|
||||
toggleSubmitButton(true);
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
if(json.success) {
|
||||
var u=decodeURI(window.location.search);
|
||||
next=u.split("next=")[1];
|
||||
if (next) {
|
||||
if (next && !isExternal(next)) {
|
||||
location.href=next;
|
||||
} else {
|
||||
location.href="${reverse('dashboard')}";
|
||||
|
||||
Reference in New Issue
Block a user