Skip to content

feat: Allow hiding password auth, changing OpenID Connect text and OpenID Connect icon #5101

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Jan 31, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3addcaf
Allow hiding password entry, changing OpenID Connect text and OpenID …
normana10 Nov 16, 2022
40bc156
Docs
normana10 Nov 16, 2022
0f4a40e
Cleaning
normana10 Nov 16, 2022
90d900c
Fix Prettier and Go test and TS compile error
normana10 Nov 16, 2022
97b5019
Fix LoginPage test
normana10 Nov 16, 2022
8019ec7
Prettier
normana10 Nov 16, 2022
97d9d46
Fix storybook
normana10 Nov 16, 2022
0858ad0
Add query param to un-hide password auth
normana10 Nov 24, 2022
f13df97
Merge branch 'main' into configurable-openid-connect-text
normana10 Dec 6, 2022
6afca64
Cleaning
normana10 Dec 6, 2022
410fc98
Merge branch 'main' into configurable-openid-connect-text
normana10 Dec 14, 2022
e9a91cb
Merge branch 'main' into configurable-openid-connect-text
normana10 Jan 16, 2023
fc12496
Hide password by default when OIDC enabled
normana10 Jan 17, 2023
9480f8e
Ran prettier, updated goldenfiles and ran "make gen"
normana10 Jan 17, 2023
475b2bf
Fixed and added LoginPage test
normana10 Jan 17, 2023
77b230c
Ran prettier
normana10 Jan 17, 2023
77f0fb2
PR Feedback and split up SignInForm.tsx
normana10 Jan 20, 2023
1ed7911
Updated golden files
normana10 Jan 20, 2023
e31a37e
Fix auto-genned-files
normana10 Jan 23, 2023
9207175
make gen -B
normana10 Jan 26, 2023
201d424
Revert provisioner files?
normana10 Jan 26, 2023
8333256
Merge branch 'main' into configurable-openid-connect-text
normana10 Jan 30, 2023
7ce525e
Fix lint error
normana10 Jan 30, 2023
3d5ec00
Merge branch 'main' into configurable-openid-connect-text
kylecarbs Jan 31, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions cli/deployment/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ func newConfig() *codersdk.DeploymentConfig {
Flag: "postgres-url",
Secret: true,
},
PasswordAuthHidden: &codersdk.DeploymentConfigField[bool]{
Name: "Flag to hide password auth",
Usage: "When this flag is set to true, the user/password form in the UI will be hidden",
Flag: "password-auth-hidden",
},
OAuth2: &codersdk.OAuth2Config{
Github: &codersdk.OAuth2GithubConfig{
ClientID: &codersdk.DeploymentConfigField[string]{
Expand Down Expand Up @@ -231,6 +236,16 @@ func newConfig() *codersdk.DeploymentConfig {
Flag: "oidc-scopes",
Default: []string{oidc.ScopeOpenID, "profile", "email"},
},
SignInText: &codersdk.DeploymentConfigField[string]{
Name: "OpenID Connect sign in text",
Usage: "The text to show on the OpenID Connect sign in button",
Flag: "oidc-sign-in-text",
},
IconURL: &codersdk.DeploymentConfigField[string]{
Name: "OpenID connect icon URL",
Usage: "URL pointing to the icon to use on the OepnID Connect login button",
Flag: "oidc-icon-url",
},
},

Telemetry: &codersdk.TelemetryConfig{
Expand Down
4 changes: 4 additions & 0 deletions cli/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,8 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co
options.TLSCertificates = tlsConfig.Certificates
}

options.PasswordAuthHidden = cfg.PasswordAuthHidden.Value

if cfg.OAuth2.Github.ClientSecret.Value != "" {
options.GithubOAuth2Config, err = configureGithubOAuth2(accessURLParsed,
cfg.OAuth2.Github.ClientID.Value,
Expand Down Expand Up @@ -419,6 +421,8 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co
}),
EmailDomain: cfg.OIDC.EmailDomain.Value,
AllowSignups: cfg.OIDC.AllowSignups.Value,
SignInText: cfg.OIDC.SignInText.Value,
IconURL: cfg.OIDC.IconURL.Value,
}
}

