@ -0,0 +1,152 @@
|
|||||||
|
# Splunk REST storage/passwords Manager for Splunk
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
|
An intuitive, full-featured, Javascript CRUD interface to the [Splunk storage/passwords REST endpoint](http://docs.splunk.com/Documentation/Splunk/7.0.3/RESTREF/RESTaccess#storage.2Fpasswordsstorage/passwords). If you're an app developer looking to securely store passwords for API's, Custom Alert Actions, Modular Inputs or to access any resource that requires a password, this is your tool! Create, update, delete, view passwords, change permissions, sharing and app scope. Ditch your curl commands and upgrade to this simple to use interface.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
To store passwords the user must have the `admin_all_objects` capability enabled within an assigned role. To read passwords a user must have `list_storage_passwords` capabilty enabled within an assigned role.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
The Credential Management dashboard provides a CRUD interface to create, update and delete credentials to be used within Splunk apps.
|
||||||
|
|
||||||
|
#### Create Credential
|
||||||
|
Simply click the create button to reveal the credential creation form.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Fill out the form specifying a username, password and optionally a realm. The realm can be used as a descriptor for the credential or left blank; e.g., prod or dev. The form will populate with sane defaults for owner, read users, write users, app scope and sharing. You can update them to whatever you like, including the target app context, before you hit create.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Once created, the dashboard will be refreshed automatically.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
#### Update Credential
|
||||||
|
|
||||||
|
Right click on a table entry to reveal a context menu that allows you to update the credential.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Alternatively, you can click the detail view (plus icon) in the table to update the credential.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The update form will be rendered under the selected row in the table. You can change the password, any of the permissions or the app context when updating. The realm is the only field that cannot be changed. This is a limitation of the storage/passwords REST endpoint, not the app. You don't have to set the password to update the ACL's on the credential or move between apps. Simply choose new permissions or app scope and hit update.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
#### Delete Credential
|
||||||
|
|
||||||
|
Right click on a table entry to reveal a context menu that allows you to delete the credential.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Alternatively, select any individual credential or select all using the checkbox in the header column and press the delte button.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
#### Reveal Clear Password
|
||||||
|
|
||||||
|
Click the eye icon to view the plain text password.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Using Stored Passwords
|
||||||
|
Please see this [awesome blog post](http://www.georgestarcher.com/splunk-stored-encrypted-credentials/) on using your newly stored credentials. When all else fails, dig into [dev.splunk.com](http://dev.splunk.com/search/?q=storage%2Fpasswords&l=en&submit=Search) for more details.
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
Some of the components included in REST storage/passwords Manager App for Splunk are licensed under free or open source licenses. We wish to thank the contributors to those projects.
|
||||||
|
|
||||||
|
Twitter Bootstrap dropdown.js v3.3.7
|
||||||
|
|
||||||
|
Copyright (c) 2011-2018 Twitter, Inc.
|
||||||
|
Copyright (c) 2011-2018 The Bootstrap Authors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
bootstrap-table.js v1.11.1
|
||||||
|
|
||||||
|
(The MIT License)
|
||||||
|
|
||||||
|
Copyright (c) 2012-2017 Zhixin Wen <wenzhixin2010@gmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
bootstrap-table-contextmenu.js v1.1.4
|
||||||
|
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 David Graham
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
### Feature Requests
|
||||||
|
Please [submit feature requests through Github](https://github.com/sghaskell/rest-storage-passwords-manager/labels/enhancement) using the ``enhancement`` label so they can be tracked and discussed.
|
||||||
|
|
||||||
|
### Bugs
|
||||||
|
Please [submit bugs through Github](https://github.com/sghaskell/rest-storage-passwords-manager/labels/bug) using the ``bug`` label so they can be tracked and discussed.
|
||||||
|
|
||||||
|
###### For all other inquiries
|
||||||
|
Scott Haskell ([shaskell@splunk.com](mailto:shaskell@splunk.com))
|
||||||
|
###### [Code hosted at Github](https://github.com/sghaskell/rest-storage-passwords-manager)
|
||||||
@ -0,0 +1,133 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
|
||||||
|
|
||||||
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||||
|
|
||||||
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||||
|
|
||||||
|
function _setModalMaxHeight(element) {
|
||||||
|
this.$element = $(element);
|
||||||
|
this.$content = this.$element.find('.modal-content');
|
||||||
|
var borderWidth = this.$content.outerHeight() - this.$content.innerHeight();
|
||||||
|
var dialogMargin = $(window).width() < 768 ? 20 : 60;
|
||||||
|
var contentHeight = $(window).height() - (dialogMargin + borderWidth);
|
||||||
|
var headerHeight = this.$element.find('.modal-header').outerHeight() || 0;
|
||||||
|
var footerHeight = this.$element.find('.modal-footer').outerHeight() || 0;
|
||||||
|
var maxHeight = contentHeight - (headerHeight + footerHeight);
|
||||||
|
|
||||||
|
this.$content.css({
|
||||||
|
'overflow': 'hidden'
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$element
|
||||||
|
.find('.modal-body').css({
|
||||||
|
'max-height': maxHeight,
|
||||||
|
'overflow-y': 'auto'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
define(['underscore'], function (_) {
|
||||||
|
return function () {
|
||||||
|
/**
|
||||||
|
* A utility wrapper around Bootstrap's modal.
|
||||||
|
* @param {string|object} id Either an id or a jQuery element that contains the id in its "data-target" attribute
|
||||||
|
* @param {object} [options] Bootstrap modal options
|
||||||
|
* @param {boolean|string} [options.backdrop] Whether or not to show a backdrop, or the string "static" to show a backdrop that doesn't close the modal when clicked
|
||||||
|
* @param {boolean} [options.keyboard] Whether or not the escape key clsoes the modal
|
||||||
|
* @param {boolean} [options.show=false] Whether or not to show the modal when it's created
|
||||||
|
* @param {string} [options.type='normal'] Can be 'normal', 'wide', or 'noPadding'
|
||||||
|
* @param {string} [options.title] The modal's title
|
||||||
|
* @param {boolean} [options.destroyOnHide=true] Destroy the modal when it's hidden
|
||||||
|
* @returns {element}
|
||||||
|
*/
|
||||||
|
function Modal(id, options) {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
_classCallCheck(this, Modal);
|
||||||
|
|
||||||
|
var modalOptions = _.extend({ show: false}, options);
|
||||||
|
|
||||||
|
// if "id" is the element that triggers the modal display, extract the actual id from it; otherwise use it as-is
|
||||||
|
var modalId = id != null && (typeof id === 'undefined' ? 'undefined' : _typeof(id)) === 'object' && id.jquery != null ? id.attr('data-target').slice(1) : id;
|
||||||
|
|
||||||
|
var header = $('<div>').addClass('modal-header');
|
||||||
|
|
||||||
|
var headerCloseButton = $('<button>').addClass('close').attr({
|
||||||
|
'type': 'button',
|
||||||
|
'data-dismiss': 'modal',
|
||||||
|
'aria-label': 'Close'
|
||||||
|
}).append($('<span>').attr('aria-hidden', true).text('×'));
|
||||||
|
|
||||||
|
this.title = $('<h3>').addClass('modal-title');
|
||||||
|
|
||||||
|
this.body = $('<div>').addClass('modal-body');
|
||||||
|
|
||||||
|
this.footer = $('<div>').addClass('modal-footer');
|
||||||
|
|
||||||
|
// Multiselect can grow large and step over footer causing issues clicking button in footer
|
||||||
|
this.footer.css('position', 'relative');
|
||||||
|
this.footer.css('z-index', 1);
|
||||||
|
|
||||||
|
this.$el = $('<div>').addClass('modal hide fade mlts-modal').attr('id', modalId).append($('<div>').addClass('modal-dialog').append($('<div>').addClass('modal-content').append(header.append(headerCloseButton, this.title), this.body, this.footer)));
|
||||||
|
|
||||||
|
if (modalOptions.title != null) this.setTitle(modalOptions.title);
|
||||||
|
|
||||||
|
if (modalOptions.type === 'wide') this.$el.addClass('modal-wide');else if (modalOptions.type === 'noPadding') this.$el.addClass('mlts-modal-no-padding');
|
||||||
|
|
||||||
|
// remove the modal from the dom after it's hidden
|
||||||
|
if (modalOptions.destroyOnHide !== false) {
|
||||||
|
this.$el.on('hidden.bs.modal', function () {
|
||||||
|
return _this.$el.remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$el.on('show.bs.modal', function() {
|
||||||
|
$(this).show();
|
||||||
|
_setModalMaxHeight(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(window).resize(function() {
|
||||||
|
if ($('.modal.in').length != 0) {
|
||||||
|
_setModalMaxHeight($('.modal.in'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$el.modal(modalOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
_createClass(Modal, [{
|
||||||
|
key: 'setTitle',
|
||||||
|
value: function setTitle(titleText) {
|
||||||
|
this.title.text(titleText);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'setAlert',
|
||||||
|
value: function setAlert(alertMessage, alertType) {
|
||||||
|
if (this.alert == null) {
|
||||||
|
this.alert = $('<div>').addClass('mlts-modal-alert');
|
||||||
|
this.body.prepend(this.alert);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Messages.setAlert(this.alert, alertMessage, alertType, undefined, true);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'removeAlert',
|
||||||
|
value: function removeAlert() {
|
||||||
|
//Messages.removeAlert(this.alert, true);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'show',
|
||||||
|
value: function show() {
|
||||||
|
this.$el.modal('show');
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'hide',
|
||||||
|
value: function hide() {
|
||||||
|
this.$el.modal('hide');
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return Modal;
|
||||||
|
}();
|
||||||
|
});
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
.btn-danger {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #d9534f;
|
||||||
|
border-color: #d43f3a;
|
||||||
|
box-shadow: inset 0 1px 0 #d43f3a;
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
.btn-danger:hover {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #c9302c;
|
||||||
|
border-color: #ac2925;
|
||||||
|
background-image: linear-gradient(180deg,#ee5f5b,#bd362f);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn.disabled, .btn.disabled:focus, .btn.disabled:hover, .btn[disabled], .btn[disabled]:focus, .btn[disabled]:hover {
|
||||||
|
cursor: not-allowed;
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: none;
|
||||||
|
opacity: .65;
|
||||||
|
box-shadow: none;
|
||||||
|
background-image: linear-gradient(180deg,#ee5f5b,#bd362f);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-danger.active,
|
||||||
|
.btn-danger.disabled,
|
||||||
|
.btn-danger:active,
|
||||||
|
.btn-danger:focus,
|
||||||
|
.btn-danger:hover,
|
||||||
|
.btn-danger[disabled] {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #bd362f;
|
||||||
|
background-image: linear-gradient(180deg,#c9302c,#ac2925);
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
border-radius: 4px;
|
||||||
|
position: relative;
|
||||||
|
padding: 8px 35px 8px 27px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*=" icon-check-circle"]:before, [class^=icon-check-circle]:before {
|
||||||
|
font-family: Splunk Icons;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
text-decoration: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #5cc05c;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*=" icon-visible"]:before, [class^=icon-visible]:before {
|
||||||
|
font-family: Splunk Icons;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
text-decoration: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
@ -0,0 +1,324 @@
|
|||||||
|
|
||||||
|
.dropup,
|
||||||
|
.dropdown {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropup .caret,
|
||||||
|
.dropdown .caret {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
.dropdown-toggle::after {
|
||||||
|
display: inline-block;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
margin-left: 0.3em;
|
||||||
|
vertical-align: middle;
|
||||||
|
content: "";
|
||||||
|
border-top: 0.3em solid;
|
||||||
|
border-right: 0.3em solid transparent;
|
||||||
|
border-left: 0.3em solid transparent;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
.dropdown-toggle:focus {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropup .dropdown-toggle::after {
|
||||||
|
border-top: 0;
|
||||||
|
border-bottom: 0.3em solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
display: none;
|
||||||
|
float: left;
|
||||||
|
min-width: 10rem;
|
||||||
|
/* padding: 0.5rem 0; */
|
||||||
|
margin: 0.125rem 0 0;
|
||||||
|
/* font-size: 1rem; */
|
||||||
|
color: #292b2c;
|
||||||
|
text-align: left;
|
||||||
|
list-style: none;
|
||||||
|
background-color: #fff;
|
||||||
|
-webkit-background-clip: padding-box;
|
||||||
|
background-clip: padding-box;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.15);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-divider {
|
||||||
|
height: 1px;
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #eceeef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: 3px 1.5rem;
|
||||||
|
clear: both;
|
||||||
|
font-weight: normal;
|
||||||
|
color: #292b2c;
|
||||||
|
text-align: inherit;
|
||||||
|
white-space: nowrap;
|
||||||
|
background: none;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item:focus, .dropdown-item:hover {
|
||||||
|
color: #1d1e1f;
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #f7f7f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item.active, .dropdown-item:active {
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #0275d8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item.disabled, .dropdown-item:disabled {
|
||||||
|
color: #636c72;
|
||||||
|
cursor: not-allowed;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.show > .dropdown-menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.show > a {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu-right {
|
||||||
|
right: 0;
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu-left {
|
||||||
|
right: auto;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-header {
|
||||||
|
display: block;
|
||||||
|
padding: 0.5rem 1.5rem;
|
||||||
|
margin-bottom: 0;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: #636c72;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-backdrop {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 990;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropup .dropdown-menu {
|
||||||
|
top: auto;
|
||||||
|
bottom: 100%;
|
||||||
|
margin-bottom: 0.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group,
|
||||||
|
.btn-group-vertical {
|
||||||
|
position: relative;
|
||||||
|
display: -webkit-inline-box;
|
||||||
|
display: -webkit-inline-flex;
|
||||||
|
display: -ms-inline-flexbox;
|
||||||
|
display: inline-flex;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group > .btn,
|
||||||
|
.btn-group-vertical > .btn {
|
||||||
|
position: relative;
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-webkit-flex: 0 1 auto;
|
||||||
|
-ms-flex: 0 1 auto;
|
||||||
|
flex: 0 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group > .btn:hover,
|
||||||
|
.btn-group-vertical > .btn:hover {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,
|
||||||
|
.btn-group-vertical > .btn:focus,
|
||||||
|
.btn-group-vertical > .btn:active,
|
||||||
|
.btn-group-vertical > .btn.active {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group .btn + .btn,
|
||||||
|
.btn-group .btn + .btn-group,
|
||||||
|
.btn-group .btn-group + .btn,
|
||||||
|
.btn-group .btn-group + .btn-group,
|
||||||
|
.btn-group-vertical .btn + .btn,
|
||||||
|
.btn-group-vertical .btn + .btn-group,
|
||||||
|
.btn-group-vertical .btn-group + .btn,
|
||||||
|
.btn-group-vertical .btn-group + .btn-group {
|
||||||
|
margin-left: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-toolbar {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-pack: start;
|
||||||
|
-webkit-justify-content: flex-start;
|
||||||
|
-ms-flex-pack: start;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-toolbar .input-group {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group > .btn:first-child {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group > .btn:last-child:not(:first-child),
|
||||||
|
.btn-group > .dropdown-toggle:not(:first-child) {
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group > .btn-group {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
|
||||||
|
.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group .dropdown-toggle:active,
|
||||||
|
.btn-group.open .dropdown-toggle {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn + .dropdown-toggle-split {
|
||||||
|
padding-right: 0.75rem;
|
||||||
|
padding-left: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn + .dropdown-toggle-split::after {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {
|
||||||
|
padding-right: 0.375rem;
|
||||||
|
padding-left: 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {
|
||||||
|
padding-right: 1.125rem;
|
||||||
|
padding-left: 1.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group-vertical {
|
||||||
|
display: -webkit-inline-box;
|
||||||
|
display: -webkit-inline-flex;
|
||||||
|
display: -ms-inline-flexbox;
|
||||||
|
display: inline-flex;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-box-direction: normal;
|
||||||
|
-webkit-flex-direction: column;
|
||||||
|
-ms-flex-direction: column;
|
||||||
|
flex-direction: column;
|
||||||
|
-webkit-box-align: start;
|
||||||
|
-webkit-align-items: flex-start;
|
||||||
|
-ms-flex-align: start;
|
||||||
|
align-items: flex-start;
|
||||||
|
-webkit-box-pack: center;
|
||||||
|
-webkit-justify-content: center;
|
||||||
|
-ms-flex-pack: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group-vertical .btn,
|
||||||
|
.btn-group-vertical .btn-group {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group-vertical > .btn + .btn,
|
||||||
|
.btn-group-vertical > .btn + .btn-group,
|
||||||
|
.btn-group-vertical > .btn-group + .btn,
|
||||||
|
.btn-group-vertical > .btn-group + .btn-group {
|
||||||
|
margin-top: -1px;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group-vertical > .btn:first-child:not(:last-child) {
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group-vertical > .btn:last-child:not(:first-child) {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
|
||||||
|
.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-toggle="buttons"] > .btn input[type="radio"],
|
||||||
|
[data-toggle="buttons"] > .btn input[type="checkbox"],
|
||||||
|
[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
|
||||||
|
[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
|
||||||
|
position: absolute;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
@ -0,0 +1,165 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* Bootstrap: dropdown.js v3.3.7
|
||||||
|
* http://getbootstrap.com/javascript/#dropdowns
|
||||||
|
* ========================================================================
|
||||||
|
* Copyright 2011-2016 Twitter, Inc.
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
|
* ======================================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
+function ($) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// DROPDOWN CLASS DEFINITION
|
||||||
|
// =========================
|
||||||
|
|
||||||
|
var backdrop = '.dropdown-backdrop'
|
||||||
|
var toggle = '[data-toggle="dropdown"]'
|
||||||
|
var Dropdown = function (element) {
|
||||||
|
$(element).on('click.bs.dropdown', this.toggle)
|
||||||
|
}
|
||||||
|
|
||||||
|
Dropdown.VERSION = '3.3.7'
|
||||||
|
|
||||||
|
function getParent($this) {
|
||||||
|
var selector = $this.attr('data-target')
|
||||||
|
|
||||||
|
if (!selector) {
|
||||||
|
selector = $this.attr('href')
|
||||||
|
selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
|
||||||
|
}
|
||||||
|
|
||||||
|
var $parent = selector && $(selector)
|
||||||
|
|
||||||
|
return $parent && $parent.length ? $parent : $this.parent()
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearMenus(e) {
|
||||||
|
if (e && e.which === 3) return
|
||||||
|
$(backdrop).remove()
|
||||||
|
$(toggle).each(function () {
|
||||||
|
var $this = $(this)
|
||||||
|
var $parent = getParent($this)
|
||||||
|
var relatedTarget = { relatedTarget: this }
|
||||||
|
|
||||||
|
if (!$parent.hasClass('open')) return
|
||||||
|
|
||||||
|
if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
|
||||||
|
|
||||||
|
$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
|
||||||
|
|
||||||
|
if (e.isDefaultPrevented()) return
|
||||||
|
|
||||||
|
$this.attr('aria-expanded', 'false')
|
||||||
|
$parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Dropdown.prototype.toggle = function (e) {
|
||||||
|
var $this = $(this)
|
||||||
|
|
||||||
|
if ($this.is('.disabled, :disabled')) return
|
||||||
|
|
||||||
|
var $parent = getParent($this)
|
||||||
|
var isActive = $parent.hasClass('open')
|
||||||
|
|
||||||
|
clearMenus()
|
||||||
|
|
||||||
|
if (!isActive) {
|
||||||
|
if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
|
||||||
|
// if mobile we use a backdrop because click events don't delegate
|
||||||
|
$(document.createElement('div'))
|
||||||
|
.addClass('dropdown-backdrop')
|
||||||
|
.insertAfter($(this))
|
||||||
|
.on('click', clearMenus)
|
||||||
|
}
|
||||||
|
|
||||||
|
var relatedTarget = { relatedTarget: this }
|
||||||
|
$parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
|
||||||
|
|
||||||
|
if (e.isDefaultPrevented()) return
|
||||||
|
|
||||||
|
$this
|
||||||
|
.trigger('focus')
|
||||||
|
.attr('aria-expanded', 'true')
|
||||||
|
|
||||||
|
$parent
|
||||||
|
.toggleClass('open')
|
||||||
|
.trigger($.Event('shown.bs.dropdown', relatedTarget))
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
Dropdown.prototype.keydown = function (e) {
|
||||||
|
if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
|
||||||
|
|
||||||
|
var $this = $(this)
|
||||||
|
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
|
||||||
|
if ($this.is('.disabled, :disabled')) return
|
||||||
|
|
||||||
|
var $parent = getParent($this)
|
||||||
|
var isActive = $parent.hasClass('open')
|
||||||
|
|
||||||
|
if (!isActive && e.which != 27 || isActive && e.which == 27) {
|
||||||
|
if (e.which == 27) $parent.find(toggle).trigger('focus')
|
||||||
|
return $this.trigger('click')
|
||||||
|
}
|
||||||
|
|
||||||
|
var desc = ' li:not(.disabled):visible a'
|
||||||
|
var $items = $parent.find('.dropdown-menu' + desc)
|
||||||
|
|
||||||
|
if (!$items.length) return
|
||||||
|
|
||||||
|
var index = $items.index(e.target)
|
||||||
|
|
||||||
|
if (e.which == 38 && index > 0) index-- // up
|
||||||
|
if (e.which == 40 && index < $items.length - 1) index++ // down
|
||||||
|
if (!~index) index = 0
|
||||||
|
|
||||||
|
$items.eq(index).trigger('focus')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// DROPDOWN PLUGIN DEFINITION
|
||||||
|
// ==========================
|
||||||
|
|
||||||
|
function Plugin(option) {
|
||||||
|
return this.each(function () {
|
||||||
|
var $this = $(this)
|
||||||
|
var data = $this.data('bs.dropdown')
|
||||||
|
|
||||||
|
if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
|
||||||
|
if (typeof option == 'string') data[option].call($this)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var old = $.fn.dropdown
|
||||||
|
|
||||||
|
$.fn.dropdown = Plugin
|
||||||
|
$.fn.dropdown.Constructor = Dropdown
|
||||||
|
|
||||||
|
|
||||||
|
// DROPDOWN NO CONFLICT
|
||||||
|
// ====================
|
||||||
|
|
||||||
|
$.fn.dropdown.noConflict = function () {
|
||||||
|
$.fn.dropdown = old
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// APPLY TO STANDARD DROPDOWN ELEMENTS
|
||||||
|
// ===================================
|
||||||
|
|
||||||
|
$(document)
|
||||||
|
.on('click.bs.dropdown.data-api', clearMenus)
|
||||||
|
.on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
|
||||||
|
.on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
|
||||||
|
.on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
|
||||||
|
.on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
|
||||||
|
|
||||||
|
}(jQuery);
|
||||||
@ -0,0 +1,170 @@
|
|||||||
|
/**
|
||||||
|
* @author David Graham <prograhammer@gmail.com>
|
||||||
|
* @version v1.1.4
|
||||||
|
* @link https://github.com/prograhammer/bootstrap-table-contextmenu
|
||||||
|
*/
|
||||||
|
|
||||||
|
!function($) {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
|
// Option defaults
|
||||||
|
contextMenu: undefined,
|
||||||
|
contextMenuTrigger: 'right',
|
||||||
|
contextMenuAutoClickRow: true,
|
||||||
|
contextMenuButton: undefined,
|
||||||
|
beforeContextMenuRow: function (e, row, buttonElement) {
|
||||||
|
// return false here to prevent menu showing
|
||||||
|
},
|
||||||
|
// Event default handlers
|
||||||
|
onContextMenuItem: function (row, $element) {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
onContextMenuRow: function (row, $element) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
$.fn.bootstrapTable.methods.push('showContextMenu');
|
||||||
|
|
||||||
|
// Events
|
||||||
|
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
|
||||||
|
'contextmenu-item.bs.table': 'onContextMenuItem',
|
||||||
|
'contextmenu-row.bs.table': 'onContextMenuRow'
|
||||||
|
});
|
||||||
|
|
||||||
|
var BootstrapTable = $.fn.bootstrapTable.Constructor,
|
||||||
|
_initBody = BootstrapTable.prototype.initBody;
|
||||||
|
|
||||||
|
BootstrapTable.prototype.initBody = function () {
|
||||||
|
|
||||||
|
// Init Body
|
||||||
|
_initBody.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
|
|
||||||
|
// Init Context menu
|
||||||
|
if (this.options.contextMenu || this.options.contextMenuButton || this.options.beforeContextMenuRow) {
|
||||||
|
this.initContextMenu();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Init context menu
|
||||||
|
BootstrapTable.prototype.initContextMenu = function () {
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
// Context menu on Right-click
|
||||||
|
if (that.options.contextMenuTrigger == 'right' || that.options.contextMenuTrigger == 'both') {
|
||||||
|
that.$body.find('> tr[data-index]').off('contextmenu.contextmenu').on('contextmenu.contextmenu', function (e) {
|
||||||
|
var rowData = that.data[$(this).data('index')],
|
||||||
|
beforeShow = that.options.beforeContextMenuRow.apply(this, [e, rowData, null]);
|
||||||
|
|
||||||
|
if(beforeShow !== false){
|
||||||
|
that.showContextMenu({event: e});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context menu on Left-click
|
||||||
|
if (that.options.contextMenuTrigger == 'left' || that.options.contextMenuTrigger == 'both') {
|
||||||
|
that.$body.find('> tr[data-index]').off('click.contextmenu').on('click.contextmenu', function (e) {
|
||||||
|
var rowData = that.data[$(this).data('index')],
|
||||||
|
beforeShow = that.options.beforeContextMenuRow.apply(this, [e, rowData, null]);
|
||||||
|
|
||||||
|
if(beforeShow !== false){
|
||||||
|
that.showContextMenu({event: e});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context menu on Button-click
|
||||||
|
if (typeof that.options.contextMenuButton === 'string') {
|
||||||
|
that.$body.find('> tr[data-index]').find(that.options.contextMenuButton).off('click.contextmenu').on('click.contextmenu', function (e) {
|
||||||
|
var rowData = that.data[$(this).closest('tr[data-index]').data('index')],
|
||||||
|
beforeShow = that.options.beforeContextMenuRow.apply(this, [e, rowData, this]);
|
||||||
|
|
||||||
|
if(beforeShow !== false){
|
||||||
|
that.showContextMenu({event: e, buttonElement: this});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Show context menu
|
||||||
|
BootstrapTable.prototype.showContextMenu = function (params) {
|
||||||
|
if(!params || !params.event){ return false; }
|
||||||
|
if(params && !params.contextMenu && typeof this.options.contextMenu !== 'string'){ return false; }
|
||||||
|
|
||||||
|
var that = this,
|
||||||
|
$menu, screenPosX, screenPosY,
|
||||||
|
$tr = $(params.event.target).closest('tr[data-index]'),
|
||||||
|
item = that.data[$tr.data('index')];
|
||||||
|
|
||||||
|
if(params && !params.contextMenu && typeof this.options.contextMenu === 'string'){
|
||||||
|
screenPosX = params.event.clientX;
|
||||||
|
screenPosY = params.event.clientY;
|
||||||
|
$menu = $(this.options.contextMenu);
|
||||||
|
}
|
||||||
|
if(params && params.contextMenu){
|
||||||
|
screenPosX = params.event.clientX;
|
||||||
|
screenPosY = params.event.clientY;
|
||||||
|
$menu = $(params.contextMenu);
|
||||||
|
}
|
||||||
|
if (params && params.buttonElement) {
|
||||||
|
screenPosX = params.buttonElement.getBoundingClientRect().left;
|
||||||
|
screenPosY = params.buttonElement.getBoundingClientRect().bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMenuPosition($menu, screenPos, direction, scrollDir) {
|
||||||
|
var win = $(window)[direction](),
|
||||||
|
scroll = $(window)[scrollDir](),
|
||||||
|
menu = $menu[direction](),
|
||||||
|
position = screenPos + scroll;
|
||||||
|
|
||||||
|
if (screenPos + menu > win && menu < screenPos)
|
||||||
|
position -= menu;
|
||||||
|
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind click on menu item
|
||||||
|
$menu.find('li').off('click.contextmenu').on('click.contextmenu', function (e) {
|
||||||
|
var rowData = that.data[$menu.data('index')];
|
||||||
|
that.trigger('contextmenu-item', rowData, $(this));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Click anywhere to hide the menu
|
||||||
|
$(document).triggerHandler('click.contextmenu');
|
||||||
|
$(document).off('click.contextmenu').on('click.contextmenu', function (e) {
|
||||||
|
// Fixes problem on Mac OSX
|
||||||
|
if(that.pageX != e.pageX || that.pageY != e.pageY){
|
||||||
|
$menu.hide();
|
||||||
|
$(document).off('click.contextmenu');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
that.pageX = params.event.pageX;
|
||||||
|
that.pageY = params.event.pageY;
|
||||||
|
|
||||||
|
// Show the menu
|
||||||
|
$menu.data('index', $tr.data('index'))
|
||||||
|
.appendTo($('body'))
|
||||||
|
.css({
|
||||||
|
position: "absolute",
|
||||||
|
left: getMenuPosition($menu, screenPosX, 'width', 'scrollLeft'),
|
||||||
|
top: getMenuPosition($menu, screenPosY, 'height', 'scrollTop'),
|
||||||
|
zIndex: 1100
|
||||||
|
})
|
||||||
|
.show();
|
||||||
|
|
||||||
|
// Trigger events
|
||||||
|
that.trigger('contextmenu-row', item, $tr);
|
||||||
|
if(that.options.contextMenuAutoClickRow && that.options.contextMenuTrigger == 'right') {
|
||||||
|
that.trigger('click-row', item, $tr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}(jQuery);
|
||||||
@ -0,0 +1,313 @@
|
|||||||
|
/**
|
||||||
|
* @author zhixin wen <wenzhixin2010@gmail.com>
|
||||||
|
* version: 1.11.1
|
||||||
|
* https://github.com/wenzhixin/bootstrap-table/
|
||||||
|
*/
|
||||||
|
|
||||||
|
.bootstrap-table .table {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
border-bottom: 1px solid #dddddd;
|
||||||
|
border-collapse: collapse !important;
|
||||||
|
border-radius: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bootstrap-table .table:not(.table-condensed),
|
||||||
|
.bootstrap-table .table:not(.table-condensed) > tbody > tr > th,
|
||||||
|
.bootstrap-table .table:not(.table-condensed) > tfoot > tr > th,
|
||||||
|
.bootstrap-table .table:not(.table-condensed) > thead > tr > td,
|
||||||
|
.bootstrap-table .table:not(.table-condensed) > tbody > tr > td,
|
||||||
|
.bootstrap-table .table:not(.table-condensed) > tfoot > tr > td {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bootstrap-table .table.table-no-bordered > thead > tr > th,
|
||||||
|
.bootstrap-table .table.table-no-bordered > tbody > tr > td {
|
||||||
|
border-right: 2px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bootstrap-table .table.table-no-bordered > tbody > tr > td:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container {
|
||||||
|
position: relative;
|
||||||
|
clear: both;
|
||||||
|
border: 1px solid #dddddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container.table-no-bordered {
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-footer,
|
||||||
|
.fixed-table-header {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-footer {
|
||||||
|
border-top: 1px solid #dddddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-body {
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: auto;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container thead th {
|
||||||
|
height: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
border-left: 1px solid #dddddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container thead th:focus {
|
||||||
|
outline: 0 solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container thead th:first-child {
|
||||||
|
border-left: none;
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
-webkit-border-top-left-radius: 4px;
|
||||||
|
-moz-border-radius-topleft: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container thead th .th-inner,
|
||||||
|
.fixed-table-container tbody td .th-inner {
|
||||||
|
padding: 8px;
|
||||||
|
line-height: 24px;
|
||||||
|
vertical-align: top;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container thead th .sortable {
|
||||||
|
cursor: pointer;
|
||||||
|
background-position: right;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
padding-right: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container thead th .both {
|
||||||
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC');
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container thead th .asc {
|
||||||
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg==');
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container thead th .desc {
|
||||||
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= ');
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container th.detail {
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container tbody td {
|
||||||
|
border-left: 1px solid #dddddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container tbody tr:first-child td {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container tbody td:first-child {
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the same color with .active */
|
||||||
|
.fixed-table-container tbody .selected td {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container .bs-checkbox {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container .bs-checkbox .th-inner {
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container input[type="radio"],
|
||||||
|
.fixed-table-container input[type="checkbox"] {
|
||||||
|
margin: 0 auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-container .no-records-found {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-pagination div.pagination,
|
||||||
|
.fixed-table-pagination .pagination-detail {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-pagination div.pagination .pagination {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-pagination .pagination a {
|
||||||
|
padding: 6px 12px;
|
||||||
|
line-height: 1.428571429;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-pagination .pagination-info {
|
||||||
|
line-height: 34px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-pagination .btn-group {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-pagination .dropup .dropdown-menu {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-pagination .page-list {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-toolbar .columns-left {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-toolbar .columns-right {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-toolbar .columns label {
|
||||||
|
display: block;
|
||||||
|
padding: 3px 20px;
|
||||||
|
clear: both;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 1.428571429;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-toolbar .bs-bars,
|
||||||
|
.fixed-table-toolbar .search,
|
||||||
|
.fixed-table-toolbar .columns {
|
||||||
|
position: relative;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
line-height: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-pagination li.disabled a {
|
||||||
|
pointer-events: none;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-loading {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 42px;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 99;
|
||||||
|
background-color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-body .card-view .title {
|
||||||
|
font-weight: bold;
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 30%;
|
||||||
|
text-align: left !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* support bootstrap 2 */
|
||||||
|
.fixed-table-body thead th .th-inner {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table th, .table td {
|
||||||
|
vertical-align: middle;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-toolbar .dropdown-menu {
|
||||||
|
text-align: left;
|
||||||
|
max-height: 300px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-toolbar .btn-group > .btn-group {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: -1px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-toolbar .btn-group > .btn-group > .btn {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-toolbar .btn-group > .btn-group:first-child > .btn {
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-table-toolbar .btn-group > .btn-group:last-child > .btn {
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bootstrap-table .table > thead > tr > th {
|
||||||
|
vertical-align: bottom;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* support bootstrap 3 */
|
||||||
|
.bootstrap-table .table thead > tr > th {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bootstrap-table .fixed-table-footer tbody > tr > td {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bootstrap-table .fixed-table-footer .table {
|
||||||
|
border-bottom: none;
|
||||||
|
border-radius: 0;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bootstrap-table .pull-right .dropdown-menu {
|
||||||
|
right: 0;
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate scrollbar width */
|
||||||
|
p.fixed-table-scroll-inner {
|
||||||
|
width: 100%;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.fixed-table-scroll-outer {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
width: 200px;
|
||||||
|
height: 150px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for get correct heights */
|
||||||
|
.fixed-table-toolbar:after, .fixed-table-pagination:after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 91 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 99 KiB |
|
After Width: | Height: | Size: 100 KiB |
@ -0,0 +1 @@
|
|||||||
|
This is where you put any scripts you want to add to this app.
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
#
|
||||||
|
# Splunk app configuration file
|
||||||
|
#
|
||||||
|
|
||||||
|
[install]
|
||||||
|
is_configured = 0
|
||||||
|
state_change_requires_restart = false
|
||||||
|
|
||||||
|
[ui]
|
||||||
|
is_visible = 1
|
||||||
|
label = REST storage/passwords Manager for Splunk
|
||||||
|
|
||||||
|
[launcher]
|
||||||
|
author = Scott Haskell
|
||||||
|
description = An intuitive, full-featured, Javascript CRUD interface to the storage/passwords REST endpoint.
|
||||||
|
version = 1.0.8
|
||||||
|
|
||||||
|
[package]
|
||||||
|
id = rest-storage-passwords-manager
|
||||||
|
check_for_updates = 1
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
<nav search_view="credential_management" color="#65A637">
|
||||||
|
<view name="credential_management" />
|
||||||
|
<view name="help" />
|
||||||
|
</nav>
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<panel>
|
||||||
|
<html>
|
||||||
|
<div id="create-user"/>
|
||||||
|
<div id="update-user"/>
|
||||||
|
<div id="context-menu"/>
|
||||||
|
<div id="password-table"/>
|
||||||
|
</html>
|
||||||
|
</panel>
|
||||||
@ -0,0 +1 @@
|
|||||||
|
Add all the views that your app needs in this directory
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
<dashboard script="bootstrap-dropdown.js,bootstrap-table.js,bootstrap-table-contextmenu.js,password-crud.js" stylesheet="bootstrap-table.css, bootstrap-dropdown.css, bootstrap-btn-danger.css" refresh="300">
|
||||||
|
<label>Credential Management</label>
|
||||||
|
<row>
|
||||||
|
<panel>
|
||||||
|
<html>
|
||||||
|
<div id="create-user"></div>
|
||||||
|
<div id="update-user"></div>
|
||||||
|
<div id="context-menu"></div>
|
||||||
|
<div id="password-table"></div>
|
||||||
|
</html>
|
||||||
|
</panel>
|
||||||
|
</row>
|
||||||
|
</dashboard>
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
<dashboard>
|
||||||
|
<label>Help</label>
|
||||||
|
<row>
|
||||||
|
<html><h1 id="splunkreststoragepasswordsmanager">Splunk REST storage/passwords Manager for Splunk</h1>
|
||||||
|
<h2 id="about">About</h2>
|
||||||
|
<p>The password manager app provides a Javascript CRUD interface to the <a href="http://docs.splunk.com/Documentation/Splunk/7.0.3/RESTREF/RESTaccess#storage.2Fpasswords">Splunk storage/passwords REST endpoint</a>. </p>
|
||||||
|
<h2 id="dependencies">Dependencies</h2>
|
||||||
|
<p>To store passwords the user must have the <code>admin_all_objects</code> capability enabled within an assigned role. To read passwords a user must have <code>list_storage_passwords</code> capabilty enabled within an assigned role.</p>
|
||||||
|
<h2 id="usage">Usage</h2>
|
||||||
|
<p>The Credential Management dashboard provides a CRUD interface to create, update and delete credentials to be used within Splunk apps. </p>
|
||||||
|
<h4 id="createcredential">Create Credential</h4>
|
||||||
|
<p>Simply click the create button to reveal the credential creation form.</p>
|
||||||
|
<p><img src="/static/app/rest-storage-passwords-manager/img/credential_management-tour:enterprise/credential-create.png?raw=true" alt="Alt text" /></p>
|
||||||
|
<p>Fill out the form specifying a username, password and optionally a realm. The realm can be used as a descriptor for the credential or left blank; e.g., prod or dev. The form will populate with sane defaults for owner, read users, write users, app scope and sharing. You can update them to whatever you like, including the target app context, before you hit create.</p>
|
||||||
|
<p><img src="/static/app/rest-storage-passwords-manager/img/credential_management-tour:enterprise/create-form.png?raw=true" alt="Alt text" /></p>
|
||||||
|
<p><img src="/static/app/rest-storage-passwords-manager/img/credential_management-tour:enterprise/create-success-modal.png?raw=true" alt="Alt text" /></p>
|
||||||
|
<p>Once created, the dashboard will be refreshed automatically. </p>
|
||||||
|
<p><img src="/static/app/rest-storage-passwords-manager/img/credential_management-tour:enterprise/table.png?raw=true" alt="Alt text" /></p>
|
||||||
|
<h4 id="updatecredential">Update Credential</h4>
|
||||||
|
<p>Right click on a table entry to reveal a context menu that allows you to update the credential. </p>
|
||||||
|
<p><img src="/static/app/rest-storage-passwords-manager/img/credential_management-tour:enterprise/context-update.png?raw=true" alt="Alt text" /></p>
|
||||||
|
<p>Alternately, you can click the detail view (plus icon) in the table to update the credential.</p>
|
||||||
|
<p><img src="/static/app/rest-storage-passwords-manager/img/credential_management-tour:enterprise/detail-view.png?raw=true" alt="Alt text" /></p>
|
||||||
|
<p>The update form will be rendered under the selected row in the table. You can change the password, any of the permissions or the app context when updating. The realm is the only field that cannot be changed. This is a limitation of the storage/passwords REST endpoint, not the app. You don't have to set the password to update the ACL's on the credential or move between apps. Simply choose new permissions or app scope and hit update.</p>
|
||||||
|
<p><img src="/static/app/rest-storage-passwords-manager/img/credential_management-tour:enterprise/inline-update.png?raw=true" alt="Alt text" /></p>
|
||||||
|
<h4 id="deletecredential">Delete Credential</h4>
|
||||||
|
<p>Right click on a table entry to reveal a context menu that allows you to delete the credential. </p>
|
||||||
|
<p><img src="/static/app/rest-storage-passwords-manager/img/credential_management-tour:enterprise/context-delete.png?raw=true" alt="Alt text" /></p>
|
||||||
|
<p>Alternately, select any individual credential or select all using the checkbox in the header column and press the delte button.</p>
|
||||||
|
<p><img src="/static/app/rest-storage-passwords-manager/img/credential_management-tour:enterprise/multi-delete.png?raw=true" alt="Alt text" /></p>
|
||||||
|
<p><img src="/static/app/rest-storage-passwords-manager/img/credential_management-tour:enterprise/multi-delete-confirm.png?raw=true" alt="Alt text" /></p>
|
||||||
|
<h4 id="revealclearpassword">Reveal Clear Password</h4>
|
||||||
|
<p>Click the eye icon to view the plain text password.</p>
|
||||||
|
<p><img src="/static/app/rest-storage-passwords-manager/img/credential_management-tour:enterprise/show-password.png?raw=true" alt="Alt text" /></p>
|
||||||
|
<p><img src="/static/app/rest-storage-passwords-manager/img/credential_management-tour:enterprise/clear-password-modal.png?raw=true" alt="Alt text" /></p>
|
||||||
|
<h2 id="usingstoredpasswords">Using Stored Passwords</h2>
|
||||||
|
<p>Please see this <a href="http://www.georgestarcher.com/splunk-stored-encrypted-credentials/">awesome blog post</a> on using your newly stored credentials. When all else fails, dig into <a href="http://dev.splunk.com/search/?q=storage%2Fpasswords">dev.splunk.com</a> for more details.</p>
|
||||||
|
<h2 id="support">Support</h2>
|
||||||
|
<h3 id="featurerequests">Feature Requests</h3>
|
||||||
|
<p>Please <a href="https://github.com/sghaskell/rest-storage-passwords-manager/labels/enhancement">submit feature requests through Github</a> using the <code>enhancement</code> label so they can be tracked and discussed.</p>
|
||||||
|
<h3 id="bugs">Bugs</h3>
|
||||||
|
<p>Please <a href="https://github.com/sghaskell/rest-storage-passwords-manager/labels/bug">submit bugs through Github</a> using the <code>bug</code> label so they can be tracked and discussed.</p>
|
||||||
|
<h6 id="forallotherinquiries">For all other inquiries</h6>
|
||||||
|
<p>Scott Haskell (<a href="mailto:shaskell@splunk.com">shaskell@splunk.com</a>)</p>
|
||||||
|
<h6 id="codehostedatgithubhttpsgithubcomsghaskellreststoragepasswordsmanager"><a href="https://github.com/sghaskell/rest-storage-passwords-manager">Code hosted at Github</a></h6></html>
|
||||||
|
</row>
|
||||||
|
</dashboard>
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
[credential_management-tour:enterprise]
|
||||||
|
context = rest-storage-passwords-manager
|
||||||
|
imgPath = /credential_management-tour:enterprise
|
||||||
|
label = rest-storage-passwords-manager-tour
|
||||||
|
type = image
|
||||||
|
doneURL = /app/rest-storage-passwords-manager/credential_management
|
||||||
|
imageCaption1 = Create
|
||||||
|
imageName1 = credential-create.png
|
||||||
|
skipText = Skip tour
|
||||||
|
imageCaption2 = Specify username, password, realm (optional - e.g., prod or dev), read/write permissions, app scope and sharing.
|
||||||
|
imageName2 = create-form.png
|
||||||
|
imageCaption3 = Right click on row to update via context menu
|
||||||
|
imageName3 = context-update.png
|
||||||
|
imageCaption4 = Use the detail view to update a row
|
||||||
|
imageName4 = detail-view.png
|
||||||
|
imageCaption5 = Update password, permissions, app scope or sharing for the credential
|
||||||
|
imageName5 = inline-update.png
|
||||||
|
imageCaption6 = Right click on a row to delete via the context menu
|
||||||
|
imageName6 = context-delete.png
|
||||||
|
imageCaption7 = Delete multiple credentials by selecting individual rows or use the select all checkbox in the table header and click delete
|
||||||
|
imageName7 = multi-delete.png
|
||||||
|
imageCaption8 = Reveal the clear text password for a credential
|
||||||
|
imageName8 = show-password.png
|
||||||
|
imageCaption9 = The Dude abides!
|
||||||
|
imageName9 = clear-password-modal.png
|
||||||
|
viewed = 0
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
[expose:configs_conf-PASSWORDS_MOVE]
|
||||||
|
methods = POST
|
||||||
|
pattern = configs/conf-passwords/*/move
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
[]
|
||||||
|
export = system
|
||||||
|
|
||||||
|
[views/credential_management]
|
||||||
|
access = read : [ * ]
|
||||||
|
export = none
|
||||||
|
owner = nobody
|
||||||
|
|
||||||
|
[views/help]
|
||||||
|
access = read : [ * ]
|
||||||
|
export = none
|
||||||
|
owner = nobody
|
||||||
@ -0,0 +1,194 @@
|
|||||||
|
{
|
||||||
|
"version": "1.0",
|
||||||
|
"date": "2022-11-14T09:53:21.380255565Z",
|
||||||
|
"hashAlgorithm": "SHA-256",
|
||||||
|
"app": {
|
||||||
|
"id": 4013,
|
||||||
|
"version": "1.0.8",
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"path": "README.md",
|
||||||
|
"hash": "17917df1b2742bf6ced6529ad9b5a388f830ef8e2b0bc8cde7a73f6359e6c2c5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/Modal.js",
|
||||||
|
"hash": "86c6704ab58ca8527cafe352f15381cf28dc0493accb8e335a461c93f93d4f59"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/bootstrap-btn-danger.css",
|
||||||
|
"hash": "92f3372b358f048e72cf443ec43b65ba9b0281e81d1da8a13328ed99166e23c9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/bootstrap-dropdown.css",
|
||||||
|
"hash": "17c1446fbbcf629f3c9c6f07babcd6e672ab6c68f48333ee1c628152785754c7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/bootstrap-dropdown.js",
|
||||||
|
"hash": "1e27ab65eddd056cf3bf185c8a4784c53e5657faeadbb6742830d0f1367f638f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/bootstrap-table-contextmenu.js",
|
||||||
|
"hash": "4498c41efcf6a551260efc7bbdc37cb53b83ecb6c7d8d62e99f2ac563ee5183d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/bootstrap-table.css",
|
||||||
|
"hash": "72805bd7db12be1db2918f9f41096b92c48f618865a7d43ff3bedfa9223ebe42"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/bootstrap-table.js",
|
||||||
|
"hash": "e477192a88ad98341e4db3122706c526f50e5353b3d81a619813e2eafcdce717"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/img/credential_management-tour:enterprise/clear-password-modal.png",
|
||||||
|
"hash": "00a55d412d8ccd7e57404fe348020e465b3b570b7823a62a6862b7afb9c47123"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/img/credential_management-tour:enterprise/context-delete.png",
|
||||||
|
"hash": "8acd50c1563a144572925e929790602c86cf4b40a3a95f04344ae9269c84752d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/img/credential_management-tour:enterprise/context-menu.png",
|
||||||
|
"hash": "f00f0a3e8d8898bf04f0574fcb48d5cffa409bdb14bd0d8741f7994a9396eda1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/img/credential_management-tour:enterprise/context-update.png",
|
||||||
|
"hash": "43bf7a6c56c9d57305fc0d61dbade90ac212dca546e23e54422ca69711e5cc75"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/img/credential_management-tour:enterprise/create-form.png",
|
||||||
|
"hash": "2c6656d39f432bf3ae612e9e83b17b2b96aaeb08aa9c8caf687ef80773a68309"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/img/credential_management-tour:enterprise/create-success-modal.png",
|
||||||
|
"hash": "ecaf138a7d423cba326d9b96665e0bfbbc85c979a687c6b44ba9741f589546d0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/img/credential_management-tour:enterprise/credential-create.png",
|
||||||
|
"hash": "c27abf488122cee4851f055db2324c39a022c08ccb5d37acb8a7461d12ded463"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/img/credential_management-tour:enterprise/detail-view.png",
|
||||||
|
"hash": "37091e1a66a36d50ce8f46d710f110843c161c834e177a0acd1f80d1d06e6452"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/img/credential_management-tour:enterprise/filter.png",
|
||||||
|
"hash": "ad0363ff48bd0f3553f1d968e96e29eb1f732b006cda2686272449cda4bf1e05"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/img/credential_management-tour:enterprise/inline-update.png",
|
||||||
|
"hash": "9f5911e98e630a49663bffd1d03e5e1bf01ca5dbba6537144d2e6482da0fbdb0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/img/credential_management-tour:enterprise/multi-delete-confirm.png",
|
||||||
|
"hash": "c9adaf61556c5267c6d79a497d5892c0f08fb3f64ffe5e15954b5cf6a65ece1b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/img/credential_management-tour:enterprise/multi-delete.png",
|
||||||
|
"hash": "a2b6a9ccca6b61fbc640d521a7ad229a9de0e28ab7663323bc854cc6f418c3d7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/img/credential_management-tour:enterprise/show-password.png",
|
||||||
|
"hash": "0ed1bb7e0b6b1d5d55a9f03eda9db4b22783719f2ec971a26da61aeee4ab6365"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/img/credential_management-tour:enterprise/table.png",
|
||||||
|
"hash": "77b7c9f782d629121f8b5f359b9816eb852f3c99dd868106827ed90ad072c763"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "appserver/static/password-crud.js",
|
||||||
|
"hash": "097bd3e3c74f0ff8e2b834c00b71141ba56c8dc945e91cd6a41ed585ee06247e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "bin/README",
|
||||||
|
"hash": "597cdad620bec4e52e0e8adc3cad99de9b3ce45da0dd18e4159e1009c976e957"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "default/app.conf",
|
||||||
|
"hash": "2c081ec42551be5ff60e81cece40a5a2529c69b1538cbc88b63899a59c759ced"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "default/data/ui/nav/default.xml",
|
||||||
|
"hash": "61ff3213833d58ffe188165b2c471bcf190a817544a6b0c5e15395b45e8de40c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "default/data/ui/panels/credential-management.xml",
|
||||||
|
"hash": "3f94d92418394f18c6679aa6ac261faf312e7bfadfdcd04f8eb0f1b90211bb08"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "default/data/ui/views/README",
|
||||||
|
"hash": "4ccd9dc2dca5bd634f7c07ad1749e4e63a7969c84e2eff83517256f7c884cd29"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "default/data/ui/views/credential_management.xml",
|
||||||
|
"hash": "cb253d7f6279d28091bb008737d400f62f3072f5e8395bc84d619bf990da5c1a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "default/data/ui/views/help.xml",
|
||||||
|
"hash": "d6ea7a342026d1c2f159d2b31b3bef8da2da3ec683f9c801b3163f331212bf00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "default/ui-tour.conf",
|
||||||
|
"hash": "9adafad611a6408b1448e300f9c33d9f085c4c65c2a6c7d943e948ed4a4c13c9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "default/web.conf",
|
||||||
|
"hash": "5f7f8165052a710dadd4c8a3ee3575027bf3ec9c19a8673526b4f23725f01e41"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "metadata/default.meta",
|
||||||
|
"hash": "da00a88bf168a3f7079ee944d539511865d3e704d8be37ceb0027217955f7649"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "static/appIcon.png",
|
||||||
|
"hash": "7e2aa1f79791147b9390a927d5c90eda59147c97b127968c165497e152470066"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "static/appIconAlt.png",
|
||||||
|
"hash": "7e2aa1f79791147b9390a927d5c90eda59147c97b127968c165497e152470066"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "static/appIconAlt_2x.png",
|
||||||
|
"hash": "ab60db107ac936dc61e74632c3db46797d265b32410be3631c21cdfef5cfd33b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "static/appIcon_2x.png",
|
||||||
|
"hash": "ab60db107ac936dc61e74632c3db46797d265b32410be3631c21cdfef5cfd33b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "static/appLogo.png",
|
||||||
|
"hash": "0f6bf549bed7bdabe188535cd756399d49fa6834a53670c20627466049952973"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "static/appLogo_2x.png",
|
||||||
|
"hash": "997037f671cb741a1c55f122a74188c0124ed9c4b820e731b93bb62e58a15e83"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"products": [
|
||||||
|
{
|
||||||
|
"platform": "splunk",
|
||||||
|
"product": "enterprise",
|
||||||
|
"versions": [
|
||||||
|
"7.0",
|
||||||
|
"7.1",
|
||||||
|
"7.2",
|
||||||
|
"7.3",
|
||||||
|
"8.0",
|
||||||
|
"8.1",
|
||||||
|
"8.2",
|
||||||
|
"9.0"
|
||||||
|
],
|
||||||
|
"architectures": [
|
||||||
|
"x86_64"
|
||||||
|
],
|
||||||
|
"operatingSystems": [
|
||||||
|
"windows",
|
||||||
|
"linux",
|
||||||
|
"macos",
|
||||||
|
"freebsd",
|
||||||
|
"solaris",
|
||||||
|
"aix"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 5.8 KiB |