webui: use asynchronous call for authentication

Change `IPA.login_password` and `IPA.get_credentials` to use async AJAX
and to return promise instead of blocking the code.

IPA.get_credentials is still partially blocking because of negotiate process.
We can't do anything about that.

It allows activity indicators to do their job.

https://fedorahosted.org/freeipa/ticket/3903

Reviewed-By: Adam Misnyovszki <amisnyov@redhat.com>
This commit is contained in:
Petr Vobornik 2014-02-20 18:05:16 +01:00
parent 2ec5d969a2
commit 937533c48e
3 changed files with 58 additions and 39 deletions

View File

@ -23,6 +23,7 @@
*/
define([
'dojo/Deferred',
'dojo/keys',
'dojo/topic',
'./jquery',
@ -36,8 +37,8 @@ define([
'./rpc',
'./text',
'exports'
], function(keys, topic, $, JSON, i18n, auth, datetime, metadata_provider,
builder, reg, rpc, text, exports) {
], function(Deferred, keys, topic, $, JSON, i18n, auth, datetime,
metadata_provider, builder, reg, rpc, text, exports) {
/**
* @class
@ -366,28 +367,30 @@ IPA.object = function(s) {
*/
IPA.get_credentials = function() {
var status;
var d = new Deferred();
function error_handler(xhr, text_status, error_thrown) {
status = xhr.status;
d.resolve(xhr.status);
IPA.hide_activity_icon();
}
function success_handler(data, text_status, xhr) {
status = xhr.status;
auth.current.set_authenticated(true, 'kerberos');
d.resolve(xhr.status);
IPA.hide_activity_icon();
}
var request = {
url: IPA.login_url,
cache: false,
async: false,
type: "GET",
success: success_handler,
error: error_handler
};
IPA.display_activity_icon();
$.ajax(request);
return status;
return d.promise;
};
/**
@ -415,6 +418,7 @@ IPA.logout = function() {
}
function success_handler(data, text_status, xhr) {
IPA.hide_activity_icon();
if (data && data.error) {
show_error(data.error.message);
} else {
@ -423,6 +427,7 @@ IPA.logout = function() {
}
function error_handler(xhr, text_status, error_thrown) {
IPA.hide_activity_icon();
if (xhr.status === 401) {
reload();
} else {
@ -441,7 +446,7 @@ IPA.logout = function() {
success: success_handler,
error: error_handler
};
IPA.display_activity_icon();
$.ajax(request);
};
@ -456,14 +461,18 @@ IPA.logout = function() {
IPA.login_password = function(username, password) {
var result = 'invalid';
var d = new Deferred();
function success_handler(data, text_status, xhr) {
IPA.hide_activity_icon();
result = 'success';
auth.current.set_authenticated(true, 'password');
d.resolve(result);
}
function error_handler(xhr, text_status, error_thrown) {
IPA.hide_activity_icon();
if (xhr.status === 401) {
var reason = xhr.getResponseHeader("X-IPA-Rejection-Reason");
@ -473,6 +482,7 @@ IPA.login_password = function(username, password) {
result = reason;
}
}
d.resolve(result);
}
var data = {
@ -486,7 +496,6 @@ IPA.login_password = function(username, password) {
contentType: 'application/x-www-form-urlencoded',
processData: true,
dataType: 'html',
async: false,
type: 'POST',
success: success_handler,
error: error_handler
@ -494,9 +503,8 @@ IPA.login_password = function(username, password) {
IPA.display_activity_icon();
$.ajax(request);
IPA.hide_activity_icon();
return result;
return d.promise;
};
/**

View File

@ -228,17 +228,26 @@ rpc.command = function(spec) {
* session credentials.
*/
function error_handler_login(xhr, text_status, error_thrown) {
if (xhr.status === 401) {
var login_status = IPA.get_credentials();
if (login_status === 200) {
that.request.error = error_handler;
$.ajax(that.request);
return;
}
var self = this;
function proceed() {
// error_handler() calls IPA.hide_activity_icon()
error_handler.call(self, xhr, text_status, error_thrown);
}
if (xhr.status === 401) {
IPA.get_credentials().then(function(login_status) {
if (login_status === 200) {
that.request.error = error_handler;
$.ajax(that.request);
return;
}
proceed();
});
} else {
proceed();
}
// error_handler() calls IPA.hide_activity_icon()
error_handler.call(this, xhr, text_status, error_thrown);
}
/*

View File

@ -337,14 +337,14 @@ define(['dojo/_base/declare',
login_with_kerberos: function() {
var status = IPA.get_credentials();
if (status === 200) {
this.emit('logged_in');
} else {
var val_summary = this.get_widget('validation');
val_summary.add_error('login', this.krb_auth_failed);
}
IPA.get_credentials().then(lang.hitch(this, function(status) {
if (status === 200) {
this.emit('logged_in');
} else {
var val_summary = this.get_widget('validation');
val_summary.add_error('login', this.krb_auth_failed);
}
}));
},
login_with_password: function() {
@ -356,18 +356,20 @@ define(['dojo/_base/declare',
var password_f = this.get_field('password');
var password = password_f.get_value()[0];
var result = IPA.login_password(login, password);
IPA.login_password(login, password).then(
lang.hitch(this, function(result) {
if (result === 'success') {
this.emit('logged_in');
password_f.set_value('');
} else if (result === 'password-expired') {
this.set('view', 'reset');
val_summary.add_error('login', this.password_expired);
} else {
val_summary.add_error('login', this.form_auth_failed);
password_f.set_value('');
}
if (result === 'success') {
this.emit('logged_in');
password_f.set_value('');
} else if (result === 'password-expired') {
this.set('view', 'reset');
val_summary.add_error('login', this.password_expired);
} else {
val_summary.add_error('login', this.form_auth_failed);
password_f.set_value('');
}
}));
},
login_and_reset: function() {