diff --git a/ui/src/admin/actions/index.js b/ui/src/admin/actions/index.js index b4ee6a7cf..eb77e26cd 100644 --- a/ui/src/admin/actions/index.js +++ b/ui/src/admin/actions/index.js @@ -6,12 +6,12 @@ import { createRole as createRoleAJAX, deleteUser as deleteUserAJAX, deleteRole as deleteRoleAJAX, - updateRoleUsers as updateRoleUsersAJAX, - updateRolePermissions as updateRolePermissionsAJAX, + updateRole as updateRoleAJAX, + updateUser as updateUserAJAX, } from 'src/admin/apis' + import {killQuery as killQueryProxy} from 'shared/apis/metaQuery' import {publishNotification} from 'src/shared/actions/notifications'; - import {ADMIN_NOTIFICATION_DELAY} from 'shared/constants' export const loadUsers = ({users}) => ({ @@ -191,7 +191,7 @@ export const deleteUserAsync = (user, addFlashMessage) => (dispatch) => { export const updateRoleUsersAsync = (role, users) => async (dispatch) => { try { - await updateRoleUsersAJAX(role.links.self, users) + await updateRoleAJAX(role.links.self, users, role.permissions) dispatch(publishNotification('success', 'Role users updated')) } catch (error) { dispatch(publishNotification('error', `Failed to update role: ${error.data.message}`)) @@ -200,9 +200,27 @@ export const updateRoleUsersAsync = (role, users) => async (dispatch) => { export const updateRolePermissionsAsync = (role, permissions) => async (dispatch) => { try { - await updateRolePermissionsAJAX(role.links.self, permissions) + await updateRoleAJAX(role.links.self, role.users, permissions) dispatch(publishNotification('success', 'Role permissions updated')) } catch (error) { dispatch(publishNotification('error', `Failed to updated role: ${error.data.message}`)) } } + +export const updateUserPermissionsAsync = (user, permissions) => async (dispatch) => { + try { + await updateUserAJAX(user.links.self, user.roles, permissions) + dispatch(publishNotification('success', 'User permissions updated')) + } catch (error) { + dispatch(publishNotification('error', `Failed to updated user: ${error.data.message}`)) + } +} + +export const updateUserRolesAsync = (user, roles) => async (dispatch) => { + try { + await updateUserAJAX(user.links.self, roles, user.permissions) + dispatch(publishNotification('success', 'User roles updated')) + } catch (error) { + dispatch(publishNotification('error', `Failed to updated user: ${error.data.message}`)) + } +} diff --git a/ui/src/admin/apis/index.js b/ui/src/admin/apis/index.js index 788e51e22..09517f837 100644 --- a/ui/src/admin/apis/index.js +++ b/ui/src/admin/apis/index.js @@ -97,26 +97,28 @@ export const deleteUser = async (url, addFlashMessage, username) => { } } -export const updateRoleUsers = async (url, users) => { +export const updateRole = async (url, users, permissions) => { try { await AJAX({ method: 'PATCH', url, data: { users, - }, - }) - } catch (error) { - console.error(error) - } -} - -export const updateRolePermissions = async (url, permissions) => { - try { - await AJAX({ - method: 'PATCH', - url, - data: { + permissions, + }, + }) + } catch (error) { + console.error(error) + } +} + +export const updateUser = async (url, roles, permissions) => { + try { + await AJAX({ + method: 'PATCH', + url, + data: { + roles, permissions, }, }) diff --git a/ui/src/admin/components/AdminTabs.js b/ui/src/admin/components/AdminTabs.js index b8aaae8d6..159d4ba71 100644 --- a/ui/src/admin/components/AdminTabs.js +++ b/ui/src/admin/components/AdminTabs.js @@ -25,6 +25,8 @@ const AdminTabs = ({ onFilterUsers, onUpdateRoleUsers, onUpdateRolePermissions, + onUpdateUserRoles, + onUpdateUserPermissions, }) => { let tabs = [ { @@ -42,6 +44,8 @@ const AdminTabs = ({ onEdit={onEditUser} onDelete={onDeleteUser} onFilter={onFilterUsers} + onUpdatePermissions={onUpdateUserPermissions} + onUpdateRoles={onUpdateUserRoles} /> ), }, @@ -124,6 +128,8 @@ AdminTabs.propTypes = { onUpdateRoleUsers: func.isRequired, onUpdateRolePermissions: func.isRequired, hasRoles: bool.isRequired, + onUpdateUserPermissions: func, + onUpdateUserRoles: func, } export default AdminTabs diff --git a/ui/src/admin/components/UserRow.js b/ui/src/admin/components/UserRow.js index d8aa090e0..6d5e513c3 100644 --- a/ui/src/admin/components/UserRow.js +++ b/ui/src/admin/components/UserRow.js @@ -19,7 +19,17 @@ const UserRow = ({ onSave, onCancel, onDelete, + onUpdatePermissions, + onUpdateRoles, }) => { + const handleUpdatePermissions = (allowed) => { + onUpdatePermissions(user, [{scope: 'all', allowed}]) + } + + const handleUpdateRoles = (roleNames) => { + onUpdateRoles(user, allRoles.filter(r => roleNames.find(rn => rn === r.name))) + } + if (isEditing) { return ( @@ -43,7 +53,7 @@ const UserRow = ({ items={allRoles.map((r) => r.name)} selectedItems={roles ? roles.map((r) => r.name) : []/* TODO remove check when server returns empty list */} label={roles && roles.length ? '' : 'Select Roles'} - onApply={() => '//TODO'} + onApply={handleUpdateRoles} /> : null @@ -55,7 +65,7 @@ const UserRow = ({ items={allPermissions} selectedItems={_.get(permissions, ['0', 'allowed'], [])} label={permissions && permissions.length ? '' : 'Select Permissions'} - onApply={() => '//TODO'} + onApply={handleUpdatePermissions} /> : null } @@ -93,6 +103,8 @@ UserRow.propTypes = { onEdit: func, onSave: func, onDelete: func.isRequired, + onUpdatePermissions: func, + onUpdateRoles: func, } export default UserRow diff --git a/ui/src/admin/components/UsersTable.js b/ui/src/admin/components/UsersTable.js index 584f63019..a8bd24e83 100644 --- a/ui/src/admin/components/UsersTable.js +++ b/ui/src/admin/components/UsersTable.js @@ -16,6 +16,8 @@ const UsersTable = ({ onCancel, onDelete, onFilter, + onUpdatePermissions, + onUpdateRoles, }) => (
@@ -45,6 +47,8 @@ const UsersTable = ({ allRoles={allRoles} hasRoles={hasRoles} allPermissions={permissions} + onUpdatePermissions={onUpdatePermissions} + onUpdateRoles={onUpdateRoles} />) : } @@ -83,6 +87,8 @@ UsersTable.propTypes = { allRoles: arrayOf(shape()), permissions: arrayOf(string), hasRoles: bool.isRequired, + onUpdatePermissions: func, + onUpdateRoles: func, } export default UsersTable diff --git a/ui/src/admin/containers/AdminPage.js b/ui/src/admin/containers/AdminPage.js index fd60a3755..37ff0688f 100644 --- a/ui/src/admin/containers/AdminPage.js +++ b/ui/src/admin/containers/AdminPage.js @@ -17,9 +17,12 @@ import { deleteRoleAsync, updateRoleUsersAsync, updateRolePermissionsAsync, + updateUserPermissionsAsync, + updateUserRolesAsync, filterUsers as filterUsersAction, filterRoles as filterRolesAction, } from 'src/admin/actions' + import AdminTabs from 'src/admin/components/AdminTabs' const isValidUser = (user) => { @@ -47,6 +50,8 @@ class AdminPage extends Component { this.handleDeleteUser = ::this.handleDeleteUser this.handleUpdateRoleUsers = ::this.handleUpdateRoleUsers this.handleUpdateRolePermissions = ::this.handleUpdateRolePermissions + this.handleUpdateUserPermissions = ::this.handleUpdateUserPermissions + this.handleUpdateUserRoles = ::this.handleUpdateUserRoles } componentDidMount() { @@ -124,6 +129,14 @@ class AdminPage extends Component { this.props.updateRolePermissions(role, permissions) } + handleUpdateUserPermissions(user, permissions) { + this.props.updateUserPermissions(user, permissions) + } + + handleUpdateUserRoles(user, roles) { + this.props.updateUserRoles(user, roles) + } + render() { const {users, roles, source, permissions, filterUsers, filterRoles} = this.props const hasRoles = !!source.links.roles @@ -167,6 +180,8 @@ class AdminPage extends Component { onFilterRoles={filterRoles} onUpdateRoleUsers={this.handleUpdateRoleUsers} onUpdateRolePermissions={this.handleUpdateRolePermissions} + onUpdateUserPermissions={this.handleUpdateUserPermissions} + onUpdateUserRoles={this.handleUpdateUserRoles} /> : Loading... } @@ -213,6 +228,8 @@ AdminPage.propTypes = { filterUsers: func, updateRoleUsers: func, updateRolePermissions: func, + updateUserPermissions: func, + updateUserRoles: func, } const mapStateToProps = ({admin: {users, roles, permissions}}) => ({ @@ -239,6 +256,8 @@ const mapDispatchToProps = (dispatch) => ({ filterRoles: bindActionCreators(filterRolesAction, dispatch), updateRoleUsers: bindActionCreators(updateRoleUsersAsync, dispatch), updateRolePermissions: bindActionCreators(updateRolePermissionsAsync, dispatch), + updateUserPermissions: bindActionCreators(updateUserPermissionsAsync, dispatch), + updateUserRoles: bindActionCreators(updateUserRolesAsync, dispatch), }) export default connect(mapStateToProps, mapDispatchToProps)(AdminPage)