Skip to content
This repository has been archived by the owner on Mar 27, 2019. It is now read-only.

Commit

Permalink
Add ItemList Class (#175)
Browse files Browse the repository at this point in the history
* Introduce ItemList obj

* Upgrade base node image

* Add ItemList to AWS, clean up

* Add ItemList to AWSEc2, clean up

* Fix deleteobject logic

* Fix delete for AWS

* Fix delete for awsec2

* Add max items per page option

* Fix bug that randomly sets page

* Bug fixes + itemlist progress

* More bug fixes

* Cleanup and rename policypicker to itempicker

* Add ItemList to Radius

* Add ItemList to UserPass

* Refactor Secrets to use ItemList

* Fix styling

* Remove case insensitivity

* Clean up directory separator

* Fix delete regression

* Cleanup itemUri
  • Loading branch information
djenriquez authored Aug 29, 2017
1 parent fc7caa5 commit 0539041
Show file tree
Hide file tree
Showing 17 changed files with 1,696 additions and 1,740 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:8.1.4-alpine
FROM node:8.4.0-alpine

MAINTAINER Vault-UI Contributors

Expand Down
83 changes: 23 additions & 60 deletions app/components/Authentication/AppRole/AppRole.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,22 @@ import React, { PropTypes } from 'react';
// Material UI
import Dialog from 'material-ui/Dialog';
import TextField from 'material-ui/TextField';
import IconButton from 'material-ui/IconButton';
import { Tabs, Tab } from 'material-ui/Tabs';
import Paper from 'material-ui/Paper';
import { List, ListItem } from 'material-ui/List';
import { List } from 'material-ui/List';
import FlatButton from 'material-ui/FlatButton';
import { Toolbar, ToolbarGroup } from 'material-ui/Toolbar';
import Subheader from 'material-ui/Subheader';
import ActionAccountBox from 'material-ui/svg-icons/action/account-box';
import ActionDelete from 'material-ui/svg-icons/action/delete';
import ActionDeleteForever from 'material-ui/svg-icons/action/delete-forever';
import Avatar from 'material-ui/Avatar';
import Toggle from 'material-ui/Toggle';
import { red500 } from 'material-ui/styles/colors.js';

// Styles
import styles from './approle.css';
import sharedStyles from '../../shared/styles.css';
// Misc
import _ from 'lodash';
import update from 'immutability-helper';
import PolicyPicker from '../../shared/PolicyPicker/PolicyPicker.jsx'
import VaultObjectDeleter from '../../shared/DeleteObject/DeleteObject.jsx'
import ItemPicker from '../../shared/ItemPicker/ItemPicker.jsx';
import ItemList from '../../shared/ItemList/ItemList.jsx';
import { callVaultApi, tokenHasCapabilities, history } from '../../shared/VaultUtils.jsx';

function snackBarMessage(message) {
Expand Down Expand Up @@ -221,7 +215,6 @@ export default class AppRoleAuthBackend extends React.Component {

updateRoleId() {
if (this.state.itemConfig.role_id) {
console.log()
tokenHasCapabilities(['update'], `${this.baseVaultPath}/role/${this.state.selectedItemName}/role-id`)
.then(() => {
callVaultApi('post', `${this.baseVaultPath}/role/${this.state.selectedItemName}/role-id`, null, { role_id: this.state.itemConfig.role_id })
Expand Down Expand Up @@ -388,7 +381,7 @@ export default class AppRoleAuthBackend extends React.Component {
{this.state.openEditItemDialog && renderEditFields()}
{renderConstantFields()}
<Subheader>Assigned Groups</Subheader>
<PolicyPicker
<ItemPicker
key='policies'
type={`approle`}
item={`policies`}
Expand Down Expand Up @@ -476,54 +469,10 @@ export default class AppRoleAuthBackend extends React.Component {
);
};

let renderListItems = () => {
let list = this.state.itemList;
return _.map(list, (item) => {
let avatar = (<Avatar icon={<ActionAccountBox />} />);
let action = (
<IconButton
tooltip='Delete'
onTouchTap={() => this.setState({ deleteUserPath: `${this.baseVaultPath}/role/${item}` })}
>
{window.localStorage.getItem('showDeleteModal') === 'false' ? <ActionDeleteForever color={red500} /> : <ActionDelete color={red500} />}
</IconButton>
);

let obj = (
<ListItem
key={item}
primaryText={item}
insetChildren={true}
leftAvatar={avatar}
rightIconButton={action}
onTouchTap={() => {
this.setState({ itemConfig: _.clone(this.itemConfigSchema), selectedItemName: `${item}` });
tokenHasCapabilities(['read'], `${this.baseVaultPath}/role/${item}`).then(() => {
history.push(`${this.baseUrl}role/${item}`);
}).catch(() => {
snackBarMessage(new Error('Access denied'));
})

}}
/>
)
return obj;
});
};

return (
<div>
{this.state.openNewItemDialog && renderNewDialog()}
{this.state.openEditItemDialog && renderEditDialog()}
<VaultObjectDeleter
path={this.state.deleteUserPath}
onReceiveResponse={() => {
snackBarMessage(`Object '${this.state.deleteUserPath}' deleted`)
this.setState({ deleteUserPath: '' })
this.listAppRoles();
}}
onReceiveError={(err) => snackBarMessage(err)}
/>
<Tabs
onChange={(e) => {
history.push(`${this.baseUrl}${e}/`);
Expand All @@ -539,8 +488,8 @@ export default class AppRoleAuthBackend extends React.Component {
>
<Paper className={sharedStyles.TabInfoSection} zDepth={0}>
Here you can add, edit or delete AppRoles with this backend
</Paper>
<Paper className={sharedStyles.TabContentSection} zDepth={0}>
</Paper>
<Paper label='toolbar' className={sharedStyles.TabContentSection} zDepth={0}>
<Toolbar>
<ToolbarGroup firstChild={true}>
<FlatButton
Expand All @@ -555,9 +504,23 @@ export default class AppRoleAuthBackend extends React.Component {
/>
</ToolbarGroup>
</Toolbar>
<List className={sharedStyles.listStyle}>
{renderListItems()}
</List>
<ItemList
itemList={this.state.itemList}
itemUri={`${this.baseVaultPath}/role`}
maxItemsPerPage={25}
onDeleteTap={(deletedItem) => {
snackBarMessage(`Object '${deletedItem}' deleted`)
this.listAppRoles();
}}
onTouchTap={(item) => {
this.setState({ itemConfig: _.clone(this.itemConfigSchema), selectedItemName: `${item}` });
tokenHasCapabilities(['read'], `${this.baseVaultPath}/role/${item}`).then(() => {
history.push(`${this.baseUrl}role/${item}`);
}).catch(() => {
snackBarMessage(new Error('Access denied'));
})
}}
/>
</Paper>
</Tab>
</Tabs>
Expand Down
103 changes: 25 additions & 78 deletions app/components/Authentication/Aws/Aws.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,24 @@ import React, { PropTypes } from 'react';
// Material UI
import Dialog from 'material-ui/Dialog';
import TextField from 'material-ui/TextField';
import IconButton from 'material-ui/IconButton';
import { Tabs, Tab } from 'material-ui/Tabs';
import Paper from 'material-ui/Paper';
import { List, ListItem } from 'material-ui/List';
import FlatButton from 'material-ui/FlatButton';
import { Toolbar, ToolbarGroup } from 'material-ui/Toolbar';
import Subheader from 'material-ui/Subheader';
import ActionAccountBox from 'material-ui/svg-icons/action/account-box';
import ActionDelete from 'material-ui/svg-icons/action/delete';
import ActionDeleteForever from 'material-ui/svg-icons/action/delete-forever';
import Toggle from 'material-ui/Toggle';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
// Styles
import styles from './aws.css';
import sharedStyles from '../../shared/styles.css';
import { red500 } from 'material-ui/styles/colors.js';
import { callVaultApi, tokenHasCapabilities, history } from '../../shared/VaultUtils.jsx';
// Misc
import _ from 'lodash';
import update from 'immutability-helper';
import Avatar from 'material-ui/Avatar';
import PolicyPicker from '../../shared/PolicyPicker/PolicyPicker.jsx'
import VaultObjectDeleter from '../../shared/DeleteObject/DeleteObject.jsx'
import ItemPicker from '../../shared/ItemPicker/ItemPicker.jsx';
import ItemList from '../../shared/ItemList/ItemList.jsx';

function snackBarMessage(message) {
document.dispatchEvent(new CustomEvent('snackbar', { detail: { message: message } }));
Expand Down Expand Up @@ -82,15 +76,13 @@ export default class AwsAuthBackend extends React.Component {
baseUrl: `/auth/aws/${this.props.params.namespace}/`,
baseVaultPath: `auth/${this.props.params.namespace}`,
ec2Roles: [],
filteredEc2RoleList: [],
configObj: this.ec2ConfigSchema,
newConfigObj: this.ec2ConfigSchema,
newRoleConfig: this.roleConfigSchema,
selectedRoleId: '',
newSecretBtnDisabled: false,
openNewRoleDialog: false,
openEditRoleDialog: false,
deleteUserPath: '',
selectedTab: 'roles',
isBackendConfigured: false
};
Expand All @@ -112,13 +104,13 @@ export default class AwsAuthBackend extends React.Component {
callVaultApi('get', `${this.state.baseVaultPath}/role`, { list: true }, null)
.then((resp) => {
let roles = _.get(resp, 'data.data.keys', []);
this.setState({ ec2Roles: _.valuesIn(roles), filteredEc2RoleList: _.valuesIn(roles) });
this.setState({ ec2Roles: _.valuesIn(roles) });
})
.catch((error) => {
if (error.response.status !== 404) {
snackBarMessage(error);
} else {
this.setState({ ec2Roles: [], filteredEc2RoleList: [] });
this.setState({ ec2Roles: [] });
}
});
})
Expand Down Expand Up @@ -270,7 +262,6 @@ export default class AwsAuthBackend extends React.Component {
baseUrl: `/auth/aws/${nextProps.params.namespace}/`,
baseVaultPath: `auth/${nextProps.params.namespace}`,
ec2Roles: [],
filteredEc2RoleList: [],
selectedRoleId: '',
newConfigObj: this.roleConfigSchema,
configObj: this.ec2ConfigSchema,
Expand All @@ -283,7 +274,7 @@ export default class AwsAuthBackend extends React.Component {
}

render() {

let renderFields = () => {
let renderAuthTypes = () => {
return this.authTypes.map((authType) => (
Expand Down Expand Up @@ -335,7 +326,7 @@ export default class AwsAuthBackend extends React.Component {
return (
[
<Subheader>Assigned Policies</Subheader>,
<PolicyPicker
<ItemPicker
height='200px'
selectedPolicies={this.state.newRoleConfig.policies}
onSelectedChange={(newPolicies) => {
Expand Down Expand Up @@ -606,41 +597,6 @@ export default class AwsAuthBackend extends React.Component {
)
}

let renderRoleListItems = () => {
return _.map(this.state.filteredEc2RoleList, (role) => {
let avatar = (<Avatar icon={<ActionAccountBox />} />);
let action = (
<IconButton
tooltip='Delete'
onTouchTap={() => this.setState({ deleteUserPath: `${this.state.baseVaultPath}/role/${role}` })}
>
{window.localStorage.getItem('showDeleteModal') === 'false' ? <ActionDeleteForever color={red500} /> : <ActionDelete color={red500} />}
</IconButton>
);

let item = (
<ListItem
key={role}
primaryText={role}
insetChildren={true}
leftAvatar={avatar}
rightIconButton={action}
onTouchTap={() => {
tokenHasCapabilities(['read'], `${this.state.baseVaultPath}/role/${role}`)
.then(() => {
this.setState({ selectedRoleId: role });
history.push(`${this.state.baseUrl}roles/${role}`);
}).catch(() => {
snackBarMessage(new Error('Access denied'));
})

}}
/>
)
return item;
});
}

let renderNewRoleDialog = () => {
let validateAndSubmit = () => {
if (this.state.selectedRoleId === '') {
Expand Down Expand Up @@ -725,15 +681,6 @@ export default class AwsAuthBackend extends React.Component {
<div>
{this.state.openEditRoleDialog && renderEditRoleDialog()}
{this.state.openNewRoleDialog && renderNewRoleDialog()}
<VaultObjectDeleter
path={this.state.deleteUserPath}
onReceiveResponse={() => {
snackBarMessage(`Object '${this.state.deleteUserPath}' deleted`)
this.setState({ deleteUserPath: '' })
this.listEc2Roles();
}}
onReceiveError={(err) => snackBarMessage(err)}
/>
<Tabs
onChange={(e) => {
history.push(`${this.state.baseUrl}${e}/`);
Expand Down Expand Up @@ -765,26 +712,26 @@ export default class AwsAuthBackend extends React.Component {
}}
/>
</ToolbarGroup>
<ToolbarGroup lastChild={true}>
<TextField
floatingLabelFixed={true}
floatingLabelText="Filter"
hintText="Filter list items"
onChange={(e, v) => {
let filtered = _.filter(this.state.ec2Roles, (item) => {
return item.toLowerCase().includes(v.toLowerCase());
});
if (filtered.length > 0)
this.setState({
filteredEc2RoleList: filtered
});
}}
/>
</ToolbarGroup>
</Toolbar>
<List className={sharedStyles.listStyle}>
{renderRoleListItems()}
</List>
<ItemList
itemList={this.state.ec2Roles}
itemUri={`${this.state.baseVaultPath}/role`}
maxItemsPerPage={25}
onDeleteTap={(deletedItem) => {
snackBarMessage(`Role '${deletedItem}' deleted`)
this.listEc2Roles();
}}
onTouchTap={(role) => {
tokenHasCapabilities(['read'], `${this.state.baseVaultPath}/role/${role}`)
.then(() => {
this.setState({ selectedRoleId: role });
history.push(`${this.state.baseUrl}roles/${role}`);
}).catch(() => {
snackBarMessage(new Error('Access denied'));
})

}}
/>
</Paper>
</Tab>
<Tab
Expand Down
Loading

0 comments on commit 0539041

Please sign in to comment.