From 5cdf612cb6e2f4f271515e1b4678e1be51d29f56 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 31 Jan 2024 16:19:18 +0100 Subject: [PATCH 01/17] feat: custom error message on signups disabled page --- cli/server.go | 1 + coderd/apidoc/docs.go | 3 +++ coderd/apidoc/swagger.json | 3 +++ coderd/userauth.go | 12 ++++++++++-- codersdk/deployment.go | 10 ++++++++++ docs/api/general.md | 1 + docs/api/schemas.md | 4 ++++ docs/cli/server.md | 10 ++++++++++ site/src/api/typesGenerated.ts | 1 + 9 files changed, 43 insertions(+), 2 deletions(-) diff --git a/cli/server.go b/cli/server.go index 1df5f49855909..a0bcf7896072b 100644 --- a/cli/server.go +++ b/cli/server.go @@ -179,6 +179,7 @@ func createOIDCConfig(ctx context.Context, vals *codersdk.DeploymentValues) (*co UserRoleMapping: vals.OIDC.UserRoleMapping.Value, UserRolesDefault: vals.OIDC.UserRolesDefault.GetSlice(), SignInText: vals.OIDC.SignInText.String(), + SignupsDisabledText: vals.OIDC.SignupsDisabledText.String(), IconURL: vals.OIDC.IconURL.String(), IgnoreEmailVerified: vals.OIDC.IgnoreEmailVerified.Value(), }, nil diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 4f7a7d3ebc38b..07ea323129e45 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -10071,6 +10071,9 @@ const docTemplate = `{ "sign_in_text": { "type": "string" }, + "signups_disabled_text": { + "type": "string" + }, "user_role_field": { "type": "string" }, diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index c7696a4157ab9..a8bd250085be2 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -9052,6 +9052,9 @@ "sign_in_text": { "type": "string" }, + "signups_disabled_text": { + "type": "string" + }, "user_role_field": { "type": "string" }, diff --git a/coderd/userauth.go b/coderd/userauth.go index 37a0402fa5713..9011e43d5c873 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -740,6 +740,8 @@ type OIDCConfig struct { SignInText string // IconURL points to the URL of an icon to display on the OIDC login button IconURL string + // SignupsDisabledText is the text do display on the static error page. + SignupsDisabledText string } func (cfg OIDCConfig) RoleSyncEnabled() bool { @@ -1313,9 +1315,15 @@ func (api *API) oauthLogin(r *http.Request, params *oauthLoginParams) ([]*http.C } if user.ID == uuid.Nil && !params.AllowSignups { + signupsDisabledText := api.OIDCConfig.SignupsDisabledText + if signupsDisabledText == "" { + signupsDisabledText = "Please contact your Coder administrator to request access." + } return httpError{ - code: http.StatusForbidden, - msg: fmt.Sprintf("Signups are not allowed for login type %q", params.LoginType), + code: http.StatusBadRequest, + msg: "Signups are disabled", + detail: signupsDisabledText, + renderStaticPage: true, } } diff --git a/codersdk/deployment.go b/codersdk/deployment.go index c02eea595924f..80f50e0580672 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -303,6 +303,7 @@ type OIDCConfig struct { UserRolesDefault clibase.StringArray `json:"user_roles_default" typescript:",notnull"` SignInText clibase.String `json:"sign_in_text" typescript:",notnull"` IconURL clibase.URL `json:"icon_url" typescript:",notnull"` + SignupsDisabledText clibase.String `json:"signups_disabled_text" typescript:",notnull"` } type TelemetryConfig struct { @@ -1266,6 +1267,15 @@ when required by your organization's security policy.`, Group: &deploymentGroupOIDC, YAML: "iconURL", }, + { + Name: "Signups disabled text", + Description: "The custom text to show on the error page informing about disabled OIDC signups.", + Flag: "oidc-signups-disabled-text", + Env: "CODER_OIDC_SIGNUPS_DISABLED_TEXT", + Value: &c.OIDC.SignupsDisabledText, + Group: &deploymentGroupOIDC, + YAML: "signupsDisabledText", + }, // Telemetry settings { Name: "Telemetry Enable", diff --git a/docs/api/general.md b/docs/api/general.md index 1069a7d3328e5..764972919761d 100644 --- a/docs/api/general.md +++ b/docs/api/general.md @@ -298,6 +298,7 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \ "issuer_url": "string", "scopes": ["string"], "sign_in_text": "string", + "signups_disabled_text": "string", "user_role_field": "string", "user_role_mapping": {}, "user_roles_default": ["string"], diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 909158f2ebdc8..c650c625369d2 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -2273,6 +2273,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in "issuer_url": "string", "scopes": ["string"], "sign_in_text": "string", + "signups_disabled_text": "string", "user_role_field": "string", "user_role_mapping": {}, "user_roles_default": ["string"], @@ -2640,6 +2641,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in "issuer_url": "string", "scopes": ["string"], "sign_in_text": "string", + "signups_disabled_text": "string", "user_role_field": "string", "user_role_mapping": {}, "user_roles_default": ["string"], @@ -3747,6 +3749,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in "issuer_url": "string", "scopes": ["string"], "sign_in_text": "string", + "signups_disabled_text": "string", "user_role_field": "string", "user_role_mapping": {}, "user_roles_default": ["string"], @@ -3777,6 +3780,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in | `issuer_url` | string | false | | | | `scopes` | array of string | false | | | | `sign_in_text` | string | false | | | +| `signups_disabled_text` | string | false | | | | `user_role_field` | string | false | | | | `user_role_mapping` | object | false | | | | `user_roles_default` | array of string | false | | | diff --git a/docs/cli/server.md b/docs/cli/server.md index 2b649aa321847..14f3b8b9440ec 100644 --- a/docs/cli/server.md +++ b/docs/cli/server.md @@ -897,6 +897,16 @@ Controls if the 'Secure' property is set on browser session cookies. The token expiry duration for browser sessions. Sessions may last longer if they are actively making requests, but this functionality can be disabled via --disable-session-expiry-refresh. +### --oidc-signups-disabled-text + +| | | +| ----------- | ---------------------------------------------- | +| Type | string | +| Environment | $CODER_OIDC_SIGNUPS_DISABLED_TEXT | +| YAML | oidc.signupsDisabledText | + +The custom text to show on the error page informing about disabled OIDC signups. + ### --log-stackdriver | | | diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 6858d7a890117..9d63f492c29b6 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -752,6 +752,7 @@ export interface OIDCConfig { readonly user_roles_default: string[]; readonly sign_in_text: string; readonly icon_url: string; + readonly signups_disabled_text: string; } // From codersdk/organizations.go From 66ee2056274a6eddfe8d6a693601cb501edc4c91 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 31 Jan 2024 16:42:55 +0100 Subject: [PATCH 02/17] yaml --- cli/testdata/coder_server_--help.golden | 4 ++++ cli/testdata/server-config.yaml.golden | 3 +++ 2 files changed, 7 insertions(+) diff --git a/cli/testdata/coder_server_--help.golden b/cli/testdata/coder_server_--help.golden index 8d420da29b1e7..8696a0033a942 100644 --- a/cli/testdata/coder_server_--help.golden +++ b/cli/testdata/coder_server_--help.golden @@ -426,6 +426,10 @@ OIDC OPTIONS: --oidc-icon-url url, $CODER_OIDC_ICON_URL URL pointing to the icon to use on the OpenID Connect login button. + --oidc-signups-disabled-text string, $CODER_OIDC_SIGNUPS_DISABLED_TEXT + The custom text to show on the error page informing about disabled + OIDC signups. + PROVISIONING OPTIONS: Tune the behavior of the provisioner, which is responsible for creating, updating, and deleting workspace resources. diff --git a/cli/testdata/server-config.yaml.golden b/cli/testdata/server-config.yaml.golden index 1c9372fad62dd..a570e8eb50abe 100644 --- a/cli/testdata/server-config.yaml.golden +++ b/cli/testdata/server-config.yaml.golden @@ -348,6 +348,9 @@ oidc: # URL pointing to the icon to use on the OpenID Connect login button. # (default: , type: url) iconURL: + # The custom text to show on the error page informing about disabled OIDC signups. + # (default: , type: string) + signupsDisabledText: "" # Telemetry is critical to our ability to improve Coder. We strip all personal # information before sending data to our servers. Please only disable telemetry # when required by your organization's security policy. From 62a8aa4bf2f8ec502628eef33b8c496337f331ee Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 31 Jan 2024 16:52:26 +0100 Subject: [PATCH 03/17] Fix --- coderd/userauth.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/coderd/userauth.go b/coderd/userauth.go index 9011e43d5c873..1622878ab4bea 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -1315,9 +1315,9 @@ func (api *API) oauthLogin(r *http.Request, params *oauthLoginParams) ([]*http.C } if user.ID == uuid.Nil && !params.AllowSignups { - signupsDisabledText := api.OIDCConfig.SignupsDisabledText - if signupsDisabledText == "" { - signupsDisabledText = "Please contact your Coder administrator to request access." + signupsDisabledText := "Please contact your Coder administrator to request access." + if api.OIDCConfig != nil && api.OIDCConfig.SignupsDisabledText != "" { + signupsDisabledText = api.OIDCConfig.SignupsDisabledText } return httpError{ code: http.StatusBadRequest, From 0ed38ed4986727b44ffbcf8220cbd6e4b67d44e1 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 31 Jan 2024 17:05:18 +0100 Subject: [PATCH 04/17] Fix? --- .../cli/testdata/coder_server_--help.golden | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/enterprise/cli/testdata/coder_server_--help.golden b/enterprise/cli/testdata/coder_server_--help.golden index 5129aaed52b07..2d35cddbba36c 100644 --- a/enterprise/cli/testdata/coder_server_--help.golden +++ b/enterprise/cli/testdata/coder_server_--help.golden @@ -62,7 +62,7 @@ OPTIONS: Periodically check for new releases of Coder and inform the owner. The check is performed once per day. -CLIENT OPTIONS: +CLIENT OPTIONS: These options change the behavior of how clients interact with the Coder. Clients include the coder cli, vs code extension, and the web UI. @@ -84,17 +84,17 @@ Clients include the coder cli, vs code extension, and the web UI. The renderer to use when opening a web terminal. Valid values are 'canvas', 'webgl', or 'dom'. -CONFIG OPTIONS: +CONFIG OPTIONS: Use a YAML configuration file when your server launch become unwieldy. -c, --config yaml-config-path, $CODER_CONFIG_PATH Specify a YAML file to load configuration from. --write-config bool - + Write out the current server config as YAML to stdout. -INTROSPECTION / HEALTH CHECK OPTIONS: +INTROSPECTION / HEALTH CHECK OPTIONS: --health-check-refresh duration, $CODER_HEALTH_CHECK_REFRESH (default: 10m0s) Refresh interval for healthchecks. @@ -103,7 +103,7 @@ INTROSPECTION / HEALTH CHECK OPTIONS: the database exceeds this threshold over 5 attempts, the database is considered unhealthy. The default value is 15ms. -INTROSPECTION / LOGGING OPTIONS: +INTROSPECTION / LOGGING OPTIONS: --enable-terraform-debug-mode bool, $CODER_ENABLE_TERRAFORM_DEBUG_MODE (default: false) Allow administrators to enable Terraform debug output. @@ -120,7 +120,7 @@ INTROSPECTION / LOGGING OPTIONS: --log-stackdriver string, $CODER_LOGGING_STACKDRIVER Output Stackdriver compatible logs to a given file. -INTROSPECTION / PROMETHEUS OPTIONS: +INTROSPECTION / PROMETHEUS OPTIONS: --prometheus-address host:port, $CODER_PROMETHEUS_ADDRESS (default: 127.0.0.1:2112) The bind address to serve prometheus metrics. @@ -133,7 +133,7 @@ INTROSPECTION / PROMETHEUS OPTIONS: --prometheus-enable bool, $CODER_PROMETHEUS_ENABLE Serve prometheus metrics on the address defined by prometheus address. -INTROSPECTION / TRACING OPTIONS: +INTROSPECTION / TRACING OPTIONS: --trace-logs bool, $CODER_TRACE_LOGS Enables capturing of logs as events in traces. This is useful for debugging, but may result in a very large amount of events being sent @@ -147,14 +147,14 @@ INTROSPECTION / TRACING OPTIONS: --trace-honeycomb-api-key string, $CODER_TRACE_HONEYCOMB_API_KEY Enables trace exporting to Honeycomb.io using the provided API Key. -INTROSPECTION / PPROF OPTIONS: +INTROSPECTION / PPROF OPTIONS: --pprof-address host:port, $CODER_PPROF_ADDRESS (default: 127.0.0.1:6060) The bind address to serve pprof. --pprof-enable bool, $CODER_PPROF_ENABLE Serve pprof metrics on the address defined by pprof address. -NETWORKING OPTIONS: +NETWORKING OPTIONS: --access-url url, $CODER_ACCESS_URL The URL that users will use to access the Coder deployment. @@ -180,7 +180,7 @@ NETWORKING OPTIONS: Specifies the wildcard hostname to use for workspace applications in the form "*.example.com". -NETWORKING / DERP OPTIONS: +NETWORKING / DERP OPTIONS: Most Coder deployments never have to think about DERP because all connections between workspaces and users are peer-to-peer. However, when Coder cannot establish a peer to peer connection, Coder uses a distributed relay network @@ -222,7 +222,7 @@ backed by Tailscale and WireGuard. own DERP region, with region IDs starting at `--derp-server-region-id + 1`. Use special value 'disable' to turn off STUN completely. -NETWORKING / HTTP OPTIONS: +NETWORKING / HTTP OPTIONS: --disable-password-auth bool, $CODER_DISABLE_PASSWORD_AUTH Disable password authentication. This is recommended for security purposes in production deployments that rely on an identity provider. @@ -253,7 +253,7 @@ NETWORKING / HTTP OPTIONS: longer if they are actively making requests, but this functionality can be disabled via --disable-session-expiry-refresh. -NETWORKING / TLS OPTIONS: +NETWORKING / TLS OPTIONS: Configure TLS / HTTPS for your Coder deployment. If you're running Coder behind a TLS-terminating reverse proxy or are accessing Coder over a secure link, you can safely ignore these settings. @@ -315,7 +315,7 @@ can safely ignore these settings. Minimum supported version of TLS. Accepted values are "tls10", "tls11", "tls12" or "tls13". -OAUTH2 / GITHUB OPTIONS: +OAUTH2 / GITHUB OPTIONS: --oauth2-github-allow-everyone bool, $CODER_OAUTH2_GITHUB_ALLOW_EVERYONE Allow all logins, setting this option means allowed orgs and teams must be empty. @@ -340,7 +340,7 @@ OAUTH2 / GITHUB OPTIONS: Base URL of a GitHub Enterprise deployment to use for Login with GitHub. -OIDC OPTIONS: +OIDC OPTIONS: --oidc-group-auto-create bool, $CODER_OIDC_GROUP_AUTO_CREATE (default: false) Automatically creates missing groups from a user's groups claim. @@ -427,7 +427,11 @@ OIDC OPTIONS: --oidc-icon-url url, $CODER_OIDC_ICON_URL URL pointing to the icon to use on the OpenID Connect login button. -PROVISIONING OPTIONS: + --oidc-signups-disabled-text string, $CODER_OIDC_SIGNUPS_DISABLED_TEXT + The custom text to show on the error page informing about disabled + OIDC signups. + +PROVISIONING OPTIONS: Tune the behavior of the provisioner, which is responsible for creating, updating, and deleting workspace resources. @@ -448,7 +452,7 @@ updating, and deleting workspace resources. Number of provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this. -TELEMETRY OPTIONS: +TELEMETRY OPTIONS: Telemetry is critical to our ability to improve Coder. We strip all personalinformation before sending data to our servers. Please only disable telemetrywhen required by your organization's security policy. @@ -457,7 +461,7 @@ telemetrywhen required by your organization's security policy. Whether telemetry is enabled or not. Coder collects anonymized usage data to help improve our product. -USER QUIET HOURS SCHEDULE OPTIONS: +USER QUIET HOURS SCHEDULE OPTIONS: Allow users to set quiet hours schedules each day for workspaces to avoid workspaces stopping during the day due to template max TTL. @@ -477,7 +481,7 @@ workspaces stopping during the day due to template max TTL. must be *. Only one hour and minute can be specified (ranges or comma separated values are not supported). -⚠️ DANGEROUS OPTIONS: +⚠️ DANGEROUS OPTIONS: --dangerous-allow-path-app-sharing bool, $CODER_DANGEROUS_ALLOW_PATH_APP_SHARING Allow workspace apps that are not served from subdomains to be shared. Path-based app sharing is DISABLED by default for security purposes. @@ -494,7 +498,7 @@ workspaces stopping during the day due to template max TTL. can be disabled entirely with --disable-path-apps for further security. -ENTERPRISE OPTIONS: +ENTERPRISE OPTIONS: These options are only available in the Enterprise Edition. --browser-only bool, $CODER_BROWSER_ONLY From 5b4d9a5f996816cdd1b3fa21e0a5d3592094db91 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 31 Jan 2024 17:06:30 +0100 Subject: [PATCH 05/17] StatusForbidden --- coderd/userauth.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/userauth.go b/coderd/userauth.go index 1622878ab4bea..141022576e57c 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -1320,7 +1320,7 @@ func (api *API) oauthLogin(r *http.Request, params *oauthLoginParams) ([]*http.C signupsDisabledText = api.OIDCConfig.SignupsDisabledText } return httpError{ - code: http.StatusBadRequest, + code: http.StatusForbidden, msg: "Signups are disabled", detail: signupsDisabledText, renderStaticPage: true, From f2ccc2b51a5d6318d972197cea3ec09dc92db807 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 31 Jan 2024 17:48:10 +0100 Subject: [PATCH 06/17] Fix? --- cli/testdata/coder_server_--help.golden | 38 ++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/cli/testdata/coder_server_--help.golden b/cli/testdata/coder_server_--help.golden index 8696a0033a942..022682e085a6a 100644 --- a/cli/testdata/coder_server_--help.golden +++ b/cli/testdata/coder_server_--help.golden @@ -61,7 +61,7 @@ OPTIONS: Periodically check for new releases of Coder and inform the owner. The check is performed once per day. -CLIENT OPTIONS: +CLIENT OPTIONS: These options change the behavior of how clients interact with the Coder. Clients include the coder cli, vs code extension, and the web UI. @@ -83,17 +83,17 @@ Clients include the coder cli, vs code extension, and the web UI. The renderer to use when opening a web terminal. Valid values are 'canvas', 'webgl', or 'dom'. -CONFIG OPTIONS: +CONFIG OPTIONS: Use a YAML configuration file when your server launch become unwieldy. -c, --config yaml-config-path, $CODER_CONFIG_PATH Specify a YAML file to load configuration from. --write-config bool - + Write out the current server config as YAML to stdout. -INTROSPECTION / HEALTH CHECK OPTIONS: +INTROSPECTION / HEALTH CHECK OPTIONS: --health-check-refresh duration, $CODER_HEALTH_CHECK_REFRESH (default: 10m0s) Refresh interval for healthchecks. @@ -102,7 +102,7 @@ INTROSPECTION / HEALTH CHECK OPTIONS: the database exceeds this threshold over 5 attempts, the database is considered unhealthy. The default value is 15ms. -INTROSPECTION / LOGGING OPTIONS: +INTROSPECTION / LOGGING OPTIONS: --enable-terraform-debug-mode bool, $CODER_ENABLE_TERRAFORM_DEBUG_MODE (default: false) Allow administrators to enable Terraform debug output. @@ -119,7 +119,7 @@ INTROSPECTION / LOGGING OPTIONS: --log-stackdriver string, $CODER_LOGGING_STACKDRIVER Output Stackdriver compatible logs to a given file. -INTROSPECTION / PROMETHEUS OPTIONS: +INTROSPECTION / PROMETHEUS OPTIONS: --prometheus-address host:port, $CODER_PROMETHEUS_ADDRESS (default: 127.0.0.1:2112) The bind address to serve prometheus metrics. @@ -132,7 +132,7 @@ INTROSPECTION / PROMETHEUS OPTIONS: --prometheus-enable bool, $CODER_PROMETHEUS_ENABLE Serve prometheus metrics on the address defined by prometheus address. -INTROSPECTION / TRACING OPTIONS: +INTROSPECTION / TRACING OPTIONS: --trace-logs bool, $CODER_TRACE_LOGS Enables capturing of logs as events in traces. This is useful for debugging, but may result in a very large amount of events being sent @@ -146,14 +146,14 @@ INTROSPECTION / TRACING OPTIONS: --trace-honeycomb-api-key string, $CODER_TRACE_HONEYCOMB_API_KEY Enables trace exporting to Honeycomb.io using the provided API Key. -INTROSPECTION / PPROF OPTIONS: +INTROSPECTION / PPROF OPTIONS: --pprof-address host:port, $CODER_PPROF_ADDRESS (default: 127.0.0.1:6060) The bind address to serve pprof. --pprof-enable bool, $CODER_PPROF_ENABLE Serve pprof metrics on the address defined by pprof address. -NETWORKING OPTIONS: +NETWORKING OPTIONS: --access-url url, $CODER_ACCESS_URL The URL that users will use to access the Coder deployment. @@ -179,7 +179,7 @@ NETWORKING OPTIONS: Specifies the wildcard hostname to use for workspace applications in the form "*.example.com". -NETWORKING / DERP OPTIONS: +NETWORKING / DERP OPTIONS: Most Coder deployments never have to think about DERP because all connections between workspaces and users are peer-to-peer. However, when Coder cannot establish a peer to peer connection, Coder uses a distributed relay network @@ -221,7 +221,7 @@ backed by Tailscale and WireGuard. own DERP region, with region IDs starting at `--derp-server-region-id + 1`. Use special value 'disable' to turn off STUN completely. -NETWORKING / HTTP OPTIONS: +NETWORKING / HTTP OPTIONS: --disable-password-auth bool, $CODER_DISABLE_PASSWORD_AUTH Disable password authentication. This is recommended for security purposes in production deployments that rely on an identity provider. @@ -252,7 +252,7 @@ NETWORKING / HTTP OPTIONS: longer if they are actively making requests, but this functionality can be disabled via --disable-session-expiry-refresh. -NETWORKING / TLS OPTIONS: +NETWORKING / TLS OPTIONS: Configure TLS / HTTPS for your Coder deployment. If you're running Coder behind a TLS-terminating reverse proxy or are accessing Coder over a secure link, you can safely ignore these settings. @@ -314,7 +314,7 @@ can safely ignore these settings. Minimum supported version of TLS. Accepted values are "tls10", "tls11", "tls12" or "tls13". -OAUTH2 / GITHUB OPTIONS: +OAUTH2 / GITHUB OPTIONS: --oauth2-github-allow-everyone bool, $CODER_OAUTH2_GITHUB_ALLOW_EVERYONE Allow all logins, setting this option means allowed orgs and teams must be empty. @@ -339,7 +339,7 @@ OAUTH2 / GITHUB OPTIONS: Base URL of a GitHub Enterprise deployment to use for Login with GitHub. -OIDC OPTIONS: +OIDC OPTIONS: --oidc-group-auto-create bool, $CODER_OIDC_GROUP_AUTO_CREATE (default: false) Automatically creates missing groups from a user's groups claim. @@ -430,7 +430,7 @@ OIDC OPTIONS: The custom text to show on the error page informing about disabled OIDC signups. -PROVISIONING OPTIONS: +PROVISIONING OPTIONS: Tune the behavior of the provisioner, which is responsible for creating, updating, and deleting workspace resources. @@ -451,7 +451,7 @@ updating, and deleting workspace resources. Number of provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this. -TELEMETRY OPTIONS: +TELEMETRY OPTIONS: Telemetry is critical to our ability to improve Coder. We strip all personalinformation before sending data to our servers. Please only disable telemetrywhen required by your organization's security policy. @@ -460,7 +460,7 @@ telemetrywhen required by your organization's security policy. Whether telemetry is enabled or not. Coder collects anonymized usage data to help improve our product. -USER QUIET HOURS SCHEDULE OPTIONS: +USER QUIET HOURS SCHEDULE OPTIONS: Allow users to set quiet hours schedules each day for workspaces to avoid workspaces stopping during the day due to template max TTL. @@ -480,7 +480,7 @@ workspaces stopping during the day due to template max TTL. must be *. Only one hour and minute can be specified (ranges or comma separated values are not supported). -⚠️ DANGEROUS OPTIONS: +⚠️ DANGEROUS OPTIONS: --dangerous-allow-path-app-sharing bool, $CODER_DANGEROUS_ALLOW_PATH_APP_SHARING Allow workspace apps that are not served from subdomains to be shared. Path-based app sharing is DISABLED by default for security purposes. @@ -497,7 +497,7 @@ workspaces stopping during the day due to template max TTL. can be disabled entirely with --disable-path-apps for further security. -ENTERPRISE OPTIONS: +ENTERPRISE OPTIONS: These options are only available in the Enterprise Edition. --browser-only bool, $CODER_BROWSER_ONLY From 0ae057fec56c9986dd1eab522f2c4979efa1e354 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 31 Jan 2024 17:50:05 +0100 Subject: [PATCH 07/17] Fix? --- cli/testdata/coder_server_--help.golden | 39 +++++++++++++------------ 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/cli/testdata/coder_server_--help.golden b/cli/testdata/coder_server_--help.golden index 022682e085a6a..b6bab928611d2 100644 --- a/cli/testdata/coder_server_--help.golden +++ b/cli/testdata/coder_server_--help.golden @@ -9,6 +9,7 @@ SUBCOMMANDS: create-admin-user Create a new admin user with the given username, email and password and adds it to every organization. + dbcrypt Manage database encryption. postgres-builtin-serve Run the built-in PostgreSQL deployment. postgres-builtin-url Output the connection URL for the built-in PostgreSQL deployment. @@ -61,7 +62,7 @@ OPTIONS: Periodically check for new releases of Coder and inform the owner. The check is performed once per day. -CLIENT OPTIONS: +CLIENT OPTIONS: These options change the behavior of how clients interact with the Coder. Clients include the coder cli, vs code extension, and the web UI. @@ -83,17 +84,17 @@ Clients include the coder cli, vs code extension, and the web UI. The renderer to use when opening a web terminal. Valid values are 'canvas', 'webgl', or 'dom'. -CONFIG OPTIONS: +CONFIG OPTIONS: Use a YAML configuration file when your server launch become unwieldy. -c, --config yaml-config-path, $CODER_CONFIG_PATH Specify a YAML file to load configuration from. --write-config bool - + Write out the current server config as YAML to stdout. -INTROSPECTION / HEALTH CHECK OPTIONS: +INTROSPECTION / HEALTH CHECK OPTIONS: --health-check-refresh duration, $CODER_HEALTH_CHECK_REFRESH (default: 10m0s) Refresh interval for healthchecks. @@ -102,7 +103,7 @@ INTROSPECTION / HEALTH CHECK OPTIONS: the database exceeds this threshold over 5 attempts, the database is considered unhealthy. The default value is 15ms. -INTROSPECTION / LOGGING OPTIONS: +INTROSPECTION / LOGGING OPTIONS: --enable-terraform-debug-mode bool, $CODER_ENABLE_TERRAFORM_DEBUG_MODE (default: false) Allow administrators to enable Terraform debug output. @@ -119,7 +120,7 @@ INTROSPECTION / LOGGING OPTIONS: --log-stackdriver string, $CODER_LOGGING_STACKDRIVER Output Stackdriver compatible logs to a given file. -INTROSPECTION / PROMETHEUS OPTIONS: +INTROSPECTION / PROMETHEUS OPTIONS: --prometheus-address host:port, $CODER_PROMETHEUS_ADDRESS (default: 127.0.0.1:2112) The bind address to serve prometheus metrics. @@ -132,7 +133,7 @@ INTROSPECTION / PROMETHEUS OPTIONS: --prometheus-enable bool, $CODER_PROMETHEUS_ENABLE Serve prometheus metrics on the address defined by prometheus address. -INTROSPECTION / TRACING OPTIONS: +INTROSPECTION / TRACING OPTIONS: --trace-logs bool, $CODER_TRACE_LOGS Enables capturing of logs as events in traces. This is useful for debugging, but may result in a very large amount of events being sent @@ -146,14 +147,14 @@ INTROSPECTION / TRACING OPTIONS: --trace-honeycomb-api-key string, $CODER_TRACE_HONEYCOMB_API_KEY Enables trace exporting to Honeycomb.io using the provided API Key. -INTROSPECTION / PPROF OPTIONS: +INTROSPECTION / PPROF OPTIONS: --pprof-address host:port, $CODER_PPROF_ADDRESS (default: 127.0.0.1:6060) The bind address to serve pprof. --pprof-enable bool, $CODER_PPROF_ENABLE Serve pprof metrics on the address defined by pprof address. -NETWORKING OPTIONS: +NETWORKING OPTIONS: --access-url url, $CODER_ACCESS_URL The URL that users will use to access the Coder deployment. @@ -179,7 +180,7 @@ NETWORKING OPTIONS: Specifies the wildcard hostname to use for workspace applications in the form "*.example.com". -NETWORKING / DERP OPTIONS: +NETWORKING / DERP OPTIONS: Most Coder deployments never have to think about DERP because all connections between workspaces and users are peer-to-peer. However, when Coder cannot establish a peer to peer connection, Coder uses a distributed relay network @@ -221,7 +222,7 @@ backed by Tailscale and WireGuard. own DERP region, with region IDs starting at `--derp-server-region-id + 1`. Use special value 'disable' to turn off STUN completely. -NETWORKING / HTTP OPTIONS: +NETWORKING / HTTP OPTIONS: --disable-password-auth bool, $CODER_DISABLE_PASSWORD_AUTH Disable password authentication. This is recommended for security purposes in production deployments that rely on an identity provider. @@ -252,7 +253,7 @@ NETWORKING / HTTP OPTIONS: longer if they are actively making requests, but this functionality can be disabled via --disable-session-expiry-refresh. -NETWORKING / TLS OPTIONS: +NETWORKING / TLS OPTIONS: Configure TLS / HTTPS for your Coder deployment. If you're running Coder behind a TLS-terminating reverse proxy or are accessing Coder over a secure link, you can safely ignore these settings. @@ -314,7 +315,7 @@ can safely ignore these settings. Minimum supported version of TLS. Accepted values are "tls10", "tls11", "tls12" or "tls13". -OAUTH2 / GITHUB OPTIONS: +OAUTH2 / GITHUB OPTIONS: --oauth2-github-allow-everyone bool, $CODER_OAUTH2_GITHUB_ALLOW_EVERYONE Allow all logins, setting this option means allowed orgs and teams must be empty. @@ -339,7 +340,7 @@ OAUTH2 / GITHUB OPTIONS: Base URL of a GitHub Enterprise deployment to use for Login with GitHub. -OIDC OPTIONS: +OIDC OPTIONS: --oidc-group-auto-create bool, $CODER_OIDC_GROUP_AUTO_CREATE (default: false) Automatically creates missing groups from a user's groups claim. @@ -430,7 +431,7 @@ OIDC OPTIONS: The custom text to show on the error page informing about disabled OIDC signups. -PROVISIONING OPTIONS: +PROVISIONING OPTIONS: Tune the behavior of the provisioner, which is responsible for creating, updating, and deleting workspace resources. @@ -451,7 +452,7 @@ updating, and deleting workspace resources. Number of provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this. -TELEMETRY OPTIONS: +TELEMETRY OPTIONS: Telemetry is critical to our ability to improve Coder. We strip all personalinformation before sending data to our servers. Please only disable telemetrywhen required by your organization's security policy. @@ -460,7 +461,7 @@ telemetrywhen required by your organization's security policy. Whether telemetry is enabled or not. Coder collects anonymized usage data to help improve our product. -USER QUIET HOURS SCHEDULE OPTIONS: +USER QUIET HOURS SCHEDULE OPTIONS: Allow users to set quiet hours schedules each day for workspaces to avoid workspaces stopping during the day due to template max TTL. @@ -480,7 +481,7 @@ workspaces stopping during the day due to template max TTL. must be *. Only one hour and minute can be specified (ranges or comma separated values are not supported). -⚠️ DANGEROUS OPTIONS: +⚠️ DANGEROUS OPTIONS: --dangerous-allow-path-app-sharing bool, $CODER_DANGEROUS_ALLOW_PATH_APP_SHARING Allow workspace apps that are not served from subdomains to be shared. Path-based app sharing is DISABLED by default for security purposes. @@ -497,7 +498,7 @@ workspaces stopping during the day due to template max TTL. can be disabled entirely with --disable-path-apps for further security. -ENTERPRISE OPTIONS: +ENTERPRISE OPTIONS: These options are only available in the Enterprise Edition. --browser-only bool, $CODER_BROWSER_ONLY From 99c9ad7c7653ab2844dc778c9e34d3abbe34f860 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 31 Jan 2024 17:52:21 +0100 Subject: [PATCH 08/17] Fix? --- .../cli/testdata/coder_server_--help.golden | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/enterprise/cli/testdata/coder_server_--help.golden b/enterprise/cli/testdata/coder_server_--help.golden index 2d35cddbba36c..bb3cacdaf9868 100644 --- a/enterprise/cli/testdata/coder_server_--help.golden +++ b/enterprise/cli/testdata/coder_server_--help.golden @@ -62,7 +62,7 @@ OPTIONS: Periodically check for new releases of Coder and inform the owner. The check is performed once per day. -CLIENT OPTIONS: +CLIENT OPTIONS: These options change the behavior of how clients interact with the Coder. Clients include the coder cli, vs code extension, and the web UI. @@ -84,17 +84,17 @@ Clients include the coder cli, vs code extension, and the web UI. The renderer to use when opening a web terminal. Valid values are 'canvas', 'webgl', or 'dom'. -CONFIG OPTIONS: +CONFIG OPTIONS: Use a YAML configuration file when your server launch become unwieldy. -c, --config yaml-config-path, $CODER_CONFIG_PATH Specify a YAML file to load configuration from. --write-config bool - + Write out the current server config as YAML to stdout. -INTROSPECTION / HEALTH CHECK OPTIONS: +INTROSPECTION / HEALTH CHECK OPTIONS: --health-check-refresh duration, $CODER_HEALTH_CHECK_REFRESH (default: 10m0s) Refresh interval for healthchecks. @@ -103,7 +103,7 @@ INTROSPECTION / HEALTH CHECK OPTIONS: the database exceeds this threshold over 5 attempts, the database is considered unhealthy. The default value is 15ms. -INTROSPECTION / LOGGING OPTIONS: +INTROSPECTION / LOGGING OPTIONS: --enable-terraform-debug-mode bool, $CODER_ENABLE_TERRAFORM_DEBUG_MODE (default: false) Allow administrators to enable Terraform debug output. @@ -120,7 +120,7 @@ INTROSPECTION / LOGGING OPTIONS: --log-stackdriver string, $CODER_LOGGING_STACKDRIVER Output Stackdriver compatible logs to a given file. -INTROSPECTION / PROMETHEUS OPTIONS: +INTROSPECTION / PROMETHEUS OPTIONS: --prometheus-address host:port, $CODER_PROMETHEUS_ADDRESS (default: 127.0.0.1:2112) The bind address to serve prometheus metrics. @@ -133,7 +133,7 @@ INTROSPECTION / PROMETHEUS OPTIONS: --prometheus-enable bool, $CODER_PROMETHEUS_ENABLE Serve prometheus metrics on the address defined by prometheus address. -INTROSPECTION / TRACING OPTIONS: +INTROSPECTION / TRACING OPTIONS: --trace-logs bool, $CODER_TRACE_LOGS Enables capturing of logs as events in traces. This is useful for debugging, but may result in a very large amount of events being sent @@ -147,14 +147,14 @@ INTROSPECTION / TRACING OPTIONS: --trace-honeycomb-api-key string, $CODER_TRACE_HONEYCOMB_API_KEY Enables trace exporting to Honeycomb.io using the provided API Key. -INTROSPECTION / PPROF OPTIONS: +INTROSPECTION / PPROF OPTIONS: --pprof-address host:port, $CODER_PPROF_ADDRESS (default: 127.0.0.1:6060) The bind address to serve pprof. --pprof-enable bool, $CODER_PPROF_ENABLE Serve pprof metrics on the address defined by pprof address. -NETWORKING OPTIONS: +NETWORKING OPTIONS: --access-url url, $CODER_ACCESS_URL The URL that users will use to access the Coder deployment. @@ -180,7 +180,7 @@ NETWORKING OPTIONS: Specifies the wildcard hostname to use for workspace applications in the form "*.example.com". -NETWORKING / DERP OPTIONS: +NETWORKING / DERP OPTIONS: Most Coder deployments never have to think about DERP because all connections between workspaces and users are peer-to-peer. However, when Coder cannot establish a peer to peer connection, Coder uses a distributed relay network @@ -222,7 +222,7 @@ backed by Tailscale and WireGuard. own DERP region, with region IDs starting at `--derp-server-region-id + 1`. Use special value 'disable' to turn off STUN completely. -NETWORKING / HTTP OPTIONS: +NETWORKING / HTTP OPTIONS: --disable-password-auth bool, $CODER_DISABLE_PASSWORD_AUTH Disable password authentication. This is recommended for security purposes in production deployments that rely on an identity provider. @@ -253,7 +253,7 @@ NETWORKING / HTTP OPTIONS: longer if they are actively making requests, but this functionality can be disabled via --disable-session-expiry-refresh. -NETWORKING / TLS OPTIONS: +NETWORKING / TLS OPTIONS: Configure TLS / HTTPS for your Coder deployment. If you're running Coder behind a TLS-terminating reverse proxy or are accessing Coder over a secure link, you can safely ignore these settings. @@ -315,7 +315,7 @@ can safely ignore these settings. Minimum supported version of TLS. Accepted values are "tls10", "tls11", "tls12" or "tls13". -OAUTH2 / GITHUB OPTIONS: +OAUTH2 / GITHUB OPTIONS: --oauth2-github-allow-everyone bool, $CODER_OAUTH2_GITHUB_ALLOW_EVERYONE Allow all logins, setting this option means allowed orgs and teams must be empty. @@ -340,7 +340,7 @@ OAUTH2 / GITHUB OPTIONS: Base URL of a GitHub Enterprise deployment to use for Login with GitHub. -OIDC OPTIONS: +OIDC OPTIONS: --oidc-group-auto-create bool, $CODER_OIDC_GROUP_AUTO_CREATE (default: false) Automatically creates missing groups from a user's groups claim. @@ -428,10 +428,10 @@ OIDC OPTIONS: URL pointing to the icon to use on the OpenID Connect login button. --oidc-signups-disabled-text string, $CODER_OIDC_SIGNUPS_DISABLED_TEXT - The custom text to show on the error page informing about disabled - OIDC signups. + The custom text to show on the error page informing about disabled + OIDC signups. -PROVISIONING OPTIONS: +PROVISIONING OPTIONS: Tune the behavior of the provisioner, which is responsible for creating, updating, and deleting workspace resources. @@ -452,7 +452,7 @@ updating, and deleting workspace resources. Number of provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this. -TELEMETRY OPTIONS: +TELEMETRY OPTIONS: Telemetry is critical to our ability to improve Coder. We strip all personalinformation before sending data to our servers. Please only disable telemetrywhen required by your organization's security policy. @@ -461,7 +461,7 @@ telemetrywhen required by your organization's security policy. Whether telemetry is enabled or not. Coder collects anonymized usage data to help improve our product. -USER QUIET HOURS SCHEDULE OPTIONS: +USER QUIET HOURS SCHEDULE OPTIONS: Allow users to set quiet hours schedules each day for workspaces to avoid workspaces stopping during the day due to template max TTL. @@ -481,7 +481,7 @@ workspaces stopping during the day due to template max TTL. must be *. Only one hour and minute can be specified (ranges or comma separated values are not supported). -⚠️ DANGEROUS OPTIONS: +⚠️ DANGEROUS OPTIONS: --dangerous-allow-path-app-sharing bool, $CODER_DANGEROUS_ALLOW_PATH_APP_SHARING Allow workspace apps that are not served from subdomains to be shared. Path-based app sharing is DISABLED by default for security purposes. @@ -498,7 +498,7 @@ workspaces stopping during the day due to template max TTL. can be disabled entirely with --disable-path-apps for further security. -ENTERPRISE OPTIONS: +ENTERPRISE OPTIONS: These options are only available in the Enterprise Edition. --browser-only bool, $CODER_BROWSER_ONLY From 775ee3413088a75287957c56c1f494326b652a43 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 31 Jan 2024 17:53:21 +0100 Subject: [PATCH 09/17] Fix? --- cli/testdata/coder_server_--help.golden | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/testdata/coder_server_--help.golden b/cli/testdata/coder_server_--help.golden index b6bab928611d2..8696a0033a942 100644 --- a/cli/testdata/coder_server_--help.golden +++ b/cli/testdata/coder_server_--help.golden @@ -9,7 +9,6 @@ SUBCOMMANDS: create-admin-user Create a new admin user with the given username, email and password and adds it to every organization. - dbcrypt Manage database encryption. postgres-builtin-serve Run the built-in PostgreSQL deployment. postgres-builtin-url Output the connection URL for the built-in PostgreSQL deployment. From 967cdde7d5b9a76bde13c8694adc9114d1760d5a Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 1 Feb 2024 10:12:03 +0100 Subject: [PATCH 10/17] fmt --- enterprise/cli/testdata/coder_server_--help.golden | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/enterprise/cli/testdata/coder_server_--help.golden b/enterprise/cli/testdata/coder_server_--help.golden index bb3cacdaf9868..b6bab928611d2 100644 --- a/enterprise/cli/testdata/coder_server_--help.golden +++ b/enterprise/cli/testdata/coder_server_--help.golden @@ -428,8 +428,8 @@ OIDC OPTIONS: URL pointing to the icon to use on the OpenID Connect login button. --oidc-signups-disabled-text string, $CODER_OIDC_SIGNUPS_DISABLED_TEXT - The custom text to show on the error page informing about disabled - OIDC signups. + The custom text to show on the error page informing about disabled + OIDC signups. PROVISIONING OPTIONS: Tune the behavior of the provisioner, which is responsible for creating, From d5ecf161b7d7a46003b916cd9fec08f02451ec69 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 1 Feb 2024 11:28:01 +0100 Subject: [PATCH 11/17] WIP --- .../parameter/{plaintext.go => renderer.go} | 31 +++++++++++++++++++ .../{plaintext_test.go => renderer_test.go} | 22 +++++++++++++ 2 files changed, 53 insertions(+) rename coderd/parameter/{plaintext.go => renderer.go} (72%) rename coderd/parameter/{plaintext_test.go => renderer_test.go} (65%) diff --git a/coderd/parameter/plaintext.go b/coderd/parameter/renderer.go similarity index 72% rename from coderd/parameter/plaintext.go rename to coderd/parameter/renderer.go index bbee00d098c23..c8913122019f1 100644 --- a/coderd/parameter/plaintext.go +++ b/coderd/parameter/renderer.go @@ -1,6 +1,7 @@ package parameter import ( + "regexp" "strings" "github.com/charmbracelet/glamour" @@ -95,3 +96,33 @@ func Plaintext(markdown string) (string, error) { return strings.TrimSpace(output), nil } + +var ( + reBold = regexp.MustCompile(`\*\*([^*]+)\*\*`) + reItalic = regexp.MustCompile(`\*([^*]+)\*`) + reStrikethrough = regexp.MustCompile(`~~([^~]+)~~`) + reLink = regexp.MustCompile(`\[([^]]+)\]\(([^)]+)\)`) +) + +func HTML(markdown string) string { + draft := replaceBold(markdown) // bold regexp must go before italic - ** vs. * + draft = replaceItalic(draft) + draft = replaceStrikethrough(draft) + return replaceLinks(draft) +} + +func replaceItalic(markdown string) string { + return reItalic.ReplaceAllString(markdown, "$1") +} + +func replaceBold(markdown string) string { + return reBold.ReplaceAllString(markdown, "$1") +} + +func replaceStrikethrough(markdown string) string { + return reStrikethrough.ReplaceAllString(markdown, "$1") +} + +func replaceLinks(markdown string) string { + return reLink.ReplaceAllString(markdown, `$1`) +} diff --git a/coderd/parameter/plaintext_test.go b/coderd/parameter/renderer_test.go similarity index 65% rename from coderd/parameter/plaintext_test.go rename to coderd/parameter/renderer_test.go index 78945d9984e10..71ff19b90b696 100644 --- a/coderd/parameter/plaintext_test.go +++ b/coderd/parameter/renderer_test.go @@ -47,3 +47,25 @@ __This is bold text.__ require.Equal(t, nothingChanges, stripped) }) } + +func TestHTML(t *testing.T) { + t.Parallel() + t.Run("Simple", func(t *testing.T) { + t.Parallel() + + mdDescription := `**Coder** is in *early access* mode. To ~~register~~ request access, fill out [this form](https://internal.example.com). ***Thank you!***` + expected := `Coder is in early access mode. To register request access, fill out this form. Thank you!` + + rendered := parameter.HTML(mdDescription) + require.Equal(t, expected, rendered) + }) + + t.Run("Nothing changes", func(t *testing.T) { + t.Parallel() + + nothingChanges := "This is a simple description, so nothing changes." + + rendered := parameter.HTML(nothingChanges) + require.Equal(t, nothingChanges, rendered) + }) +} From 9c6a49665e48794be5c45063f638a334f6b5f4ed Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 1 Feb 2024 12:17:42 +0100 Subject: [PATCH 12/17] Use third-party renderer --- coderd/parameter/renderer.go | 38 +++++++----------------- coderd/parameter/renderer_test.go | 49 ++++++++++++++++++++----------- coderd/userauth.go | 3 +- go.mod | 5 +++- go.sum | 2 ++ 5 files changed, 50 insertions(+), 47 deletions(-) diff --git a/coderd/parameter/renderer.go b/coderd/parameter/renderer.go index c8913122019f1..f46853d2d81af 100644 --- a/coderd/parameter/renderer.go +++ b/coderd/parameter/renderer.go @@ -1,11 +1,14 @@ package parameter import ( - "regexp" + "bytes" "strings" "github.com/charmbracelet/glamour" "github.com/charmbracelet/glamour/ansi" + gomarkdown "github.com/gomarkdown/markdown" + "github.com/gomarkdown/markdown/html" + "github.com/gomarkdown/markdown/parser" "golang.org/x/xerrors" ) @@ -97,32 +100,11 @@ func Plaintext(markdown string) (string, error) { return strings.TrimSpace(output), nil } -var ( - reBold = regexp.MustCompile(`\*\*([^*]+)\*\*`) - reItalic = regexp.MustCompile(`\*([^*]+)\*`) - reStrikethrough = regexp.MustCompile(`~~([^~]+)~~`) - reLink = regexp.MustCompile(`\[([^]]+)\]\(([^)]+)\)`) -) - func HTML(markdown string) string { - draft := replaceBold(markdown) // bold regexp must go before italic - ** vs. * - draft = replaceItalic(draft) - draft = replaceStrikethrough(draft) - return replaceLinks(draft) -} - -func replaceItalic(markdown string) string { - return reItalic.ReplaceAllString(markdown, "$1") -} - -func replaceBold(markdown string) string { - return reBold.ReplaceAllString(markdown, "$1") -} - -func replaceStrikethrough(markdown string) string { - return reStrikethrough.ReplaceAllString(markdown, "$1") -} - -func replaceLinks(markdown string) string { - return reLink.ReplaceAllString(markdown, `$1`) + p := parser.NewWithExtensions(parser.CommonExtensions) + doc := p.Parse([]byte(markdown)) + renderer := html.NewRenderer(html.RendererOptions{ + Flags: html.CommonFlags | html.SkipHTML}, + ) + return string(bytes.TrimSpace(gomarkdown.Render(doc, renderer))) } diff --git a/coderd/parameter/renderer_test.go b/coderd/parameter/renderer_test.go index 71ff19b90b696..9c511665383c4 100644 --- a/coderd/parameter/renderer_test.go +++ b/coderd/parameter/renderer_test.go @@ -50,22 +50,37 @@ __This is bold text.__ func TestHTML(t *testing.T) { t.Parallel() - t.Run("Simple", func(t *testing.T) { - t.Parallel() - - mdDescription := `**Coder** is in *early access* mode. To ~~register~~ request access, fill out [this form](https://internal.example.com). ***Thank you!***` - expected := `Coder is in early access mode. To register request access, fill out this form. Thank you!` - rendered := parameter.HTML(mdDescription) - require.Equal(t, expected, rendered) - }) - - t.Run("Nothing changes", func(t *testing.T) { - t.Parallel() - - nothingChanges := "This is a simple description, so nothing changes." - - rendered := parameter.HTML(nothingChanges) - require.Equal(t, nothingChanges, rendered) - }) + tests := []struct { + name string + input string + expected string + }{ + { + name: "Simple", + input: `**Coder** is in *early access* mode. To ~~register~~ request access, fill out [this form](https://internal.example.com). ***Thank you!***`, + expected: `

