User friendly error messages during OAUTH and SAML flows (#16795)
* Renders error messages in webapp * Added unit test Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
9aaf29ffb4
Коммит
01e83f64da
@@ -111,6 +111,7 @@ func RenderWebError(config *model.Config, w http.ResponseWriter, r *http.Request
|
|||||||
fmt.Fprintln(w, `<!DOCTYPE html><html><head></head>`)
|
fmt.Fprintln(w, `<!DOCTYPE html><html><head></head>`)
|
||||||
fmt.Fprintln(w, `<body onload="window.location = '`+template.HTMLEscapeString(template.JSEscapeString(destination))+`'">`)
|
fmt.Fprintln(w, `<body onload="window.location = '`+template.HTMLEscapeString(template.JSEscapeString(destination))+`'">`)
|
||||||
fmt.Fprintln(w, `<noscript><meta http-equiv="refresh" content="0; url=`+template.HTMLEscapeString(destination)+`"></noscript>`)
|
fmt.Fprintln(w, `<noscript><meta http-equiv="refresh" content="0; url=`+template.HTMLEscapeString(destination)+`"></noscript>`)
|
||||||
|
fmt.Fprintln(w, `<!-- web error message -->`)
|
||||||
fmt.Fprintln(w, `<a href="`+template.HTMLEscapeString(destination)+`" style="color: #c0c0c0;">...</a>`)
|
fmt.Fprintln(w, `<a href="`+template.HTMLEscapeString(destination)+`" style="color: #c0c0c0;">...</a>`)
|
||||||
fmt.Fprintln(w, `</body></html>`)
|
fmt.Fprintln(w, `</body></html>`)
|
||||||
}
|
}
|
||||||
@@ -170,6 +171,7 @@ func RenderMobileMessage(w http.ResponseWriter, message string) {
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<!-- mobile app message -->
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="message-container">
|
<div class="message-container">
|
||||||
`+message+`
|
`+message+`
|
||||||
|
|||||||
@@ -286,12 +286,8 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderError := func(err *model.AppError) {
|
renderError := func(err *model.AppError) {
|
||||||
if isMobile {
|
if isMobile && hasRedirectURL {
|
||||||
if hasRedirectURL {
|
utils.RenderMobileError(c.App.Config(), w, err, redirectURL)
|
||||||
utils.RenderMobileError(c.App.Config(), w, err, redirectURL)
|
|
||||||
} else {
|
|
||||||
w.Write([]byte(err.ToJson()))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
utils.RenderWebAppError(c.App.Config(), w, r, err, c.App.AsymmetricSigningKey())
|
utils.RenderWebAppError(c.App.Config(), w, r, err, c.App.AsymmetricSigningKey())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
package web
|
package web
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -17,6 +18,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/v5/einterfaces"
|
"github.com/mattermost/mattermost-server/v5/einterfaces"
|
||||||
|
"github.com/mattermost/mattermost-server/v5/mlog"
|
||||||
"github.com/mattermost/mattermost-server/v5/model"
|
"github.com/mattermost/mattermost-server/v5/model"
|
||||||
"github.com/mattermost/mattermost-server/v5/utils"
|
"github.com/mattermost/mattermost-server/v5/utils"
|
||||||
)
|
)
|
||||||
@@ -522,6 +524,44 @@ func TestOAuthComplete(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOAuthComplete_ErrorMessages(t *testing.T) {
|
||||||
|
th := Setup(t).InitBasic()
|
||||||
|
defer th.TearDown()
|
||||||
|
c := &Context{
|
||||||
|
App: th.App,
|
||||||
|
Params: &Params{
|
||||||
|
Service: "gitlab",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
translationFunc := utils.GetUserTranslations("en")
|
||||||
|
c.App.SetT(translationFunc)
|
||||||
|
buffer := &bytes.Buffer{}
|
||||||
|
c.Logger = mlog.NewTestingLogger(t, buffer)
|
||||||
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GitLabSettings.Enable = true })
|
||||||
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOAuthServiceProvider = true })
|
||||||
|
provider := &MattermostTestProvider{}
|
||||||
|
einterfaces.RegisterOauthProvider(model.SERVICE_GITLAB, provider)
|
||||||
|
|
||||||
|
responseWriter := httptest.NewRecorder()
|
||||||
|
|
||||||
|
// Renders for web & mobile app with webview
|
||||||
|
request, _ := http.NewRequest(http.MethodGet, th.App.GetSiteURL()+"/signup/gitlab/complete?code=1234", nil)
|
||||||
|
|
||||||
|
completeOAuth(c, responseWriter, request)
|
||||||
|
assert.Contains(t, responseWriter.Body.String(), "<!-- web error message -->")
|
||||||
|
|
||||||
|
// Renders for mobile app with redirect url
|
||||||
|
stateProps := map[string]string{}
|
||||||
|
stateProps["action"] = model.OAUTH_ACTION_MOBILE
|
||||||
|
stateProps["redirect_to"] = th.App.Config().NativeAppSettings.AppCustomURLSchemes[0]
|
||||||
|
state := base64.StdEncoding.EncodeToString([]byte(model.MapToJson(stateProps)))
|
||||||
|
request2, _ := http.NewRequest(http.MethodGet, th.App.GetSiteURL()+"/signup/gitlab/complete?code=1234&state="+url.QueryEscape(state), nil)
|
||||||
|
|
||||||
|
completeOAuth(c, responseWriter, request2)
|
||||||
|
assert.Contains(t, responseWriter.Body.String(), "<!-- mobile app message -->")
|
||||||
|
}
|
||||||
|
|
||||||
func HttpGet(url string, httpClient *http.Client, authToken string, followRedirect bool) (*http.Response, *model.AppError) {
|
func HttpGet(url string, httpClient *http.Client, authToken string, followRedirect bool) (*http.Response, *model.AppError) {
|
||||||
rq, _ := http.NewRequest("GET", url, nil)
|
rq, _ := http.NewRequest("GET", url, nil)
|
||||||
rq.Close = true
|
rq.Close = true
|
||||||
|
|||||||
@@ -111,13 +111,9 @@ func completeSaml(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleError := func(err *model.AppError) {
|
handleError := func(err *model.AppError) {
|
||||||
if isMobile {
|
if isMobile && hasRedirectURL {
|
||||||
err.Translate(c.App.T)
|
err.Translate(c.App.T)
|
||||||
if hasRedirectURL {
|
utils.RenderMobileError(c.App.Config(), w, err, redirectURL)
|
||||||
utils.RenderMobileError(c.App.Config(), w, err, redirectURL)
|
|
||||||
} else {
|
|
||||||
w.Write([]byte(err.ToJson()))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
c.Err = err
|
c.Err = err
|
||||||
c.Err.StatusCode = http.StatusFound
|
c.Err.StatusCode = http.StatusFound
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user