You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
434 lines
14 KiB
434 lines
14 KiB
require.config({
|
|
paths: {
|
|
'app': '../app'
|
|
}
|
|
});
|
|
|
|
require([
|
|
"underscore",
|
|
"jquery",
|
|
"splunkjs/mvc/utils",
|
|
"splunkjs/mvc",
|
|
"splunkjs/mvc/tokenutils",
|
|
"splunkjs/mvc/simplexml",
|
|
"splunkjs/mvc/layoutview",
|
|
"splunkjs/mvc/simplexml/dashboardview",
|
|
"splunkjs/mvc/simplexml/dashboard/panelref",
|
|
"splunkjs/mvc/simplexml/element/chart",
|
|
"splunkjs/mvc/simplexml/element/event",
|
|
"splunkjs/mvc/simplexml/element/html",
|
|
"splunkjs/mvc/simplexml/element/list",
|
|
"splunkjs/mvc/simplexml/element/map",
|
|
"splunkjs/mvc/simplexml/element/single",
|
|
"splunkjs/mvc/simplexml/element/table",
|
|
"splunkjs/mvc/simplexml/element/visualization",
|
|
"splunkjs/mvc/simpleform/formutils",
|
|
"splunkjs/mvc/simplexml/eventhandler",
|
|
"splunkjs/mvc/simplexml/searcheventhandler",
|
|
"splunkjs/mvc/simpleform/input/dropdown",
|
|
"splunkjs/mvc/simpleform/input/radiogroup",
|
|
"splunkjs/mvc/simpleform/input/linklist",
|
|
"splunkjs/mvc/simpleform/input/multiselect",
|
|
"splunkjs/mvc/simpleform/input/checkboxgroup",
|
|
"splunkjs/mvc/simpleform/input/text",
|
|
"splunkjs/mvc/simpleform/input/timerange",
|
|
"splunkjs/mvc/simpleform/input/submit",
|
|
"splunkjs/mvc/searchmanager",
|
|
"splunkjs/mvc/savedsearchmanager",
|
|
"splunkjs/mvc/postprocessmanager",
|
|
"splunkjs/mvc/simplexml/urltokenmodel",
|
|
"splunkjs/mvc/tableview",
|
|
"splunkjs/mvc/simplexml/ready!"
|
|
], function(
|
|
_,
|
|
$,
|
|
utils,
|
|
mvc,
|
|
TokenUtils,
|
|
DashboardController,
|
|
LayoutView,
|
|
Dashboard,
|
|
PanelRef,
|
|
ChartElement,
|
|
EventElement,
|
|
HtmlElement,
|
|
ListElement,
|
|
MapElement,
|
|
SingleElement,
|
|
TableElement,
|
|
VisualizationElement,
|
|
FormUtils,
|
|
EventHandler,
|
|
SearchEventHandler,
|
|
DropdownInput,
|
|
RadioGroupInput,
|
|
LinkListInput,
|
|
MultiSelectInput,
|
|
CheckboxGroupInput,
|
|
TextInput,
|
|
TimeRangeInput,
|
|
SubmitButton,
|
|
SearchManager,
|
|
SavedSearchManager,
|
|
PostProcessManager,
|
|
UrlTokenModel,
|
|
TableView
|
|
) {
|
|
require(["splunkjs/mvc/simplexml/ready!"], function () {
|
|
|
|
let isAdmin = false;
|
|
|
|
let roleSearchManager = new SearchManager({
|
|
"id": "roleSearch",
|
|
"status_buckets": 300,
|
|
"search": '|rest splunk_server=local /services/authentication/current-context |table roles |mvexpand roles',
|
|
});
|
|
|
|
var roleResults = roleSearchManager.data("results", {count:0});
|
|
|
|
roleResults.on("data", function() {
|
|
console.log("Got Search Results");
|
|
var d = roleResults.data();
|
|
if (d && d.rows) {
|
|
for (var i = 0; i < d.rows.length; i++) {
|
|
if ( (d.rows[i][0] === 'admin') || (d.rows[i][0] === 'incident_intelligence_admin') || (d.rows[i][0] === 'sc_admin') ) {
|
|
isAdmin = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (isAdmin) {
|
|
$("#protocol").removeAttr("disabled");
|
|
$("#host").removeAttr("disabled");
|
|
$("#port").removeAttr("disabled");
|
|
$("#useAuth").removeAttr("disabled");
|
|
$("#user").removeAttr("disabled");
|
|
$("#password").removeAttr("disabled");
|
|
$("#submit1").show();
|
|
$("#delete1").show();
|
|
}
|
|
});
|
|
|
|
roleSearchManager.startSearch();
|
|
|
|
// Create a service object using the Splunk SDK for JavaScript
|
|
// to send REST requests
|
|
let service = mvc.createService({ owner: "nobody" , app: "splunk_incident_intelligence_app"});
|
|
|
|
let serviceParams = {
|
|
output_mode: "JSON"
|
|
};
|
|
|
|
// Lookup proxy config and load UI fields.
|
|
findProxy(function(result) {
|
|
if (result) {
|
|
if(result.user && result.user.length) {
|
|
console.log('Loading UI with proxy configuration with user details.');
|
|
// Lookup password then set fields.
|
|
lookupPassword(result._key, function(value) {
|
|
$('#protocol').val(result.protocol);
|
|
$("#host").val(result.host);
|
|
$("#port").val(result.port);
|
|
$("#user").val(result.user);
|
|
$("#key1").val(result._key); // Hidden field
|
|
if (value) {
|
|
$("#password").val(value);
|
|
} else {
|
|
console.error('User specified in Proxy Config but password not found!');
|
|
}
|
|
if (result.user.length > 0) {
|
|
console.log('Entry is enabled, setting checkbox and enabling user details');
|
|
$("#useAuth").prop('checked', true);
|
|
$("#user").prop('disabled', false);
|
|
$("#password").prop('disabled', false);
|
|
} else {
|
|
console.log('Entry is disabled, unchecking checkbox and disabling user details');
|
|
$("#useAuth").prop('checked', false);
|
|
$("#user").prop('disabled', true);
|
|
$("#password").prop('disabled', true);
|
|
}
|
|
});
|
|
} else {
|
|
console.log('Loading UI with proxy configuration w/out user details.');
|
|
// No user / password display values from proxy config only.
|
|
$('#protocol').val(result.protocol);
|
|
$("#host").val(result.host);
|
|
$("#port").val(result.port);
|
|
$("#key1").val(result._key); // Hidden field
|
|
}
|
|
} else {
|
|
console.log('Existing proxy config not found.');
|
|
}
|
|
});
|
|
|
|
|
|
// Find the proxy entry in the kvstore, will invoke callback (cb) passing the _key of proxy if exists
|
|
// or undefined if the entry does not exist.
|
|
function findProxy(cb) {
|
|
|
|
// For create, we need to lookup the _key in the kvstore. The key will be used for the
|
|
// password and updated on the form.
|
|
const query = '| inputlookup proxy_lookup | table protocol,host,port,user,_key';
|
|
|
|
const search = service.oneshotSearch(
|
|
query,
|
|
null,
|
|
function(err,results) {
|
|
|
|
if (err) {
|
|
console.error('Proxy entry lookup error - ', err);
|
|
return cb(undefined);
|
|
}
|
|
|
|
if (!results || !results.rows || results.rows.length === 0) {
|
|
console.log ('proxy record does not exist in the the kvstore.');
|
|
return cb(undefined);
|
|
}
|
|
|
|
// Add the new API to the kvstore
|
|
const protocol = results.rows[0][0];
|
|
const host = results.rows[0][1];
|
|
const port = results.rows[0][2];
|
|
const user = results.rows[0][3];
|
|
const _key = results.rows[0][4];
|
|
|
|
//console.log('Found proxy config entry in kvstore: protocol' + protocol + ', host: ' + host +
|
|
// ', port: ' + port + ', user: ' + user + ', _key: ' + _key);
|
|
cb({ protocol, host, port, user, _key });
|
|
});
|
|
}
|
|
|
|
function lookupPassword(key, cb) {
|
|
// Retrieve API Key for previous version of the app.
|
|
service.get("/servicesNS/nobody/splunk_incident_intelligence_app/storage/passwords", serviceParams)
|
|
.then(function(response) {
|
|
const data = response;
|
|
const pre_api = JSON.parse(data);
|
|
|
|
let pass;
|
|
for (let i = 0; i < pre_api.entry.length; i++) {
|
|
const name = pre_api.entry[i].name;
|
|
if (name && name.indexOf(key) !== -1) {
|
|
pass = pre_api.entry[i].content.clear_password;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// API key does not exist, may not of have the previous version of the app.
|
|
if (!pass || pass.length === 0) {
|
|
cb(undefined);
|
|
} else {
|
|
cb(pass);
|
|
}
|
|
});
|
|
}
|
|
|
|
function deletePassword(key, cb) {
|
|
lookupPassword(key, function(value) {
|
|
if (value) {
|
|
service.del("storage/passwords/" + encodeURIComponent(key)).done(function() {
|
|
console.log('Successfully removed storage entry!');
|
|
cb();
|
|
});
|
|
} else {
|
|
cb();
|
|
}
|
|
});
|
|
}
|
|
|
|
function createPassword(key, password, cb) {
|
|
// Create storage/password entry with user set to the Record's KV Store _key and password
|
|
// as the unmasked API key.
|
|
const body = 'name='+ encodeURIComponent(key)+ '&password='+ encodeURIComponent(password);
|
|
service.request(
|
|
"/servicesNS/nobody/splunk_incident_intelligence_app/storage/passwords",
|
|
"POST",
|
|
null,
|
|
null,
|
|
body,
|
|
{"Content-Type": "application/x-www-form-urlencoded"},
|
|
null)
|
|
.done(function () {
|
|
cb();
|
|
});
|
|
}
|
|
|
|
function createProxy(protocol, host,port,user,pass,cb) {
|
|
// Create key
|
|
const record = {
|
|
"protocol": protocol,
|
|
"host": host,
|
|
"port": port,
|
|
"user": user,
|
|
"_key": ""
|
|
};
|
|
|
|
service.request(
|
|
"storage/collections/data/proxyconfig/",
|
|
"POST",
|
|
null,
|
|
null,
|
|
JSON.stringify(record),
|
|
{"Content-Type": "application/json"},
|
|
null)
|
|
.done(function () {
|
|
console.log('Successfully created proxy configuration in kvStore.');
|
|
cb();
|
|
});
|
|
}
|
|
|
|
function updateProxy(protocol, host,port,user,pass,key, cb) {
|
|
|
|
// Search to update the proxy configuration entry in the kvstore with new values.
|
|
const updateSearch = '| inputlookup proxy_lookup ' +
|
|
'| search _key=' + key +
|
|
'| eval protocol="' + protocol + '" ' +
|
|
'| eval host="' + host + '" ' +
|
|
'| eval port=' + port + ' ' +
|
|
'| eval user="' + user + '" ' +
|
|
'| outputlookup proxy_lookup append=True';
|
|
service.oneshotSearch(
|
|
updateSearch,
|
|
null,
|
|
function (err, results) {
|
|
cb();
|
|
});
|
|
}
|
|
|
|
// Create / Update proxy config. This involves:
|
|
// 1. Create or update entry in the proxyconfig collection
|
|
// 2. Delete password entry (which may not exist).
|
|
// 3. Create password entry if password is present.
|
|
function createProxyConfig(protocol,host,port,user,pass,key) {
|
|
|
|
if (!key || !key.length) {
|
|
createProxy(protocol,host,port,user,pass, function() {
|
|
// Save password in secure storage.
|
|
findProxy(function(proxyConfig) {
|
|
if (!proxyConfig) {
|
|
console.error('Failed find proxyConfig in kvStore!');
|
|
alert ('Failed find proxy configuration in kvstore!');
|
|
return;
|
|
}
|
|
const kvStoreKey = proxyConfig._key;
|
|
// Update value of key1 hidden field. This is used in the update and delete scenarios.
|
|
$("#key1").val(kvStoreKey);
|
|
// Create the password.
|
|
if (pass && pass.length) {
|
|
createPassword(kvStoreKey, pass, function() {
|
|
alert('Successfully created proxy configuration!');
|
|
});
|
|
} else {
|
|
console.log('User details not specified, skipping creation of proxy entry.');
|
|
alert('Successfully created proxy configuration!');
|
|
}
|
|
});
|
|
});
|
|
} else {
|
|
// Update key.
|
|
updateProxy(protocol,host,port,user,pass,key, function() {
|
|
console.log('update proxy config done, updating user details...');
|
|
// For the case of update, cannot update a password in passwords/storage endpoint,
|
|
// thus must delete then re-create (if password is specified).
|
|
deletePassword(key, function() {
|
|
console.log('Successfully deleted proxy configuration entry.');
|
|
if (pass && pass.length) {
|
|
// Create the password.
|
|
createPassword(key, pass, function() {
|
|
alert('Successfully updated proxy configuration!');
|
|
});
|
|
} else {
|
|
console.log('User details not specified, not updating proxy configuration entry.');
|
|
alert('Successfully updated proxy configuration!');
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
function validateFormData() {
|
|
const protocol = $('#protocol').val();
|
|
const host = $("#host").val();
|
|
const port = $("#port").val();
|
|
const user = $("#user").val();
|
|
const pass = $("#password").val();
|
|
const key = $("#key1").val();
|
|
if (!protocol || !host || !port) {
|
|
alert('Missing Required fields!');
|
|
return false;
|
|
}
|
|
|
|
if (user && user.length && (!pass || pass.length === 0)) {
|
|
alert('Password must be specified when user is present.')
|
|
return false;
|
|
}
|
|
|
|
if (pass && pass.length && (!user || user.length === 0)) {
|
|
alert('User must be specified when password is present.')
|
|
return false;
|
|
}
|
|
|
|
let numericPort = Number(port);
|
|
if (!numericPort) {
|
|
alert('Port must be numeric');
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Use Authentication Checkbox
|
|
$("#useAuth").on("click", function(e) {
|
|
if($(this).is(":checked")) {
|
|
console.log('The check box is checked!');
|
|
$("#user").prop('disabled', false);
|
|
$("#password").prop('disabled', false);
|
|
} else {
|
|
console.log('The check box is NOT checked!');
|
|
$("#user").prop('disabled', true);
|
|
$("#password").prop('disabled', true);
|
|
$("#user").val('');
|
|
$("#password").val('');
|
|
}
|
|
});
|
|
|
|
// Submit Button
|
|
$("#submit1").on("click", function (e) {
|
|
if (!validateFormData()) {
|
|
// Invalid form data
|
|
return;
|
|
}
|
|
const protocol = $('#protocol').val();
|
|
const host = $("#host").val();
|
|
const port = $("#port").val();
|
|
const user = $("#user").val();
|
|
const pass = $("#password").val();
|
|
const key = $("#key1").val();
|
|
createProxyConfig(protocol,host,port,user,pass,key);
|
|
});
|
|
|
|
// Delete button.
|
|
$("#delete1").on("click", function (e) {
|
|
const key = $("#key1").val();
|
|
if (key && key.length) {
|
|
if (confirm("Are you sure you want to delete Proxy Configuration?") == true) {
|
|
service.del("storage/collections/data/proxyconfig/" + encodeURIComponent(key)).done(function () {
|
|
deletePassword(key, function () {
|
|
// Delete done Clear fields.
|
|
$('#protocol').val('');
|
|
$("#host").val('');
|
|
$("#port").val('');
|
|
$("#user").val('');
|
|
$("#password").val('');
|
|
$("#key1").val('');
|
|
});
|
|
});
|
|
} else {
|
|
console.log('Proxy config delete cancelled by user.');
|
|
}
|
|
} else {
|
|
console.log('Delete clicked but found nothing to delete.');
|
|
}
|
|
});
|
|
});
|
|
});
|