From d10b30fc67af8697f1f39da1276b11ad4db50958 Mon Sep 17 00:00:00 2001 From: Jan Losinski Date: Thu, 22 Dec 2022 16:12:11 +0100 Subject: [PATCH 1/4] feat: allow to set the username claim field in OIDC Gitlab does not set the preferred_username field. Therefore, coder generates something from the users email address, which is not very helpful. This allows the administrator to change the field used for the username (e.g. to "nickname") Signed-off-by: Jan Losinski --- cli/deployment/config.go | 6 ++++++ cli/server.go | 5 +++-- cli/testdata/coder_server_--help.golden | 4 ++++ coderd/coderdtest/coderdtest.go | 1 + coderd/userauth.go | 4 +++- codersdk/deploymentconfig.go | 1 + 6 files changed, 18 insertions(+), 3 deletions(-) diff --git a/cli/deployment/config.go b/cli/deployment/config.go index 97177d235996c..91d7cb9e9e659 100644 --- a/cli/deployment/config.go +++ b/cli/deployment/config.go @@ -248,6 +248,12 @@ func newConfig() *codersdk.DeploymentConfig { Flag: "oidc-ignore-email-verified", Default: false, }, + UsernameField: &codersdk.DeploymentConfigField[string]{ + Name: "OIDC Username field", + Usage: "OIDC claim filed to use as user-name.", + Flag: "oidc-username-field", + Default: "preferred_username", + }, }, Telemetry: &codersdk.TelemetryConfig{ diff --git a/cli/server.go b/cli/server.go index 740782779ab19..e04ffc4283cb7 100644 --- a/cli/server.go +++ b/cli/server.go @@ -526,8 +526,9 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co Verifier: oidcProvider.Verifier(&oidc.Config{ ClientID: cfg.OIDC.ClientID.Value, }), - EmailDomain: cfg.OIDC.EmailDomain.Value, - AllowSignups: cfg.OIDC.AllowSignups.Value, + EmailDomain: cfg.OIDC.EmailDomain.Value, + AllowSignups: cfg.OIDC.AllowSignups.Value, + UsernameField: cfg.OIDC.UsernameField.Value, } } diff --git a/cli/testdata/coder_server_--help.golden b/cli/testdata/coder_server_--help.golden index 43b97ccb2189b..e38f60d971349 100644 --- a/cli/testdata/coder_server_--help.golden +++ b/cli/testdata/coder_server_--help.golden @@ -112,6 +112,10 @@ Flags: OIDC. Consumes $CODER_OIDC_SCOPES (default [openid,profile,email]) + --oidc-username-field string OIDC claim filed to use as user-name. + Consumes + $CODER_OIDC_USERNAME_FILED (default + "preferred_username") --postgres-url string URL of a PostgreSQL database. If empty, PostgreSQL binaries will be downloaded from Maven diff --git a/coderd/coderdtest/coderdtest.go b/coderd/coderdtest/coderdtest.go index 7da86ad83d6f6..34b44ab883dad 100644 --- a/coderd/coderdtest/coderdtest.go +++ b/coderd/coderdtest/coderdtest.go @@ -880,6 +880,7 @@ func (o *OIDCConfig) OIDCConfig() *coderd.OIDCConfig { }, &oidc.Config{ SkipClientIDCheck: true, }), + UsernameField: "preferred_username", } } diff --git a/coderd/userauth.go b/coderd/userauth.go index 1197aa8d2cea6..baa3d81a084e1 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -198,6 +198,8 @@ type OIDCConfig struct { // IgnoreEmailVerified allows ignoring the email_verified claim // from an upstream OIDC provider. See #5065 for context. IgnoreEmailVerified bool + // UsernameField selects the claim field to be used as username + UsernameField string } func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) { @@ -236,7 +238,7 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) { }) return } - usernameRaw, ok := claims["preferred_username"] + usernameRaw, ok := claims[api.OIDCConfig.UsernameField] var username string if ok { username, _ = usernameRaw.(string) diff --git a/codersdk/deploymentconfig.go b/codersdk/deploymentconfig.go index 7a336595f91e4..639c4408dd49e 100644 --- a/codersdk/deploymentconfig.go +++ b/codersdk/deploymentconfig.go @@ -99,6 +99,7 @@ type OIDCConfig struct { IssuerURL *DeploymentConfigField[string] `json:"issuer_url" typescript:",notnull"` Scopes *DeploymentConfigField[[]string] `json:"scopes" typescript:",notnull"` IgnoreEmailVerified *DeploymentConfigField[bool] `json:"ignore_email_verified" typescript:",notnull"` + UsernameField *DeploymentConfigField[string] `json:"username_filed" typescript:",notnull"` } type TelemetryConfig struct { From 3243913d91e80640d08a21a4dc328e49f1e2c672 Mon Sep 17 00:00:00 2001 From: Colin Adler Date: Wed, 4 Jan 2023 14:54:22 -0600 Subject: [PATCH 2/4] fix golden file --- cli/deployment/config.go | 4 ++-- cli/testdata/coder_server_--help.golden | 7 +++---- coderd/userauth.go | 3 ++- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cli/deployment/config.go b/cli/deployment/config.go index 91d7cb9e9e659..aaa64d2bea963 100644 --- a/cli/deployment/config.go +++ b/cli/deployment/config.go @@ -249,8 +249,8 @@ func newConfig() *codersdk.DeploymentConfig { Default: false, }, UsernameField: &codersdk.DeploymentConfigField[string]{ - Name: "OIDC Username field", - Usage: "OIDC claim filed to use as user-name.", + Name: "OIDC Username Field", + Usage: "OIDC claim field to use as the username.", Flag: "oidc-username-field", Default: "preferred_username", }, diff --git a/cli/testdata/coder_server_--help.golden b/cli/testdata/coder_server_--help.golden index e38f60d971349..69fbd20d9b3a5 100644 --- a/cli/testdata/coder_server_--help.golden +++ b/cli/testdata/coder_server_--help.golden @@ -112,10 +112,9 @@ Flags: OIDC. Consumes $CODER_OIDC_SCOPES (default [openid,profile,email]) - --oidc-username-field string OIDC claim filed to use as user-name. - Consumes - $CODER_OIDC_USERNAME_FILED (default - "preferred_username") + --oidc-username-field string OIDC claim field to use as the username. + Consumes $CODER_OIDC_USERNAME_FILED + (default "preferred_username") --postgres-url string URL of a PostgreSQL database. If empty, PostgreSQL binaries will be downloaded from Maven diff --git a/coderd/userauth.go b/coderd/userauth.go index baa3d81a084e1..5a23b86c8de71 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -198,7 +198,8 @@ type OIDCConfig struct { // IgnoreEmailVerified allows ignoring the email_verified claim // from an upstream OIDC provider. See #5065 for context. IgnoreEmailVerified bool - // UsernameField selects the claim field to be used as username + // UsernameField selects the claim field to be used as the created user's + // username. UsernameField string } From 673bade3dfe060f8418dd5a9e93c89b812c06582 Mon Sep 17 00:00:00 2001 From: Colin Adler Date: Wed, 4 Jan 2023 14:58:13 -0600 Subject: [PATCH 3/4] fixup! fix golden file --- cli/testdata/coder_server_--help.golden | 2 +- codersdk/deploymentconfig.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/testdata/coder_server_--help.golden b/cli/testdata/coder_server_--help.golden index 69fbd20d9b3a5..fa7cc9eeba05f 100644 --- a/cli/testdata/coder_server_--help.golden +++ b/cli/testdata/coder_server_--help.golden @@ -113,7 +113,7 @@ Flags: Consumes $CODER_OIDC_SCOPES (default [openid,profile,email]) --oidc-username-field string OIDC claim field to use as the username. - Consumes $CODER_OIDC_USERNAME_FILED + Consumes $CODER_OIDC_USERNAME_FIELD (default "preferred_username") --postgres-url string URL of a PostgreSQL database. If empty, PostgreSQL binaries will be downloaded diff --git a/codersdk/deploymentconfig.go b/codersdk/deploymentconfig.go index 639c4408dd49e..8d12426292241 100644 --- a/codersdk/deploymentconfig.go +++ b/codersdk/deploymentconfig.go @@ -99,7 +99,7 @@ type OIDCConfig struct { IssuerURL *DeploymentConfigField[string] `json:"issuer_url" typescript:",notnull"` Scopes *DeploymentConfigField[[]string] `json:"scopes" typescript:",notnull"` IgnoreEmailVerified *DeploymentConfigField[bool] `json:"ignore_email_verified" typescript:",notnull"` - UsernameField *DeploymentConfigField[string] `json:"username_filed" typescript:",notnull"` + UsernameField *DeploymentConfigField[string] `json:"username_field" typescript:",notnull"` } type TelemetryConfig struct { From 60162c6a84224c7bc91b8d87996e586609580966 Mon Sep 17 00:00:00 2001 From: Colin Adler Date: Wed, 4 Jan 2023 15:04:03 -0600 Subject: [PATCH 4/4] fixup! fix golden file --- coderd/apidoc/docs.go | 3 +++ coderd/apidoc/swagger.json | 3 +++ docs/api/general.md | 11 +++++++++++ docs/api/schemas.md | 23 +++++++++++++++++++++++ site/src/api/typesGenerated.ts | 1 + 5 files changed, 41 insertions(+) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 9b45d84e515da..ebd1a8a8e4498 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -1975,6 +1975,9 @@ const docTemplate = `{ }, "scopes": { "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "username_field": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" } } }, diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 8474aebfee1cd..3b3514852255e 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1795,6 +1795,9 @@ }, "scopes": { "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "username_field": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" } } }, diff --git a/docs/api/general.md b/docs/api/general.md index f8293d32c8709..d9355f7f1c505 100644 --- a/docs/api/general.md +++ b/docs/api/general.md @@ -535,6 +535,17 @@ curl -X GET http://coder-server:8080/api/v2/config/deployment \ "shorthand": "string", "usage": "string", "value": "string" + }, + "username_field": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" } }, "pg_connection_url": { diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 511cd2402aede..478403c1fc166 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -1119,6 +1119,17 @@ CreateParameterRequest is a structure used to create a new parameter value for a "shorthand": "string", "usage": "string", "value": "string" + }, + "username_field": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" } }, "pg_connection_url": { @@ -2072,6 +2083,17 @@ CreateParameterRequest is a structure used to create a new parameter value for a "shorthand": "string", "usage": "string", "value": "string" + }, + "username_field": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" } } ``` @@ -2087,6 +2109,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `ignore_email_verified` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | | `issuer_url` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | | `scopes` | [codersdk.DeploymentConfigField-array_string](#codersdkdeploymentconfigfield-array_string) | false | | | +| `username_field` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | ## codersdk.Parameter diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index eaea70ca0ff95..72669b8f01fab 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -452,6 +452,7 @@ export interface OIDCConfig { readonly issuer_url: DeploymentConfigField readonly scopes: DeploymentConfigField readonly ignore_email_verified: DeploymentConfigField + readonly username_field: DeploymentConfigField } // From codersdk/organizations.go