Skip to content

Commit ad8e0db

Browse files
authored
feat: add custom error message on signups disabled page (coder#11959)
1 parent e070a55 commit ad8e0db

File tree

18 files changed

+135
-5
lines changed

18 files changed

+135
-5
lines changed

cli/server.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ func createOIDCConfig(ctx context.Context, vals *codersdk.DeploymentValues) (*co
179179
UserRoleMapping: vals.OIDC.UserRoleMapping.Value,
180180
UserRolesDefault: vals.OIDC.UserRolesDefault.GetSlice(),
181181
SignInText: vals.OIDC.SignInText.String(),
182+
SignupsDisabledText: vals.OIDC.SignupsDisabledText.String(),
182183
IconURL: vals.OIDC.IconURL.String(),
183184
IgnoreEmailVerified: vals.OIDC.IgnoreEmailVerified.Value(),
184185
}, nil

cli/testdata/coder_server_--help.golden

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,10 @@ OIDC OPTIONS:
426426
--oidc-icon-url url, $CODER_OIDC_ICON_URL
427427
URL pointing to the icon to use on the OpenID Connect login button.
428428

429+
--oidc-signups-disabled-text string, $CODER_OIDC_SIGNUPS_DISABLED_TEXT
430+
The custom text to show on the error page informing about disabled
431+
OIDC signups. Markdown format is supported.
432+
429433
PROVISIONING OPTIONS:
430434
Tune the behavior of the provisioner, which is responsible for creating,
431435
updating, and deleting workspace resources.

cli/testdata/server-config.yaml.golden

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,10 @@ oidc:
348348
# URL pointing to the icon to use on the OpenID Connect login button.
349349
# (default: <unset>, type: url)
350350
iconURL:
351+
# The custom text to show on the error page informing about disabled OIDC signups.
352+
# Markdown format is supported.
353+
# (default: <unset>, type: string)
354+
signupsDisabledText: ""
351355
# Telemetry is critical to our ability to improve Coder. We strip all personal
352356
# information before sending data to our servers. Please only disable telemetry
353357
# when required by your organization's security policy.

coderd/apidoc/docs.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/parameter/plaintext.go renamed to coderd/parameter/renderer.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package parameter
22

33
import (
4+
"bytes"
45
"strings"
56

67
"github.com/charmbracelet/glamour"
78
"github.com/charmbracelet/glamour/ansi"
9+
gomarkdown "github.com/gomarkdown/markdown"
10+
"github.com/gomarkdown/markdown/html"
11+
"github.com/gomarkdown/markdown/parser"
812
"golang.org/x/xerrors"
913
)
1014

@@ -95,3 +99,13 @@ func Plaintext(markdown string) (string, error) {
9599

96100
return strings.TrimSpace(output), nil
97101
}
102+
103+
func HTML(markdown string) string {
104+
p := parser.NewWithExtensions(parser.CommonExtensions)
105+
doc := p.Parse([]byte(markdown))
106+
renderer := html.NewRenderer(html.RendererOptions{
107+
Flags: html.CommonFlags | html.SkipHTML,
108+
},
109+
)
110+
return string(bytes.TrimSpace(gomarkdown.Render(doc, renderer)))
111+
}

coderd/parameter/plaintext_test.go renamed to coderd/parameter/renderer_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,45 @@ __This is bold text.__
4747
require.Equal(t, nothingChanges, stripped)
4848
})
4949
}
50+
51+
func TestHTML(t *testing.T) {
52+
t.Parallel()
53+
54+
tests := []struct {
55+
name string
56+
input string
57+
expected string
58+
}{
59+
{
60+
name: "Simple",
61+
input: `**Coder** is in *early access* mode. To ~~register~~ request access, fill out [this form](https://internal.example.com). ***Thank you!***`,
62+
expected: `<p><strong>Coder</strong> is in <em>early access</em> mode. To <del>register</del> request access, fill out <a href="https://internal.example.com">this form</a>. <strong><em>Thank you!</em></strong></p>`,
63+
},
64+
{
65+
name: "Tricky",
66+
input: `**Cod*er** is in *early a**ccess** <img src="foobar">mode`,
67+
expected: `<p><strong>Cod*er</strong> is in *early a<strong>ccess</strong> mode</p>`,
68+
},
69+
{
70+
name: "XSS",
71+
input: `<p onclick="alert(\"omghax\")">Click here to get access!</p>?`,
72+
expected: `<p>Click here to get access!?</p>`,
73+
},
74+
{
75+
name: "No Markdown tags",
76+
input: "This is a simple description, so nothing changes.",
77+
expected: "<p>This is a simple description, so nothing changes.</p>",
78+
},
79+
}
80+
81+
for _, tt := range tests {
82+
tt := tt
83+
84+
t.Run(tt.name, func(t *testing.T) {
85+
t.Parallel()
86+
87+
rendered := parameter.HTML(tt.input)
88+
require.Equal(t, tt.expected, rendered)
89+
})
90+
}
91+
}

