Integrate third party auth into the combined login/registration page.

Change third party auth login failure code to a 401, to detect authentication
success with no linked account.

If already authenticated, redirect immediately to the dashboard.

Use "Location" header correctly for 302 redirects from student views.

Add utility functions for simulating a running third-party auth pipeline.

Add a utility function for checking whether third party auth is enabled.

Respect default values sent by the server
This commit is contained in:
Will Daly
2014-10-21 06:41:13 -04:00
parent afefe21c4f
commit 9e9dec1de1
23 changed files with 648 additions and 132 deletions

View File

@@ -7,7 +7,7 @@ var edx = edx || {};
edx.student.account = edx.student.account || {};
return new edx.student.account.AccessView({
mode: $('#login-and-registration-container').data('initial-mode') || 'login',
thirdPartyAuth: $('#login-and-registration-container').data('third-party-auth-providers') || false
mode: $('#login-and-registration-container').data('initial-mode'),
thirdPartyAuth: $('#login-and-registration-container').data('third-party-auth')
});
})(jQuery);
})(jQuery);

View File

@@ -26,7 +26,13 @@ var edx = edx || {};
initialize: function( obj ) {
this.tpl = $(this.tpl).html();
this.activeForm = obj.mode;
this.activeForm = obj.mode || 'login';
this.thirdPartyAuth = obj.thirdPartyAuth || {
currentProvider: null,
providers: []
};
console.log(obj);
this.render();
},
@@ -48,12 +54,12 @@ var edx = edx || {};
loadForm: function( type ) {
if ( type === 'login' ) {
this.subview.login = new edx.student.account.LoginView();
this.subview.login = new edx.student.account.LoginView( this.thirdPartyAuth );
// Listen for 'password-help' event to toggle sub-views
this.listenTo( this.subview.login, 'password-help', this.resetPassword );
} else if ( type === 'register' ) {
this.subview.register = new edx.student.account.RegisterView();
this.subview.register = new edx.student.account.RegisterView( this.thirdPartyAuth );
} else if ( type === 'reset' ) {
this.subview.passwordHelp = new edx.student.account.PasswordResetView();
}

View File

@@ -17,15 +17,20 @@ var edx = edx || {};
events: {
'click .js-login': 'submitForm',
'click .forgot-password': 'forgotPassword'
'click .forgot-password': 'forgotPassword',
'click .login-provider': 'thirdPartyAuth'
},
errors: [],
$form: {},
initialize: function() {
initialize: function( thirdPartyAuthInfo ) {
this.tpl = $(this.tpl).html();
this.providers = thirdPartyAuthInfo.providers || [];
this.currentProvider = thirdPartyAuthInfo.currentProvider || "";
this.getInitialData();
},
@@ -34,7 +39,9 @@ var edx = edx || {};
var fields = html || '';
$(this.el).html( _.template( this.tpl, {
fields: fields
fields: fields,
currentProvider: this.currentProvider,
providers: this.providers
}));
this.postRender();
@@ -44,9 +51,16 @@ var edx = edx || {};
postRender: function() {
var $container = $(this.el);
this.$form = $container.find('form');
this.$errors = $container.find('.error-msg');
this.$alreadyAuthenticatedMsg = $container.find('.already-authenticated-msg');
// If we're already authenticated with a third-party
// provider, try logging in. The easiest way to do this
// is to simply submit the form.
if (this.currentProvider) {
this.model.save();
}
},
getInitialData: function() {
@@ -58,8 +72,8 @@ var edx = edx || {};
url: '/user_api/v1/account/login_session/',
success: function( data ) {
console.log(data);
that.buildForm( data.fields );
that.initModel( data.submit_url, data.method );
that.buildForm( data.fields );
},
error: function( jqXHR, textStatus, errorThrown ) {
console.log('fail ', errorThrown);
@@ -72,9 +86,7 @@ var edx = edx || {};
url: url
});
this.listenTo( this.model, 'error', function( error ) {
console.log(error.status, ' error: ', error.responseText);
});
this.listenTo( this.model, 'error', this.saveError );
},
buildForm: function( data ) {
@@ -148,6 +160,16 @@ var edx = edx || {};
}
},
thirdPartyAuth: function( event ) {
var providerUrl = $(event.target).data("provider-url") || "";
if (providerUrl) {
window.location.href = providerUrl;
} else {
// TODO -- error handling here
console.log("No URL available for third party auth provider");
}
},
toggleErrorMsg: function( show ) {
if ( show ) {
this.$errors.removeClass('hidden');
@@ -158,6 +180,23 @@ var edx = edx || {};
validate: function( $el ) {
return edx.utils.validate( $el );
},
saveError: function( error ) {
console.log(error.status, ' error: ', error.responseText);
// If we've gotten a 401 error, it means that we've successfully
// authenticated with a third-party provider, but we haven't
// linked the account to an EdX account. In this case,
// we need to prompt the user to enter a little more information
// to complete the registration process.
if (error.status === 401 && this.currentProvider) {
this.$alreadyAuthenticatedMsg.removeClass("hidden");
}
else {
this.$alreadyAuthenticatedMsg.addClass("hidden");
// TODO -- display the error
}
}
});

View File

@@ -16,15 +16,19 @@ var edx = edx || {};
fieldTpl: $('#form_field-tpl').html(),
events: {
'click .js-register': 'submitForm'
'click .js-register': 'submitForm',
'click .login-provider': 'thirdPartyAuth'
},
errors: [],
$form: {},
initialize: function() {
initialize: function( thirdPartyAuthInfo ) {
this.tpl = $(this.tpl).html();
this.providers = thirdPartyAuthInfo.providers || [];
this.currentProvider = thirdPartyAuthInfo.currentProvider || "";
this.getInitialData();
},
@@ -33,7 +37,9 @@ var edx = edx || {};
var fields = html || '';
$(this.el).html( _.template( this.tpl, {
fields: fields
fields: fields,
currentProvider: this.currentProvider,
providers: this.providers
}));
this.postRender();
@@ -81,8 +87,10 @@ var edx = edx || {};
i,
len = data.length,
fieldTpl = this.fieldTpl;
console.log('buildForm ', data);
for ( i=0; i<len; i++ ) {
// "default" is reserved in JavaScript
data[i].value = data[i]["default"];
html.push( _.template( fieldTpl, $.extend( data[i], {
form: 'register'
}) ) );
@@ -142,6 +150,16 @@ console.log(this.model);
}
},
thirdPartyAuth: function( event ) {
var providerUrl = $(event.target).data("provider-url") || "";
if (providerUrl) {
window.location.href = providerUrl;
} else {
// TODO -- error handling here
console.log("No URL available for third party auth provider");
}
},
toggleErrorMsg: function( show ) {
if ( show ) {
this.$errors.removeClass('hidden');