feat(ui): create DB user with enhanced validations
parent
dc16f3387b
commit
4becfd9404
|
@ -1,7 +1,7 @@
|
|||
import React, {useCallback, useMemo, useState} from 'react'
|
||||
import {connect, ResolveThunks} from 'react-redux'
|
||||
import {withSource} from 'src/CheckSources'
|
||||
import {Source} from 'src/types'
|
||||
import {Source, NotificationAction} from 'src/types'
|
||||
import {UserRole, User, Database} from 'src/types/influxAdmin'
|
||||
import {notify as notifyAction} from 'src/shared/actions/notifications'
|
||||
import {
|
||||
|
@ -11,7 +11,11 @@ import {
|
|||
createUserAsync,
|
||||
filterUsers as filterUsersAction,
|
||||
} from 'src/admin/actions/influxdb'
|
||||
import {notifyDBUserNamePasswordInvalid} from 'src/shared/copy/notifications'
|
||||
import {
|
||||
notifyDBUserNameInvalid,
|
||||
notifyDBPasswordInvalid,
|
||||
notifyDBUserNameExists,
|
||||
} from 'src/shared/copy/notifications'
|
||||
import AdminInfluxDBTabbedPage, {
|
||||
hasRoleManagement,
|
||||
isConnectedToLDAP,
|
||||
|
@ -25,10 +29,23 @@ import MultiSelectDropdown from 'src/reusable_ui/components/dropdowns/MultiSelec
|
|||
import {ComponentSize, SlideToggle} from 'src/reusable_ui'
|
||||
import computeEffectiveDBPermissions from './util/computeEffectiveDBPermissions'
|
||||
import allOrParticularSelection from './util/allOrParticularSelection'
|
||||
import CreateUserDialog from '../../components/influxdb/CreateUserDialog'
|
||||
import {withRouter, WithRouterProps} from 'react-router'
|
||||
|
||||
const isValidUser = (user: User) => {
|
||||
const minLen = 3
|
||||
return user.name.length >= minLen && user.password.length >= minLen
|
||||
const minLen = 3
|
||||
const validateUser = (
|
||||
user: Pick<User, 'name' | 'password'>,
|
||||
notify: NotificationAction
|
||||
) => {
|
||||
if (user.name.length < minLen) {
|
||||
notify(notifyDBUserNameInvalid())
|
||||
return false
|
||||
}
|
||||
if (user.password.length < minLen) {
|
||||
notify(notifyDBPasswordInvalid())
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const mapStateToProps = ({adminInfluxDB: {databases, users, roles}}) => ({
|
||||
|
@ -56,9 +73,10 @@ interface ConnectedProps {
|
|||
}
|
||||
|
||||
type ReduxDispatchProps = ResolveThunks<typeof mapDispatchToProps>
|
||||
type Props = OwnProps & ConnectedProps & ReduxDispatchProps
|
||||
type Props = WithRouterProps & OwnProps & ConnectedProps & ReduxDispatchProps
|
||||
|
||||
const UsersPage = ({
|
||||
router,
|
||||
source,
|
||||
databases,
|
||||
users,
|
||||
|
@ -66,14 +84,12 @@ const UsersPage = ({
|
|||
notify,
|
||||
createUser,
|
||||
filterUsers,
|
||||
addUser,
|
||||
removeUser,
|
||||
editUser,
|
||||
}: Props) => {
|
||||
const handleSaveUser = useCallback(
|
||||
async (user: User) => {
|
||||
if (!isValidUser(user)) {
|
||||
notify(notifyDBUserNamePasswordInvalid())
|
||||
if (!validateUser(user, notify)) {
|
||||
return
|
||||
}
|
||||
if (user.isNew) {
|
||||
|
@ -82,8 +98,6 @@ const UsersPage = ({
|
|||
},
|
||||
[notify, source]
|
||||
)
|
||||
const isEditing = useMemo(() => users.some(u => u.isEditing), [users])
|
||||
|
||||
const [isEnterprise, usersPage] = useMemo(
|
||||
() => [
|
||||
hasRoleManagement(source),
|
||||
|
@ -130,8 +144,34 @@ const UsersPage = ({
|
|||
showRoles,
|
||||
setShowRoles,
|
||||
])
|
||||
|
||||
const [createVisible, setCreateVisible] = useState(false)
|
||||
const createNew = useCallback(
|
||||
async (user: {name: string; password: string}) => {
|
||||
if (users.some(x => x.name === user.name)) {
|
||||
notify(notifyDBUserNameExists())
|
||||
return
|
||||
}
|
||||
if (!validateUser(user, notify)) {
|
||||
return
|
||||
}
|
||||
await createUser(source.links.users, user)
|
||||
router.push(
|
||||
`/sources/${source.id}/admin-influxdb/users/${encodeURIComponent(
|
||||
user.name
|
||||
)}`
|
||||
)
|
||||
},
|
||||
[users, router, source, notify]
|
||||
)
|
||||
|
||||
return (
|
||||
<AdminInfluxDBTabbedPage activeTab="users" source={source}>
|
||||
<CreateUserDialog
|
||||
visible={createVisible}
|
||||
setVisible={setCreateVisible}
|
||||
create={createNew}
|
||||
/>
|
||||
<div className="panel panel-solid influxdb-admin">
|
||||
<div className="panel-heading">
|
||||
<div className="search-widget">
|
||||
|
@ -186,8 +226,7 @@ const UsersPage = ({
|
|||
<div className="panel-heading--right">
|
||||
<button
|
||||
className="btn btn-sm btn-primary"
|
||||
disabled={isEditing}
|
||||
onClick={addUser}
|
||||
onClick={() => setCreateVisible(true)}
|
||||
data-test="create-user--button"
|
||||
>
|
||||
<span className="icon plus" /> Create User
|
||||
|
@ -265,5 +304,5 @@ const UsersPageAvailable = (props: Props) => {
|
|||
}
|
||||
|
||||
export default withSource(
|
||||
connect(mapStateToProps, mapDispatchToProps)(UsersPageAvailable)
|
||||
withRouter(connect(mapStateToProps, mapDispatchToProps)(UsersPageAvailable))
|
||||
)
|
||||
|
|
|
@ -419,9 +419,19 @@ export const notifyDatabaseDeleteConfirmationRequired = (
|
|||
message: `Type "DELETE ${databaseName}" to confirm. This action cannot be undone.`,
|
||||
})
|
||||
|
||||
export const notifyDBUserNamePasswordInvalid = (): Notification => ({
|
||||
export const notifyDBUserNameInvalid = (): Notification => ({
|
||||
...defaultErrorNotification,
|
||||
message: 'Username and/or Password too short.',
|
||||
message: 'User name is too short.',
|
||||
})
|
||||
|
||||
export const notifyDBPasswordInvalid = (): Notification => ({
|
||||
...defaultErrorNotification,
|
||||
message: 'Password is too short.',
|
||||
})
|
||||
|
||||
export const notifyDBUserNameExists = (): Notification => ({
|
||||
...defaultErrorNotification,
|
||||
message: 'User name already exists.',
|
||||
})
|
||||
|
||||
export const notifyRoleNameInvalid = (): Notification => ({
|
||||
|
|
Loading…
Reference in New Issue