webui: handle back button when unauthenticated

using browser history when unauthenticated causes transition to
the original and/or preceding facets. But nothing works since
all commands fail due to expired credentials in session.

These changes make sure that user stays on login screen if he misses
valid session credentials while he wants to switch to facet which
requires authentication.

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

Reviewed-By: Endi Sukma Dewata <edewata@redhat.com>
This commit is contained in:
Petr Vobornik 2014-05-21 10:07:19 +02:00
parent 4b2d20a1f9
commit 905d58a2a4
6 changed files with 52 additions and 21 deletions

View File

@ -27,6 +27,7 @@ define([
'dojo/topic', 'dojo/topic',
'dojo/query', 'dojo/query',
'dojo/dom-class', 'dojo/dom-class',
'./auth',
'./json2', './json2',
'./widgets/App', './widgets/App',
'./widgets/FacetContainer', './widgets/FacetContainer',
@ -36,7 +37,7 @@ define([
'./navigation/Router', './navigation/Router',
'./navigation/menu_spec' './navigation/menu_spec'
], ],
function(declare, lang, array, Deferred, on, topic, query, dom_class, function(declare, lang, array, Deferred, on, topic, query, dom_class, auth,
JSON, App_widget, FacetContainer, IPA, reg, Menu, Router, menu_spec) { JSON, App_widget, FacetContainer, IPA, reg, Menu, Router, menu_spec) {
/** /**
@ -297,6 +298,12 @@ define([
show_facet: function(facet) { show_facet: function(facet) {
// prevent changing facet when authenticating
if (this.current_facet && this.current_facet.name === 'login' &&
!auth.current.authenticated && facet.requires_auth) {
return;
}
// choose container // choose container
var container = this.containers[facet.preferred_container]; var container = this.containers[facet.preferred_container];
if (!container) container = this.containers.main; if (!container) container = this.containers.main;
@ -455,7 +462,6 @@ define([
var login_facet = reg.facet.get('login'); var login_facet = reg.facet.get('login');
on.once(login_facet, "logged_in", function() { on.once(login_facet, "logged_in", function() {
if (facet) { if (facet) {
self.show_facet(facet); self.show_facet(facet);
} }

View File

@ -220,6 +220,13 @@ exp.facet = IPA.facet = function(spec, no_init) {
*/ */
that._needs_update = spec.needs_update; that._needs_update = spec.needs_update;
/**
* Facet is shown
* @property {Boolean}
*/
that.is_shown = false;
/** /**
* Marks facet as expired - needs update * Marks facet as expired - needs update
* *
@ -291,6 +298,13 @@ exp.facet = IPA.facet = function(spec, no_init) {
*/ */
that.redirect_info = spec.redirect_info; that.redirect_info = spec.redirect_info;
/**
* Facet requires authenticated user
* @type {Boolean}
*/
that.requires_auth = spec.requires_auth !== undefined ? spec.requires_auth : true;
/** /**
* Public state * Public state
* @property {facet.FacetState} * @property {facet.FacetState}
@ -480,7 +494,7 @@ exp.facet = IPA.facet = function(spec, no_init) {
that.old_state = state; that.old_state = state;
// we don't have to reflect any changes if facet dom is not yet created // we don't have to reflect any changes if facet dom is not yet created
if (!that.dom_node) { if (!that.dom_node || !that.is_shown) {
if (needs_update) that.set_expired_flag(); if (needs_update) that.set_expired_flag();
return; return;
} }
@ -651,30 +665,29 @@ exp.facet = IPA.facet = function(spec, no_init) {
*/ */
that.show = function() { that.show = function() {
if (that.is_shown) return;
that.is_shown = true;
that.entity.facet = that; // FIXME: remove that.entity.facet = that; // FIXME: remove
if (!that.dom_node) { if (!that.dom_node) {
that.create(); that.create();
}
var state = that.state.clone(); var state = that.state.clone();
var needs_update = that.needs_update(state); var needs_update = that.needs_update(state);
that.old_state = state; that.old_state = state;
if (needs_update) { if (needs_update) {
that.clear(); that.clear();
} }
that.dom_node.addClass('active-facet'); that.dom_node.addClass('active-facet');
that.show_content(); that.show_content();
that.header.select_tab(); that.header.select_tab();
if (needs_update) { if (needs_update) {
that.refresh(); that.refresh();
}
} else {
that.dom_node.addClass('active-facet');
that.show_content();
that.header.select_tab();
} }
}; };
@ -714,6 +727,7 @@ exp.facet = IPA.facet = function(spec, no_init) {
* Un-mark itself as active facet * Un-mark itself as active facet
*/ */
that.hide = function() { that.hide = function() {
that.is_shown = false;
that.dom_node.removeClass('active-facet'); that.dom_node.removeClass('active-facet');
}; };

View File

@ -112,6 +112,12 @@ define(['dojo/_base/declare',
*/ */
redirect_info: null, redirect_info: null,
/**
* Facet requires authenticated user
* @type {Boolean}
*/
requires_auth: true,
/** /**
* Public state * Public state
* @property {facet.FacetState} * @property {facet.FacetState}
@ -323,6 +329,9 @@ define(['dojo/_base/declare',
this.container_node = spec.container_node; this.container_node = spec.container_node;
this.dom_node = spec.dom_node; this.dom_node = spec.dom_node;
this.redirect_info = spec.redirect_info; this.redirect_info = spec.redirect_info;
if (spec.requires_auth !== undefined) {
this.requires_auth = spec.requires_auth;
}
this.state = new mod_facet.FacetState(); this.state = new mod_facet.FacetState();
on(this.state, 'set', lang.hitch(this, this.on_state_set)); on(this.state, 'set', lang.hitch(this, this.on_state_set));
} }

View File

@ -40,6 +40,7 @@ define([
load.facet_spec = { load.facet_spec = {
name: 'load', name: 'load',
preferred_container: 'simple', preferred_container: 'simple',
requires_auth: false,
'class': 'login-pf-body', 'class': 'login-pf-body',
widgets: [ widgets: [
{ {

View File

@ -43,6 +43,7 @@ define(['dojo/_base/declare',
login.facet_spec = { login.facet_spec = {
name: 'login', name: 'login',
preferred_container: 'simple', preferred_container: 'simple',
requires_auth: false,
widgets: [ widgets: [
{ {
$type: 'activity', $type: 'activity',
@ -60,7 +61,7 @@ define(['dojo/_base/declare',
login.LoginFacet = declare([Facet], { login.LoginFacet = declare([Facet], {
can_leave: function() { can_leave: function() {
return auth.authenticated; return auth.current.authenticated;
}, },
init: function() { init: function() {

View File

@ -289,7 +289,7 @@ rpc.command = function(spec) {
// With trusts, user from trusted domain can use his ticket but he // With trusts, user from trusted domain can use his ticket but he
// doesn't have rights for LDAP modify. It will throw internal error. // doesn't have rights for LDAP modify. It will throw internal error.
// We should offer form base login. // We should offer form base login.
if (xhr.status === 500 && auth.authenticated_by === 'kerberos' && if (xhr.status === 500 && auth.current.authenticated_by === 'kerberos' &&
!IPA.ui.initialized) { !IPA.ui.initialized) {
error_handler_auth(xhr, text_status, error_thrown); error_handler_auth(xhr, text_status, error_thrown);
return; return;