Expand Down
10 changes: 10 additions & 0 deletions cli/testdata/coder_server_--help.golden
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,22 @@ Flags:
--oidc-email-domain string Email domain that clients logging in with
OIDC must match.
Consumes $CODER_OIDC_EMAIL_DOMAIN
--oidc-icon-url string URL pointing to the icon to use on the
OepnID Connect login button
Consumes $CODER_OIDC_ICON_URL
--oidc-issuer-url string Issuer URL to use for Login with OIDC.
Consumes $CODER_OIDC_ISSUER_URL
--oidc-scopes strings Scopes to grant when authenticating with
OIDC.
Consumes $CODER_OIDC_SCOPES (default
[openid,profile,email])
--oidc-sign-in-text string The text to show on the OpenID Connect
sign in button
Consumes $CODER_OIDC_SIGN_IN_TEXT
--password-auth-hidden When this flag is set to true, the
user/password form in the UI will be
hidden
Consumes $CODER_PASSWORD_AUTH_HIDDEN
--postgres-url string URL of a PostgreSQL database. If empty,
PostgreSQL binaries will be downloaded
from Maven
Expand Down
1 change: 1 addition & 0 deletions coderd/coderd.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ type Options struct {
Authorizer rbac.Authorizer
AzureCertificates x509.VerifyOptions
GoogleTokenValidator *idtoken.Validator
PasswordAuthHidden bool
GithubOAuth2Config *GithubOAuth2Config
OIDCConfig *OIDCConfig
PrometheusRegistry *prometheus.Registry
Expand Down
25 changes: 22 additions & 3 deletions coderd/userauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,27 @@ type GithubOAuth2Config struct {
}

func (api *API) userAuthMethods(rw http.ResponseWriter, r *http.Request) {
var signInText string
var iconURL string

if api.OIDCConfig != nil {
signInText = api.OIDCConfig.SignInText
}
if api.OIDCConfig != nil {
iconURL = api.OIDCConfig.IconURL
}

httpapi.Write(r.Context(), rw, http.StatusOK, codersdk.AuthMethods{
Password: true,
Github: api.GithubOAuth2Config != nil,
OIDC: api.OIDCConfig != nil,
Password: codersdk.PasswordMethod{
AuthMethod: codersdk.AuthMethod{Enabled: true},
Hidden: api.PasswordAuthHidden,
},
Github: codersdk.AuthMethod{Enabled: api.GithubOAuth2Config != nil},
OIDC: codersdk.OIDCMethod{
AuthMethod: codersdk.AuthMethod{Enabled: api.OIDCConfig != nil},
SignInText: signInText,
IconURL: iconURL,
},
})
}

Expand Down Expand Up @@ -195,6 +212,8 @@ type OIDCConfig struct {
// EmailDomain is the domain to enforce when a user authenticates.
EmailDomain string
AllowSignups bool
SignInText string
IconURL string
}

func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
Expand Down
8 changes: 4 additions & 4 deletions coderd/userauth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ func TestUserAuthMethods(t *testing.T) {

methods, err := client.AuthMethods(ctx)
require.NoError(t, err)
require.True(t, methods.Password)
require.False(t, methods.Github)
require.True(t, methods.Password.Enabled)
require.False(t, methods.Github.Enabled)
})
t.Run("Github", func(t *testing.T) {
t.Parallel()
Expand All @@ -91,8 +91,8 @@ func TestUserAuthMethods(t *testing.T) {

methods, err := client.AuthMethods(ctx)
require.NoError(t, err)
require.True(t, methods.Password)
require.True(t, methods.Github)
require.True(t, methods.Password.Enabled)
require.True(t, methods.Github.Enabled)
})
}