Coder is in early access mode. To register request access, fill out this form. Thank you!

`, + }, + { + name: "Tricky", + input: `**Cod*er** is in *early a**ccess** mode`, + expected: `

Cod*er is in *early access mode

`, + }, + { + name: "No Markdown tags", + input: "This is a simple description, so nothing changes.", + expected: "

This is a simple description, so nothing changes.

", + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + rendered := parameter.HTML(tt.input) + require.Equal(t, tt.expected, rendered) + }) + } } diff --git a/coderd/userauth.go b/coderd/userauth.go index 141022576e57c..86ea953a92103 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -31,6 +31,7 @@ import ( "github.com/coder/coder/v2/coderd/database/dbtime" "github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpmw" + "github.com/coder/coder/v2/coderd/parameter" "github.com/coder/coder/v2/coderd/promoauth" "github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/userpassword" @@ -1317,7 +1318,7 @@ func (api *API) oauthLogin(r *http.Request, params *oauthLoginParams) ([]*http.C if user.ID == uuid.Nil && !params.AllowSignups { signupsDisabledText := "Please contact your Coder administrator to request access." if api.OIDCConfig != nil && api.OIDCConfig.SignupsDisabledText != "" { - signupsDisabledText = api.OIDCConfig.SignupsDisabledText + signupsDisabledText = parameter.HTML(api.OIDCConfig.SignupsDisabledText) } return httpError{ code: http.StatusForbidden, diff --git a/go.mod b/go.mod index bbdc6462f4495..a647298f69a8a 100644 --- a/go.mod +++ b/go.mod @@ -206,7 +206,10 @@ require ( require go.uber.org/mock v0.4.0 -require github.com/benbjohnson/clock v1.3.5 +require ( + github.com/benbjohnson/clock v1.3.5 + github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 +) require github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 // indirect diff --git a/go.sum b/go.sum index c74f064e40c20..9b44935426d7d 100644 --- a/go.sum +++ b/go.sum @@ -427,6 +427,8 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 h1:k4Tw0nt6lwro3Uin8eqoET7MDA4JnT8YgbCjc/g5E3k= +github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/flatbuffers v23.1.21+incompatible h1:bUqzx/MXCDxuS0hRJL2EfjyZL3uQrPbMocUa8zGqsTA= From f13919111cf08eec36d9782303c01dd48693aab6 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 1 Feb 2024 13:02:07 +0100 Subject: [PATCH 13/17] Renderer works --- coderd/userauth.go | 6 ++++++ site/site.go | 9 ++++++++- site/static/error.html | 4 ++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/coderd/userauth.go b/coderd/userauth.go index 86ea953a92103..dbb01f12e31ad 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -1255,6 +1255,8 @@ type httpError struct { msg string detail string renderStaticPage bool + + renderDetailMarkdown bool } func (e httpError) Write(rw http.ResponseWriter, r *http.Request) { @@ -1266,6 +1268,8 @@ func (e httpError) Write(rw http.ResponseWriter, r *http.Request) { Description: e.detail, RetryEnabled: false, DashboardURL: "/login", + + RenderDescriptionMarkdown: e.renderDetailMarkdown, }) return } @@ -1325,6 +1329,8 @@ func (api *API) oauthLogin(r *http.Request, params *oauthLoginParams) ([]*http.C msg: "Signups are disabled", detail: signupsDisabledText, renderStaticPage: true, + + renderDetailMarkdown: true, } } diff --git a/site/site.go b/site/site.go index ba6004fc3ce09..0476565521ac9 100644 --- a/site/site.go +++ b/site/site.go @@ -773,6 +773,8 @@ type ErrorPageData struct { RetryEnabled bool DashboardURL string Warnings []string + + RenderDescriptionMarkdown bool } // RenderStaticErrorPage renders the static error page. This is used by app @@ -781,12 +783,17 @@ type ErrorPageData struct { func RenderStaticErrorPage(rw http.ResponseWriter, r *http.Request, data ErrorPageData) { type outerData struct { Error ErrorPageData + + ErrorDescriptionHTML htmltemplate.HTML } rw.Header().Set("Content-Type", "text/html; charset=utf-8") rw.WriteHeader(data.Status) - err := errorTemplate.Execute(rw, outerData{Error: data}) + err := errorTemplate.Execute(rw, outerData{ + Error: data, + ErrorDescriptionHTML: htmltemplate.HTML(data.Description), //nolint:gosec // gosec thinks this is user-input, but it is from Coder deployment configuration. + }) if err != nil { httpapi.Write(r.Context(), rw, http.StatusInternalServerError, codersdk.Response{ Message: "Failed to render error page: " + err.Error(), diff --git a/site/static/error.html b/site/static/error.html index 46c9a1b9e7f7a..3203da56c94c2 100644 --- a/site/static/error.html +++ b/site/static/error.html @@ -167,7 +167,11 @@

{{- if not .Error.HideStatus }}{{ .Error.Status }} - {{end}}{{ .Error.Title }}

+ {{- if .Error.RenderDescriptionMarkdown }} + {{ .ErrorDescriptionHTML }} + {{ else }}

{{ .Error.Description }}

+ {{ end }} {{- if .Error.Warnings }}
From cb3796f66c287c9a574f9c992a16dfd4d78357e1 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 1 Feb 2024 13:05:02 +0100 Subject: [PATCH 14/17] fmt --- coderd/parameter/renderer.go | 3 ++- site/static/error.html | 8 +++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/coderd/parameter/renderer.go b/coderd/parameter/renderer.go index f46853d2d81af..3767f63cd889c 100644 --- a/coderd/parameter/renderer.go +++ b/coderd/parameter/renderer.go @@ -104,7 +104,8 @@ func HTML(markdown string) string { p := parser.NewWithExtensions(parser.CommonExtensions) doc := p.Parse([]byte(markdown)) renderer := html.NewRenderer(html.RendererOptions{ - Flags: html.CommonFlags | html.SkipHTML}, + Flags: html.CommonFlags | html.SkipHTML, + }, ) return string(bytes.TrimSpace(gomarkdown.Render(doc, renderer))) } diff --git a/site/static/error.html b/site/static/error.html index 3203da56c94c2..a07c96b8ec5aa 100644 --- a/site/static/error.html +++ b/site/static/error.html @@ -167,12 +167,10 @@

{{- if not .Error.HideStatus }}{{ .Error.Status }} - {{end}}{{ .Error.Title }}

- {{- if .Error.RenderDescriptionMarkdown }} - {{ .ErrorDescriptionHTML }} - {{ else }} + {{- if .Error.RenderDescriptionMarkdown }} {{ .ErrorDescriptionHTML }} {{ + else }}

{{ .Error.Description }}

- {{ end }} - {{- if .Error.Warnings }} + {{ end }} {{- if .Error.Warnings }}
Date: Thu, 1 Feb 2024 16:08:28 +0100 Subject: [PATCH 15/17] xss --- coderd/parameter/renderer_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/coderd/parameter/renderer_test.go b/coderd/parameter/renderer_test.go index 9c511665383c4..f0765a7a6eb14 100644 --- a/coderd/parameter/renderer_test.go +++ b/coderd/parameter/renderer_test.go @@ -66,6 +66,11 @@ func TestHTML(t *testing.T) { input: `**Cod*er** is in *early a**ccess** mode`, expected: `

