updated the login flow for multiple enterprise
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
define([
|
||||
'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers',
|
||||
'js/student_account/multiple_enterprise',
|
||||
'js/student_account/utils'
|
||||
],
|
||||
function(AjaxHelpers, MultipleEnterpriseInterface, Utils) {
|
||||
'use strict';
|
||||
|
||||
describe('MultipleEnterpriseInterface', function() {
|
||||
var LEARNER_URL = '/enterprise/api/v1/enterprise-learner/?username=test-learner',
|
||||
NEXT_URL = '/dashboard',
|
||||
REDIRECT_URL = '/enterprise/select/active/?success_url=/dashboard';
|
||||
|
||||
beforeEach(function() {
|
||||
// Mock the redirect call
|
||||
spyOn(MultipleEnterpriseInterface, 'redirect').and.callFake(function() {});
|
||||
spyOn(Utils, 'userFromEdxUserCookie').and.returnValue({username: 'test-learner'});
|
||||
});
|
||||
|
||||
it('gets learner information and checks redirect to enterprise selection page', function() {
|
||||
// Spy on Ajax requests
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
|
||||
// Attempt to fetch a learner
|
||||
MultipleEnterpriseInterface.check(NEXT_URL);
|
||||
|
||||
// Expect that the correct request was made to the server
|
||||
AjaxHelpers.expectRequest(
|
||||
requests,
|
||||
'GET',
|
||||
LEARNER_URL,
|
||||
null
|
||||
);
|
||||
|
||||
// Simulate a successful response from the server
|
||||
AjaxHelpers.respondWithJson(requests, {count: 2});
|
||||
|
||||
// Verify that the user was redirected correctly
|
||||
expect(MultipleEnterpriseInterface.redirect).toHaveBeenCalledWith(REDIRECT_URL);
|
||||
});
|
||||
|
||||
it('gets learner information and checks that enterprise selection page is bypassed', function() {
|
||||
// Spy on Ajax requests
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
|
||||
// Attempt to fetch a learner
|
||||
MultipleEnterpriseInterface.check(NEXT_URL);
|
||||
|
||||
// Expect that the correct request was made to the server
|
||||
AjaxHelpers.expectRequest(
|
||||
requests,
|
||||
'GET',
|
||||
LEARNER_URL,
|
||||
null
|
||||
);
|
||||
|
||||
// Simulate a successful response from the server
|
||||
AjaxHelpers.respondWithJson(requests, {count: 1});
|
||||
|
||||
// Verify that the user was redirected correctly
|
||||
expect(MultipleEnterpriseInterface.redirect).toHaveBeenCalledWith(NEXT_URL);
|
||||
});
|
||||
|
||||
it('correctly redirects the user if learner information call fails', function() {
|
||||
// Spy on Ajax requests
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
|
||||
// Attempt to fetch a learner
|
||||
MultipleEnterpriseInterface.check(NEXT_URL);
|
||||
|
||||
// Simulate an error response from the server
|
||||
AjaxHelpers.respondWithError(requests);
|
||||
|
||||
// Verify that the user was redirected
|
||||
expect(MultipleEnterpriseInterface.redirect).toHaveBeenCalledWith(NEXT_URL);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
52
lms/static/js/student_account/multiple_enterprise.js
Normal file
52
lms/static/js/student_account/multiple_enterprise.js
Normal file
@@ -0,0 +1,52 @@
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define(['jquery', 'js/student_account/utils', 'jquery.cookie'], function($, Utils) {
|
||||
var MultipleEnterpriseInterface = {
|
||||
|
||||
urls: {
|
||||
learners: '/enterprise/api/v1/enterprise-learner/',
|
||||
multipleEnterpriseUrl: '/enterprise/select/active/?success_url='
|
||||
},
|
||||
|
||||
headers: {
|
||||
'X-CSRFToken': $.cookie('csrftoken')
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch the learner data, then redirect the user to a enterprise selection page if multiple
|
||||
* enterprises were found.
|
||||
* @param {string} nextUrl The URL to redirect to after multiple enterprise selection.
|
||||
*/
|
||||
check: function(nextUrl) {
|
||||
var redirectUrl = this.urls.multipleEnterpriseUrl + encodeURI(nextUrl);
|
||||
var username = Utils.userFromEdxUserCookie().username;
|
||||
var next = nextUrl || '/';
|
||||
$.ajax({
|
||||
url: this.urls.learners + '?username=' + username,
|
||||
type: 'GET',
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
headers: this.headers,
|
||||
context: this
|
||||
}).fail(function() {
|
||||
this.redirect(next);
|
||||
}).done(function(response) {
|
||||
if (response.count > 1 && redirectUrl) {
|
||||
this.redirect(redirectUrl);
|
||||
} else {
|
||||
this.redirect(next);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Redirect to a URL.
|
||||
* @param {string} url The URL to redirect to.
|
||||
*/
|
||||
redirect: function(url) {
|
||||
window.location.href = url;
|
||||
}
|
||||
};
|
||||
|
||||
return MultipleEnterpriseInterface;
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
28
lms/static/js/student_account/utils.js
Normal file
28
lms/static/js/student_account/utils.js
Normal file
@@ -0,0 +1,28 @@
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define(['jquery'], function($) {
|
||||
var userFromEdxUserCookie = function() {
|
||||
var hostname = window.location.hostname;
|
||||
var isLocalhost = hostname.indexOf('localhost') >= 0;
|
||||
var isStage = hostname.indexOf('stage') >= 0;
|
||||
var edxUserCookie, prefix, user;
|
||||
|
||||
if (isLocalhost) {
|
||||
// localhost doesn't have prefixes
|
||||
edxUserCookie = 'edx-user-info';
|
||||
} else {
|
||||
// does not take sandboxes into account
|
||||
prefix = isStage ? 'stage' : 'prod';
|
||||
edxUserCookie = prefix + '-edx-user-info';
|
||||
}
|
||||
// returns the user object from cookie. Replaces '054' with ',' and removes '\'
|
||||
user = $.cookie(edxUserCookie).replace(/\\/g, '').replace(/054/g, ',');
|
||||
user = user.substring(1, user.length - 1);
|
||||
return JSON.parse(user);
|
||||
};
|
||||
|
||||
return {
|
||||
userFromEdxUserCookie: userFromEdxUserCookie
|
||||
};
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
@@ -16,10 +16,12 @@
|
||||
'js/student_account/views/InstitutionLoginView',
|
||||
'js/student_account/views/HintedLoginView',
|
||||
'edx-ui-toolkit/js/utils/html-utils',
|
||||
'js/student_account/multiple_enterprise',
|
||||
'js/vendor/history'
|
||||
],
|
||||
function($, utility, _, _s, Backbone, LoginModel, PasswordResetModel, RegisterModel, AccountRecoveryModel,
|
||||
LoginView, PasswordResetView, RegisterView, InstitutionLoginView, HintedLoginView, HtmlUtils) {
|
||||
LoginView, PasswordResetView, RegisterView, InstitutionLoginView, HintedLoginView, HtmlUtils,
|
||||
multipleEnterpriseInterface) {
|
||||
return Backbone.View.extend({
|
||||
tpl: '#access-tpl',
|
||||
events: {
|
||||
@@ -43,7 +45,6 @@
|
||||
* Underscore namespace
|
||||
*/
|
||||
_.mixin(_s.exports());
|
||||
|
||||
this.tpl = $(this.tpl).html();
|
||||
|
||||
this.activeForm = options.initial_mode || 'login';
|
||||
@@ -70,7 +71,6 @@
|
||||
institution_login: null,
|
||||
hinted_login: null
|
||||
};
|
||||
|
||||
this.platformName = options.platform_name;
|
||||
this.supportURL = options.support_link;
|
||||
this.passwordResetSupportUrl = options.password_reset_support_link;
|
||||
@@ -79,6 +79,8 @@
|
||||
this.pipelineUserDetails = options.third_party_auth.pipeline_user_details;
|
||||
this.enterpriseName = options.enterprise_name || '';
|
||||
this.isAccountRecoveryFeatureEnabled = options.is_account_recovery_feature_enabled || false;
|
||||
this.isMultipleUserEnterprisesFeatureEnabled =
|
||||
options.is_multiple_user_enterprises_feature_enabled || false;
|
||||
|
||||
// The login view listens for 'sync' events from the reset model
|
||||
this.resetModel = new PasswordResetModel({}, {
|
||||
@@ -158,7 +160,11 @@
|
||||
this.listenTo(this.subview.login, 'password-help', this.resetPassword);
|
||||
|
||||
// Listen for 'auth-complete' event so we can enroll/redirect the user appropriately.
|
||||
this.listenTo(this.subview.login, 'auth-complete', this.authComplete);
|
||||
if (this.isMultipleUserEnterprisesFeatureEnabled === true) {
|
||||
this.listenTo(this.subview.login, 'auth-complete', this.loginComplete);
|
||||
} else {
|
||||
this.listenTo(this.subview.login, 'auth-complete', this.authComplete);
|
||||
}
|
||||
},
|
||||
|
||||
reset: function(data) {
|
||||
@@ -286,6 +292,20 @@
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
/**
|
||||
* Take a learner attached to multiple enterprises to the enterprise selection page:
|
||||
*
|
||||
*/
|
||||
loginComplete: function() {
|
||||
if (this.thirdPartyAuth && this.thirdPartyAuth.finishAuthUrl) {
|
||||
multipleEnterpriseInterface.check(this.thirdPartyAuth.finishAuthUrl);
|
||||
// Note: the third party auth URL likely contains another redirect URL embedded inside
|
||||
} else {
|
||||
multipleEnterpriseInterface.check(this.nextUrl);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Redirect to a URL. Mainly useful for mocking out in tests.
|
||||
* @param {string} url The URL to redirect to.
|
||||
|
||||
@@ -786,6 +786,7 @@
|
||||
'js/spec/student_account/institution_login_spec.js',
|
||||
'js/spec/student_account/login_spec.js',
|
||||
'js/spec/student_account/logistration_factory_spec.js',
|
||||
'js/spec/student_account/multiple_enterprise_spec.js',
|
||||
'js/spec/student_account/password_reset_spec.js',
|
||||
'js/spec/student_account/register_spec.js',
|
||||
'js/spec/student_account/shoppingcart_spec.js',
|
||||
|
||||
@@ -18,6 +18,10 @@ from six.moves.urllib.parse import urlparse # pylint: disable=import-error
|
||||
|
||||
from openedx.core.djangoapps.site_configuration.models import SiteConfiguration
|
||||
from openedx.core.djangoapps.theming.helpers import get_config_value_from_site_or_settings, get_current_site
|
||||
from openedx.core.djangoapps.user_api.config.waffle import (
|
||||
ENABLE_MULTIPLE_USER_ENTERPRISES_FEATURE,
|
||||
waffle as user_api_waffle
|
||||
)
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
|
||||
@@ -214,3 +218,13 @@ def is_secondary_email_feature_enabled_for_user(user):
|
||||
# import is placed here to avoid cyclic import.
|
||||
from openedx.features.enterprise_support.utils import is_enterprise_learner
|
||||
return is_secondary_email_feature_enabled() and is_enterprise_learner(user)
|
||||
|
||||
|
||||
def is_multiple_user_enterprises_feature_enabled():
|
||||
"""
|
||||
Checks to see if the django-waffle switch for enabling the multiple user enterprises feature is active
|
||||
|
||||
Returns:
|
||||
Boolean value representing switch status
|
||||
"""
|
||||
return user_api_waffle().is_enabled(ENABLE_MULTIPLE_USER_ENTERPRISES_FEATURE)
|
||||
|
||||
@@ -12,6 +12,7 @@ WAFFLE_NAMESPACE = u'user_api'
|
||||
|
||||
# Switches
|
||||
PREVENT_AUTH_USER_WRITES = u'prevent_auth_user_writes'
|
||||
ENABLE_MULTIPLE_USER_ENTERPRISES_FEATURE = u'enable_multiple_user_enterprises_feature'
|
||||
|
||||
|
||||
def waffle():
|
||||
|
||||
@@ -17,7 +17,10 @@ from django.views.decorators.http import require_http_methods
|
||||
import third_party_auth
|
||||
from edxmako.shortcuts import render_to_response
|
||||
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
|
||||
from openedx.core.djangoapps.user_api.accounts.utils import is_secondary_email_feature_enabled
|
||||
from openedx.core.djangoapps.user_api.accounts.utils import (
|
||||
is_secondary_email_feature_enabled,
|
||||
is_multiple_user_enterprises_feature_enabled
|
||||
)
|
||||
from openedx.core.djangoapps.user_api.api import (
|
||||
get_login_session_form,
|
||||
)
|
||||
@@ -124,7 +127,8 @@ def login_and_registration_form(request, initial_mode="login"):
|
||||
'password_reset_form_desc': json.loads(form_descriptions['password_reset']),
|
||||
'account_creation_allowed': configuration_helpers.get_value(
|
||||
'ALLOW_PUBLIC_ACCOUNT_CREATION', settings.FEATURES.get('ALLOW_PUBLIC_ACCOUNT_CREATION', True)),
|
||||
'is_account_recovery_feature_enabled': is_secondary_email_feature_enabled()
|
||||
'is_account_recovery_feature_enabled': is_secondary_email_feature_enabled(),
|
||||
'is_multiple_user_enterprises_feature_enabled': is_multiple_user_enterprises_feature_enabled()
|
||||
},
|
||||
'login_redirect_url': redirect_to, # This gets added to the query string of the "Sign In" button in header
|
||||
'responsive': True,
|
||||
|
||||
Reference in New Issue
Block a user