Better support for external logins

This commit is contained in:
Robin Ward 2015-03-04 10:59:21 -05:00
parent 0523750d18
commit 70931b78d9
3 changed files with 58 additions and 97 deletions

View File

@ -1,6 +1,15 @@
import ModalFunctionality from 'discourse/mixins/modal-functionality';
import DiscourseController from 'discourse/controllers/controller';
// This is happening outside of the app via popup
function showModal(modal) {
const route = Discourse.__container__.lookup('route:application');
Discourse.Route.showModal(route, modal);
}
const AuthErrors =
['requires_invite', 'awaiting_approval', 'awaiting_confirmation', 'admin_not_allowed_from_ip_address',
'not_allowed_from_ip_address'];
export default DiscourseController.extend(ModalFunctionality, {
needs: ['modal', 'createAccount', 'forgotPassword', 'application'],
authenticate: null,
@ -146,42 +155,27 @@ export default DiscourseController.extend(ModalFunctionality, {
}).property('authenticate'),
authenticationComplete: function(options) {
if (options.requires_invite) {
this.send('showLogin');
this.flash(I18n.t('login.requires_invite'), 'success');
this.set('authenticate', null);
return;
const self = this;
function loginError(errorMsg, className) {
showModal('login');
Ember.run.next(function() {
self.flash(errorMsg, className || 'success');
self.set('authenticate', null);
});
}
if (options.awaiting_approval) {
this.send('showLogin');
this.flash(I18n.t('login.awaiting_approval'), 'success');
this.set('authenticate', null);
return;
}
if (options.awaiting_activation) {
this.send('showLogin');
this.flash(I18n.t('login.awaiting_confirmation'), 'success');
this.set('authenticate', null);
return;
}
if (options.admin_not_allowed_from_ip_address) {
this.send('showLogin');
this.flash(I18n.t('login.admin_not_allowed_from_ip_address'), 'success');
this.set('authenticate', null);
return;
}
if (options.not_allowed_from_ip_address) {
this.send('showLogin');
this.flash(I18n.t('login.not_allowed_from_ip_address'), 'success');
this.set('authenticate', null);
return;
for (let i=0; i<AuthErrors.length; i++) {
const cond = AuthErrors[i];
if (options[cond]) {
return loginError(I18n.t("login." + cond));
}
}
if (options.suspended) {
this.send('showLogin');
this.flash(options.suspended_message, 'error');
this.set('authenticate', null);
return;
return loginError(options.suspended_message, 'error');
}
// Reload the page if we're authenticated
if (options.authenticated) {
if (window.location.pathname === Discourse.getURL('/login')) {
@ -199,7 +193,7 @@ export default DiscourseController.extend(ModalFunctionality, {
accountName: options.name,
authOptions: Em.Object.create(options)
});
this.send('showCreateAccount');
showModal('createAccount');
}
});

View File

@ -1,3 +1,13 @@
function unlessReadOnly(method) {
return function() {
if (this.site.get("isReadOnly")) {
bootbox.alert(I18n.t("read_only_mode.login_disabled"));
} else {
this[method]();
}
};
}
const ApplicationRoute = Discourse.Route.extend({
siteTitle: Discourse.computed.setting('title'),
@ -59,32 +69,9 @@ const ApplicationRoute = Discourse.Route.extend({
this.intermediateTransitionTo('exception');
},
showLogin() {
if (this.site.get("isReadOnly")) {
bootbox.alert(I18n.t("read_only_mode.login_disabled"));
} else {
this.handleShowLogin();
}
},
showLogin: unlessReadOnly('handleShowLogin'),
showCreateAccount() {
if (this.site.get("isReadOnly")) {
bootbox.alert(I18n.t("read_only_mode.login_disabled"));
} else {
this.handleShowCreateAccount();
}
},
autoLogin(modal, onFail){
const methods = Em.get('Discourse.LoginMethod.all');
if (!Discourse.SiteSettings.enable_local_logins &&
methods.length === 1) {
Discourse.Route.showModal(this, modal);
this.controllerFor('login').send('externalLogin', methods[0]);
} else {
onFail();
}
},
showCreateAccount: unlessReadOnly('handleShowCreateAccount'),
showForgotPassword() {
Discourse.Route.showModal(this, 'forgotPassword');
@ -114,12 +101,7 @@ const ApplicationRoute = Discourse.Route.extend({
},
/**
Close the current modal, and destroy its state.
@method closeModal
**/
// Close the current modal, and destroy its state.
closeModal() {
this.render('hide-modal', {into: 'modal', outlet: 'modalBody'});
},
@ -128,18 +110,11 @@ const ApplicationRoute = Discourse.Route.extend({
Hide the modal, but keep it with all its state so that it can be shown again later.
This is useful if you want to prompt for confirmation. hideModal, ask "Are you sure?",
user clicks "No", showModal. If user clicks "Yes", be sure to call closeModal.
@method hideModal
**/
hideModal() {
$('#discourse-modal').modal('hide');
},
/**
Show the modal. Useful after calling hideModal.
@method showModal
**/
showModal() {
$('#discourse-modal').modal('show');
},
@ -153,11 +128,6 @@ const ApplicationRoute = Discourse.Route.extend({
});
},
/**
Deletes a user and all posts and topics created by that user.
@method deleteSpammer
**/
deleteSpammer: function (user) {
this.send('closeModal');
user.deleteAsSpammer(function() { window.location.reload(); });
@ -177,26 +147,28 @@ const ApplicationRoute = Discourse.Route.extend({
},
handleShowLogin() {
const self = this;
if(Discourse.SiteSettings.enable_sso) {
if (this.siteSettings.enable_sso) {
const returnPath = encodeURIComponent(window.location.pathname);
window.location = Discourse.getURL('/session/sso?return_path=' + returnPath);
} else {
this.send('autoLogin', 'login', function(){
Discourse.Route.showModal(self, 'login');
self.controllerFor('login').resetForm();
});
this._autoLogin('login', () => this.controllerFor('login').resetForm());
}
},
handleShowCreateAccount() {
const self = this;
this._autoLogin('createAccount');
},
_autoLogin(modal, notAuto) {
const methods = Em.get('Discourse.LoginMethod.all');
if (!this.siteSettings.enable_local_logins && methods.length === 1) {
this.controllerFor('login').send('externalLogin', methods[0]);
} else {
Discourse.Route.showModal(this, modal);
if (notAuto) { notAuto(); }
}
},
self.send('autoLogin', 'createAccount', function(){
Discourse.Route.showModal(self, 'createAccount');
});
}
});
RSVP.EventTarget.mixin(ApplicationRoute);

View File

@ -197,15 +197,10 @@ Discourse.Route.reopenClass({
appEvents.trigger('dom:clean');
},
/**
Shows a modal
@method showModal
**/
showModal: function(router, name, model) {
router.controllerFor('modal').set('modalClass', null);
router.render(name, {into: 'modal', outlet: 'modalBody'});
var controller = router.controllerFor(name);
showModal: function(route, name, model) {
route.controllerFor('modal').set('modalClass', null);
route.render(name, {into: 'modal', outlet: 'modalBody'});
var controller = route.controllerFor(name);
if (controller) {
if (model) {
controller.set('model', model);