fix(ui): sync users' roles after role's users change, sync roles' users after user's roles change

pull/5937/head
Pavel Zavora 2022-06-10 18:45:55 +02:00
parent a51ce4d8a1
commit ff7929b297
2 changed files with 117 additions and 21 deletions

View File

@ -2,6 +2,10 @@ import reject from 'lodash/reject'
import {NEW_DEFAULT_DATABASE, NEW_EMPTY_RP} from 'src/admin/constants'
import uuid from 'uuid'
import {parseDuration, compareDurations} from 'src/utils/influxDuration'
import {
changeNamedCollection,
computeNamedChanges,
} from '../util/changeNamedCollection'
const querySorters = {
'+time'(queries) {
@ -94,26 +98,59 @@ const adminInfluxDB = (state = initialState, action) => {
case 'INFLUXDB_SYNC_USER': {
const {staleUser, syncedUser} = action.payload
const newState = staleUser.links
? {
users: state.users.map(u =>
u.links.self === staleUser.links.self ? {...syncedUser} : u
),
const newUsers = staleUser.links
? state.users.map(u =>
u.links.self === staleUser.links.self ? {...syncedUser} : u
)
: [{...syncedUser}, ...state.users]
const rolesChange = computeNamedChanges(
staleUser.roles || [],
syncedUser.roles || []
)
if (rolesChange) {
// update affected roles to sync this user
const newRoles = state.roles.map(r => {
const change = rolesChange[r.name]
if (change !== undefined) {
return {
...r,
users: changeNamedCollection(r.users, {...syncedUser}, change),
}
}
: {users: [{...syncedUser}, ...state.users]}
return {...state, ...newState}
return r
})
return {...state, users: newUsers, roles: newRoles}
}
return {...state, users: newUsers}
}
case 'INFLUXDB_SYNC_ROLE': {
const {staleRole, syncedRole} = action.payload
const newState = staleRole.links
? {
roles: state.roles.map(r =>
r.links.self === staleRole.links.self ? {...syncedRole} : r
),
const newRoles = staleRole.links
? state.roles.map(r =>
r.links.self === staleRole.links.self ? {...syncedRole} : r
)
: [{...syncedRole}, ...state.roles]
const usersChange = computeNamedChanges(
staleRole.users || [],
syncedRole.users || []
)
if (usersChange) {
// update affected users to sync this role
const newUsers = state.users.map(u => {
const change = usersChange[u.name]
if (change !== undefined) {
return {
...u,
roles: changeNamedCollection(u.roles, {...syncedRole}, change),
}
}
: {roles: [{...syncedRole}, ...state.roles]}
return {...state, ...newState}
return u
})
return {...state, users: newUsers, roles: newRoles}
}
return {...state, roles: newRoles}
}
case 'INFLUXDB_SYNC_DATABASE': {

View File

@ -212,7 +212,7 @@ describe('Admin.InfluxDB.Reducers', () => {
it('it can sync a stale user', () => {
const staleUser = {...u1, roles: []}
state = {users: [u2, staleUser]}
state = {users: [u2, staleUser], roles: []}
const actual = reducer(state, syncUser(staleUser, u1))
const expected = {
@ -222,20 +222,50 @@ describe('Admin.InfluxDB.Reducers', () => {
expect(actual.users).toEqual(expected.users)
})
it('it can sync a new user', () => {
const staleUser = {user: 'new-user', password: 'pwd'}
const staleUser = {name: 'new-user', password: 'pwd'}
state = {users: [u2]}
const actual = reducer(state, syncUser(staleUser, u1))
const syncedUser = {
name: 'new-user',
roles: [],
permissions: [],
links: {self: ''},
}
const actual = reducer(state, syncUser(staleUser, syncedUser))
const expected = {
users: [u1, u2],
users: [syncedUser, u2],
}
expect(actual.users).toEqual(expected.users)
})
it('it can sync a user with changed roles', () => {
const shared = {permissions: [], links: {self: 'a'}}
const staleUser = {...shared, name: 'u1', roles: [{name: 'r1'}]}
state = {
users: [staleUser],
roles: [
{name: 'r1', users: [{name: 'u1'}]},
{name: 'r2', users: []},
],
}
const syncedUser = {...shared, name: 'u1', roles: [{name: 'r2'}]}
const actual = reducer(state, syncUser(staleUser, syncedUser))
const expected = {
users: [syncedUser],
roles: [
{name: 'r1', users: []},
{name: 'r2', users: [syncedUser]},
],
}
expect(actual.users).toEqual(expected.users)
expect(actual.roles).toEqual(expected.roles)
})
it('it can sync a stale role', () => {
const staleRole = {...r1, permissions: []}
state = {roles: [r2, staleRole]}
state = {roles: [r2, staleRole], users: []}
const actual = reducer(state, syncRole(staleRole, r1))
const expected = {
@ -247,14 +277,43 @@ describe('Admin.InfluxDB.Reducers', () => {
it('it can sync a new role', () => {
const staleRole = {name: 'new-role'}
state = {roles: [r2]}
const syncedRole = {
name: 'new-role',
users: [],
permissions: [],
links: {self: ''},
}
const actual = reducer(state, syncRole(staleRole, r1))
const actual = reducer(state, syncRole(staleRole, syncedRole))
const expected = {
roles: [r1, r2],
roles: [syncedRole, r2],
}
expect(actual.roles).toEqual(expected.roles)
})
it('it can sync a role with changed users', () => {
const shared = {permissions: [], links: {self: 'a'}}
const staleRole = {...shared, name: 'r1', users: [{name: 'u1'}]}
state = {
roles: [staleRole],
users: [
{name: 'u1', roles: [{name: 'u1'}]},
{name: 'u2', roles: []},
],
}
const syncedRole = {...shared, name: 'u1', users: [{name: 'u2'}]}
const actual = reducer(state, syncRole(staleRole, syncedRole))
const expected = {
roles: [syncedRole],
users: [
{name: 'u1', roles: []},
{name: 'u2', roles: [syncedRole]},
],
}
expect(actual.roles).toEqual(expected.roles)
expect(actual.users).toEqual(expected.users)
})
it('it can load the roles', () => {
const actual = reducer(state, loadRoles({roles}))