[MM-46216] P3 Bugfix - Oauth redirectURI with query parameters generates malformed redirect URL (#20854)
* Parse and reconstruct URI, instead of using string concatenation * Rename parse error, add test Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
91f7eb0957
Коммит
2171ad8abf
19
app/oauth.go
19
app/oauth.go
@@ -165,11 +165,22 @@ func (a *App) GetOAuthCodeRedirect(userID string, authRequest *model.AuthorizeRe
|
||||
authData := &model.AuthData{UserId: userID, ClientId: authRequest.ClientId, CreateAt: model.GetMillis(), RedirectUri: authRequest.RedirectURI, State: authRequest.State, Scope: authRequest.Scope}
|
||||
authData.Code = model.NewId() + model.NewId()
|
||||
|
||||
if _, err := a.Srv().Store().OAuth().SaveAuthData(authData); err != nil {
|
||||
return authRequest.RedirectURI + "?error=server_error&state=" + authRequest.State, nil
|
||||
// parse authRequest.RedirectURI to handle query parameters see: https://mattermost.atlassian.net/browse/MM-46216
|
||||
uri, err := url.Parse(authRequest.RedirectURI)
|
||||
if err != nil {
|
||||
return authRequest.RedirectURI + "?error=redirect_uri_parse_error&state=" + authRequest.State, nil
|
||||
}
|
||||
|
||||
return authRequest.RedirectURI + "?code=" + url.QueryEscape(authData.Code) + "&state=" + url.QueryEscape(authData.State), nil
|
||||
queryParams := uri.Query()
|
||||
if _, err := a.Srv().Store().OAuth().SaveAuthData(authData); err != nil {
|
||||
queryParams.Set("error", "server_error")
|
||||
queryParams.Set("state", authRequest.State)
|
||||
uri.RawQuery = queryParams.Encode()
|
||||
return uri.String(), nil
|
||||
}
|
||||
queryParams.Set("code", url.QueryEscape(authData.Code))
|
||||
queryParams.Set("state", url.QueryEscape(authData.State))
|
||||
uri.RawQuery = queryParams.Encode()
|
||||
return uri.String(), nil
|
||||
}
|
||||
|
||||
func (a *App) AllowOAuthAppAccessToUser(userID string, authRequest *model.AuthorizeRequest) (string, *model.AppError) {
|
||||
|
||||
@@ -137,6 +137,35 @@ func TestAuthorizeOAuthApp(t *testing.T) {
|
||||
_, resp, err = apiClient.AuthorizeOAuthApp(authRequest)
|
||||
require.Error(t, err)
|
||||
CheckNotFoundStatus(t, resp)
|
||||
|
||||
// test callback URI doesn't have malformed query parameters
|
||||
oappWithQueryParamInCallback := &model.OAuthApp{
|
||||
Name: GenerateTestAppName(),
|
||||
Homepage: "https://nowhere.com",
|
||||
Description: "test",
|
||||
CallbackUrls: []string{"https://nowhere.com?simply=lovely"},
|
||||
CreatorId: th.SystemAdminUser.Id,
|
||||
}
|
||||
|
||||
rapp, appErr = th.App.CreateOAuthApp(oappWithQueryParamInCallback)
|
||||
require.Nil(t, appErr)
|
||||
|
||||
authRequest = &model.AuthorizeRequest{
|
||||
ResponseType: model.AuthCodeResponseType,
|
||||
ClientId: rapp.Id,
|
||||
RedirectURI: rapp.CallbackUrls[0],
|
||||
Scope: "",
|
||||
State: "123",
|
||||
}
|
||||
uriResponse, _, err := apiClient.AuthorizeOAuthApp(authRequest)
|
||||
require.NoError(t, err)
|
||||
ru, _ = url.Parse(uriResponse)
|
||||
require.NotEmpty(t, uriResponse, "redirect url should be set")
|
||||
require.NotNil(t, ru, "redirect url unparseable")
|
||||
// require no query parameter to have "?"
|
||||
require.False(t, strings.Contains(ru.RawQuery, "?"), "should not malform query parameters")
|
||||
require.NotEmpty(t, ru.Query().Get("code"), "authorization code not returned")
|
||||
require.Equal(t, ru.Query().Get("state"), authRequest.State, "returned state doesn't match")
|
||||
}
|
||||
|
||||
func TestDeauthorizeOAuthApp(t *testing.T) {
|
||||
|
||||
Ссылка в новой задаче
Block a user