From 3f8bb5e57e4f4f741a29bb56b0b961dcea652a8f Mon Sep 17 00:00:00 2001 From: djenriquez Date: Tue, 25 Apr 2017 21:44:41 -0700 Subject: [PATCH 1/4] Add mount description, stub ability to update --- app/components/Secrets/Generic/Generic.jsx | 90 ++++++++++++++++++++-- app/components/shared/styles.css | 4 + 2 files changed, 87 insertions(+), 7 deletions(-) diff --git a/app/components/Secrets/Generic/Generic.jsx b/app/components/Secrets/Generic/Generic.jsx index 6cebaf9..dd59637 100644 --- a/app/components/Secrets/Generic/Generic.jsx +++ b/app/components/Secrets/Generic/Generic.jsx @@ -59,6 +59,9 @@ class GenericSecretBackend extends React.Component { wrapPath: null, useRootKey: window.localStorage.getItem("useRootKey") === 'true' || false, rootKey: window.localStorage.getItem("secretsRootKey") || '', + description: '', + disableDescEdit: true, + genericName: '' } _.bindAll( @@ -71,7 +74,13 @@ class GenericSecretBackend extends React.Component { 'DeleteObject', 'renderNewObjectDialog', 'renderEditObjectDialog', - 'renderDeleteConfirmationDialog' + 'renderDeleteConfirmationDialog', + /* + TODO: + Waiting on the ability to update mount description: https://github.com/hashicorp/vault/issues/2645 + 'editDescription', + 'updateDescription' + */ ); } @@ -131,11 +140,54 @@ class GenericSecretBackend extends React.Component { }) } + getMountDescription() { + this.setState({ genericName: this.props.params.namespace }); + tokenHasCapabilities(['read'], 'sys/mounts') + .then(() => { + callVaultApi('get', 'sys/mounts') + .then((resp) => { + let desc = _.get(resp, `data.data.${this.state.genericName}/.description`, null); + if (desc) this.setState({ description: desc }) + }); + }) + .catch(); + } + + /* + TODO: + Waiting on the ability to update mount description: https://github.com/hashicorp/vault/issues/2645 + + editDescription() { + let uri = `/sys/mounts/${this.state.genericName}`; + tokenHasCapabilities(['post'], uri) + .then(() => { + this.setState({ disableDescEdit: false }); + }) + .catch(); + } + + updateDescription() { + let uri = `/sys/mounts/${this.state.genericName}`; + tokenHasCapabilities(['post'], uri) + .then(() => { + callVaultApi('post', uri, {}, { description: this.state.description, type: 'generic', path: this.state.genericName }) + .then((resp) => { + snackBarMessage('Description updated') + }) + .catch((error) => { + snackBarMessage(error); + }); + }) + .catch(); + } + */ + componentWillMount() { this.setState({ currentLogicalPath: `${this.props.params.namespace}/${this.props.params.splat}` }) } componentDidMount() { + this.getMountDescription(); if (this.isPathDirectory(this.props.params.splat)) { this.loadSecretsList(); } else { @@ -148,13 +200,15 @@ class GenericSecretBackend extends React.Component { if (!_.isEqual(this.props.params.namespace, nextProps.params.namespace)) { // Reset this.setState({ - secretList: [] + secretList: [], + description: '' }) } } componentDidUpdate(prevProps) { if (!_.isEqual(this.props.params, prevProps.params)) { + this.getMountDescription(); if (this.isPathDirectory(this.props.params.splat)) { this.loadSecretsList(); } else { @@ -432,7 +486,29 @@ class GenericSecretBackend extends React.Component { {this.renderDeleteConfirmationDialog()} - + + {this.state.description ? { + this.setState({ disableDescEdit: true }); + this.updateDescription(); + }} + onChange={(e) => { + this.setState({ description: e.target.value }) + }} + /> : null} Here you can browse, edit, create and delete secrets. @@ -456,14 +532,14 @@ class GenericSecretBackend extends React.Component { {this.setState({secretSortDir: v})}} + value={this.state.secretSortDir} onChange={(e, i, v) => { this.setState({ secretSortDir: v }) }} > - - + + diff --git a/app/components/shared/styles.css b/app/components/shared/styles.css index 2c8a742..b6e50eb 100644 --- a/app/components/shared/styles.css +++ b/app/components/shared/styles.css @@ -4,6 +4,10 @@ font-style: italic; } +.descriptionField { + text-align: center; +} + .TabContentSection { padding: 10px; } From c35d63fddd89854a0dfd6abb01b85676352c7bf7 Mon Sep 17 00:00:00 2001 From: djenriquez Date: Tue, 25 Apr 2017 21:55:17 -0700 Subject: [PATCH 2/4] Clean up --- app/components/shared/styles.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/components/shared/styles.css b/app/components/shared/styles.css index b6e50eb..2c8a742 100644 --- a/app/components/shared/styles.css +++ b/app/components/shared/styles.css @@ -4,10 +4,6 @@ font-style: italic; } -.descriptionField { - text-align: center; -} - .TabContentSection { padding: 10px; } From b5d7e723c530d671d7370305d12751e74e20fc63 Mon Sep 17 00:00:00 2001 From: Matteo Sessa Date: Wed, 26 Apr 2017 15:40:25 +1000 Subject: [PATCH 3/4] Display backend description in main navigation menu --- app/components/shared/Menu/Menu.jsx | 38 ++++++++++++++++++++++++----- app/components/shared/Menu/menu.css | 13 +++++++--- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/app/components/shared/Menu/Menu.jsx b/app/components/shared/Menu/Menu.jsx index f59527c..8deb596 100644 --- a/app/components/shared/Menu/Menu.jsx +++ b/app/components/shared/Menu/Menu.jsx @@ -130,11 +130,22 @@ class Menu extends React.Component { config: backend.config } + let secondaryText = ( +

+ {backend.description && + {backend.description}
+ } + type: {backend.type} +

+ ) + return ( + {backend.description && + {backend.description}
+ } + type: {backend.type} +

+ ) + return ( this.setState({openNewSecretMountDialog: true})} + onTouchTap={() => this.setState({ openNewSecretMountDialog: true })} > } /> this.setState({openNewAuthMountDialog: true})} + onTouchTap={() => this.setState({ openNewAuthMountDialog: true })} > @@ -258,15 +282,17 @@ class Menu extends React.Component { /> , - + , + ]} /> div > div > div { + font-size: 20px; + font-weight: 250; } .link { @@ -31,4 +31,11 @@ .disabled { display: none; +} + +.mountSecondaryText { + font-size: 12px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } \ No newline at end of file From 72fc11444512e96f144304c9e499b241b000050b Mon Sep 17 00:00:00 2001 From: Matteo Sessa Date: Wed, 26 Apr 2017 15:42:38 +1000 Subject: [PATCH 4/4] Add description text field --- app/components/shared/MountUtils/NewMount.jsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/components/shared/MountUtils/NewMount.jsx b/app/components/shared/MountUtils/NewMount.jsx index a7130e0..eec7688 100644 --- a/app/components/shared/MountUtils/NewMount.jsx +++ b/app/components/shared/MountUtils/NewMount.jsx @@ -122,6 +122,15 @@ export default class NewMountDialog extends Component { onChange={(e) => this.setState({ backendPath: e.target.value }) } /> +
+ this.setState({ backendDescription: e.target.value }) } + /> +
}