coderd/userauth.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/coder/coder/v2/coderd/database/dbtime"
3232
"github.com/coder/coder/v2/coderd/httpapi"
3333
"github.com/coder/coder/v2/coderd/httpmw"
34+
"github.com/coder/coder/v2/coderd/parameter"
3435
"github.com/coder/coder/v2/coderd/promoauth"
3536
"github.com/coder/coder/v2/coderd/rbac"
3637
"github.com/coder/coder/v2/coderd/userpassword"
@@ -740,6 +741,8 @@ type OIDCConfig struct {
740741
SignInText string
741742
// IconURL points to the URL of an icon to display on the OIDC login button
742743
IconURL string
744+
// SignupsDisabledText is the text do display on the static error page.
745+
SignupsDisabledText string
743746
}
744747

745748
func (cfg OIDCConfig) RoleSyncEnabled() bool {
@@ -1252,6 +1255,8 @@ type httpError struct {
12521255
msg string
12531256
detail string
12541257
renderStaticPage bool
1258+
1259+
renderDetailMarkdown bool
12551260
}
12561261

12571262
func (e httpError) Write(rw http.ResponseWriter, r *http.Request) {
@@ -1263,6 +1268,8 @@ func (e httpError) Write(rw http.ResponseWriter, r *http.Request) {
12631268
Description: e.detail,
12641269
RetryEnabled: false,
12651270
DashboardURL: "/login",
1271+
1272+
RenderDescriptionMarkdown: e.renderDetailMarkdown,
12661273
})
12671274
return
12681275
}
@@ -1313,9 +1320,17 @@ func (api *API) oauthLogin(r *http.Request, params *oauthLoginParams) ([]*http.C
13131320
}
13141321

13151322
if user.ID == uuid.Nil && !params.AllowSignups {
1323+
signupsDisabledText := "Please contact your Coder administrator to request access."
1324+
if api.OIDCConfig != nil && api.OIDCConfig.SignupsDisabledText != "" {
1325+
signupsDisabledText = parameter.HTML(api.OIDCConfig.SignupsDisabledText)
1326+
}
13161327
return httpError{
1317-
code: http.StatusForbidden,
1318-
msg: fmt.Sprintf("Signups are not allowed for login type %q", params.LoginType),
1328+
code: http.StatusForbidden,
1329+
msg: "Signups are disabled",
1330+
detail: signupsDisabledText,
1331+
renderStaticPage: true,
1332+
1333+
renderDetailMarkdown: true,
13191334
}
13201335
}
13211336

codersdk/deployment.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ type OIDCConfig struct {
303303
UserRolesDefault clibase.StringArray `json:"user_roles_default" typescript:",notnull"`
304304
SignInText clibase.String `json:"sign_in_text" typescript:",notnull"`
305305
IconURL clibase.URL `json:"icon_url" typescript:",notnull"`
306+
SignupsDisabledText clibase.String `json:"signups_disabled_text" typescript:",notnull"`
306307
}
307308

308309
type TelemetryConfig struct {
@@ -1266,6 +1267,15 @@ when required by your organization's security policy.`,
12661267
Group: &deploymentGroupOIDC,
12671268
YAML: "iconURL",
12681269
},
1270+
{
1271+
Name: "Signups disabled text",
1272+
Description: "The custom text to show on the error page informing about disabled OIDC signups. Markdown format is supported.",
1273+
Flag: "oidc-signups-disabled-text",
1274+
Env: "CODER_OIDC_SIGNUPS_DISABLED_TEXT",
1275+
Value: &c.OIDC.SignupsDisabledText,
1276+
Group: &deploymentGroupOIDC,
1277+
YAML: "signupsDisabledText",
1278+
},
12691279
// Telemetry settings
12701280
{
12711281
Name: "Telemetry Enable",

docs/api/general.md

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)