Skip to content

Commit b4c2a42

Browse files
committed
Hide create user if password auth is disabled
1 parent 50d0dcb commit b4c2a42

File tree

4 files changed

+80
-25
lines changed

4 files changed

+80
-25
lines changed

coderd/users.go

+9
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,15 @@ func (api *API) postUser(rw http.ResponseWriter, r *http.Request) {
293293
return
294294
}
295295

296+
// If password auth is disabled, don't allow new users to be
297+
// created with a password!
298+
if api.DeploymentConfig.DisablePasswordAuth.Value {
299+
httpapi.Write(ctx, rw, http.StatusForbidden, codersdk.Response{
300+
Message: "You cannot manually provision new users with password authentication disabled!",
301+
})
302+
return
303+
}
304+
296305
// TODO: @emyrk Authorize the organization create if the createUser will do that.
297306

298307
_, err := api.Database.GetUserByEmailOrUsername(ctx, database.GetUserByEmailOrUsernameParams{

coderd/users_test.go

+2-15
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,6 @@ func TestPostLogin(t *testing.T) {
187187
t.Parallel()
188188

189189
dc := coderdtest.DeploymentConfig(t)
190-
dc.DisablePasswordAuth.Value = true
191190
client := coderdtest.New(t, &coderdtest.Options{
192191
DeploymentConfig: dc,
193192
})
@@ -207,6 +206,8 @@ func TestPostLogin(t *testing.T) {
207206
})
208207
require.NoError(t, err)
209208

209+
dc.DisablePasswordAuth.Value = true
210+
210211
userClient := codersdk.New(client.URL)
211212
_, err = userClient.LoginWithPassword(ctx, codersdk.LoginWithPasswordRequest{
212213
Email: user.Email,
@@ -217,20 +218,6 @@ func TestPostLogin(t *testing.T) {
217218
require.ErrorAs(t, err, &apiErr)
218219
require.Equal(t, http.StatusForbidden, apiErr.StatusCode())
219220
require.Contains(t, apiErr.Message, "Password authentication is disabled")
220-
221-
// Promote the user account to an owner.
222-
_, err = client.UpdateUserRoles(ctx, user.ID.String(), codersdk.UpdateRoles{
223-
Roles: []string{rbac.RoleOwner(), rbac.RoleMember()},
224-
})
225-
require.NoError(t, err)
226-
227-
// Login with the user account.
228-
res, err := userClient.LoginWithPassword(ctx, codersdk.LoginWithPasswordRequest{
229-
Email: user.Email,
230-
Password: password,
231-
})
232-
require.NoError(t, err)
233-
require.NotEmpty(t, res.SessionToken)
234221
})
235222

236223
t.Run("Success", func(t *testing.T) {

site/src/components/UsersLayout/UsersLayout.tsx

+14-10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Link from "@material-ui/core/Link"
33
import { makeStyles } from "@material-ui/core/styles"
44
import GroupAdd from "@material-ui/icons/GroupAddOutlined"
55
import PersonAdd from "@material-ui/icons/PersonAddOutlined"
6+
import { useMachine } from "@xstate/react"
67
import { USERS_LINK } from "components/NavbarView/NavbarView"
78
import { PageHeader, PageHeaderTitle } from "components/PageHeader/PageHeader"
89
import { useFeatureVisibility } from "hooks/useFeatureVisibility"
@@ -15,13 +16,15 @@ import {
1516
useNavigate,
1617
} from "react-router-dom"
1718
import { combineClasses } from "util/combineClasses"
19+
import { authMethodsXService } from "xServices/auth/authMethodsXService"
1820
import { Margins } from "../../components/Margins/Margins"
1921
import { Stack } from "../../components/Stack/Stack"
2022

2123
export const UsersLayout: FC = () => {
2224
const styles = useStyles()
2325
const { createUser: canCreateUser, createGroup: canCreateGroup } =
2426
usePermissions()
27+
const [authMethods] = useMachine(authMethodsXService)
2528
const navigate = useNavigate()
2629
const { template_rbac: isTemplateRBACEnabled } = useFeatureVisibility()
2730

@@ -31,16 +34,17 @@ export const UsersLayout: FC = () => {
3134
<PageHeader
3235
actions={
3336
<>
34-
{canCreateUser && (
35-
<Button
36-
onClick={() => {
37-
navigate("/users/create")
38-
}}
39-
startIcon={<PersonAdd />}
40-
>
41-
Create user
42-
</Button>
43-
)}
37+
{canCreateUser &&
38+
authMethods.context.authMethods?.password.enabled && (
39+
<Button
40+
onClick={() => {
41+
navigate("/users/create")
42+
}}
43+
startIcon={<PersonAdd />}
44+
>
45+
Create user
46+
</Button>
47+
)}
4448
{canCreateGroup && isTemplateRBACEnabled && (
4549
<Link
4650
underline="none"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { assign, createMachine } from "xstate"
2+
import * as TypeGen from "api/typesGenerated"
3+
import * as API from "api/api"
4+
5+
export interface AuthMethodsContext {
6+
authMethods?: TypeGen.AuthMethods
7+
error?: Error | unknown
8+
}
9+
10+
export const authMethodsXService = createMachine(
11+
{
12+
id: "authMethods",
13+
predictableActionArguments: true,
14+
tsTypes: {} as import("./authMethodsXService.typegen").Typegen0,
15+
schema: {
16+
context: {} as AuthMethodsContext,
17+
services: {} as {
18+
getAuthMethods: {
19+
data: TypeGen.AuthMethods
20+
}
21+
},
22+
},
23+
context: {},
24+
initial: "gettingAuthMethods",
25+
states: {
26+
gettingAuthMethods: {
27+
invoke: {
28+
src: "getAuthMethods",
29+
onDone: {
30+
target: "idle",
31+
actions: ["assignAuthMethods"],
32+
},
33+
onError: {
34+
target: "idle",
35+
actions: ["setError"],
36+
},
37+
},
38+
},
39+
idle: {},
40+
},
41+
},
42+
{
43+
actions: {
44+
assignAuthMethods: assign({
45+
authMethods: (_, event) => event.data,
46+
}),
47+
setError: assign({
48+
error: (_, event) => event.data,
49+
}),
50+
},
51+
services: {
52+
getAuthMethods: () => API.getAuthMethods(),
53+
},
54+
},
55+
)

0 commit comments

Comments
 (0)