470 lines
13 KiB
JavaScript
470 lines
13 KiB
JavaScript
/**
|
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
|
* This file is licensed under the Affero General Public License version 3 or later.
|
|
* See the COPYING-README file.
|
|
*/
|
|
|
|
OCA = OCA || {};
|
|
|
|
(function() {
|
|
|
|
/**
|
|
* @classdesc main view class. It takes care of tab-unrelated control
|
|
* elements (status bar, control buttons) and does or requests configuration
|
|
* checks. It also manages the separate tab views.
|
|
*
|
|
* @constructor
|
|
*/
|
|
var WizardView = function() {};
|
|
|
|
WizardView.prototype = {
|
|
/** @constant {number} */
|
|
STATUS_ERROR: 0,
|
|
/** @constant {number} */
|
|
STATUS_INCOMPLETE: 1,
|
|
/** @constant {number} */
|
|
STATUS_SUCCESS: 2,
|
|
/** @constant {number} */
|
|
STATUS_UNTESTED: 3,
|
|
|
|
/**
|
|
* initializes the instance. Always call it after creating the instance.
|
|
*/
|
|
init: function () {
|
|
this.tabs = {};
|
|
this.tabs.server = new OCA.LDAP.Wizard.WizardTabElementary();
|
|
this.$settings = $('#ldapSettings');
|
|
this.$saveSpinners = $('.ldap_saving');
|
|
this.saveProcesses = 0;
|
|
_.bindAll(this, 'onTabChange', 'onTestButtonClick');
|
|
},
|
|
|
|
/**
|
|
* applies click events to the forward and backword buttons
|
|
*/
|
|
initControls: function() {
|
|
var view = this;
|
|
$('.ldap_action_continue').click(function(event) {
|
|
event.preventDefault();
|
|
view._controlContinue(view);
|
|
});
|
|
|
|
$('.ldap_action_back').click(function(event) {
|
|
event.preventDefault();
|
|
view._controlBack(view);
|
|
});
|
|
|
|
$('.ldap_action_test_connection').click(this.onTestButtonClick);
|
|
},
|
|
|
|
/**
|
|
* registers a tab
|
|
*
|
|
* @param {OCA.LDAP.Wizard.WizardTabGeneric} tabView
|
|
* @param {string} index
|
|
* @returns {boolean}
|
|
*/
|
|
registerTab: function(tabView, index) {
|
|
if( _.isUndefined(this.tabs[index])
|
|
&& tabView instanceof OCA.LDAP.Wizard.WizardTabGeneric
|
|
) {
|
|
this.tabs[index] = tabView;
|
|
this.tabs[index].setModel(this.configModel);
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
|
|
/**
|
|
* checks certain config values for completeness and depending on them
|
|
* enables or disables non-elementary tabs.
|
|
*/
|
|
basicStatusCheck: function(view) {
|
|
var host = view.configModel.configuration.ldap_host;
|
|
var port = view.configModel.configuration.ldap_port;
|
|
var base = view.configModel.configuration.ldap_base;
|
|
var agent = view.configModel.configuration.ldap_dn;
|
|
var pwd = view.configModel.configuration.ldap_agent_password;
|
|
|
|
if((host && port && base) && ((!agent && !pwd) || (agent && pwd))) {
|
|
view.enableTabs();
|
|
} else {
|
|
view.disableTabs();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* if the configuration is sufficient the model is being request to
|
|
* perform a configuration test. Otherwise, the status indicator is
|
|
* being updated with the status "incomplete"
|
|
*/
|
|
functionalityCheck: function() {
|
|
// this method should be called only if necessary, because it may
|
|
// cause an LDAP request!
|
|
var host = this.configModel.configuration.ldap_host;
|
|
var port = this.configModel.configuration.ldap_port;
|
|
var base = this.configModel.configuration.ldap_base;
|
|
var userFilter = this.configModel.configuration.ldap_userlist_filter;
|
|
var loginFilter = this.configModel.configuration.ldap_login_filter;
|
|
|
|
if(host && port && base && userFilter && loginFilter) {
|
|
this.configModel.requestConfigurationTest();
|
|
} else {
|
|
this._updateStatusIndicator(this.STATUS_INCOMPLETE);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* will request a functionality check if one of the related configuration
|
|
* settings was changed.
|
|
*
|
|
* @param {ConfigSetPayload|Object} [changeSet]
|
|
*/
|
|
considerFunctionalityCheck: function(changeSet) {
|
|
var testTriggers = [
|
|
'ldap_host', 'ldap_port', 'ldap_dn', 'ldap_agent_password',
|
|
'ldap_base', 'ldap_userlist_filter', 'ldap_login_filter'
|
|
];
|
|
for(var key in changeSet) {
|
|
if($.inArray(key, testTriggers) >= 0) {
|
|
this.functionalityCheck();
|
|
return;
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* keeps number of running save processes and shows a spinner if
|
|
* necessary
|
|
*
|
|
* @param {WizardView} [view]
|
|
* @listens ConfigModel#setRequested
|
|
*/
|
|
onSetRequested: function(view) {
|
|
view.saveProcesses += 1;
|
|
if(view.saveProcesses === 1) {
|
|
view.showSaveSpinner();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* keeps number of running save processes and hides the spinner if
|
|
* necessary. Also triggers checks, to adjust tabs state and status bar.
|
|
*
|
|
* @param {WizardView} [view]
|
|
* @param {ConfigSetPayload} [result]
|
|
* @listens ConfigModel#setCompleted
|
|
*/
|
|
onSetRequestDone: function(view, result) {
|
|
if(view.saveProcesses > 0) {
|
|
view.saveProcesses -= 1;
|
|
if(view.saveProcesses === 0) {
|
|
view.hideSaveSpinner();
|
|
}
|
|
}
|
|
|
|
view.basicStatusCheck(view);
|
|
var param = {};
|
|
param[result.key] = 1;
|
|
view.considerFunctionalityCheck(param);
|
|
},
|
|
|
|
/**
|
|
* Base DN test results will arrive here
|
|
*
|
|
* @param {WizardTabElementary} view
|
|
* @param {FeaturePayload} payload
|
|
*/
|
|
onDetectionTestCompleted: function(view, payload) {
|
|
if(payload.feature === 'TestBaseDN') {
|
|
if(payload.data.status === 'success') {
|
|
var objectsFound = parseInt(payload.data.changes.ldap_test_base, 10);
|
|
if(objectsFound > 0) {
|
|
view._updateStatusIndicator(view.STATUS_SUCCESS);
|
|
return;
|
|
}
|
|
}
|
|
view._updateStatusIndicator(view.STATUS_ERROR);
|
|
OC.Notification.showTemporary(t('user_ldap', 'The Base DN appears to be wrong'));
|
|
}
|
|
},
|
|
|
|
/**
|
|
* updates the status indicator based on the configuration test result
|
|
*
|
|
* @param {WizardView} [view]
|
|
* @param {ConfigTestPayload} [result]
|
|
* @listens ConfigModel#configurationTested
|
|
*/
|
|
onTestCompleted: function(view, result) {
|
|
if(result.isSuccess) {
|
|
view.configModel.requestWizard('ldap_test_base');
|
|
} else {
|
|
view._updateStatusIndicator(view.STATUS_ERROR);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* triggers initial checks upon configuration loading to update status
|
|
* controls
|
|
*
|
|
* @param {WizardView} [view]
|
|
* @listens ConfigModel#configLoaded
|
|
*/
|
|
onConfigLoaded: function(view) {
|
|
view._updateStatusIndicator(view.STATUS_UNTESTED);
|
|
view.basicStatusCheck(view);
|
|
view.functionalityCheck();
|
|
},
|
|
|
|
/**
|
|
* reacts on attempts to switch to a different tab
|
|
*
|
|
* @param {object} event
|
|
* @param {object} ui
|
|
* @returns {boolean}
|
|
*/
|
|
onTabChange: function(event, ui) {
|
|
if(this.saveProcesses > 0) {
|
|
return false;
|
|
}
|
|
|
|
var newTabID = ui.newTab[0].id;
|
|
if(newTabID === '#ldapWizard1') {
|
|
newTabID = 'server';
|
|
}
|
|
var oldTabID = ui.oldTab[0].id;
|
|
if(oldTabID === '#ldapWizard1') {
|
|
oldTabID = 'server';
|
|
}
|
|
if(!_.isUndefined(this.tabs[newTabID])) {
|
|
this.tabs[newTabID].isActive = true;
|
|
this.tabs[newTabID].onActivate();
|
|
} else {
|
|
console.warn('Unreferenced activated tab ' + newTabID);
|
|
}
|
|
if(!_.isUndefined(this.tabs[oldTabID])) {
|
|
this.tabs[oldTabID].isActive = false;
|
|
} else {
|
|
console.warn('Unreferenced left tab ' + oldTabID);
|
|
}
|
|
|
|
if(!_.isUndefined(this.tabs[newTabID])) {
|
|
this._controlUpdate(this.tabs[newTabID].tabIndex);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* triggers checks upon configuration updates to keep status controls
|
|
* up to date
|
|
*
|
|
* @param {WizardView} [view]
|
|
* @param {object} [changeSet]
|
|
* @listens ConfigModel#configUpdated
|
|
*/
|
|
onConfigUpdated: function(view, changeSet) {
|
|
view.basicStatusCheck(view);
|
|
view.considerFunctionalityCheck(changeSet);
|
|
},
|
|
|
|
/**
|
|
* requests a configuration test
|
|
*/
|
|
onTestButtonClick: function() {
|
|
this.configModel.requestWizard('ldap_action_test_connection', {ldap_serverconfig_chooser: this.configModel.configID});
|
|
},
|
|
|
|
/**
|
|
* sets the model instance and registers event listeners
|
|
*
|
|
* @param {OCA.LDAP.Wizard.ConfigModel} [configModel]
|
|
*/
|
|
setModel: function(configModel) {
|
|
/** @type {OCA.LDAP.Wizard.ConfigModel} */
|
|
this.configModel = configModel;
|
|
for(var i in this.tabs) {
|
|
this.tabs[i].setModel(configModel);
|
|
}
|
|
|
|
// make sure this is definitely run after tabs did their work, order is important here
|
|
// for now this works, because tabs are supposed to register their listeners in their
|
|
// setModel() method.
|
|
// alternative: make Elementary Tab a Publisher as well.
|
|
this.configModel.on('configLoaded', this.onConfigLoaded, this);
|
|
this.configModel.on('configUpdated', this.onConfigUpdated, this);
|
|
this.configModel.on('setRequested', this.onSetRequested, this);
|
|
this.configModel.on('setCompleted', this.onSetRequestDone, this);
|
|
this.configModel.on('configurationTested', this.onTestCompleted, this);
|
|
this.configModel.on('receivedLdapFeature', this.onDetectionTestCompleted, this);
|
|
},
|
|
|
|
/**
|
|
* enables tab and navigation buttons
|
|
*/
|
|
enableTabs: function() {
|
|
//do not use this function directly, use basicStatusCheck instead.
|
|
if(this.saveProcesses === 0) {
|
|
$('.ldap_action_continue').removeAttr('disabled');
|
|
$('.ldap_action_back').removeAttr('disabled');
|
|
this.$settings.tabs('option', 'disabled', []);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* disables tab and navigation buttons
|
|
*/
|
|
disableTabs: function() {
|
|
$('.ldap_action_continue').attr('disabled', 'disabled');
|
|
$('.ldap_action_back').attr('disabled', 'disabled');
|
|
this.$settings.tabs('option', 'disabled', [1, 2, 3, 4, 5]);
|
|
},
|
|
|
|
/**
|
|
* shows a save spinner
|
|
*/
|
|
showSaveSpinner: function() {
|
|
this.$saveSpinners.removeClass('hidden');
|
|
$('#ldap *').addClass('save-cursor');
|
|
},
|
|
|
|
/**
|
|
* hides the save spinner
|
|
*/
|
|
hideSaveSpinner: function() {
|
|
this.$saveSpinners.addClass('hidden');
|
|
$('#ldap *').removeClass('save-cursor');
|
|
},
|
|
|
|
/**
|
|
* performs a config load request to the model
|
|
*
|
|
* @param {string} [configID]
|
|
* @private
|
|
*/
|
|
_requestConfig: function(configID) {
|
|
this.configModel.load(configID);
|
|
},
|
|
|
|
/**
|
|
* bootstraps the visual appearance and event listeners, as well as the
|
|
* first config
|
|
*/
|
|
render: function () {
|
|
$('#ldapAdvancedAccordion').accordion({ heightStyle: 'content', animate: 'easeInOutCirc'});
|
|
this.$settings.tabs({});
|
|
$('#ldapSettings button:not(.icon-default-style):not(.ui-multiselect)').button();
|
|
$('#ldapSettings').tabs({ beforeActivate: this.onTabChange });
|
|
$('#ldapSettings :input').tooltip({placement: "right", container: "body", trigger: "hover"});
|
|
|
|
this.initControls();
|
|
this.disableTabs();
|
|
|
|
this._requestConfig(this.tabs.server.getConfigID());
|
|
},
|
|
|
|
/**
|
|
* updates the status indicator / bar
|
|
*
|
|
* @param {number} [state]
|
|
* @private
|
|
*/
|
|
_updateStatusIndicator: function(state) {
|
|
var $indicator = $('.ldap_config_state_indicator');
|
|
var $indicatorLight = $('.ldap_config_state_indicator_sign');
|
|
|
|
switch(state) {
|
|
case this.STATUS_UNTESTED:
|
|
$indicator.text(t('user_ldap',
|
|
'Testing configuration…'
|
|
));
|
|
$indicator.addClass('ldap_grey');
|
|
$indicatorLight.removeClass('error');
|
|
$indicatorLight.removeClass('success');
|
|
break;
|
|
case this.STATUS_ERROR:
|
|
$indicator.text(t('user_ldap',
|
|
'Configuration incorrect'
|
|
));
|
|
$indicator.removeClass('ldap_grey');
|
|
$indicatorLight.addClass('error');
|
|
$indicatorLight.removeClass('success');
|
|
break;
|
|
case this.STATUS_INCOMPLETE:
|
|
$indicator.text(t('user_ldap',
|
|
'Configuration incomplete'
|
|
));
|
|
$indicator.removeClass('ldap_grey');
|
|
$indicatorLight.removeClass('error');
|
|
$indicatorLight.removeClass('success');
|
|
break;
|
|
case this.STATUS_SUCCESS:
|
|
$indicator.text(t('user_ldap', 'Configuration OK'));
|
|
$indicator.addClass('ldap_grey');
|
|
$indicatorLight.removeClass('error');
|
|
$indicatorLight.addClass('success');
|
|
if(!this.tabs.server.isActive) {
|
|
this.configModel.set('ldap_configuration_active', 1);
|
|
}
|
|
break;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* handles a click on the Back button
|
|
*
|
|
* @param {WizardView} [view]
|
|
* @private
|
|
*/
|
|
_controlBack: function(view) {
|
|
var curTabIndex = view.$settings.tabs('option', 'active');
|
|
if(curTabIndex == 0) {
|
|
return;
|
|
}
|
|
view.$settings.tabs('option', 'active', curTabIndex - 1);
|
|
view._controlUpdate(curTabIndex - 1);
|
|
},
|
|
|
|
/**
|
|
* handles a click on the Continue button
|
|
*
|
|
* @param {WizardView} [view]
|
|
* @private
|
|
*/
|
|
_controlContinue: function(view) {
|
|
var curTabIndex = view.$settings.tabs('option', 'active');
|
|
if(curTabIndex == 3) {
|
|
return;
|
|
}
|
|
view.$settings.tabs('option', 'active', 1 + curTabIndex);
|
|
view._controlUpdate(curTabIndex + 1);
|
|
},
|
|
|
|
/**
|
|
* updates the controls (navigation buttons)
|
|
*
|
|
* @param {number} [nextTabIndex] - index of the tab being switched to
|
|
* @private
|
|
*/
|
|
_controlUpdate: function(nextTabIndex) {
|
|
if(nextTabIndex == 0) {
|
|
$('.ldap_action_back').addClass('invisible');
|
|
$('.ldap_action_continue').removeClass('invisible');
|
|
} else
|
|
if(nextTabIndex == 1) {
|
|
$('.ldap_action_back').removeClass('invisible');
|
|
$('.ldap_action_continue').removeClass('invisible');
|
|
} else
|
|
if(nextTabIndex == 2) {
|
|
$('.ldap_action_continue').removeClass('invisible');
|
|
$('.ldap_action_back').removeClass('invisible');
|
|
} else
|
|
if(nextTabIndex == 3) {
|
|
$('.ldap_action_back').removeClass('invisible');
|
|
$('.ldap_action_continue').addClass('invisible');
|
|
}
|
|
}
|
|
};
|
|
|
|
OCA.LDAP.Wizard.WizardView = WizardView;
|
|
})();
|