Skip to content

Commit fc12496

Browse files
committed
Hide password by default when OIDC enabled
1 parent e9a91cb commit fc12496

File tree

9 files changed

+35
-59
lines changed

9 files changed

+35
-59
lines changed

cli/deployment/config.go

-5
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,6 @@ func newConfig() *codersdk.DeploymentConfig {
168168
Flag: "postgres-url",
169169
Secret: true,
170170
},
171-
PasswordAuthHidden: &codersdk.DeploymentConfigField[bool]{
172-
Name: "Flag to hide password auth",
173-
Usage: "When this flag is set to true, the user/password form in the UI will be hidden",
174-
Flag: "password-auth-hidden",
175-
},
176171
OAuth2: &codersdk.OAuth2Config{
177172
Github: &codersdk.OAuth2GithubConfig{
178173
ClientID: &codersdk.DeploymentConfigField[string]{

cli/server.go

+2-4
Original file line numberDiff line numberDiff line change
@@ -481,8 +481,6 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co
481481
options.TLSCertificates = tlsConfig.Certificates
482482
}
483483

484-
options.PasswordAuthHidden = cfg.PasswordAuthHidden.Value
485-
486484
if cfg.UpdateCheck.Value {
487485
options.UpdateCheckOptions = &updatecheck.Options{
488486
// Avoid spamming GitHub API checking for updates.
@@ -552,8 +550,8 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co
552550
EmailDomain: cfg.OIDC.EmailDomain.Value,
553551
AllowSignups: cfg.OIDC.AllowSignups.Value,
554552
UsernameField: cfg.OIDC.UsernameField.Value,
555-
SignInText: cfg.OIDC.SignInText.Value,
556-
IconURL: cfg.OIDC.IconURL.Value,
553+
SignInText: cfg.OIDC.SignInText.Value,
554+
IconURL: cfg.OIDC.IconURL.Value,
557555
}
558556
}
559557

coderd/coderd.go

-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ type Options struct {
9797
Authorizer rbac.Authorizer
9898
AzureCertificates x509.VerifyOptions
9999
GoogleTokenValidator *idtoken.Validator
100-
PasswordAuthHidden bool
101100
GithubOAuth2Config *GithubOAuth2Config
102101
OIDCConfig *OIDCConfig
103102
PrometheusRegistry *prometheus.Registry

coderd/userauth.go

+4-7
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,8 @@ func (api *API) userAuthMethods(rw http.ResponseWriter, r *http.Request) {
6262
}
6363

6464
httpapi.Write(r.Context(), rw, http.StatusOK, codersdk.AuthMethods{
65-
Password: codersdk.PasswordMethod{
66-
AuthMethod: codersdk.AuthMethod{Enabled: true},
67-
Hidden: api.PasswordAuthHidden,
68-
},
69-
Github: codersdk.AuthMethod{Enabled: api.GithubOAuth2Config != nil},
65+
Password: codersdk.AuthMethod{Enabled: true},
66+
Github: codersdk.AuthMethod{Enabled: api.GithubOAuth2Config != nil},
7067
OIDC: codersdk.OIDCMethod{
7168
AuthMethod: codersdk.AuthMethod{Enabled: api.OIDCConfig != nil},
7269
SignInText: signInText,
@@ -233,9 +230,9 @@ type OIDCConfig struct {
233230
// username.
234231
UsernameField string
235232
// SignInText is the text to display on the OIDC login button
236-
SignInText string
233+
SignInText string
237234
// IconURL points to the URL of an icon to display on the OIDC login button
238-
IconURL string
235+
IconURL string
239236
}
240237

241238
// @Summary OpenID Connect Callback

codersdk/users.go

+4-9
Original file line numberDiff line numberDiff line change
@@ -105,22 +105,17 @@ type CreateOrganizationRequest struct {
105105
Name string `json:"name" validate:"required,username"`
106106
}
107107

108-
// AuthMethods contains authentication method information like whether they are enabled or not or hidden or not, etc.
108+
// AuthMethods contains authentication method information like whether they are enabled or not or custom text, etc.
109109
type AuthMethods struct {
110-
Password PasswordMethod `json:"password"`
111-
Github AuthMethod `json:"github"`
112-
OIDC OIDCMethod `json:"oidc"`
110+
Password AuthMethod `json:"password"`
111+
Github AuthMethod `json:"github"`
112+
OIDC OIDCMethod `json:"oidc"`
113113
}
114114

115115
type AuthMethod struct {
116116
Enabled bool `json:"enabled"`
117117
}
118118

119-
type PasswordMethod struct {
120-
AuthMethod
121-
Hidden bool `json:"hidden"`
122-
}
123-
124119
type OIDCMethod struct {
125120
AuthMethod
126121
SignInText string `json:"signInText"`

docs/admin/auth.md

-12
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,6 @@ By default, Coder is accessible via password authentication.
44

55
The following steps explain how to set up GitHub OAuth or OpenID Connect.
66

7-
If after configuring another authentication method you'd like to hide password authentication, you can configure that like so:
8-
9-
```console
10-
CODER_PASSWORD_AUTH_HIDDEN=true
11-
```
12-
13-
If your external authentication method(s) were to go down, you can un-hide password authentication with the following URL query parameter:
14-
15-
```console
16-
https://coder.domain.com/login?auth=password
17-
```
18-
197
## GitHub
208

219
### Step 1: Configure the OAuth application in GitHub

site/src/api/typesGenerated.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export interface AuthMethod {
9696

9797
// From codersdk/users.go
9898
export interface AuthMethods {
99-
readonly password: PasswordMethod
99+
readonly password: AuthMethod
100100
readonly github: AuthMethod
101101
readonly oidc: OIDCMethod
102102
}
@@ -538,11 +538,6 @@ export interface ParameterSchema {
538538
readonly validation_contains?: string[]
539539
}
540540

541-
// From codersdk/users.go
542-
export interface PasswordMethod extends AuthMethod {
543-
readonly hidden: boolean
544-
}
545-
546541
// From codersdk/groups.go
547542
export interface PatchGroupRequest {
548543
readonly add_users: string[]

site/src/components/SignInForm/SignInForm.stories.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Loading.args = {
2929
...SignedOut.args,
3030
isLoading: true,
3131
authMethods: {
32-
password: { enabled: true, hidden: false },
32+
password: { enabled: true },
3333
github: { enabled: true },
3434
oidc: { enabled: false, signInText: "", iconUrl: "" },
3535
},
@@ -100,7 +100,7 @@ export const WithGithub = Template.bind({})
100100
WithGithub.args = {
101101
...SignedOut.args,
102102
authMethods: {
103-
password: { enabled: true, hidden: false },
103+
password: { enabled: true },
104104
github: { enabled: true },
105105
oidc: { enabled: false, signInText: "", iconUrl: "" },
106106
},
@@ -110,7 +110,7 @@ export const WithOIDC = Template.bind({})
110110
WithOIDC.args = {
111111
...SignedOut.args,
112112
authMethods: {
113-
password: { enabled: true, hidden: false },
113+
password: { enabled: true },
114114
github: { enabled: false },
115115
oidc: { enabled: true, signInText: "", iconUrl: "" },
116116
},
@@ -120,7 +120,7 @@ export const WithGithubAndOIDC = Template.bind({})
120120
WithGithubAndOIDC.args = {
121121
...SignedOut.args,
122122
authMethods: {
123-
password: { enabled: true, hidden: false },
123+
password: { enabled: true },
124124
github: { enabled: true },
125125
oidc: { enabled: true, signInText: "", iconUrl: "" },
126126
},

site/src/components/SignInForm/SignInForm.tsx

+20-11
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ import Box from "@material-ui/core/Box"
22
import Button from "@material-ui/core/Button"
33
import Link from "@material-ui/core/Link"
44
import { makeStyles } from "@material-ui/core/styles"
5+
import Typography from "@material-ui/core/Typography"
56
import TextField from "@material-ui/core/TextField"
67
import GitHubIcon from "@material-ui/icons/GitHub"
78
import KeyIcon from "@material-ui/icons/VpnKey"
89
import { Stack } from "components/Stack/Stack"
910
import { FormikContextType, FormikTouched, useFormik } from "formik"
10-
import { FC } from "react"
11+
import { FC, useState } from "react"
1112
import * as Yup from "yup"
1213
import { AuthMethods } from "../../api/typesGenerated"
1314
import { getFormHelpers, onChangeTrimmed } from "../../util/formUtils"
1415
import { LoadingButton } from "./../LoadingButton/LoadingButton"
1516
import { AlertBanner } from "components/AlertBanner/AlertBanner"
1617
import { useTranslation } from "react-i18next"
17-
import { useSearchParams } from "react-router-dom"
1818

1919
/**
2020
* BuiltInAuthFormValues describes a form using built-in (email/password)
@@ -95,6 +95,12 @@ const useStyles = makeStyles((theme) => ({
9595
fontSize: 12,
9696
letterSpacing: 1,
9797
},
98+
showPasswordLink: {
99+
cursor: "pointer",
100+
fontSize: 12,
101+
color: theme.palette.text.secondary,
102+
marginTop: 12,
103+
}
98104
}))
99105

100106
export interface SignInFormProps {
@@ -115,8 +121,10 @@ export const SignInForm: FC<React.PropsWithChildren<SignInFormProps>> = ({
115121
onSubmit,
116122
initialTouched,
117123
}) => {
124+
const nonPasswordAuthEnabled = authMethods?.github.enabled || authMethods?.oidc.enabled
125+
126+
const [showPasswordAuth, setShowPasswordAuth] = useState(!nonPasswordAuthEnabled);
118127
const styles = useStyles()
119-
const [searchParams] = useSearchParams()
120128
const form: FormikContextType<BuiltInAuthFormValues> =
121129
useFormik<BuiltInAuthFormValues>({
122130
initialValues: {
@@ -139,17 +147,13 @@ export const SignInForm: FC<React.PropsWithChildren<SignInFormProps>> = ({
139147
const commonTranslation = useTranslation("common")
140148
const loginPageTranslation = useTranslation("loginPage")
141149

142-
const passwordHidden = authMethods?.password.hidden
143-
const urlParamOverride = searchParams.get("auth") === "password"
144-
const showPasswordLogin = !passwordHidden || urlParamOverride
145-
146150
return (
147151
<div className={styles.root}>
148152
<h1 className={styles.title}>
149153
{loginPageTranslation.t("signInTo")}{" "}
150154
<strong>{commonTranslation.t("coder")}</strong>
151155
</h1>
152-
{showPasswordLogin && (
156+
{showPasswordAuth && (
153157
<form onSubmit={form.handleSubmit}>
154158
<Stack>
155159
{Object.keys(loginErrors).map(
@@ -195,15 +199,15 @@ export const SignInForm: FC<React.PropsWithChildren<SignInFormProps>> = ({
195199
</Stack>
196200
</form>
197201
)}
198-
{showPasswordLogin &&
199-
(authMethods?.github.enabled || authMethods?.oidc.enabled) && (
202+
{showPasswordAuth &&
203+
(nonPasswordAuthEnabled) && (
200204
<div className={styles.divider}>
201205
<div className={styles.dividerLine} />
202206
<div className={styles.dividerLabel}>Or</div>
203207
<div className={styles.dividerLine} />
204208
</div>
205209
)}
206-
{(authMethods?.github.enabled || authMethods?.oidc.enabled) && (
210+
{(nonPasswordAuthEnabled) && (
207211
<Box display="grid" gridGap="16px">
208212
{authMethods.github.enabled && (
209213
<Link
@@ -255,6 +259,11 @@ export const SignInForm: FC<React.PropsWithChildren<SignInFormProps>> = ({
255259
)}
256260
</Box>
257261
)}
262+
{!showPasswordAuth &&
263+
<Typography className={styles.showPasswordLink} onClick={() => setShowPasswordAuth(true)}>
264+
Show password login
265+
</Typography>
266+
}
258267
</div>
259268
)
260269
}

0 commit comments

Comments
 (0)