mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix: hide New user button if no permission (#1794)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { fireEvent, screen, waitFor, within } from "@testing-library/react"
|
||||
import { rest } from "msw"
|
||||
import React from "react"
|
||||
import * as API from "../../api/api"
|
||||
import { Role } from "../../api/typesGenerated"
|
||||
@@ -7,8 +8,11 @@ import { Language as ResetPasswordDialogLanguage } from "../../components/ResetP
|
||||
import { Language as RoleSelectLanguage } from "../../components/RoleSelect/RoleSelect"
|
||||
import { Language as UsersTableLanguage } from "../../components/UsersTable/UsersTable"
|
||||
import { MockAuditorRole, MockUser, MockUser2, render } from "../../testHelpers/renderHelpers"
|
||||
import { server } from "../../testHelpers/server"
|
||||
import { permissionsToCheck } from "../../xServices/auth/authXService"
|
||||
import { Language as usersXServiceLanguage } from "../../xServices/users/usersXService"
|
||||
import { Language as UsersPageLanguage, UsersPage } from "./UsersPage"
|
||||
import { Language as UsersViewLanguage } from "./UsersPageView"
|
||||
|
||||
const suspendUser = async (setupActionSpies: () => void) => {
|
||||
// Get the first user in the table
|
||||
@@ -99,6 +103,32 @@ describe("Users Page", () => {
|
||||
expect(users.length).toEqual(2)
|
||||
})
|
||||
|
||||
it("shows 'New user' button to an authorized user", () => {
|
||||
render(<UsersPage />)
|
||||
const newUserButton = screen.queryByText(UsersViewLanguage.newUserButton)
|
||||
expect(newUserButton).toBeDefined()
|
||||
})
|
||||
|
||||
it("does not show 'New user' button to unauthorized user", () => {
|
||||
server.use(
|
||||
rest.post("/api/v2/users/:userId/authorization", async (req, res, ctx) => {
|
||||
const permissions = Object.keys(permissionsToCheck)
|
||||
const response = permissions.reduce((obj, permission) => {
|
||||
return {
|
||||
...obj,
|
||||
[permission]: true,
|
||||
createUser: false,
|
||||
}
|
||||
}, {})
|
||||
|
||||
return res(ctx.status(200), ctx.json(response))
|
||||
}),
|
||||
)
|
||||
render(<UsersPage />)
|
||||
const newUserButton = screen.queryByText(UsersViewLanguage.newUserButton)
|
||||
expect(newUserButton).toBeNull()
|
||||
})
|
||||
|
||||
describe("suspend user", () => {
|
||||
describe("when it is success", () => {
|
||||
it("shows a success message and refresh the page", async () => {
|
||||
|
||||
@@ -23,6 +23,7 @@ export const UsersPage: React.FC = () => {
|
||||
const userToResetPassword = users?.find((u) => u.id === userIdToResetPassword)
|
||||
const permissions = useSelector(xServices.authXService, selectPermissions)
|
||||
const canEditUsers = permissions && permissions.updateUsers
|
||||
const canCreateUser = permissions && permissions.createUser
|
||||
const { roles } = rolesState.context
|
||||
// Is loading if
|
||||
// - permissions are not loaded or
|
||||
@@ -70,6 +71,7 @@ export const UsersPage: React.FC = () => {
|
||||
isUpdatingUserRoles={usersState.matches("updatingUserRoles")}
|
||||
isLoading={isLoading}
|
||||
canEditUsers={canEditUsers}
|
||||
canCreateUser={canCreateUser}
|
||||
/>
|
||||
|
||||
<ConfirmDialog
|
||||
|
||||
@@ -10,13 +10,16 @@ export default {
|
||||
|
||||
const Template: Story<UsersPageViewProps> = (args) => <UsersPageView {...args} />
|
||||
|
||||
export const Ready = Template.bind({})
|
||||
Ready.args = {
|
||||
export const Admin = Template.bind({})
|
||||
Admin.args = {
|
||||
users: [MockUser, MockUser2],
|
||||
roles: MockSiteRoles,
|
||||
canCreateUser: true,
|
||||
canEditUsers: true,
|
||||
}
|
||||
|
||||
export const Member = Template.bind({})
|
||||
Member.args = { ...Admin.args, canCreateUser: false, canEditUsers: false }
|
||||
|
||||
export const Empty = Template.bind({})
|
||||
Empty.args = {
|
||||
users: [],
|
||||
roles: MockSiteRoles,
|
||||
}
|
||||
Empty.args = { ...Admin.args, users: [] }
|
||||
|
||||
@@ -17,6 +17,7 @@ export interface UsersPageViewProps {
|
||||
error?: unknown
|
||||
isUpdatingUserRoles?: boolean
|
||||
canEditUsers?: boolean
|
||||
canCreateUser?: boolean
|
||||
isLoading?: boolean
|
||||
openUserCreationDialog: () => void
|
||||
onSuspendUser: (user: TypesGen.User) => void
|
||||
@@ -34,11 +35,13 @@ export const UsersPageView: React.FC<UsersPageViewProps> = ({
|
||||
error,
|
||||
isUpdatingUserRoles,
|
||||
canEditUsers,
|
||||
canCreateUser,
|
||||
isLoading,
|
||||
}) => {
|
||||
const newUserAction = canCreateUser ? { text: Language.newUserButton, onClick: openUserCreationDialog } : undefined
|
||||
return (
|
||||
<Stack spacing={4}>
|
||||
<Header title={Language.pageTitle} action={{ text: Language.newUserButton, onClick: openUserCreationDialog }} />
|
||||
<Header title={Language.pageTitle} action={newUserAction} />
|
||||
<Margins>
|
||||
{error ? (
|
||||
<ErrorSummary error={error} />
|
||||
|
||||
@@ -12,6 +12,7 @@ export const Language = {
|
||||
export const checks = {
|
||||
readAllUsers: "readAllUsers",
|
||||
updateUsers: "updateUsers",
|
||||
createUser: "createUser",
|
||||
createTemplates: "createTemplates",
|
||||
} as const
|
||||
|
||||
@@ -28,6 +29,12 @@ export const permissionsToCheck = {
|
||||
},
|
||||
action: "update",
|
||||
},
|
||||
[checks.createUser]: {
|
||||
object: {
|
||||
resource_type: "user",
|
||||
},
|
||||
action: "create",
|
||||
},
|
||||
[checks.createTemplates]: {
|
||||
object: {
|
||||
resource_type: "template",
|
||||
|
||||
Reference in New Issue
Block a user