/** Copyright (C) 2009-2021 Splunk Inc. All Rights Reserved. **/ /** * The window.onload function hides the Splunk dashboard header so that the dashboard editor is not presented * on the SA-ldapsearch configuration editing page. */ window.onload = function () { var dashboardHeaders = document.getElementsByClassName('dashboard-header'); if (dashboardHeaders.length == 1) { dashboardHeaders[0].setAttribute('style', 'visibility: hidden; margin: 0 0 0 0; padding: 0 0 0 0; height: 0;'); } }; require.config({paths: {'SA-ldapsearch': '/static/app/SA-ldapsearch'}}); require([ '/static/app/SA-ldapsearch/third-party/jquery_private.js', 'splunkjs/mvc', '/static/app/SA-ldapsearch/swc-ldapsearch/index.js', 'splunkjs/mvc/searchmanager', 'splunkjs/mvc/simplesplunkview', '/static/app/SA-ldapsearch/third-party/bootstrap_def.js', 'splunkjs/mvc/simplexml/ready!', ], function ($,mvc,index, SearchManager, SimpleView) { const Messages = index.MVCMessages; var TestConnectionView = SimpleView.extend({ output_mode: "json", createView: function () { return true; }, displayMessage: function (info) { if (this._isJobDone && this.manager.job != null) { this._completeDialog(); } this._viz = null; Messages.render(info, this.$el); return this; }, updateView: function (visualization, data) { this._completeDialog(); $(this.$el).text('distinguishedName: ' + data[0].distinguishedName); }, _completeDialog: function () { var self = configurationEditor; var messages = this.manager.job.properties().messages; var header = $('#testConnectionDialog_header').text('Connection test for ' + $('#configured_domain').val()); var connectionStatus; if (messages.length == 0) { connectionStatus = {type: 'info', text: 'Test succeeded'}; header.text(header.text() + ' succeeded'); } else { connectionStatus = {type: 'error', text: 'Test failed'}; var messagePart = messages[0].text.split('\n'); var messageText; try { messageText = messagePart[2] .replace(/""/g, '"') .replace(/ # host: /g, '

'); } catch (error) { messageText = messagePart.join('\n'); } var message = $('#testConnectionDialog_message'); message.empty().append('

Error

' + messageText + '
'); message.css({display: ''}); header.text(header.text() + ' failed'); } self._updateConnectionStatus(connectionStatus); $('#domains').children(':selected').data("connection.status", connectionStatus); $('#testConnectionDialog_close').text('Close'); this.manager.job = null; } }); /** * The `configurationEditor` object implements the actions behind the SA-ldapsearch configuration editing page. */ var configurationEditor = { initialize: function (service) { var self = configurationEditor; //// Initialize Splunk service objects self._searchManager = new SearchManager({ id: 'TestConnectionSearchManager.f7d52d1a-2a21-11e4-b1fe-10ddb1b57bc3', autostart: false}); self._service = new splunkjs.Service(service.http, { scheme: service.scheme, host: service.host, port: service.port, username: service.username, password: service.password, owner: 'nobody', app: service.app, sessionKey: service.sessionKey, autologin: service.autologin, version: service.version }); var namespace = {app: self._service.app}; var storagePasswords = self._service.storagePasswords(namespace); var defaultConfigurationStanza = new splunkjs.Service.Endpoint(self._service, "properties/ldap/default"); var defaultStoragePassword = storagePasswords.instantiateEntity({name: 'SA-ldapsearch:default:', acl: namespace}); var configuration = self._service.configurations(namespace).instantiateEntity({name: 'ldap', acl: namespace}); self._storagePasswords = storagePasswords; self._configuration = configuration; splunkjs.Async.parallel( [ function (done) { // Get default stanza defaultConfigurationStanza.get(undefined, {}, function (err, response) { if (err != null) { return done(err, response); } var settings = {}; response.data.entry.forEach(function (entry) { settings[entry.name] = entry.content; }); return done(null, settings); }); }, function (done) { // Get default storage password defaultStoragePassword.fetch({}, function (err, response) { if (err == null) { return done(null, null); } if (err.status == 404) { return done(null, undefined); } return done(err, undefined); }); }, function (done) { // Get the full list of additional stanza names configuration.fetch({count: 0}, function (err, response) { if (err) { return done(err, undefined); } var entries = response.properties().entry; var count = entries.length; var configurationStanzas = {}; for (var i = 0; i < count; i++) { configurationStanzas[entries[i].name] = entries[i].content.alternatedomain; } return done(null, configurationStanzas); }); } ], function (err, defaultSettings, defaultPassword, configurationStanzas) { if (err) { self._alert('error', 'Initialization failed', err); return; } var domains = $('#domains'); //// Transfer settings and set the current selection to the default stanza var connectionStatus = {type: 'alert alert-warning', text: 'Untested'}; var defaultDomain = domains.children().first(); defaultDomain .data('alternatedomain', defaultSettings.alternatedomain) .data('connection.status', connectionStatus) .data('password', defaultStoragePassword) .data('stanza', defaultConfigurationStanza); self._transferSettings(defaultSettings); self._setSelection(defaultDomain); self._isDirty(false); //// Create the list of domains for (var name in configurationStanzas) { if (configurationStanzas.hasOwnProperty(name)) { var option = $(document.createElement('option')) .attr('value', name) .text(name) .val(name) .data('alternatedomain', configurationStanzas[name]) .data('connection.status', connectionStatus) .data('password', storagePasswords.instantiateEntity( {name: self._toStoragePasswordName(name), acl: namespace})) .data('stanza', configuration.instantiateEntity({name: name, acl: namespace})); domains.append(option); } } var nameMap = {}; domains.children('option').each(function (index, option) { var alternatedomain = $(option).data('alternatedomain'); if (nameMap[alternatedomain] == undefined) { // First guy in wins; forget the others nameMap[alternatedomain] = option; } nameMap[$(option).val()] = option; // Splunk guarantees that stanza names are unique }); domains.data('name.map', nameMap); self._bindEventHandlers(); }); }, add: function () { var self = configurationEditor; if (self._isDirty()) { self.save().done(self._add()); } else { self._add(); } }, read: function () { var self = configurationEditor; var domain = $('#domains').children(':selected'); if (domain.index() == 0) { self._readDefaults(); return; } var configurationStanza = domain.data('stanza'); var storagePassword = domain.data('password'); splunkjs.Async.parallel( [ function (done) { // Read configuration stanza configurationStanza.fetch({count: 0}, function (err, resource) { return done(null, {err: err, value: err == null ? resource.properties() : {}}); }); }, function (done) { // Read storage password storagePassword.fetch({}, function (err, resource) { if (err == null) { return done(null, {err: null, value: null}); } if (err.status != 404) { return done(null, {err: err, value: undefined}); } storagePassword = $('#domains').children().first().data('password'); storagePassword.fetch({}, function (err, resource) { if (err == null) { return done(null, {err: null, value: null}); } if (err.status != 404) { return done(null, {err: err, value: undefined}); } return done(null, {err: null, value: undefined}); }); }); } ], function (err, settings, password) { // Transfer settings self._transferSettings(settings.value); self._isDirty(false); if (password.err || settings.err) { self._alert('error', 'Error reading configuration for ' + $('#domains').val(), settings.err, password.err) } }); }, remove: function () { var self = configurationEditor; var domains = $('#domains'); var currentSelection = domains.children(':selected'); if (currentSelection.index() == 0) { // Silently ignore the request to remove the default domain configuration return; } var nextSelection = currentSelection.next(); if (nextSelection.length == 0) { nextSelection = currentSelection.prev(); } self._remove(currentSelection, function (cserr, sperr) { if (cserr || sperr) { self._alert('error', 'Failed to remove the configuration for ' + currentSelection.val(), cserr, sperr); return; } var currentAlternateDomainName = currentSelection.data('alternatedomain'); var currentDomainName = currentSelection.val(); var nameMap = domains.data('name.map'); if (currentAlternateDomainName !== undefined) { delete nameMap[currentAlternateDomainName]; } delete nameMap[currentDomainName]; self._setSelection(nextSelection); self.read(domains.val()); currentSelection.remove(); }); }, save: function () { var self = configurationEditor; //// Check for configuration errors $('#configured_domain,#alternatedomain,#basedn,#server').each(function (index, target) { self._validateRequiredInputElement(target); }); $('#configured_domain,#alternatedomain').each(function (index, target) { self._validateDomainName(target); }); $('#alternatedomain').each(function (index, target) { self._validateUpperCase(target); }); var input = $('#configured_domain,#alternatedomain,#basedn,#server,#port,#ssl,#binddn,#password').parent(); if (input.hasClass('error')) { var deferred = $.Deferred(); modal = self._alert('error', 'LDAP Configuration errors', 'Please correct them in order to proceed.'); modal.on('hidden.bs.modal', function () { deferred.reject(); }); return deferred; } //// Rename the domain, if its name has changed; otherwise simply save it var domain = $('#domains').children('[selected="selected"]'); var name = $('#configured_domain').val(); return domain.val() !== name ? self._renameAndSave(domain, name) : self._save(domain); }, select: function () { var self = configurationEditor; var deferred = $.Deferred(); var domains = $('#domains'); var selected = domains.children('[selected]'); if ($('#domainError').val()) { /// Don't let the user change the selection until the domain name is corrected modal = self._alert('error', 'Duplicate domain name', 'You cannot change the selection until you ' + 'correct the domain name.'); modal.on('hidden.bs.modal', function () { $('#configured_domain').select().focus(); domains.val(selected.val()); deferred.reject(); }); } else if (self._isDirty()) { //// Prompt the user to discard or save changes var question = 'Do you want to save changes to "' + selected.text() + '" before editing "' + domains.children(':selected').text() + '"?'; var dialog = self._confirm('warning', 'Save changes', question, [ { text: 'Cancel', action: function () { self._setSelection(selected); deferred.resolve(); }}, { text: 'Discard changes', action: function () { self._changeSelection(); deferred.resolve(); }}, { text: 'Save changes', primary: true, action: function () { self.save() .done(function () { self._changeSelection(); deferred.resolve(); }) .fail(function () { self._setSelection(selected); deferred.reject(); }); }} ] ); } else { self._changeSelection(); deferred.resolve(); } return deferred.promise(); }, test: function () { var self = configurationEditor; self.save().done(function () { var domainName = $('#configured_domain').val().trim(); var command = '| ldaptestconnection domain=' + JSON.stringify(domainName); var result = $('#testConnectionDialog_result'); var message = $('#testConnectionDialog_message'); result.val(''); message.text(''); message.css({display: 'none'}); $('#testConnectionDialog_header').text('Testing connection to ' + domainName); $('#testConnectionDialog_command').text(command); $('#testConnectionDialog_close').text('Cancel'); jQuery.noConflict(); window.$('#testConnectionDialog').modal('show'); var searchManager = self._searchManager; searchManager.settings.set('search', command); searchManager.startSearch(); var view = new TestConnectionView({el: result, managerid: searchManager.id}); }); }, //// Privates _alertHeaders: {info: 'Information', warning: 'Warning', error: 'Error'}, _configuration: null, _service: null, _searchManager: null, _storagePasswords: null, _alert: function (type, title, message) { var self = configurationEditor; var header = $('#alertDialog_header'); var body = $('#alertDialog_body'); header.text(title ? title : self._alertHeaders[type]); body.attr('class', 'alert alert-' + type); var text = ''; for (var i = 2; i < arguments.length; i++) { message = arguments[i]; if (message == null) { continue; } if (typeof message === 'object') { var messages = message.data.messages; messages.forEach(function (item) { text += item.type + ': ' + item.text.trim() + '
'; }); } else { text += message; } } body.html('' + text); jQuery.noConflict(); return window.$('#alertDialog').modal('show'); }, _confirm: function (type, title, message, commands) { $('#confirmDialog_header') .text(title ? title : self._alertHeaders[type]); $('#confirmDialog_body') .attr('class', 'alert alert-' + type) .html('' + message); var footer = $('#confirmDialog_footer'); var cancel = null; footer.empty(); commands.forEach(function (command) { if (command.text === 'Cancel') { cancel = command.action; } var button = document.createElement('a'); button.setAttribute('class', command.primary ? 'btn btn-primary' : 'btn'); button.setAttribute('data-dismiss', 'modal'); button.setAttribute('href', '#'); button.appendChild(document.createTextNode(command.text)); footer.append(button); footer.children(':last-child').click(command.action); }); jQuery.noConflict(); var dialog = window.$('#confirmDialog').modal({'show': true, 'backdrop': 'static'}); if (cancel != null) { $('#confirmDialog_cross').click(cancel); } return dialog; }, _add: function () { var self = configurationEditor; var domains = $('#domains'); var configuration = self._configuration; var storagePasswords = self._storagePasswords; var nameMap = domains.data('name.map'); var base = 'untitled domain'; var name = base; for (var i = 2; name in nameMap; i++) { name = base + ' ' + i; } var currentSelection = domains.children(':selected'); var namespace = configuration.namespace; var nextSelection = currentSelection.after('