diff --git a/ui/src/admin/containers/influxdb/AdminInfluxDBPage.tsx b/ui/src/admin/containers/influxdb/AdminInfluxDBPage.tsx index a9e8ba42b..813d79ea0 100644 --- a/ui/src/admin/containers/influxdb/AdminInfluxDBPage.tsx +++ b/ui/src/admin/containers/influxdb/AdminInfluxDBPage.tsx @@ -2,22 +2,13 @@ import React, {PureComponent} from 'react' import {connect} from 'react-redux' import {Action, bindActionCreators, Dispatch} from 'redux' import { - addRole, - editRole, - deleteRole, loadUsersAsync, loadRolesAsync, - createRoleAsync, - deleteRoleAsync, loadPermissionsAsync, - updateRoleUsersAsync, - updateRolePermissionsAsync, - filterRoles as filterRolesAction, loadDBsAndRPsAsync, } from 'src/admin/actions/influxdb' import PageSpinner from 'src/shared/components/PageSpinner' -import RolesTable from 'src/admin/components/RolesTable' import QueriesPage from './QueriesPage' import DatabaseManagerPage from './DatabaseManagerPage' import {Page} from 'src/reusable_ui' @@ -25,50 +16,20 @@ import SubSections from 'src/shared/components/SubSections' import {ErrorHandling} from 'src/shared/decorators/errors' import {notify as notifyAction} from 'src/shared/actions/notifications' -import { - Source, - User as InfluxDBUser, - Role as InfluxDBRole, - Permission, - RemoteDataState, - SourceAuthenticationMethod, -} from 'src/types' -import {InfluxDBPermissions} from 'src/types/auth' +import {Source, RemoteDataState, SourceAuthenticationMethod} from 'src/types' import {NotificationAction} from 'src/types/notifications' -import {notifyRoleNameInvalid} from 'src/shared/copy/notifications' import UsersPage from './UsersPage' +import RolesPage from './RolesPage' -const isValidRole = role => { - const minLen = 3 - return role.name.length >= minLen -} - -interface User extends InfluxDBUser { - isEditing: boolean -} - -interface Role extends InfluxDBRole { - isEditing: boolean -} - +type LoaderFunc = (url: string) => Promise interface Props { source: Source - users: User[] - roles: Role[] - permissions: Permission[] - loadUsers: (url: string) => Promise - loadRoles: (url: string) => Promise - loadPermissions: (url: string) => Promise - loadDBsAndRPs: (url: string) => Promise - addRole: () => void - removeRole: (role: Role) => void - editRole: (role: Role, updates: Partial) => void - createRole: (url: string, role: Role) => void - deleteRole: (role: Role) => void - filterRoles: () => void - updateRoleUsers: (role: Role, users: User[]) => void - updateRolePermissions: (role: Role, permissions: Permission[]) => void + + loadUsers: LoaderFunc + loadRoles: LoaderFunc + loadPermissions: LoaderFunc + loadDBsAndRPs: LoaderFunc notify: NotificationAction params: { tab: string @@ -83,7 +44,7 @@ interface State { @ErrorHandling export class AdminInfluxDBPage extends PureComponent { - constructor(props) { + constructor(props: Props) { super(props) this.state = { loading: RemoteDataState.NotStarted, @@ -183,50 +144,6 @@ export class AdminInfluxDBPage extends PureComponent { ) } - private handleClickCreate = () => () => { - this.props.addRole() - } - - private handleEditRole = (role, updates) => { - this.props.editRole(role, updates) - } - - // eslint-disable-next-line @typescript-eslint/require-await - private handleSaveRole = async role => { - const {notify} = this.props - if (!isValidRole(role)) { - notify(notifyRoleNameInvalid()) - return - } - if (role.isNew) { - this.props.createRole(this.props.source.links.roles, role) - } else { - // TODO update role - } - } - - private handleCancelEditRole = role => { - this.props.removeRole(role) - } - - private handleDeleteRole = role => { - this.props.deleteRole(role) - } - - private handleUpdateRoleUsers = (role, users) => { - this.props.updateRoleUsers(role, users) - } - - private handleUpdateRolePermissions = (role, permissions) => { - this.props.updateRolePermissions(role, permissions) - } - - private get allowed(): InfluxDBPermissions[] { - const {permissions} = this.props - const globalPermissions = permissions.find(p => p.scope === 'all') - return globalPermissions ? globalPermissions.allowed : [] - } - private get hasRoles(): boolean { return !!this.props.source.links.roles } @@ -237,7 +154,7 @@ export class AdminInfluxDBPage extends PureComponent { } private get adminSubSections() { - const {users, roles, source, filterRoles} = this.props + const {source} = this.props return [ { url: 'databases', @@ -255,22 +172,7 @@ export class AdminInfluxDBPage extends PureComponent { url: 'roles', name: 'Roles', enabled: this.hasRoles && !this.isLDAP, - component: ( - r.isEditing)} - onClickCreate={this.handleClickCreate} - onEdit={this.handleEditRole} - onSave={this.handleSaveRole} - onCancel={this.handleCancelEditRole} - onDelete={this.handleDeleteRole} - onFilter={filterRoles} - onUpdateRoleUsers={this.handleUpdateRoleUsers} - onUpdateRolePermissions={this.handleUpdateRolePermissions} - /> - ), + component: , }, { url: 'queries', @@ -282,29 +184,24 @@ export class AdminInfluxDBPage extends PureComponent { } } -const mapStateToProps = ({adminInfluxDB: {users, roles, permissions}}) => ({ - users, - roles, - permissions, -}) - const mapDispatchToProps = (dispatch: Dispatch) => ({ - loadUsers: bindActionCreators(loadUsersAsync, dispatch), - loadRoles: bindActionCreators(loadRolesAsync, dispatch), - loadPermissions: bindActionCreators(loadPermissionsAsync, dispatch), - loadDBsAndRPs: bindActionCreators(loadDBsAndRPsAsync, dispatch), - addRole: bindActionCreators(addRole, dispatch), - removeRole: bindActionCreators(deleteRole, dispatch), - editRole: bindActionCreators(editRole, dispatch), - createRole: bindActionCreators(createRoleAsync, dispatch), - deleteRole: bindActionCreators(deleteRoleAsync, dispatch), - filterRoles: bindActionCreators(filterRolesAction, dispatch), - updateRoleUsers: bindActionCreators(updateRoleUsersAsync, dispatch), - updateRolePermissions: bindActionCreators( - updateRolePermissionsAsync, + loadUsers: bindActionCreators( + loadUsersAsync, + dispatch + ), + loadRoles: bindActionCreators( + loadRolesAsync, + dispatch + ), + loadPermissions: bindActionCreators( + loadPermissionsAsync, + dispatch + ), + loadDBsAndRPs: bindActionCreators( + loadDBsAndRPsAsync, dispatch ), notify: bindActionCreators(notifyAction, dispatch), }) -export default connect(mapStateToProps, mapDispatchToProps)(AdminInfluxDBPage) +export default connect(null, mapDispatchToProps)(AdminInfluxDBPage) diff --git a/ui/src/admin/containers/influxdb/RolesPage.tsx b/ui/src/admin/containers/influxdb/RolesPage.tsx new file mode 100644 index 000000000..4882baa9f --- /dev/null +++ b/ui/src/admin/containers/influxdb/RolesPage.tsx @@ -0,0 +1,152 @@ +import React from 'react' +import {Component} from 'react' +import {connect} from 'react-redux' +import {Action, bindActionCreators, Dispatch} from 'redux' +import {Source, SourceAuthenticationMethod} from 'src/types' +import {InfluxDBPermissions, Permission, Role, User} from 'src/types/auth' +import {notify as notifyAction} from 'src/shared/actions/notifications' +import {NotificationAction} from 'src/types/notifications' +import { + addRole, + editRole, + deleteRole, + createRoleAsync, + deleteRoleAsync, + updateRoleUsersAsync, + updateRolePermissionsAsync, + filterRoles as filterRolesAction, +} from 'src/admin/actions/influxdb' +import {notifyRoleNameInvalid} from 'src/shared/copy/notifications' +import RolesTable from 'src/admin/components/RolesTable' + +const isValidRole = role => { + const minLen = 3 + return role.name.length >= minLen +} + +interface Props { + source: Source + + users: User[] + roles: Role[] + permissions: Permission[] + + addRole: () => void + removeRole: (role: Role) => void + editRole: (role: Role, updates: Partial) => void + createRole: (url: string, role: Role) => void + deleteRole: (role: Role) => void + filterRoles: () => void + updateRoleUsers: (role: Role, users: User[]) => void + updateRolePermissions: (role: Role, permissions: Permission[]) => void + + notify: NotificationAction +} + +class RolesPage extends Component { + private get hasRoles(): boolean { + return !!this.props.source.links.roles + } + + private get isLDAP(): boolean { + const {source} = this.props + return source.authentication === SourceAuthenticationMethod.LDAP + } + + private get allowed(): InfluxDBPermissions[] { + const {permissions} = this.props + const globalPermissions = permissions.find(p => p.scope === 'all') + return globalPermissions ? globalPermissions.allowed : [] + } + + private handleClickCreate = () => () => { + this.props.addRole() + } + private handleEditRole = (role, updates) => { + this.props.editRole(role, updates) + } + private handleSaveRole = async role => { + const {notify} = this.props + if (!isValidRole(role)) { + notify(notifyRoleNameInvalid()) + return + } + if (role.isNew) { + this.props.createRole(this.props.source.links.roles, role) + } + } + + private handleCancelEditRole = role => { + this.props.removeRole(role) + } + + private handleDeleteRole = role => { + this.props.deleteRole(role) + } + + private handleUpdateRoleUsers = (role, users) => { + this.props.updateRoleUsers(role, users) + } + + private handleUpdateRolePermissions = (role, permissions) => { + this.props.updateRolePermissions(role, permissions) + } + + public render() { + if (!this.hasRoles) { + return ( +
+ Roles managemebnt is not available for the currently selected InfluxDB + Connection. +
+ ) + } + if (this.isLDAP) { + return ( +
+ Users are managed via LDAP, roles management not available. +
+ ) + } + const {users, roles, filterRoles} = this.props + return ( + r.isEditing)} + onClickCreate={this.handleClickCreate} + onEdit={this.handleEditRole} + onSave={this.handleSaveRole} + onCancel={this.handleCancelEditRole} + onDelete={this.handleDeleteRole} + onFilter={filterRoles} + onUpdateRoleUsers={this.handleUpdateRoleUsers} + onUpdateRolePermissions={this.handleUpdateRolePermissions} + /> + ) + } +} + +const mapStateToProps = ({adminInfluxDB: {users, roles, permissions}}) => ({ + users, + roles, + permissions, +}) + +const mapDispatchToProps = (dispatch: Dispatch) => ({ + addRole: bindActionCreators(addRole, dispatch), + removeRole: bindActionCreators(deleteRole, dispatch), + editRole: bindActionCreators(editRole, dispatch), + createRole: bindActionCreators(createRoleAsync, dispatch), + deleteRole: bindActionCreators(deleteRoleAsync, dispatch), + filterRoles: bindActionCreators(filterRolesAction, dispatch), + updateRoleUsers: bindActionCreators(updateRoleUsersAsync, dispatch), + updateRolePermissions: bindActionCreators( + updateRolePermissionsAsync, + dispatch + ), + notify: bindActionCreators(notifyAction, dispatch), +}) + +export default connect(mapStateToProps, mapDispatchToProps)(RolesPage)