summaryrefslogtreecommitdiffstats
path: root/install/ui/src/freeipa/ipa.js
diff options
context:
space:
mode:
authorPetr Vobornik <pvoborni@redhat.com>2012-11-26 14:28:32 +0100
committerPetr Vobornik <pvoborni@redhat.com>2013-01-18 15:10:36 +0100
commitb9ef6ab0c412913234f05f788b3fcd3c3277eb69 (patch)
tree2af9ef49ce74fd152c4c7b6f0aad543b4793ba59 /install/ui/src/freeipa/ipa.js
parent8f8e790d9468245c031320d6a506a420f486638f (diff)
downloadfreeipa-b9ef6ab0c412913234f05f788b3fcd3c3277eb69.tar.gz
freeipa-b9ef6ab0c412913234f05f788b3fcd3c3277eb69.tar.xz
freeipa-b9ef6ab0c412913234f05f788b3fcd3c3277eb69.zip
Move of core Web UI files to AMD directory
SSIA https://fedorahosted.org/freeipa/ticket/112
Diffstat (limited to 'install/ui/src/freeipa/ipa.js')
-rw-r--r--install/ui/src/freeipa/ipa.js2122
1 files changed, 2122 insertions, 0 deletions
diff --git a/install/ui/src/freeipa/ipa.js b/install/ui/src/freeipa/ipa.js
new file mode 100644
index 000000000..cc62f0897
--- /dev/null
+++ b/install/ui/src/freeipa/ipa.js
@@ -0,0 +1,2122 @@
+/*jsl:import jquery.ordered-map.js */
+/* Authors:
+ * Pavel Zuna <pzuna@redhat.com>
+ * Adam Young <ayoung@redhat.com>
+ * Endi Dewata <edewata@redhat.com>
+ * John Dennis <jdennis@redhat.com>
+ * Petr Vobornik <pvoborni@redhat.com>
+ *
+ * Copyright (C) 2010 Red Hat
+ * see file 'COPYING' for use and warranty information
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+/* REQUIRES: jquery.ordered-map.js */
+/*global $:true, location:true */
+
+var IPA = function() {
+
+ var that = {
+ jsonrpc_id: 0
+ };
+
+ // live server path
+ that.url = '/ipa/ui/';
+
+ that.ajax_options = {
+ type: 'POST',
+ contentType: 'application/json',
+ dataType: 'json',
+ async: true,
+ processData: false
+ };
+
+ that.metadata = {};
+ that.messages = {};
+ that.whoami = {};
+
+ that.entities = $.ordered_map();
+ that.entity_factories = {};
+ that.field_factories = {};
+ that.widget_factories = {};
+
+ that.network_call_count = 0;
+
+ that.ui = {};
+
+ /* initialize the IPA JSON-RPC helper */
+ that.init = function(params) {
+
+ // if current path matches live server path, use live data
+ if (that.url && window.location.pathname.substring(0, that.url.length) === that.url) {
+ that.json_url = params.url || '/ipa/session/json';
+ that.login_url = params.url || '/ipa/session/login_kerberos';
+
+ } else { // otherwise use fixtures
+ that.json_path = params.url || "test/data";
+ // that.login_url is not needed for fixtures
+ }
+
+ $.ajaxSetup(that.ajax_options);
+
+ var batch = IPA.batch_command({
+ name: 'ipa_init',
+ retry: false,
+ on_success: function() {
+ that.init_metadata({
+ on_success: params.on_success,
+ on_error: params.on_error
+ });
+ },
+ on_error: function(xhr, text_status, error_thrown) {
+
+ // On IE the request is missing after authentication,
+ // so the request needs to be resent.
+ if (error_thrown.code === 909) {
+ batch.execute();
+
+ } else {
+ var ajax = this;
+
+ var dialog = IPA.error_dialog({
+ xhr: xhr,
+ text_status: text_status,
+ error_thrown: error_thrown,
+ command: batch
+ });
+
+ dialog.on_cancel = function() {
+ dialog.close();
+ if (params.on_error) {
+ params.on_error.call(ajax, xhr, text_status, error_thrown);
+ }
+ };
+
+ dialog.open();
+ }
+ }
+ });
+
+ batch.add_command(IPA.command({
+ method: 'i18n_messages',
+ on_success: function(data, text_status, xhr) {
+ that.messages = data.messages;
+ }
+ }));
+
+ batch.add_command(IPA.command({
+ entity: 'config',
+ method: 'show',
+ on_success: function(data, text_status, xhr) {
+ that.server_config = data.result;
+ }
+ }));
+
+ batch.add_command(that.get_whoami_command(true));
+
+ batch.add_command(IPA.command({
+ method: 'env',
+ on_success: function(data, text_status, xhr) {
+ that.env = data.result;
+ that.version = that.env.version;
+ }
+ }));
+
+ batch.add_command(IPA.command({
+ entity: 'dns',
+ method: 'is_enabled',
+ on_success: function(data, text_status, xhr) {
+ that.dns_enabled = data.result;
+ }
+ }));
+
+
+
+ batch.execute();
+ };
+
+ that.get_whoami_command = function(batch) {
+ return IPA.command({
+ entity: 'user',
+ method: 'find',
+ options: {
+ whoami: true,
+ all: true
+ },
+ on_success: function(data, text_status, xhr) {
+ that.whoami = batch ? data.result[0] : data.result.result[0];
+ that.principal = that.whoami.krbprincipalname[0];
+ }
+ });
+ };
+
+ that.init_metadata = function(params) {
+
+ var objects = IPA.command({
+ name: 'ipa_init_objects',
+ method: 'json_metadata',
+ options: {
+ object: 'all'
+ },
+ on_success: function(data, text_status, xhr) {
+ that.metadata.objects = data.result.objects;
+ }
+ });
+
+ var commands = IPA.command({
+ name: 'ipa_init_commands',
+ method: 'json_metadata',
+ options: {
+ command: 'all'
+ },
+ on_success: function(data, text_status, xhr) {
+ that.metadata.commands = data.result.commands;
+ }
+ });
+
+ var metadata_command = IPA.concurrent_command({
+ commands: [
+ objects,
+ commands
+ ],
+ on_success: function(data, text_status, xhr) {
+ IPA.ui.initialized = true;
+ if (params.on_success) {
+ params.on_success.call(this, data, text_status, xhr);
+ }
+ },
+ on_error: params.on_error
+ });
+
+ metadata_command.execute();
+ };
+
+ that.register = function(name, factory) {
+ that.remove_entity(name);
+ that.entity_factories[name] = factory;
+ };
+
+ that.create_entity = function(name) {
+ var factory = that.entity_factories[name];
+ if (!factory) return null;
+
+ try {
+ var builder = IPA.entity_builder();
+
+ builder.entity({
+ factory: factory,
+ name: name
+ });
+
+ var entity = builder.build();
+ entity.init();
+
+ return entity;
+
+ } catch (e) {
+ if (e.expected) {
+ /*expected exceptions thrown by builder just mean that
+ entities are not to be registered. */
+ return null;
+ }
+
+ if (e.message) {
+ alert(e.message);
+ } else {
+ alert(e);
+ }
+
+ return null;
+ }
+ };
+
+ that.get_entities = function() {
+ return that.entities.values;
+ };
+
+ that.get_entity = function(name) {
+ if (typeof name === 'object') return name;
+ var entity = that.entities.get(name);
+ if (!entity) {
+ entity = that.create_entity(name);
+ if (entity) that.add_entity(entity);
+ }
+ return entity;
+ };
+
+ that.add_entity = function(entity) {
+ that.entities.put(entity.name, entity);
+ };
+
+ that.remove_entity = function(name) {
+ that.entities.remove(name);
+ };
+
+ that.display_activity_icon = function() {
+ that.network_call_count++;
+ $('.network-activity-indicator').css('visibility', 'visible');
+ };
+
+ that.hide_activity_icon = function() {
+ that.network_call_count--;
+
+ if (0 === that.network_call_count) {
+ $('.network-activity-indicator').css('visibility', 'hidden');
+ }
+ };
+
+ that.get_message = function(id, default_message) {
+ var messages = IPA.messages;
+ var keys = id.split(/\./);
+
+ for (var i=0; messages && i<keys.length; i++) {
+ var key = keys[i];
+ var value = messages[key];
+
+ // undefined key => not found
+ if (!value) return default_message;
+
+ // if value is string
+ if (typeof value === 'string') {
+
+ // and it's the last key => found
+ if (i === keys.length-1) return value;
+
+ // otherwise value should have been a container => not found
+ return default_message;
+ }
+
+ // value is container => check next key
+ messages = value;
+ }
+
+ // no more keys/messages => not found
+ return default_message;
+ };
+
+ return that;
+}();
+
+IPA.get_credentials = function() {
+ var status;
+
+ function error_handler(xhr, text_status, error_thrown) {
+ status = xhr.status;
+ IPA.ui.logged_kerberos = false;
+ }
+
+ function success_handler(data, text_status, xhr) {
+ status = xhr.status;
+ IPA.ui.logged_kerberos = true;
+ }
+
+ var request = {
+ url: IPA.login_url,
+ cache: false,
+ async: false,
+ type: "GET",
+ success: success_handler,
+ error: error_handler
+ };
+
+ $.ajax(request);
+
+ return status;
+};
+
+IPA.logout = function() {
+
+ function show_error(message) {
+ var dialog = IPA.message_dialog({
+ name: 'logout_error',
+ message: message,
+ title: IPA.messages.login.logout_error
+ });
+ dialog.open();
+ }
+
+ function redirect () {
+ window.location = 'logout.html';
+ }
+
+ function success_handler(data, text_status, xhr) {
+ if (data && data.error) {
+ show_error(data.error.message);
+ } else {
+ redirect();
+ }
+ }
+
+ function error_handler(xhr, text_status, error_thrown) {
+ if (xhr.status === 401) {
+ redirect();
+ } else {
+ show_error(text_status);
+ }
+ }
+
+ var command = {
+ method: 'session_logout',
+ params: [[], {}]
+ };
+
+ var request = {
+ url: IPA.json_url || IPA.json_path + '/session_logout.json',
+ data: JSON.stringify(command),
+ success: success_handler,
+ error: error_handler
+ };
+
+ $.ajax(request);
+};
+
+IPA.login_password = function(username, password) {
+
+ var result = 'invalid';
+
+ function success_handler(data, text_status, xhr) {
+ result = 'success';
+ IPA.ui.logged_password = true;
+ }
+
+ function error_handler(xhr, text_status, error_thrown) {
+
+ if (xhr.status === 401) {
+ var reason = xhr.getResponseHeader("X-IPA-Rejection-Reason");
+
+ //change result from invalid only if we have a header which we
+ //understand
+ if (reason === 'password-expired' || reason === 'denied') {
+ result = reason;
+ }
+ }
+
+ IPA.ui.logged_password = false;
+ }
+
+ var data = {
+ user: username,
+ password: password
+ };
+
+ var request = {
+ url: '/ipa/session/login_password',
+ data: data,
+ contentType: 'application/x-www-form-urlencoded',
+ processData: true,
+ dataType: 'html',
+ async: false,
+ type: 'POST',
+ success: success_handler,
+ error: error_handler
+ };
+
+ IPA.display_activity_icon();
+ $.ajax(request);
+ IPA.hide_activity_icon();
+
+ return result;
+};
+
+IPA.reset_password = function(username, old_password, new_password) {
+
+ //possible results: 'ok', 'invalid-password', 'policy-error'
+
+ var status, result, reason, invalid, failure, data, request;
+
+ status = 'invalid';
+ result = {
+ status: status,
+ message: IPA.get_message('password.reset_failure',
+ "Password reset was not successful.")
+ };
+
+ function success_handler(data, text_status, xhr) {
+
+ result.status = xhr.getResponseHeader("X-IPA-Pwchange-Result") || status;
+
+ if (result.status === 'policy-error') {
+ result.message = xhr.getResponseHeader("X-IPA-Pwchange-Policy-Error");
+ } else if (result.status === 'invalid-password') {
+ result.message = IPA.get_message('password.invalid_password',
+ "The password or username you entered is incorrect.");
+ }
+
+ return result;
+ }
+
+ function error_handler(xhr, text_status, error_thrown) {
+ return result;
+ }
+
+ data = {
+ user: username,
+ old_password: old_password,
+ new_password: new_password
+ };
+
+ request = {
+ url: '/ipa/session/change_password',
+ data: data,
+ contentType: 'application/x-www-form-urlencoded',
+ processData: true,
+ dataType: 'html',
+ async: false,
+ type: 'POST',
+ success: success_handler,
+ error: error_handler
+ };
+
+ IPA.display_activity_icon();
+ $.ajax(request);
+ IPA.hide_activity_icon();
+
+ return result;
+};
+
+IPA.update_password_expiration = function() {
+
+ var now, expires, notify_days, diff, message, container;
+
+ expires = IPA.whoami.krbpasswordexpiration;
+ expires = expires ? IPA.parse_utc_date(expires[0]) : null;
+
+ notify_days = IPA.server_config.ipapwdexpadvnotify;
+ notify_days = notify_days ? notify_days[0] : 0;
+
+ now = new Date();
+
+ container = $('.header-passwordexpires');
+ container.empty();
+
+ if (expires) {
+
+ diff = expires.getTime() - now.getTime();
+ diff = Math.floor(diff / 86400000);
+
+ if (diff <= notify_days) {
+ message = IPA.messages.password.expires_in;
+ message = message.replace('${days}', diff);
+ container.append(message + ' ');
+ $('<a/>', {
+ href: '#reset-password',
+ click: function() {
+ IPA.password_selfservice();
+ return false;
+ },
+ text: IPA.messages.password.reset_password_sentence,
+ title: IPA.messages.password.reset_password
+ }).appendTo(container);
+ }
+ }
+};
+
+IPA.password_selfservice = function() {
+ var reset_dialog = IPA.user_password_dialog({
+ self_service: true,
+ on_success: function() {
+ var command = IPA.get_whoami_command();
+ var orig_on_success = command.on_success;
+ command.on_success = function(data, text_status, xhr) {
+ orig_on_success.call(this, data, text_status, xhr);
+ IPA.update_password_expiration();
+ };
+ command.execute();
+
+ alert(IPA.messages.password.password_change_complete);
+ reset_dialog.close();
+ }
+ });
+ reset_dialog.open();
+};
+
+IPA.parse_utc_date = function(value) {
+
+ if (!value) return null;
+
+ // verify length
+ if (value.length != 'YYYYmmddHHMMSSZ'.length) {
+ return null;
+ }
+
+ // We only handle GMT
+ if (value.charAt(value.length -1) !== 'Z') {
+ return null;
+ }
+
+ var date = new Date();
+
+ date.setUTCFullYear(
+ value.substring(0, 4), // YYYY
+ value.substring(4, 6)-1, // mm (0-11)
+ value.substring(6, 8)); // dd (1-31)
+
+ date.setUTCHours(
+ value.substring(8, 10), // HH (0-23)
+ value.substring(10, 12), // MM (0-59)
+ value.substring(12, 14)); // SS (0-59)
+
+ return date;
+};
+
+/**
+ * Call an IPA command over JSON-RPC.
+ *
+ * Arguments:
+ * name - command name (optional)
+ * entity - command entity (optional)
+ * method - command method
+ * args - list of arguments, e.g. [username]
+ * options - dict of options, e.g. {givenname: 'Pavel'}
+ * on_success - callback function if command succeeds
+ * on_error - callback function if command fails
+ */
+IPA.command = function(spec) {
+
+ spec = spec || {};
+
+ var that = {};
+
+ that.name = spec.name;
+
+ that.entity = spec.entity;
+ that.method = spec.method;
+
+ that.args = $.merge([], spec.args || []);
+ that.options = $.extend({}, spec.options || {});
+
+ that.on_success = spec.on_success;
+ that.on_error = spec.on_error;
+
+ that.retry = typeof spec.retry == 'undefined' ? true : spec.retry;
+
+ that.error_message = spec.error_message || IPA.get_message('dialogs.batch_error_message', 'Some operations failed.');
+ that.error_messages = $.ordered_map({
+ 911: 'Missing HTTP referer. <br/> You have to configure your browser to send HTTP referer header.'
+ });
+
+ that.get_command = function() {
+ return (that.entity ? that.entity+'_' : '') + that.method;
+ };
+
+ that.add_arg = function(arg) {
+ that.args.push(arg);
+ };
+
+ that.add_args = function(args) {
+ $.merge(that.args, args);
+ };
+
+ that.set_option = function(name, value) {
+ that.options[name] = value;
+ };
+
+ that.set_options = function(options) {
+ $.extend(that.options, options);
+ };
+
+ that.add_option = function(name, value) {
+ var values = that.options[name];
+ if (!values) {
+ values = [];
+ that.options[name] = values;
+ }
+ values.push(value);
+ };
+
+ that.get_option = function(name) {
+ return that.options[name];
+ };
+
+ that.remove_option = function(name) {
+ delete that.options[name];
+ };
+
+ that.execute = function() {
+
+ function dialog_open(xhr, text_status, error_thrown) {
+
+ var ajax = this;
+
+ var dialog = IPA.error_dialog({
+ xhr: xhr,
+ text_status: text_status,
+ error_thrown: error_thrown,
+ command: that
+ });
+
+ dialog.on_cancel = function() {
+ dialog.close();
+ if (that.on_error) {
+ that.on_error.call(ajax, xhr, text_status, error_thrown);
+ }
+ };
+
+ dialog.open();
+ }
+
+ function auth_dialog_open(xhr, text_status, error_thrown) {
+
+ var ajax = this;
+
+ var dialog = IPA.unauthorized_dialog({
+ xhr: xhr,
+ text_status: text_status,
+ error_thrown: error_thrown,
+ close_on_escape: false,
+ command: that
+ });
+
+ dialog.open();
+ }
+
+ /*
+ * Special error handler used the first time this command is
+ * submitted. It checks to see if the session credentials need
+ * to be acquired and if so sends a request to a special url
+ * to establish the sesion credentials. If acquiring the
+ * session credentials is successful it simply resubmits the
+ * exact same command after setting the error handler back to
+ * the normal error handler. If aquiring the session
+ * credentials fails the normal error handler is invoked to
+ * process the error returned from the attempt to aquire the
+ * 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;
+ }
+ }
+ // error_handler() calls IPA.hide_activity_icon()
+ error_handler.call(this, xhr, text_status, error_thrown);
+ }
+
+ /*
+ * Normal error handler, handles all errors.
+ * error_handler_login() is initially used to trap the
+ * special case need to aquire session credentials, this is
+ * not a true error, rather it's an indication an extra step
+ * needs to be taken before normal processing can continue.
+ */
+ function error_handler(xhr, text_status, error_thrown) {
+
+ IPA.hide_activity_icon();
+
+ if (xhr.status === 401) {
+ auth_dialog_open(xhr, text_status, error_thrown);
+ return;
+ } else if (!error_thrown) {
+ error_thrown = {
+ name: xhr.responseText || IPA.get_message('errors.unknown_error', 'Unknown Error'),
+ message: xhr.statusText || IPA.get_message('errors.unknown_error', 'Unknown Error')
+ };
+
+ } else if (typeof error_thrown == 'string') {
+ error_thrown = {
+ name: error_thrown,
+ message: error_thrown
+ };
+ }
+
+ // custom messages for set of codes
+ var error_msg = that.error_messages.get(error_thrown.code);
+ if (error_msg) {
+ error_msg = error_msg.replace('${message}', error_thrown.message);
+ error_thrown.message = error_msg;
+ }
+
+ // global specical cases error handlers section
+
+ // With trusts, user from trusted domain can use his ticket but he
+ // doesn't have rights for LDAP modify. It will throw internal errror.
+ // We should offer form base login.
+ if (xhr.status === 500 && IPA.ui.logged_kerberos && !IPA.ui.initialized) {
+ auth_dialog_open(xhr, text_status, error_thrown);
+ return;
+ }
+
+ if (that.retry) {
+ dialog_open.call(this, xhr, text_status, error_thrown);
+
+ } else if (that.on_error) {
+ //custom error handling, maintaining AJAX call's context
+ that.on_error.call(this, xhr, text_status, error_thrown);
+ }
+ }
+
+ function success_handler(data, text_status, xhr) {
+
+ if (!data) {
+ // error_handler() calls IPA.hide_activity_icon()
+ error_handler.call(this, xhr, text_status, /* error_thrown */ {
+ name: IPA.get_message('errors.http_error', 'HTTP Error')+' '+xhr.status,
+ url: this.url,
+ message: data ? xhr.statusText : IPA.get_message('errors.no_response', 'No response')
+ });
+
+ } else if (IPA.version && data.version && IPA.version !== data.version) {
+ window.location.reload();
+
+ } else if (IPA.principal && data.principal && IPA.principal !== data.principal) {
+ window.location.reload();
+
+ } else if (data.error) {
+ // error_handler() calls IPA.hide_activity_icon()
+ error_handler.call(this, xhr, text_status, /* error_thrown */ {
+ name: IPA.get_message('errors.ipa_error', 'IPA Error')+' '+data.error.code,
+ code: data.error.code,
+ message: data.error.message,
+ data: data
+ });
+
+ } else {
+ IPA.hide_activity_icon();
+
+ var ajax = this;
+ var failed = that.get_failed(that, data.result, text_status, xhr);
+ if (!failed.is_empty()) {
+ var dialog = IPA.error_dialog({
+ xhr: xhr,
+ text_status: text_status,
+ error_thrown: {
+ name: IPA.get_message('dialogs.batch_error_title', 'Operations Error'),
+ message: that.error_message
+ },
+ command: that,
+ errors: failed.errors,
+ visible_buttons: ['ok']
+ });
+
+ dialog.on_ok = function() {
+ dialog.close();
+ if (that.on_success) that.on_success.call(ajax, data, text_status, xhr);
+ };
+
+ dialog.open();
+
+ } else {
+ //custom success handling, maintaining AJAX call's context
+ if (that.on_success) that.on_success.call(this, data, text_status, xhr);
+ }
+ }
+ }
+
+ that.data = {
+ method: that.get_command(),
+ params: [that.args, that.options]
+ };
+
+ that.request = {
+ url: IPA.json_url || IPA.json_path + '/' + (that.name || that.data.method) + '.json',
+ data: JSON.stringify(that.data),
+ success: success_handler,
+ error: error_handler_login
+ };
+
+ IPA.display_activity_icon();
+ $.ajax(that.request);
+ };
+
+ that.get_failed = function(command, result, text_status, xhr) {
+ var errors = IPA.error_list();
+ if(result && result.failed) {
+ for(var association in result.failed) {
+ for(var member_name in result.failed[association]) {
+ var member = result.failed[association][member_name];
+ for(var i = 0; i < member.length; i++) {
+ if(member[i].length > 1) {
+ var name = IPA.get_message('errors.ipa_error', 'IPA Error');
+ var message = member[i][1];
+ if(member[i][0])
+ message = member[i][0] + ': ' + message;
+ errors.add(command, name, message, text_status);
+ }
+ }
+ }
+ }
+ }
+ return errors;
+ };
+
+ that.check_option = function(option_name) {
+
+ var metadata = IPA.get_command_option(that.get_command(), option_name);
+ return metadata !== null;
+ };
+
+ that.to_json = function() {
+ var json = {};
+
+ json.method = that.get_command();
+
+ json.params = [];
+ json.params[0] = that.args || [];
+ json.params[1] = that.options || {};
+
+ return json;
+ };
+
+ that.to_string = function() {
+ var string = that.get_command().replace(/_/g, '-');
+
+ for (var i=0; i<that.args.length; i++) {
+ string += ' '+that.args[i];
+ }
+
+ for (var name in that.options) {
+ string += ' --'+name+'=\''+that.options[name]+'\'';
+ }
+
+ return string;
+ };
+
+ return that;
+};
+
+IPA.batch_command = function (spec) {
+
+ spec = spec || {};
+
+ spec.method = 'batch';
+
+ var that = IPA.command(spec);
+
+ that.commands = [];
+ that.errors = IPA.error_list();
+ that.show_error = typeof spec.show_error == 'undefined' ?
+ true : spec.show_error;
+
+ that.add_command = function(command) {
+ that.commands.push(command);
+ that.add_arg(command.to_json());
+ };
+
+ that.add_commands = function(commands) {
+ for (var i=0; i<commands.length; i++) {
+ that.add_command(commands[i]);
+ }
+ };
+
+ that.execute = function() {
+ that.errors.clear();
+
+ var command = IPA.command({
+ name: that.name,
+ entity: that.entity,
+ method: that.method,
+ args: that.args,
+ options: that.options,
+ retry: that.retry
+ });
+
+ command.on_success = that.batch_command_on_success;
+ command.on_error = that.batch_command_on_error;
+
+ command.execute();
+ };
+
+ that.batch_command_on_success = function(data, text_status, xhr) {
+
+ for (var i=0; i<that.commands.length; i++) {
+ var command = that.commands[i];
+ var result = data.result.results[i];
+
+ var name = '';
+ var message = '';
+
+ if (!result) {
+ name = IPA.get_message('errors.internal_error', 'Internal Error')+' '+xhr.status;
+ message = result ? xhr.statusText : IPA.get_message('errors.internal_error', 'Internal Error');
+
+ that.errors.add(command, name, message, text_status);
+
+ if (command.on_error) command.on_error.call(
+ this,
+ xhr,
+ text_status,
+ {
+ name: name,
+ message: message
+ }
+ );
+
+ } else if (result.error) {
+ var code = result.error.code || result.error_code;
+ name = IPA.get_message('errors.ipa_error', 'IPA Error')+(code ? ' '+code : '');
+ message = result.error.message || result.error;
+
+ if (command.retry) that.errors.add(command, name, message, text_status);
+
+ if (command.on_error) command.on_error.call(
+ this,
+ xhr,
+ text_status,
+ {
+ name: name,
+ code: code,
+ message: message,
+ data: result
+ }
+ );
+
+ } else {
+ var failed = that.get_failed(command, result, text_status, xhr);
+ that.errors.add_range(failed);
+
+ if (command.on_success) command.on_success.call(this, result, text_status, xhr);
+ }
+ }
+
+ //check for partial errors and show error dialog
+ if (that.show_error && that.errors.errors.length > 0) {
+ var ajax = this;
+ var dialog = IPA.error_dialog({
+ xhr: xhr,
+ text_status: text_status,
+ error_thrown: {
+ name: IPA.get_message('dialogs.batch_error_title', 'Operations Error'),
+ message: that.error_message
+ },
+ command: that,
+ errors: that.errors.errors,
+ visible_buttons: [ 'ok' ]
+ });
+
+ dialog.on_ok = function() {
+ dialog.close();
+ if (that.on_success) that.on_success.call(ajax, data, text_status, xhr);
+ };
+
+ dialog.open();
+
+ } else {
+ if (that.on_success) that.on_success.call(this, data, text_status, xhr);
+ }
+ };
+
+ that.batch_command_on_error = function(xhr, text_status, error_thrown) {
+ // TODO: undefined behavior
+ if (that.on_error) {
+ that.on_error.call(this, xhr, text_status, error_thrown);
+ }
+ };
+
+ return that;
+};
+
+
+IPA.concurrent_command = function(spec) {
+
+ spec = spec || {};
+ var that = {};
+
+ that.commands = [];
+ that.on_success = spec.on_success;
+ that.on_error = spec.on_error;
+
+ that.add_commands = function(commands) {
+
+ if(commands && commands.length) {
+ for(var i=0; i < commands.length; i++) {
+ that.commands.push({
+ command: commands[i]
+ });
+ }
+ }
+ };
+
+ that.execute = function() {
+
+ var command_info, command, i;
+
+ //prepare for execute
+ for(i=0; i < that.commands.length; i++) {
+ command_info = that.commands[i];
+ command = command_info.command;
+ if(!command) {
+ var dialog = IPA.message_dialog({
+ name: 'internal_error',
+ title: IPA.get_message('errors.error', 'Error'),
+ message: IPA.get_message('errors.internal_error', 'Internal error.')
+ });
+ break;
+ }
+ command_info.completed = false;
+ command_info.success = false;
+ command_info.on_success = command_info.on_success || command.on_success;
+ command_info.on_error = command_info.on_error || command.on_error;
+ command.on_success = function(command_info) {
+ return function(data, text_status, xhr) {
+ that.success_handler.call(this, command_info, data, text_status, xhr);
+ };
+ }(command_info);
+ command.on_error = function(command_info) {
+ return function(xhr, text_status, error_thrown) {
+ that.error_handler.call(this, command_info, xhr, text_status, error_thrown);
+ };
+ }(command_info);
+ }
+
+ //execute
+ for(i=0; i < that.commands.length; i++) {
+ command = that.commands[i].command;
+ command.execute();
+ }
+ };
+
+ that.error_handler = function(command_info, xhr, text_status, error_thrown) {
+
+ command_info.completed = true;
+ command_info.success = false;
+ command_info.xhr = xhr;
+ command_info.text_status = text_status;
+ command_info.error_thrown = error_thrown;
+ command_info.context = this;
+ that.command_completed();
+ };
+
+ that.success_handler = function(command_info, data, text_status, xhr) {
+
+ command_info.completed = true;
+ command_info.success = true;
+ command_info.data = data;
+ command_info.text_status = text_status;
+ command_info.xhr = xhr;
+ command_info.context = this;
+ that.command_completed();
+ };
+
+ that.command_completed = function() {
+
+ var all_completed = true;
+ var all_success = true;
+
+ for(var i=0; i < that.commands.length; i++) {
+ var command_info = that.commands[i];
+ all_completed = all_completed && command_info.completed;
+ all_success = all_success && command_info.success;
+ }
+
+ if(all_completed) {
+ if(all_success) {
+ that.on_success_all();
+ } else {
+ that.on_error_all();
+ }
+ }
+ };
+
+ that.on_success_all = function() {
+
+ for(var i=0; i < that.commands.length; i++) {
+ var command_info = that.commands[i];
+ if(command_info.on_success) {
+ command_info.on_success.call(
+ command_info.context,
+ command_info.data,
+ command_info.text_status,
+ command_info.xhr);
+ }
+ }
+
+ if(that.on_success) {
+ that.on_success();
+ }
+ };
+
+ that.on_error_all = function() {
+
+ if(that.on_error) {
+ that.on_error();
+
+ } else {
+ var dialog = IPA.message_dialog({
+ name: 'operation_error',
+ title: IPA.get_message('dialogs.batch_error_title', 'Operations Error'),
+ message: IPA.get_message('dialogs.batch_error_message', 'Some operations failed.')
+ });
+
+ dialog.open();
+ }
+ };
+
+ that.add_commands(spec.commands);
+
+ return that;
+};
+
+IPA.builder = function(spec) {
+
+ spec = spec || {};
+
+ var that = {};
+
+ that.factory = spec.factory || IPA.default_factory;
+
+ that.build = function(spec) {
+
+ var factory = spec.factory || that.factory;
+
+ //when spec is a factory function
+ if (!spec.factory && typeof spec === 'function') {
+ factory = spec;
+ spec = {};
+ }
+
+ var obj = factory(spec);
+ return obj;
+ };
+
+ that.build_objects = function(specs) {
+
+ var objects = [];
+
+ for (var i=0; i<specs.length; i++) {
+ var spec = specs[i];
+ var obj = that.build(spec);
+ objects.push(obj);
+ }
+
+ return objects;
+ };
+
+ return that;
+};
+
+IPA.build = function(spec, builder_fac) {
+
+ if (!spec) return null;
+
+ if (!builder_fac) builder_fac = IPA.builder;
+
+ var builder = builder_fac();
+ var product;
+
+ if ($.isArray(spec)) {
+ product = builder.build_objects(spec);
+ } else {
+ product = builder.build(spec);
+ }
+
+ return product;
+};
+
+IPA.build_default = function(spec, def_spec) {
+
+ var builder, factory, default_object;
+
+ if (!spec && !def_spec) return null;
+
+ if (typeof def_spec === 'function') { //factory function
+ factory = def_spec;
+ } else if (typeof def_spec === 'object') {
+ default_object = def_spec;
+ }
+
+ builder = IPA.builder({
+ factory: factory
+ });
+
+ var product;
+ spec = spec || default_object || {};
+
+ if ($.isArray(spec)) {
+ product = builder.build_objects(spec);
+ } else {
+ product = builder.build(spec);
+ }
+
+ return product;
+};
+
+IPA.default_factory = function(spec) {
+
+ spec = spec || {};
+
+ var that = {};
+
+ $.extend(that, spec);
+
+ return that;
+};
+
+/* helper function used to retrieve information about an attribute */
+IPA.get_entity_param = function(entity_name, name) {
+
+ var metadata = IPA.metadata.objects[entity_name];
+ if (!metadata) {
+ return null;
+ }
+
+ var params = metadata.takes_params;
+ if (!params) {
+ return null;
+ }
+
+ for (var i=0; i<params.length; i++) {
+ if (params[i].name === name) {
+ return params[i];
+ }
+ }
+
+ return null;
+};
+
+IPA.get_command_arg = function(command_name, arg_name) {
+
+ var metadata = IPA.metadata.commands[command_name];
+ if (!metadata) {
+ return null;
+ }
+
+ var args = metadata.takes_args;
+ if (!args) {
+ return null;
+ }
+
+ for (var i=0; i<args.length; i++) {
+ if (args[i].name === arg_name) {
+ return args[i];
+ }
+ }
+
+ return null;
+};
+
+IPA.get_command_option = function(command_name, option_name) {
+
+ var metadata = IPA.metadata.commands[command_name];
+ if (!metadata) {
+ return null;
+ }
+
+ var options = metadata.takes_options;
+ if (!options) {
+ return null;
+ }
+
+ for (var i=0; i<options.length; i++) {
+ if (options[i].name === option_name) {
+ return options[i];
+ }
+ }
+
+ return null;
+};
+
+/* helper function used to retrieve attr name with members of type `member` */
+IPA.get_member_attribute = function(obj_name, member) {
+
+ var obj = IPA.metadata.objects[obj_name];
+ if (!obj) {
+ return null;
+ }
+
+ var attribute_members = obj.attribute_members;
+ for (var a in attribute_members) {
+ var objs = attribute_members[a];
+ for (var i = 0; i < objs.length; i += 1) {
+ if (objs[i] === member){
+ return a;
+ }
+ }
+ }
+
+ return null;
+};
+
+IPA.create_network_spinner = function(){
+ var span = $('<span/>', {
+ 'class': 'network-activity-indicator'
+ });
+ $('<img/>', {
+ src: 'images/spinner-small.gif'
+ }).appendTo(span);
+ return span;
+};
+
+IPA.dirty_dialog = function(spec) {
+
+ spec = spec || {};
+ spec.title = spec.title || IPA.messages.dialogs.dirty_title;
+ spec.width = spec.width || '25em';
+
+ var that = IPA.dialog(spec);
+ that.facet = spec.facet;
+ that.message = spec.message || IPA.messages.dialogs.dirty_message;
+
+ that.create = function() {
+ that.container.append(that.message);
+ };
+
+ that.create_button({
+ name: 'update',
+ label: IPA.messages.buttons.update,
+ click: function() {
+ that.facet.update(function() {
+ that.close();
+ that.callback();
+ });
+ }
+ });
+
+ that.create_button({
+ name: 'reset',
+ label: IPA.messages.buttons.reset,
+ click: function() {
+ that.facet.reset();
+ that.close();
+ that.callback();
+ }
+ });
+
+ that.create_button({
+ name: 'cancel',
+ label: IPA.messages.buttons.cancel,
+ click: function() {
+ that.close();
+ }
+ });
+
+ that.callback = function() {
+ };
+
+ return that;
+};
+
+IPA.error_dialog = function(spec) {
+
+ spec = spec || {};
+
+ spec.id = spec.id || 'error_dialog';
+ spec.title = spec.error_thrown.name;
+
+ var that = IPA.dialog(spec);
+
+ IPA.confirm_mixin().apply(that);
+
+ that.xhr = spec.xhr || {};
+ that.text_status = spec.text_status || '';
+ that.error_thrown = spec.error_thrown || {};
+ that.command = spec.command;
+ that.errors = spec.errors;
+ that.visible_buttons = spec.visible_buttons || ['retry', 'cancel'];
+
+
+ that.beautify_message = function(container, message) {
+ var lines = message.split(/\n/g);
+ var line_span;
+ for(var i=0; i<lines.length; i++) {
+ // multi-lined text may contain TAB character as first char of the line
+ // to hint at marking the whole line differently
+ if (lines[i].charAt(0) == '\t') {
+ line_span = $('<p />', {
+ 'class': 'error-message-hinted',
+ text: lines[i].substr(1)
+ }).appendTo(container);
+ } else {
+ line_span = $('<p />', {
+ text: lines[i]
+ }).appendTo(container);
+ }
+ }
+ };
+
+ that.create = function() {
+ if (that.error_thrown.url) {
+ $('<p/>', {
+ text: IPA.get_message('errors.url', 'URL')+': '+that.error_thrown.url
+ }).appendTo(that.container);
+ }
+
+ var error_message = $('<div />', {});
+ that.beautify_message(error_message, that.error_thrown.message);
+ error_message.appendTo(that.container);
+
+ if(that.errors && that.errors.length > 0) {
+ //render errors
+ var errors_title_div = $('<div />', {
+ 'class': 'errors_title'
+ }).appendTo(that.container);
+
+ var show_details = $('<a />', {
+ href: '#',
+ title: IPA.messages.dialogs.show_details,
+ text: IPA.messages.dialogs.show_details
+ }).appendTo(errors_title_div);
+
+ var hide_details = $('<a />', {
+ href: '#',
+ title: IPA.messages.dialogs.hide_details,
+ text: IPA.messages.dialogs.hide_details,
+ style : 'display: none'
+ }).appendTo(errors_title_div);
+
+ var errors_container = $('<ul />', {
+ 'class' : 'error-container',
+ style : 'display: none'
+ }).appendTo(that.container);
+
+ for(var i=0; i < that.errors.length; i++) {
+ var error = that.errors[i];
+ if(error.message) {
+ var error_div = $('<li />', {});
+ that.beautify_message(error_div, error.message);
+ error_div.appendTo(errors_container);
+ }
+ }
+
+ show_details.click(function() {
+ errors_container.show();
+ show_details.hide();
+ hide_details.show();
+ return false;
+ });
+
+ hide_details.click(function() {
+ errors_container.hide();
+ hide_details.hide();
+ show_details.show();
+ return false;
+ });
+ }
+ };
+
+ that.create_buttons = function() {
+ /**
+ * When a user initially opens the Web UI without a Kerberos
+ * ticket, the messages including the button labels have not
+ * been loaded yet, so the button labels need default values.
+ */
+
+ var visible = that.visible_buttons.indexOf('retry') > -1;
+ var label = IPA.get_message('buttons.retry', 'Retry');
+ that.create_button({
+ name: 'retry',
+ label: label,
+ visible: visible,
+ click: function() {
+ that.on_retry();
+ }
+ });
+
+ visible = that.visible_buttons.indexOf('ok') > -1;
+ label = IPA.get_message('buttons.ok', 'OK');
+ that.create_button({
+ name: 'ok',
+ label: label,
+ visible: visible,
+ click: function() {
+ that.on_ok();
+ }
+ });
+
+ visible = that.visible_buttons.indexOf('cancel') > -1;
+ label = IPA.get_message('buttons.cancel', 'Cancel');
+ that.create_button({
+ name: 'cancel',
+ label: label,
+ visible: visible,
+ click: function() {
+ that.on_cancel();
+ }
+ });
+ };
+
+ that.on_retry = function() {
+ that.close();
+ that.command.execute();
+ };
+
+ that.on_ok = function() {
+ that.close();
+ };
+
+ that.on_cancel = function() {
+ that.close();
+ };
+
+ that.on_confirm = function() {
+ if (that.visible_buttons.indexOf('retry') > -1) that.on_retry();
+ else that.on_ok();
+ };
+
+ that.create_buttons();
+
+ return that;
+};
+
+IPA.error_list = function() {
+ var that = {};
+
+ that.clear = function() {
+ that.errors = [];
+ };
+
+ that.add = function(command, name, message, status) {
+ that.errors.push({
+ command: command,
+ name: name,
+ message: message,
+ status: status
+ });
+ };
+
+ that.add_range = function(error_list) {
+ that.errors = that.errors.concat(error_list.errors);
+ };
+
+ that.is_empty = function () {
+ return that.errors.length === 0;
+ };
+
+ that.clear();
+ return that;
+};
+
+IPA.create_4304_error_handler = function(adder_dialog) {
+
+ var set_pkey = function(result) {
+
+ var pkey_name = adder_dialog.entity.metadata.primary_key;
+ var args = adder_dialog.command.args;
+ var pkey = args[args.length-1];
+ result[pkey_name] = pkey;
+ };
+
+ return function (xhr, text_status, error_thrown) {
+
+ var ajax = this;
+ var command = adder_dialog.command;
+ var data = error_thrown.data;
+ var dialog = null;
+
+ if (data && data.error && data.error.code === 4304) {
+ dialog = IPA.message_dialog({
+ name: 'error_4304_info',
+ message: data.error.message,
+ title: adder_dialog.title,
+ on_ok: function() {
+ data.result = { result: {} };
+ set_pkey(data.result.result);
+ command.on_success.call(ajax, data, text_status, xhr);
+ }
+ });
+ } else {
+ dialog = IPA.error_dialog({
+ xhr: xhr,
+ text_status: text_status,
+ error_thrown: error_thrown,
+ command: command
+ });
+ }
+
+ dialog.open(adder_dialog.container);
+ };
+};
+
+IPA.unauthorized_dialog = function(spec) {
+
+ spec = spec || {};
+
+ spec.sections = [
+ {
+ name: 'login',
+ label: 'Login',
+ fields: [
+ {
+ name: 'username',
+ label: IPA.get_message('login.username', "Username")
+ },
+ {
+ name: 'password',
+ type: 'password',
+ label: IPA.get_message('login.password', "Password")
+ }
+ ]
+ },
+ {
+ name: 'reset',
+ label: 'Reset',
+ fields: [
+ {
+ name: 'username_r',
+ read_only: true,
+ label: IPA.get_message('login.username', "Username")
+ },
+ {
+ name: 'new_password',
+ type: 'password',
+ required: true,
+ label: IPA.get_message('password.new_password)', "New Password")
+ },
+ {
+ name: 'verify_password',
+ type: 'password',
+ required: true,
+ label: IPA.get_message('password.verify_password', "Verify Password"),
+ validators: [IPA.same_password_validator({
+ other_field: 'new_password'
+ })]
+ }
+ ]
+ }
+ ];
+
+ spec.visible_buttons = spec.visible_buttons || ['retry'];
+ spec.name = spec.name || 'unauthorized_dialog';
+ spec.id = spec.id || spec.name;
+
+ var that = IPA.error_dialog(spec);
+
+ that.title = spec.title || IPA.get_message('login.login', "Login");
+
+ that.message = spec.message || IPA.get_message('ajax.401.message',
+ "Your session has expired. Please re-login.");
+
+ that.form_auth_msg = spec.form_auth_msg || IPA.get_message('login.form_auth',
+ "To login with username and password, enter them in the fields below then click Login.");
+
+ that.krb_auth_msg = spec.krb_auth_msg || IPA.get_message('login.krb_auth_msg',
+ " To login with Kerberos, please make sure you" +
+ " have valid tickets (obtainable via kinit) and " +
+ "<a href='http://${host}/ipa/config/unauthorized.html'>configured</a>" +
+ " the browser correctly, then click Login. ");
+
+ that.krb_auth_msg = that.krb_auth_msg.replace('${host}', window.location.hostname);
+
+ that.form_auth_failed = "<p><strong>Please re-enter your username or password</strong></p>" +
+ "<p>The password or username you entered is incorrect. " +
+ "Please try again (make sure your caps lock is off).</p>" +
+ "<p>If the problem persists, contact your administrator.</p>";
+
+ that.password_expired = "Your password has expired. Please enter a new password.";
+
+ that.denied = "Sorry you are not allowed to access this service.";
+
+ that.create = function() {
+
+ that.session_expired_form();
+ that.create_reset_form();
+ };
+
+ that.session_expired_form = function() {
+ that.session_form = $('<div\>').appendTo(that.container);
+
+ that.login_error_box = $('<div/>', {
+ 'class': 'error-box',
+ style: 'display:none',
+ html: that.form_auth_failed
+ }).appendTo(that.session_form);
+
+ $('<p/>', {
+ html: that.message
+ }).appendTo(that.session_form);
+
+ $('<p/>', {
+ html: that.krb_auth_msg
+ }).appendTo(that.session_form);
+
+ $('<p/>', {
+ html: that.form_auth_msg
+ }).appendTo(that.session_form);
+
+ $('<div>', {
+ 'class': 'auth-dialog'
+ }).appendTo(that.session_form);
+
+
+ var section = that.widgets.get_widget('login');
+ var div = $('<div/>', {
+ name: 'login',
+ 'class': 'dialog-section'
+ }).appendTo(that.session_form);
+ section.create(div);
+
+ that.username_widget = that.widgets.get_widget('login.username');
+ that.password_widget = that.widgets.get_widget('login.password');
+
+ that.username_widget.value_changed.attach(that.on_username_change);
+ };
+
+ that.create_reset_form = function() {
+
+ that.reset_form = $('<div\>', {
+ style: 'display:none'
+ }).appendTo(that.container);
+
+ that.reset_error_box = $('<div/>', {
+ 'class': 'error-box'
+ }).appendTo(that.reset_form);
+
+ $('<p/>', {
+ html: that.password_expired
+ }).appendTo(that.reset_form);
+
+ var section = that.widgets.get_widget('reset');
+ var div = $('<div/>', {
+ name: 'reset',
+ 'class': 'dialog-section'
+ }).appendTo(that.reset_form);
+ section.create(div);
+
+ that.username_r_widget = that.widgets.get_widget('reset.username_r');
+ that.new_password_widget = that.widgets.get_widget('reset.new_password');
+ that.verify_password_widget = that.widgets.get_widget('reset.verify_password');
+ };
+
+ that.create_buttons = function() {
+
+ that.buttons.empty();
+
+ var visible = that.visible_buttons.indexOf('login') > -1;
+ var label = IPA.get_message('login.login', "Login");
+ that.create_button({
+ name: 'login',
+ label: label,
+ visible: visible,
+ click: function() {
+ that.on_login();
+ }
+ });
+
+ visible = that.visible_buttons.indexOf('reset') > -1;
+ label = IPA.get_message('buttons.reset_password_and_login', "Reset Password and Login");
+ that.create_button({
+ name: 'reset',
+ label: label,
+ visible: visible,
+ click: function() {
+ that.on_reset();
+ }
+ });
+
+ visible = that.visible_buttons.indexOf('cancel') > -1;
+ label = IPA.get_message('buttons.cancel', "Cancel");
+ that.create_button({
+ name: 'cancel',
+ label: label,
+ visible: visible,
+ click: function() {
+ that.on_cancel();
+ }
+ });
+ };
+
+ that.open = function() {
+ that.dialog_open();
+ that.show_session_form();
+ that.check_error_reason();
+ };
+
+ that.check_error_reason = function() {
+ if (this.xhr) {
+ var reason = this.xhr.getResponseHeader("X-IPA-Rejection-Reason");
+ if (reason) {
+ that.show_login_error_message(reason);
+ }
+ }
+ };
+
+ that.on_username_change = function() {
+
+ var password_field = that.fields.get_field('password');
+ var user_specified = !IPA.is_empty(that.username_widget.save());
+ password_field.set_required(user_specified);
+ if (!user_specified) that.password_widget.clear();
+ };
+
+ that.enable_fields = function(field_names) {
+
+ var field, fields, i, enable;
+ fields = that.fields.get_fields();
+ for (i=0; i<fields.length; i++) {
+ field = fields[i];
+ enable = field_names.indexOf(field.name) > -1;
+ field.set_enabled(enable);
+ }
+ };
+
+ that.show_session_form = function() {
+
+ that.current_view = 'session';
+ that.enable_fields(['username', 'password']);
+ that.session_form.css('display', 'block');
+ that.reset_form.css('display', 'none');
+ that.display_buttons(['login']);
+ that.username_widget.focus_input();
+ };
+
+ that.show_reset_form = function() {
+
+ that.current_view = 'reset';
+ that.enable_fields(['new_password', 'verify_password']);
+ that.session_form.css('display', 'none');
+ that.reset_form.css('display', 'block');
+ that.display_buttons(['reset', 'cancel']);
+
+ var username = that.username_widget.save();
+ that.username_r_widget.update(username);
+ that.new_password_widget.focus_input();
+ };
+
+ that.show_login_error_message = function(reason) {
+ var errors = {
+ 'invalid': that.form_auth_failed,
+ 'denied': that.denied
+ };
+
+ var message = errors[reason];
+
+ if (message) {
+ that.login_error_box.html(message);
+ that.login_error_box.css('display', 'block');
+ }
+ };
+
+ that.on_cancel = function() {
+
+ that.username_widget.clear();
+ that.password_widget.clear();
+ that.username_r_widget.clear();
+ that.new_password_widget.clear();
+ that.verify_password_widget.clear();
+
+ that.show_session_form();
+ };
+
+ that.on_login = function() {
+
+ var username = that.username_widget.save();
+ var password = that.password_widget.save();
+
+ //if user doesn't specify username and password try kerberos auth
+ if (IPA.is_empty(username) && IPA.is_empty(password)) {
+ that.on_retry();
+ return;
+ }
+
+ if (!that.validate()) return;
+
+ IPA.display_activity_icon();
+
+ var result = IPA.login_password(username[0], password[0]);
+
+ IPA.hide_activity_icon();
+
+ if (result === 'success') {
+ that.on_login_success();
+ } else if (result === 'password-expired') {
+ that.reset_error_box.css('display', 'none');
+ that.show_reset_form();
+ } else {
+ that.show_login_error_message(result);
+ }
+ };
+
+ that.on_login_success = function() {
+ that.login_error_box.css('display', 'none');
+
+ that.username_widget.clear();
+ that.password_widget.clear();
+
+ that.on_retry();
+ };
+
+ that.on_reset = function() {
+ if (!that.validate()) return;
+
+ var username = that.username_widget.save();
+ var password = that.password_widget.save();
+ var new_password = that.new_password_widget.save();
+ var verify_password = that.verify_password_widget.save();
+
+ that.reset_error_box.css('display', 'none');
+
+ var result = IPA.reset_password(username[0],
+ password[0],
+ new_password[0]);
+
+ if (result.status === 'ok') {
+ that.on_reset_success();
+ } else {
+ that.reset_error_box.html(result.message);
+ that.reset_error_box.css('display', 'block');
+ }
+ };
+
+ that.on_reset_success = function() {
+
+ that.login_error_box.css('display', 'none');
+ that.reset_error_box.css('display', 'none');
+
+ that.password_widget.update(that.new_password_widget.save());
+
+ that.new_password_widget.clear();
+ that.verify_password_widget.clear();
+
+ that.show_session_form();
+
+ //re-login
+ that.on_login();
+ };
+
+ //replaces confirm_mixin method
+ that.on_key_up = function(event) {
+
+ if (that.switching) {
+ that.switching = false;
+ return;
+ }
+
+ if (that.current_view === 'session') {
+ if (event.keyCode === $.ui.keyCode.ENTER && !this.test_ignore(event)) {
+ that.on_login();
+ event.preventDefault();
+ }
+ } else {
+ if (event.keyCode === $.ui.keyCode.ENTER && !this.test_ignore(event)) {
+ that.on_reset();
+ event.preventDefault();
+ } else if (event.keyCode === $.ui.ESCAPE) {
+ that.on_cancel();
+ event.preventDefault();
+ }
+ }
+ };
+
+ that.create_buttons();
+
+ return that;
+};
+
+IPA.limit_text = function(value, max_length) {
+
+ if (!value) return '';
+
+ var limited_text = value;
+
+ if (value.length && value.length > max_length) {
+ limited_text = value.substring(0, max_length - 3)+'...';
+ }
+
+ return limited_text;
+};
+
+IPA.create_options = function(values) {
+
+ var options = [];
+
+ for (var i=0; i<values.length; i++) {
+ var val = values[i];
+ var option = val;
+
+ if (typeof val === 'string') {
+ option = {
+ value: val,
+ label: val
+ };
+ }
+
+ options.push(option);
+ }
+
+ return options;
+};
+
+IPA.is_empty = function(value) {
+
+ var empty = false;
+
+ if (!value) empty = true;
+
+ if (value instanceof Array) {
+ empty = empty || value.length === 0 ||
+ (value.length === 1) && (value[0] === '');
+ }
+
+ if (value === '') empty = true;
+
+ return empty;
+};
+
+IPA.defined = function(value, check_empty_str) {
+ return value !== null && value !== undefined &&
+ ((check_empty_str && value !== '') || !check_empty_str);
+};
+
+IPA.array_diff = function(a, b) {
+
+ if (a === b || (!a && !b)) return false;
+
+ if (!a || !b) return true;
+
+ if (a.length !== b.length) return true;
+
+ for (var i=0; i<a.length; i++) {
+ if (a[i] !== b[i]) return true;
+ }
+
+ return false;
+};
+
+IPA.confirm = function(msg) {
+ return window.confirm(msg);
+};
+
+IPA.notify_success = function(message, timeout) {
+
+ if (!message) return; // don't show undefined, null and such
+
+ function destroy_timeout() {
+ if (IPA.notify_success.timeout) window.clearTimeout(IPA.notify_success.timeout);
+ }
+
+ var notification_area = $('.notification-area');
+
+ if (notification_area.length === 0) {
+ notification_area = $('<div/>', {
+ 'class': 'notification-area ui-corner-all ui-state-highlight',
+ click: function() {
+ destroy_timeout();
+ notification_area.fadeOut(100);
+ }
+ });
+
+ notification_area.appendTo('#container');
+ }
+
+ notification_area.text(message);
+
+ destroy_timeout();
+ notification_area.fadeIn(IPA.config.message_fadein_time);
+
+ IPA.notify_success.timeout = window.setTimeout(function() {
+ notification_area.fadeOut(IPA.config.message_fadeout_time);
+ }, timeout || IPA.config.message_timeout);
+};
+
+IPA.config = {
+ default_priority: 500,
+ message_timeout: 3000, // [ms]
+ message_fadeout_time: 800, // [ms]
+ message_fadein_time: 400 // [ms]
+};