Cod*er is in *early access mode

`, }, + { + name: "XSS", + input: `

Click here to get access!

?`, + expected: `

Click here to get access!?

`, + }, { name: "No Markdown tags", input: "This is a simple description, so nothing changes.", From de24c0b3160780c7f7ede059b13899123e34f591 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 1 Feb 2024 16:48:26 +0100 Subject: [PATCH 16/17] comment --- cli/testdata/coder_server_--help.golden | 2 +- codersdk/deployment.go | 2 +- docs/cli/server.md | 2 +- enterprise/cli/testdata/coder_server_--help.golden | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/testdata/coder_server_--help.golden b/cli/testdata/coder_server_--help.golden index 8696a0033a942..632a96a470354 100644 --- a/cli/testdata/coder_server_--help.golden +++ b/cli/testdata/coder_server_--help.golden @@ -428,7 +428,7 @@ OIDC OPTIONS: --oidc-signups-disabled-text string, $CODER_OIDC_SIGNUPS_DISABLED_TEXT The custom text to show on the error page informing about disabled - OIDC signups. + OIDC signups. Markdown format is supported. PROVISIONING OPTIONS: Tune the behavior of the provisioner, which is responsible for creating, diff --git a/codersdk/deployment.go b/codersdk/deployment.go index 80f50e0580672..a47e72372b881 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -1269,7 +1269,7 @@ when required by your organization's security policy.`, }, { Name: "Signups disabled text", - Description: "The custom text to show on the error page informing about disabled OIDC signups.", + Description: "The custom text to show on the error page informing about disabled OIDC signups. Markdown format is supported.", Flag: "oidc-signups-disabled-text", Env: "CODER_OIDC_SIGNUPS_DISABLED_TEXT", Value: &c.OIDC.SignupsDisabledText, diff --git a/docs/cli/server.md b/docs/cli/server.md index 14f3b8b9440ec..f678041901ba5 100644 --- a/docs/cli/server.md +++ b/docs/cli/server.md @@ -905,7 +905,7 @@ The token expiry duration for browser sessions. Sessions may last longer if they | Environment | $CODER_OIDC_SIGNUPS_DISABLED_TEXT | | YAML | oidc.signupsDisabledText | -The custom text to show on the error page informing about disabled OIDC signups. +The custom text to show on the error page informing about disabled OIDC signups. Markdown format is supported. ### --log-stackdriver diff --git a/enterprise/cli/testdata/coder_server_--help.golden b/enterprise/cli/testdata/coder_server_--help.golden index b6bab928611d2..8e9ccac868c1e 100644 --- a/enterprise/cli/testdata/coder_server_--help.golden +++ b/enterprise/cli/testdata/coder_server_--help.golden @@ -429,7 +429,7 @@ OIDC OPTIONS: --oidc-signups-disabled-text string, $CODER_OIDC_SIGNUPS_DISABLED_TEXT The custom text to show on the error page informing about disabled - OIDC signups. + OIDC signups. Markdown format is supported. PROVISIONING OPTIONS: Tune the behavior of the provisioner, which is responsible for creating, From 6264530a6b3d6404b1e0931b68e661a55952ff0c Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 1 Feb 2024 16:54:17 +0100 Subject: [PATCH 17/17] make gen --- cli/testdata/server-config.yaml.golden | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/testdata/server-config.yaml.golden b/cli/testdata/server-config.yaml.golden index a570e8eb50abe..dfc1d0ca150dc 100644 --- a/cli/testdata/server-config.yaml.golden +++ b/cli/testdata/server-config.yaml.golden @@ -349,6 +349,7 @@ oidc: # (default: , type: url) iconURL: # The custom text to show on the error page informing about disabled OIDC signups. + # Markdown format is supported. # (default: , type: string) signupsDisabledText: "" # Telemetry is critical to our ability to improve Coder. We strip all personal