Mono repo -> Master (#22553)
Combines the following repositories into one: https://github.com/mattermost/mattermost-server https://github.com/mattermost/mattermost-webapp https://github.com/mattermost/focalboard https://github.com/mattermost/mattermost-plugin-playbooks
Этот коммит содержится в:
635
server/channels/app/oauth_test.go
Обычный файл
635
server/channels/app/oauth_test.go
Обычный файл
@@ -0,0 +1,635 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/plugin/plugintest/mock"
|
||||
"github.com/mattermost/mattermost-server/v6/server/channels/einterfaces"
|
||||
"github.com/mattermost/mattermost-server/v6/server/channels/einterfaces/mocks"
|
||||
"github.com/mattermost/mattermost-server/v6/server/channels/store"
|
||||
)
|
||||
|
||||
func TestGetOAuthAccessTokenForImplicitFlow(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOAuthServiceProvider = true })
|
||||
|
||||
oapp := &model.OAuthApp{
|
||||
Name: "fakeoauthapp" + model.NewRandomString(10),
|
||||
CreatorId: th.BasicUser2.Id,
|
||||
Homepage: "https://nowhere.com",
|
||||
Description: "test",
|
||||
CallbackUrls: []string{"https://nowhere.com"},
|
||||
}
|
||||
|
||||
oapp, err := th.App.CreateOAuthApp(oapp)
|
||||
require.Nil(t, err)
|
||||
|
||||
authRequest := &model.AuthorizeRequest{
|
||||
ResponseType: model.ImplicitResponseType,
|
||||
ClientId: oapp.Id,
|
||||
RedirectURI: oapp.CallbackUrls[0],
|
||||
Scope: "",
|
||||
State: "123",
|
||||
}
|
||||
|
||||
session, err := th.App.GetOAuthAccessTokenForImplicitFlow(th.BasicUser.Id, authRequest)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, session)
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOAuthServiceProvider = false })
|
||||
|
||||
session, err = th.App.GetOAuthAccessTokenForImplicitFlow(th.BasicUser.Id, authRequest)
|
||||
assert.NotNil(t, err, "should fail - oauth2 disabled")
|
||||
assert.Nil(t, session)
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOAuthServiceProvider = true })
|
||||
authRequest.ClientId = "junk"
|
||||
|
||||
session, err = th.App.GetOAuthAccessTokenForImplicitFlow(th.BasicUser.Id, authRequest)
|
||||
assert.NotNil(t, err, "should fail - bad client id")
|
||||
assert.Nil(t, session)
|
||||
|
||||
authRequest.ClientId = oapp.Id
|
||||
|
||||
session, err = th.App.GetOAuthAccessTokenForImplicitFlow("junk", authRequest)
|
||||
assert.NotNil(t, err, "should fail - bad user id")
|
||||
assert.Nil(t, session)
|
||||
}
|
||||
|
||||
func TestOAuthRevokeAccessToken(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
session := &model.Session{}
|
||||
session.CreateAt = model.GetMillis()
|
||||
session.UserId = model.NewId()
|
||||
session.Token = model.NewId()
|
||||
session.Roles = model.SystemUserRoleId
|
||||
th.App.SetSessionExpireInHours(session, 24)
|
||||
|
||||
var err *model.AppError
|
||||
session, err = th.App.CreateSession(session)
|
||||
require.Nil(t, err)
|
||||
err = th.App.RevokeAccessToken(session.Token)
|
||||
require.NotNil(t, err, "Should have failed does not have an access token")
|
||||
require.Equal(t, http.StatusBadRequest, err.StatusCode)
|
||||
}
|
||||
|
||||
func TestOAuthDeleteApp(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
*th.App.Config().ServiceSettings.EnableOAuthServiceProvider = true
|
||||
|
||||
a1 := &model.OAuthApp{}
|
||||
a1.CreatorId = model.NewId()
|
||||
a1.Name = "TestApp" + model.NewId()
|
||||
a1.CallbackUrls = []string{"https://nowhere.com"}
|
||||
a1.Homepage = "https://nowhere.com"
|
||||
|
||||
var err *model.AppError
|
||||
a1, err = th.App.CreateOAuthApp(a1)
|
||||
require.Nil(t, err)
|
||||
|
||||
session := &model.Session{}
|
||||
session.CreateAt = model.GetMillis()
|
||||
session.UserId = model.NewId()
|
||||
session.Token = model.NewId()
|
||||
session.Roles = model.SystemUserRoleId
|
||||
session.IsOAuth = true
|
||||
th.App.ch.srv.platform.SetSessionExpireInHours(session, 24)
|
||||
|
||||
session, _ = th.App.CreateSession(session)
|
||||
|
||||
accessData := &model.AccessData{}
|
||||
accessData.Token = session.Token
|
||||
accessData.UserId = session.UserId
|
||||
accessData.RedirectUri = "http://example.com"
|
||||
accessData.ClientId = a1.Id
|
||||
accessData.ExpiresAt = session.ExpiresAt
|
||||
|
||||
_, nErr := th.App.Srv().Store().OAuth().SaveAccessData(accessData)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
err = th.App.DeleteOAuthApp(a1.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
_, err = th.App.GetSession(session.Token)
|
||||
require.NotNil(t, err, "should not get session from cache or db")
|
||||
}
|
||||
|
||||
func TestAuthorizeOAuthUser(t *testing.T) {
|
||||
setup := func(t *testing.T, enable, tokenEndpoint, userEndpoint bool, serverURL string) *TestHelper {
|
||||
th := Setup(t)
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.GitLabSettings.Enable = enable
|
||||
|
||||
if tokenEndpoint {
|
||||
*cfg.GitLabSettings.TokenEndpoint = serverURL + "/token"
|
||||
} else {
|
||||
*cfg.GitLabSettings.TokenEndpoint = ""
|
||||
}
|
||||
|
||||
if userEndpoint {
|
||||
*cfg.GitLabSettings.UserAPIEndpoint = serverURL + "/user"
|
||||
} else {
|
||||
*cfg.GitLabSettings.UserAPIEndpoint = ""
|
||||
}
|
||||
})
|
||||
|
||||
return th
|
||||
}
|
||||
|
||||
makeState := func(token *model.Token) string {
|
||||
return base64.StdEncoding.EncodeToString([]byte(model.MapToJSON(map[string]string{
|
||||
"token": token.Token,
|
||||
})))
|
||||
}
|
||||
|
||||
makeToken := func(th *TestHelper, cookie string) *model.Token {
|
||||
token, _ := th.App.CreateOAuthStateToken(generateOAuthStateTokenExtra("", "", cookie))
|
||||
return token
|
||||
}
|
||||
|
||||
makeRequest := func(cookie string) *http.Request {
|
||||
request, _ := http.NewRequest(http.MethodGet, "https://mattermost.example.com", nil)
|
||||
|
||||
if cookie != "" {
|
||||
request.AddCookie(&http.Cookie{
|
||||
Name: CookieOAuth,
|
||||
Value: cookie,
|
||||
})
|
||||
}
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
t.Run("not enabled", func(t *testing.T) {
|
||||
th := setup(t, false, true, true, "")
|
||||
defer th.TearDown()
|
||||
|
||||
_, _, _, _, err := th.App.AuthorizeOAuthUser(nil, nil, model.ServiceGitlab, "", "", "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.user.authorize_oauth_user.unsupported.app_error", err.Id)
|
||||
})
|
||||
|
||||
t.Run("with an improperly encoded state", func(t *testing.T) {
|
||||
th := setup(t, true, true, true, "")
|
||||
defer th.TearDown()
|
||||
|
||||
state := "!"
|
||||
|
||||
_, _, _, _, err := th.App.AuthorizeOAuthUser(nil, nil, model.ServiceGitlab, "", state, "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.user.authorize_oauth_user.invalid_state.app_error", err.Id)
|
||||
})
|
||||
|
||||
t.Run("without a stored token", func(t *testing.T) {
|
||||
th := setup(t, true, true, true, "")
|
||||
defer th.TearDown()
|
||||
|
||||
state := base64.StdEncoding.EncodeToString([]byte(model.MapToJSON(map[string]string{
|
||||
"token": model.NewId(),
|
||||
})))
|
||||
|
||||
_, _, _, _, err := th.App.AuthorizeOAuthUser(nil, nil, model.ServiceGitlab, "", state, "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.oauth.invalid_state_token.app_error", err.Id)
|
||||
assert.Error(t, err.Unwrap())
|
||||
})
|
||||
|
||||
t.Run("with a stored token of the wrong type", func(t *testing.T) {
|
||||
th := setup(t, true, true, true, "")
|
||||
defer th.TearDown()
|
||||
|
||||
token := model.NewToken("invalid", "")
|
||||
require.NoError(t, th.App.Srv().Store().Token().Save(token))
|
||||
|
||||
state := makeState(token)
|
||||
|
||||
_, _, _, _, err := th.App.AuthorizeOAuthUser(nil, nil, model.ServiceGitlab, "", state, "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.oauth.invalid_state_token.app_error", err.Id)
|
||||
assert.Equal(t, "", err.DetailedError)
|
||||
})
|
||||
|
||||
t.Run("with email missing when changing login types", func(t *testing.T) {
|
||||
th := setup(t, true, true, true, "")
|
||||
defer th.TearDown()
|
||||
|
||||
email := ""
|
||||
action := model.OAuthActionEmailToSSO
|
||||
cookie := model.NewId()
|
||||
|
||||
token, err := th.App.CreateOAuthStateToken(generateOAuthStateTokenExtra(email, action, cookie))
|
||||
require.Nil(t, err)
|
||||
|
||||
state := base64.StdEncoding.EncodeToString([]byte(model.MapToJSON(map[string]string{
|
||||
"action": action,
|
||||
"email": email,
|
||||
"token": token.Token,
|
||||
})))
|
||||
|
||||
_, _, _, _, err = th.App.AuthorizeOAuthUser(nil, nil, model.ServiceGitlab, "", state, "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.user.authorize_oauth_user.invalid_state.app_error", err.Id)
|
||||
})
|
||||
|
||||
t.Run("without an OAuth cookie", func(t *testing.T) {
|
||||
th := setup(t, true, true, true, "")
|
||||
defer th.TearDown()
|
||||
|
||||
cookie := model.NewId()
|
||||
request := makeRequest("")
|
||||
state := makeState(makeToken(th, cookie))
|
||||
|
||||
_, _, _, _, err := th.App.AuthorizeOAuthUser(nil, request, model.ServiceGitlab, "", state, "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.user.authorize_oauth_user.invalid_state.app_error", err.Id)
|
||||
})
|
||||
|
||||
t.Run("with an invalid token", func(t *testing.T) {
|
||||
th := setup(t, true, true, true, "")
|
||||
defer th.TearDown()
|
||||
|
||||
cookie := model.NewId()
|
||||
|
||||
token, err := th.App.CreateOAuthStateToken(model.NewId())
|
||||
require.Nil(t, err)
|
||||
|
||||
request := makeRequest(cookie)
|
||||
state := makeState(token)
|
||||
|
||||
_, _, _, _, err = th.App.AuthorizeOAuthUser(nil, request, model.ServiceGitlab, "", state, "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.user.authorize_oauth_user.invalid_state.app_error", err.Id)
|
||||
})
|
||||
|
||||
t.Run("with an incorrect token endpoint", func(t *testing.T) {
|
||||
th := setup(t, true, false, true, "")
|
||||
defer th.TearDown()
|
||||
|
||||
cookie := model.NewId()
|
||||
request := makeRequest(cookie)
|
||||
state := makeState(makeToken(th, cookie))
|
||||
|
||||
_, _, _, _, err := th.App.AuthorizeOAuthUser(&httptest.ResponseRecorder{}, request, model.ServiceGitlab, "", state, "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.user.authorize_oauth_user.token_failed.app_error", err.Id)
|
||||
})
|
||||
|
||||
t.Run("with an error token response", func(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusTeapot)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
th := setup(t, true, true, true, server.URL)
|
||||
defer th.TearDown()
|
||||
|
||||
cookie := model.NewId()
|
||||
request := makeRequest(cookie)
|
||||
state := makeState(makeToken(th, cookie))
|
||||
|
||||
_, _, _, _, err := th.App.AuthorizeOAuthUser(&httptest.ResponseRecorder{}, request, model.ServiceGitlab, "", state, "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.user.authorize_oauth_user.bad_response.app_error", err.Id)
|
||||
assert.Contains(t, err.DetailedError, "status_code=418")
|
||||
})
|
||||
|
||||
t.Run("with an invalid token response", func(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("invalid"))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
th := setup(t, true, true, true, server.URL)
|
||||
defer th.TearDown()
|
||||
|
||||
cookie := model.NewId()
|
||||
request := makeRequest(cookie)
|
||||
state := makeState(makeToken(th, cookie))
|
||||
|
||||
_, _, _, _, err := th.App.AuthorizeOAuthUser(&httptest.ResponseRecorder{}, request, model.ServiceGitlab, "", state, "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.user.authorize_oauth_user.bad_response.app_error", err.Id)
|
||||
assert.Contains(t, err.DetailedError, "response_body=invalid")
|
||||
})
|
||||
|
||||
t.Run("with an invalid token type", func(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewEncoder(w).Encode(&model.AccessResponse{
|
||||
AccessToken: model.NewId(),
|
||||
TokenType: "",
|
||||
})
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
th := setup(t, true, true, true, server.URL)
|
||||
defer th.TearDown()
|
||||
|
||||
cookie := model.NewId()
|
||||
request := makeRequest(cookie)
|
||||
state := makeState(makeToken(th, cookie))
|
||||
|
||||
_, _, _, _, err := th.App.AuthorizeOAuthUser(&httptest.ResponseRecorder{}, request, model.ServiceGitlab, "", state, "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.user.authorize_oauth_user.bad_token.app_error", err.Id)
|
||||
})
|
||||
|
||||
t.Run("with an empty token response", func(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewEncoder(w).Encode(&model.AccessResponse{
|
||||
AccessToken: "",
|
||||
TokenType: model.AccessTokenType,
|
||||
})
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
th := setup(t, true, true, true, server.URL)
|
||||
defer th.TearDown()
|
||||
|
||||
cookie := model.NewId()
|
||||
request := makeRequest(cookie)
|
||||
state := makeState(makeToken(th, cookie))
|
||||
|
||||
_, _, _, _, err := th.App.AuthorizeOAuthUser(&httptest.ResponseRecorder{}, request, model.ServiceGitlab, "", state, "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.user.authorize_oauth_user.missing.app_error", err.Id)
|
||||
})
|
||||
|
||||
t.Run("with an incorrect user endpoint", func(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewEncoder(w).Encode(&model.AccessResponse{
|
||||
AccessToken: model.NewId(),
|
||||
TokenType: model.AccessTokenType,
|
||||
})
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
th := setup(t, true, true, false, server.URL)
|
||||
defer th.TearDown()
|
||||
|
||||
cookie := model.NewId()
|
||||
request := makeRequest(cookie)
|
||||
state := makeState(makeToken(th, cookie))
|
||||
|
||||
_, _, _, _, err := th.App.AuthorizeOAuthUser(&httptest.ResponseRecorder{}, request, model.ServiceGitlab, "", state, "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.user.authorize_oauth_user.service.app_error", err.Id)
|
||||
})
|
||||
|
||||
t.Run("with an error user response", func(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/token":
|
||||
t.Log("hit token")
|
||||
json.NewEncoder(w).Encode(&model.AccessResponse{
|
||||
AccessToken: model.NewId(),
|
||||
TokenType: model.AccessTokenType,
|
||||
})
|
||||
case "/user":
|
||||
t.Log("hit user")
|
||||
w.WriteHeader(http.StatusTeapot)
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
th := setup(t, true, true, true, server.URL)
|
||||
defer th.TearDown()
|
||||
|
||||
cookie := model.NewId()
|
||||
request := makeRequest(cookie)
|
||||
state := makeState(makeToken(th, cookie))
|
||||
|
||||
_, _, _, _, err := th.App.AuthorizeOAuthUser(&httptest.ResponseRecorder{}, request, model.ServiceGitlab, "", state, "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.user.authorize_oauth_user.response.app_error", err.Id)
|
||||
})
|
||||
|
||||
t.Run("with an error user response due to GitLab TOS", func(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/token":
|
||||
t.Log("hit token")
|
||||
json.NewEncoder(w).Encode(&model.AccessResponse{
|
||||
AccessToken: model.NewId(),
|
||||
TokenType: model.AccessTokenType,
|
||||
})
|
||||
case "/user":
|
||||
t.Log("hit user")
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
w.Write([]byte("Terms of Service"))
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
th := setup(t, true, true, true, server.URL)
|
||||
defer th.TearDown()
|
||||
|
||||
cookie := model.NewId()
|
||||
request := makeRequest(cookie)
|
||||
state := makeState(makeToken(th, cookie))
|
||||
|
||||
_, _, _, _, err := th.App.AuthorizeOAuthUser(&httptest.ResponseRecorder{}, request, model.ServiceGitlab, "", state, "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "oauth.gitlab.tos.error", err.Id)
|
||||
})
|
||||
|
||||
t.Run("with error in GetSSOSettings", func(t *testing.T) {
|
||||
th := setup(t, true, true, true, "")
|
||||
defer th.TearDown()
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.OpenIdSettings.Enable = true
|
||||
})
|
||||
|
||||
providerMock := &mocks.OAuthProvider{}
|
||||
providerMock.On("GetSSOSettings", mock.Anything, model.ServiceOpenid).Return(nil, errors.New("error"))
|
||||
einterfaces.RegisterOAuthProvider(model.ServiceOpenid, providerMock)
|
||||
|
||||
_, _, _, _, err := th.App.AuthorizeOAuthUser(nil, nil, model.ServiceOpenid, "", "", "")
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.user.get_authorization_code.endpoint.app_error", err.Id)
|
||||
|
||||
})
|
||||
|
||||
t.Run("enabled and properly configured", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Description string
|
||||
SiteURL string
|
||||
ExpectedSetCookieHeaderRegexp string
|
||||
}{
|
||||
{"no subpath", "http://localhost:8065", "^MMOAUTH=; Path=/"},
|
||||
{"subpath", "http://localhost:8065/subpath", "^MMOAUTH=; Path=/subpath"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Description, func(t *testing.T) {
|
||||
userData := "Hello, World!"
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/token":
|
||||
json.NewEncoder(w).Encode(&model.AccessResponse{
|
||||
AccessToken: model.NewId(),
|
||||
TokenType: model.AccessTokenType,
|
||||
})
|
||||
case "/user":
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(userData))
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
th := setup(t, true, true, true, server.URL)
|
||||
defer th.TearDown()
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.ServiceSettings.SiteURL = tc.SiteURL
|
||||
})
|
||||
|
||||
cookie := model.NewId()
|
||||
request := makeRequest(cookie)
|
||||
|
||||
stateProps := map[string]string{
|
||||
"team_id": model.NewId(),
|
||||
"token": makeToken(th, cookie).Token,
|
||||
}
|
||||
state := base64.StdEncoding.EncodeToString([]byte(model.MapToJSON(stateProps)))
|
||||
|
||||
recorder := httptest.ResponseRecorder{}
|
||||
body, receivedTeamId, receivedStateProps, _, err := th.App.AuthorizeOAuthUser(&recorder, request, model.ServiceGitlab, "", state, "")
|
||||
|
||||
require.NotNil(t, body)
|
||||
bodyBytes, bodyErr := io.ReadAll(body)
|
||||
require.NoError(t, bodyErr)
|
||||
assert.Equal(t, userData, string(bodyBytes))
|
||||
|
||||
assert.Equal(t, stateProps["team_id"], receivedTeamId)
|
||||
assert.Equal(t, stateProps, receivedStateProps)
|
||||
assert.Nil(t, err)
|
||||
|
||||
cookies := recorder.Header().Get("Set-Cookie")
|
||||
assert.Regexp(t, tc.ExpectedSetCookieHeaderRegexp, cookies)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetAuthorizationCode(t *testing.T) {
|
||||
t.Run("not enabled", func(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.GitLabSettings.Enable = false
|
||||
})
|
||||
|
||||
_, err := th.App.GetAuthorizationCode(nil, nil, model.ServiceGitlab, map[string]string{}, "")
|
||||
require.NotNil(t, err)
|
||||
|
||||
assert.Equal(t, "api.user.authorize_oauth_user.unsupported.app_error", err.Id)
|
||||
})
|
||||
|
||||
t.Run("enabled and properly configured", func(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.GitLabSettings.Enable = true
|
||||
})
|
||||
|
||||
testCases := []struct {
|
||||
Description string
|
||||
SiteURL string
|
||||
ExpectedSetCookieHeaderRegexp string
|
||||
}{
|
||||
{"no subpath", "http://localhost:8065", "^MMOAUTH=[a-z0-9]+; Path=/"},
|
||||
{"subpath", "http://localhost:8065/subpath", "^MMOAUTH=[a-z0-9]+; Path=/subpath"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Description, func(t *testing.T) {
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.ServiceSettings.SiteURL = tc.SiteURL
|
||||
})
|
||||
|
||||
request, _ := http.NewRequest(http.MethodGet, "https://mattermost.example.com", nil)
|
||||
|
||||
stateProps := map[string]string{
|
||||
"email": "email@example.com",
|
||||
"action": "action",
|
||||
}
|
||||
|
||||
recorder := httptest.ResponseRecorder{}
|
||||
url, err := th.App.GetAuthorizationCode(&recorder, request, model.ServiceGitlab, stateProps, "")
|
||||
require.Nil(t, err)
|
||||
assert.NotEmpty(t, url)
|
||||
|
||||
cookies := recorder.Header().Get("Set-Cookie")
|
||||
assert.Regexp(t, tc.ExpectedSetCookieHeaderRegexp, cookies)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeauthorizeOAuthApp(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOAuthServiceProvider = true })
|
||||
|
||||
oapp := &model.OAuthApp{
|
||||
Name: "fakeoauthapp" + model.NewRandomString(10),
|
||||
CreatorId: th.BasicUser2.Id,
|
||||
Homepage: "https://nowhere.com",
|
||||
Description: "test",
|
||||
CallbackUrls: []string{"https://nowhere.com"},
|
||||
}
|
||||
|
||||
oapp, err := th.App.CreateOAuthApp(oapp)
|
||||
require.Nil(t, err)
|
||||
|
||||
authRequest := &model.AuthorizeRequest{
|
||||
ResponseType: model.ImplicitResponseType,
|
||||
ClientId: oapp.Id,
|
||||
RedirectURI: oapp.CallbackUrls[0],
|
||||
Scope: "",
|
||||
State: "123",
|
||||
}
|
||||
|
||||
redirectUrl, err := th.App.GetOAuthCodeRedirect(th.BasicUser.Id, authRequest)
|
||||
assert.Nil(t, err)
|
||||
|
||||
dErr := th.App.DeauthorizeOAuthAppForUser(th.BasicUser.Id, oapp.Id)
|
||||
assert.Nil(t, dErr)
|
||||
|
||||
uri, uErr := url.Parse(redirectUrl)
|
||||
require.NoError(t, uErr)
|
||||
|
||||
queryParams := uri.Query()
|
||||
code := queryParams.Get("code")
|
||||
|
||||
data, nErr := th.App.Srv().Store().OAuth().GetAuthData(code)
|
||||
require.Equal(t, store.NewErrNotFound("AuthData", fmt.Sprintf("code=%s", code)), nErr)
|
||||
assert.Nil(t, data)
|
||||
}
|
||||
Ссылка в новой задаче
Block a user