123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470 |
- /**
- * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
- * SPDX-FileCopyrightText: 2015-2016 ownCloud, Inc.
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
- 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 backward 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) || (host && base && host.indexOf('ldapi://') > -1 ))
- && ((!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) ||
- (host && base && host.indexOf('ldapi://') > -1 && 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 });
- 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;
- })();
|