Expand Down
3 changes: 3 additions & 0 deletions codersdk/deploymentconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type DeploymentConfig struct {
CacheDirectory *DeploymentConfigField[string] `json:"cache_directory" typescript:",notnull"`
InMemoryDatabase *DeploymentConfigField[bool] `json:"in_memory_database" typescript:",notnull"`
PostgresURL *DeploymentConfigField[string] `json:"pg_connection_url" typescript:",notnull"`
PasswordAuthHidden *DeploymentConfigField[bool] `json:"password_auth_hidden" typescript:",notnull"`
OAuth2 *OAuth2Config `json:"oauth2" typescript:",notnull"`
OIDC *OIDCConfig `json:"oidc" typescript:",notnull"`
Telemetry *TelemetryConfig `json:"telemetry" typescript:",notnull"`
Expand Down Expand Up @@ -92,6 +93,8 @@ type OIDCConfig struct {
EmailDomain *DeploymentConfigField[string] `json:"email_domain" typescript:",notnull"`
IssuerURL *DeploymentConfigField[string] `json:"issuer_url" typescript:",notnull"`
Scopes *DeploymentConfigField[[]string] `json:"scopes" typescript:",notnull"`
SignInText *DeploymentConfigField[string] `json:"sign_in_text" typescript:",notnull"`
IconURL *DeploymentConfigField[string] `json:"icon_url" typescript:",notnull"`
}

type TelemetryConfig struct {
Expand Down
23 changes: 19 additions & 4 deletions codersdk/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,26 @@ type CreateOrganizationRequest struct {
Name string `json:"name" validate:"required,username"`
}

// AuthMethods contains whether authentication types are enabled or not.
// AuthMethods contains authentication method information like whether they are enabled or not or hidden or not, etc.
type AuthMethods struct {
Password bool `json:"password"`
Github bool `json:"github"`
OIDC bool `json:"oidc"`
Password PasswordMethod `json:"password"`
Github AuthMethod `json:"github"`
OIDC OIDCMethod `json:"oidc"`
}

type AuthMethod struct {
Enabled bool `json:"enabled"`
}

type PasswordMethod struct {
AuthMethod
Hidden bool `json:"hidden"`
}

type OIDCMethod struct {
AuthMethod
SignInText string `json:"signInText"`
IconURL string `json:"iconUrl"`
}

// HasFirstUser returns whether the first user has been created.
Expand Down
10 changes: 10 additions & 0 deletions docs/admin/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ By default, Coder is accessible via password authentication.

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

If after configuring another authentication method you'd like to hide password authentication, you can configure that like so:
```console
CODER_PASSWORD_AUTH_HIDDEN=true
```
## GitHub

### Step 1: Configure the OAuth application in GitHub
Expand Down Expand Up @@ -81,6 +85,12 @@ CODER_TLS_CLIENT_CERT_FILE=/path/to/cert.pem
CODER_TLS_CLIENT_KEY_FILE=/path/to/key.pem
```

If you'd like to change the OpenID Connect button text and/or icon, you can configure them like so:
```console
CODER_OIDC_SIGN_IN_TEXT="Sign in with Gitea"
CODER_OIDC_ICON_URL=https://gitea.io/images/gitea.png
```

## SCIM (enterprise)

Coder supports user provisioning and deprovisioning via SCIM 2.0 with header
Expand Down
25 changes: 22 additions & 3 deletions site/src/api/typesGenerated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,16 @@ export interface AuditLogsRequest extends Pagination {
readonly q?: string
}

// From codersdk/users.go
export interface AuthMethod {
readonly enabled: boolean
}

// From codersdk/users.go
export interface AuthMethods {
readonly password: boolean
readonly github: boolean
readonly oidc: boolean
readonly password: PasswordMethod
readonly github: AuthMethod
readonly oidc: OIDCMethod
}

// From codersdk/authorization.go
Expand Down Expand Up @@ -289,6 +294,7 @@ export interface DeploymentConfig {
readonly cache_directory: DeploymentConfigField<string>
readonly in_memory_database: DeploymentConfigField<boolean>
readonly pg_connection_url: DeploymentConfigField<string>
readonly password_auth_hidden: DeploymentConfigField<boolean>
readonly oauth2: OAuth2Config
readonly oidc: OIDCConfig
readonly telemetry: TelemetryConfig
Expand Down Expand Up @@ -446,6 +452,14 @@ export interface OIDCConfig {
readonly email_domain: DeploymentConfigField<string>
readonly issuer_url: DeploymentConfigField<string>
readonly scopes: DeploymentConfigField<string[]>
readonly sign_in_text: DeploymentConfigField<string>
readonly icon_url: DeploymentConfigField<string>
}

// From codersdk/users.go
export interface OIDCMethod extends AuthMethod {
readonly signInText: string
readonly iconUrl: string
}

// From codersdk/organizations.go
Expand Down Expand Up @@ -505,6 +519,11 @@ export interface ParameterSchema {
readonly validation_contains?: string[]
}

// From codersdk/users.go
export interface PasswordMethod extends AuthMethod {
readonly hidden: boolean
}

// From codersdk/groups.go
export interface PatchGroupRequest {
readonly add_users: string[]
Expand Down
23 changes: 12 additions & 11 deletions site/src/components/SignInForm/SignInForm.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ Loading.args = {
...SignedOut.args,
isLoading: true,
authMethods: {
github: true,
password: true,
password: { enabled: true, hidden: false },
github: { enabled: true },
oidc: { enabled: false, signInText: "", iconUrl: "" },
},
}

Expand Down Expand Up @@ -99,28 +100,28 @@ export const WithGithub = Template.bind({})
WithGithub.args = {
...SignedOut.args,
authMethods: {
password: true,
github: true,
oidc: false,
password: { enabled: true, hidden: false },
github: { enabled: true },
oidc: { enabled: false, signInText: "", iconUrl: "" },
},
}

export const WithOIDC = Template.bind({})
WithOIDC.args = {
...SignedOut.args,
authMethods: {
password: true,
github: false,
oidc: true,
password: { enabled: true, hidden: false },
github: { enabled: false },
oidc: { enabled: true, signInText: "", iconUrl: "" },
},
}

export const WithGithubAndOIDC = Template.bind({})
WithGithubAndOIDC.args = {
...SignedOut.args,
authMethods: {
password: true,
github: true,
oidc: true,
password: { enabled: true, hidden: false },
github: { enabled: true },
oidc: { enabled: true, signInText: "", iconUrl: "" },
},
}
Loading