feat: add custom error message on signups disabled page (#11959)

This commit is contained in:
Marcin Tojek
2024-02-01 18:01:25 +01:00
committed by GitHub
parent e070a55142
commit ad8e0db172
18 changed files with 135 additions and 5 deletions

3
coderd/apidoc/docs.go generated
View File

@ -10071,6 +10071,9 @@ const docTemplate = `{
"sign_in_text": {
"type": "string"
},
"signups_disabled_text": {
"type": "string"
},
"user_role_field": {
"type": "string"
},

View File

@ -9052,6 +9052,9 @@
"sign_in_text": {
"type": "string"
},
"signups_disabled_text": {
"type": "string"
},
"user_role_field": {
"type": "string"
},

View File

@ -1,10 +1,14 @@
package parameter
import (
"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"
)
@ -95,3 +99,13 @@ func Plaintext(markdown string) (string, error) {
return strings.TrimSpace(output), nil
}
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,
},
)
return string(bytes.TrimSpace(gomarkdown.Render(doc, renderer)))
}

View File

@ -47,3 +47,45 @@ __This is bold text.__
require.Equal(t, nothingChanges, stripped)
})
}
func TestHTML(t *testing.T) {
t.Parallel()
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: `<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>`,
},
{
name: "Tricky",
input: `**Cod*er** is in *early a**ccess** <img src="foobar">mode`,
expected: `<p><strong>Cod*er</strong> is in *early a<strong>ccess</strong> mode</p>`,
},
{
name: "XSS",
input: `<p onclick="alert(\"omghax\")">Click here to get access!</p>?`,
expected: `<p>Click here to get access!?</p>`,
},
{
name: "No Markdown tags",
input: "This is a simple description, so nothing changes.",
expected: "<p>This is a simple description, so nothing changes.</p>",
},
}
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)
})
}
}

View File

@ -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"
@ -740,6 +741,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 {
@ -1252,6 +1255,8 @@ type httpError struct {
msg string
detail string
renderStaticPage bool
renderDetailMarkdown bool
}
func (e httpError) Write(rw http.ResponseWriter, r *http.Request) {
@ -1263,6 +1268,8 @@ func (e httpError) Write(rw http.ResponseWriter, r *http.Request) {
Description: e.detail,
RetryEnabled: false,
DashboardURL: "/login",
RenderDescriptionMarkdown: e.renderDetailMarkdown,
})
return
}
@ -1313,9 +1320,17 @@ 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 = parameter.HTML(api.OIDCConfig.SignupsDisabledText)
}
return httpError{
code: http.StatusForbidden,
msg: fmt.Sprintf("Signups are not allowed for login type %q", params.LoginType),
code: http.StatusForbidden,
msg: "Signups are disabled",
detail: signupsDisabledText,
renderStaticPage: true,
renderDetailMarkdown: true,
}
}