diff options
Diffstat (limited to 'api4')
-rw-r--r-- | api4/apitestlib.go | 63 | ||||
-rw-r--r-- | api4/channel_test.go | 148 | ||||
-rw-r--r-- | api4/context.go | 12 | ||||
-rw-r--r-- | api4/file.go | 73 | ||||
-rw-r--r-- | api4/file_test.go | 129 | ||||
-rw-r--r-- | api4/oauth.go | 24 | ||||
-rw-r--r-- | api4/oauth_test.go | 62 | ||||
-rw-r--r-- | api4/params.go | 14 | ||||
-rw-r--r-- | api4/post_test.go | 43 | ||||
-rw-r--r-- | api4/system.go | 9 | ||||
-rw-r--r-- | api4/system_test.go | 22 | ||||
-rw-r--r-- | api4/team_test.go | 71 | ||||
-rw-r--r-- | api4/user.go | 4 | ||||
-rw-r--r-- | api4/user_test.go | 53 | ||||
-rw-r--r-- | api4/webhook.go | 56 |
15 files changed, 344 insertions, 439 deletions
diff --git a/api4/apitestlib.go b/api4/apitestlib.go index a7e64ae84..e55ca8c8b 100644 --- a/api4/apitestlib.go +++ b/api4/apitestlib.go @@ -12,7 +12,6 @@ import ( "net/http" "os" "reflect" - "runtime/debug" "strconv" "strings" "sync" @@ -113,7 +112,11 @@ func setupTestHelper(enterprise bool) *TestHelper { if testStore != nil { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" }) } - th.App.StartServer() + serverErr := th.App.StartServer() + if serverErr != nil { + panic(serverErr) + } + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress }) Init(th.App, th.App.Srv.Router, true) wsapi.Init(th.App, th.App.Srv.WebSocketRouter) @@ -121,9 +124,10 @@ func setupTestHelper(enterprise bool) *TestHelper { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true }) - utils.SetIsLicensed(enterprise) if enterprise { - utils.License().Features.SetDefaults() + th.App.SetLicense(model.NewTestLicense()) + } else { + th.App.SetLicense(nil) } th.Client = th.CreateClient() @@ -298,8 +302,7 @@ func (me *TestHelper) CreateUserWithClient(client *model.Client4) *model.User { } utils.DisableDebugLogForTest() - ruser, r := client.CreateUser(user) - fmt.Println(r) + ruser, _ := client.CreateUser(user) ruser.Password = "Password1" store.Must(me.App.Srv.Store.User().VerifyEmail(ruser.Id)) utils.EnableDebugLogForTest() @@ -492,6 +495,8 @@ func GenerateTestId() string { } func CheckUserSanitization(t *testing.T, user *model.User) { + t.Helper() + if user.Password != "" { t.Fatal("password wasn't blank") } @@ -506,6 +511,8 @@ func CheckUserSanitization(t *testing.T, user *model.User) { } func CheckTeamSanitization(t *testing.T, team *model.Team) { + t.Helper() + if team.Email != "" { t.Fatal("email wasn't blank") } @@ -516,13 +523,13 @@ func CheckTeamSanitization(t *testing.T, team *model.Team) { } func CheckEtag(t *testing.T, data interface{}, resp *model.Response) { + t.Helper() + if !reflect.ValueOf(data).IsNil() { - debug.PrintStack() t.Fatal("etag data was not nil") } if resp.StatusCode != http.StatusNotModified { - debug.PrintStack() t.Log("actual: " + strconv.Itoa(resp.StatusCode)) t.Log("expected: " + strconv.Itoa(http.StatusNotModified)) t.Fatal("wrong status code for etag") @@ -530,15 +537,17 @@ func CheckEtag(t *testing.T, data interface{}, resp *model.Response) { } func CheckNoError(t *testing.T, resp *model.Response) { + t.Helper() + if resp.Error != nil { - debug.PrintStack() t.Fatal("Expected no error, got " + resp.Error.Error()) } } func CheckCreatedStatus(t *testing.T, resp *model.Response) { + t.Helper() + if resp.StatusCode != http.StatusCreated { - debug.PrintStack() t.Log("actual: " + strconv.Itoa(resp.StatusCode)) t.Log("expected: " + strconv.Itoa(http.StatusCreated)) t.Fatal("wrong status code") @@ -546,14 +555,14 @@ func CheckCreatedStatus(t *testing.T, resp *model.Response) { } func CheckForbiddenStatus(t *testing.T, resp *model.Response) { + t.Helper() + if resp.Error == nil { - debug.PrintStack() t.Fatal("should have errored with status:" + strconv.Itoa(http.StatusForbidden)) return } if resp.StatusCode != http.StatusForbidden { - debug.PrintStack() t.Log("actual: " + strconv.Itoa(resp.StatusCode)) t.Log("expected: " + strconv.Itoa(http.StatusForbidden)) t.Fatal("wrong status code") @@ -561,14 +570,14 @@ func CheckForbiddenStatus(t *testing.T, resp *model.Response) { } func CheckUnauthorizedStatus(t *testing.T, resp *model.Response) { + t.Helper() + if resp.Error == nil { - debug.PrintStack() t.Fatal("should have errored with status:" + strconv.Itoa(http.StatusUnauthorized)) return } if resp.StatusCode != http.StatusUnauthorized { - debug.PrintStack() t.Log("actual: " + strconv.Itoa(resp.StatusCode)) t.Log("expected: " + strconv.Itoa(http.StatusUnauthorized)) t.Fatal("wrong status code") @@ -576,14 +585,14 @@ func CheckUnauthorizedStatus(t *testing.T, resp *model.Response) { } func CheckNotFoundStatus(t *testing.T, resp *model.Response) { + t.Helper() + if resp.Error == nil { - debug.PrintStack() t.Fatal("should have errored with status:" + strconv.Itoa(http.StatusNotFound)) return } if resp.StatusCode != http.StatusNotFound { - debug.PrintStack() t.Log("actual: " + strconv.Itoa(resp.StatusCode)) t.Log("expected: " + strconv.Itoa(http.StatusNotFound)) t.Fatal("wrong status code") @@ -591,14 +600,14 @@ func CheckNotFoundStatus(t *testing.T, resp *model.Response) { } func CheckBadRequestStatus(t *testing.T, resp *model.Response) { + t.Helper() + if resp.Error == nil { - debug.PrintStack() t.Fatal("should have errored with status:" + strconv.Itoa(http.StatusBadRequest)) return } if resp.StatusCode != http.StatusBadRequest { - debug.PrintStack() t.Log("actual: " + strconv.Itoa(resp.StatusCode)) t.Log("expected: " + strconv.Itoa(http.StatusBadRequest)) t.Fatal("wrong status code") @@ -606,14 +615,14 @@ func CheckBadRequestStatus(t *testing.T, resp *model.Response) { } func CheckNotImplementedStatus(t *testing.T, resp *model.Response) { + t.Helper() + if resp.Error == nil { - debug.PrintStack() t.Fatal("should have errored with status:" + strconv.Itoa(http.StatusNotImplemented)) return } if resp.StatusCode != http.StatusNotImplemented { - debug.PrintStack() t.Log("actual: " + strconv.Itoa(resp.StatusCode)) t.Log("expected: " + strconv.Itoa(http.StatusNotImplemented)) t.Fatal("wrong status code") @@ -621,6 +630,8 @@ func CheckNotImplementedStatus(t *testing.T, resp *model.Response) { } func CheckOKStatus(t *testing.T, resp *model.Response) { + t.Helper() + CheckNoError(t, resp) if resp.StatusCode != http.StatusOK { @@ -629,14 +640,14 @@ func CheckOKStatus(t *testing.T, resp *model.Response) { } func CheckErrorMessage(t *testing.T, resp *model.Response, errorId string) { + t.Helper() + if resp.Error == nil { - debug.PrintStack() t.Fatal("should have errored with message:" + errorId) return } if resp.Error.Id != errorId { - debug.PrintStack() t.Log("actual: " + resp.Error.Id) t.Log("expected: " + errorId) t.Fatal("incorrect error message") @@ -644,14 +655,14 @@ func CheckErrorMessage(t *testing.T, resp *model.Response, errorId string) { } func CheckInternalErrorStatus(t *testing.T, resp *model.Response) { + t.Helper() + if resp.Error == nil { - debug.PrintStack() t.Fatal("should have errored with status:" + strconv.Itoa(http.StatusInternalServerError)) return } if resp.StatusCode != http.StatusInternalServerError { - debug.PrintStack() t.Log("actual: " + strconv.Itoa(resp.StatusCode)) t.Log("expected: " + strconv.Itoa(http.StatusInternalServerError)) t.Fatal("wrong status code") @@ -659,14 +670,14 @@ func CheckInternalErrorStatus(t *testing.T, resp *model.Response) { } func CheckPayLoadTooLargeStatus(t *testing.T, resp *model.Response) { + t.Helper() + if resp.Error == nil { - debug.PrintStack() t.Fatal("should have errored with status:" + strconv.Itoa(http.StatusRequestEntityTooLarge)) return } if resp.StatusCode != http.StatusRequestEntityTooLarge { - debug.PrintStack() t.Log("actual: " + strconv.Itoa(resp.StatusCode)) t.Log("expected: " + strconv.Itoa(http.StatusRequestEntityTooLarge)) t.Fatal("wrong status code") diff --git a/api4/channel_test.go b/api4/channel_test.go index 724b0d84b..e65918707 100644 --- a/api4/channel_test.go +++ b/api4/channel_test.go @@ -14,7 +14,6 @@ import ( "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/store/sqlstore" - "github.com/mattermost/mattermost-server/utils" ) func TestCreateChannel(t *testing.T) { @@ -82,23 +81,9 @@ func TestCreateChannel(t *testing.T) { th.LoginBasic() // Check permissions with policy config changes - isLicensed := utils.IsLicensed() - license := utils.License() - restrictPublicChannel := *th.App.Config().TeamSettings.RestrictPublicChannelCreation - restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelCreation - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelCreation = restrictPublicChannel }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelCreation = restrictPrivateChannel }) - utils.SetIsLicensed(isLicensed) - utils.SetLicense(license) - th.App.SetDefaultRolesBasedOnConfig() - }() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_ALL }) - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() + th.App.SetLicense(model.NewTestLicense()) channel.Name = GenerateTestChannelName() _, resp = Client.CreateChannel(channel) @@ -110,11 +95,8 @@ func TestCreateChannel(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_TEAM_ADMIN - }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_TEAM_ADMIN }) - th.App.SetDefaultRolesBasedOnConfig() _, resp = Client.CreateChannel(channel) CheckForbiddenStatus(t, resp) @@ -142,11 +124,8 @@ func TestCreateChannel(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_SYSTEM_ADMIN - }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_SYSTEM_ADMIN }) - th.App.SetDefaultRolesBasedOnConfig() th.LoginBasic() @@ -173,9 +152,7 @@ func TestCreateChannel(t *testing.T) { CheckNoError(t, resp) // Check that if unlicensed the policy restriction is not enforced. - utils.SetIsLicensed(false) - utils.SetLicense(nil) - th.App.SetDefaultRolesBasedOnConfig() + th.App.SetLicense(nil) channel.Name = GenerateTestChannelName() _, resp = Client.CreateChannel(channel) @@ -887,23 +864,9 @@ func TestDeleteChannel(t *testing.T) { th.InitBasic().InitSystemAdmin() - isLicensed := utils.IsLicensed() - license := utils.License() - restrictPublicChannel := *th.App.Config().TeamSettings.RestrictPublicChannelManagement - restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelManagement - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel }) - utils.SetIsLicensed(isLicensed) - utils.SetLicense(license) - th.App.SetDefaultRolesBasedOnConfig() - }() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL }) - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() + th.App.SetLicense(model.NewTestLicense()) Client = th.Client team = th.BasicTeam @@ -926,11 +889,8 @@ func TestDeleteChannel(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN - }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN }) - th.App.SetDefaultRolesBasedOnConfig() // channels created by SystemAdmin publicChannel6 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_OPEN) @@ -967,9 +927,7 @@ func TestDeleteChannel(t *testing.T) { // successful delete by team admin th.UpdateUserToTeamAdmin(user, team) th.App.InvalidateAllCaches() - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() + th.App.SetLicense(model.NewTestLicense()) _, resp = Client.DeleteChannel(publicChannel6.Id) CheckNoError(t, resp) @@ -979,16 +937,11 @@ func TestDeleteChannel(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_TEAM_ADMIN - }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_TEAM_ADMIN }) - th.App.SetDefaultRolesBasedOnConfig() th.UpdateUserToNonTeamAdmin(user, team) th.App.InvalidateAllCaches() - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() + th.App.SetLicense(model.NewTestLicense()) // channels created by SystemAdmin publicChannel6 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_OPEN) @@ -1018,9 +971,7 @@ func TestDeleteChannel(t *testing.T) { // successful delete by team admin th.UpdateUserToTeamAdmin(th.BasicUser, team) th.App.InvalidateAllCaches() - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() + th.App.SetLicense(model.NewTestLicense()) _, resp = Client.DeleteChannel(publicChannel6.Id) CheckNoError(t, resp) @@ -1030,11 +981,8 @@ func TestDeleteChannel(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_SYSTEM_ADMIN - }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_SYSTEM_ADMIN }) - th.App.SetDefaultRolesBasedOnConfig() // channels created by SystemAdmin publicChannel6 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_OPEN) @@ -1064,9 +1012,7 @@ func TestDeleteChannel(t *testing.T) { // cannot delete by team admin th.UpdateUserToTeamAdmin(th.BasicUser, team) th.App.InvalidateAllCaches() - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() + th.App.SetLicense(model.NewTestLicense()) _, resp = Client.DeleteChannel(publicChannel6.Id) CheckForbiddenStatus(t, resp) @@ -1823,16 +1769,9 @@ func TestAddChannelMember(t *testing.T) { CheckNoError(t, resp) // Test policy does not apply to TE. - restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelManageMembers - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { - *cfg.TeamSettings.RestrictPrivateChannelManageMembers = restrictPrivateChannel - }) - }() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN }) - th.App.SetDefaultRolesBasedOnConfig() Client.Login(user2.Username, user2.Password) privateChannel = th.CreatePrivateChannel() @@ -1846,18 +1785,8 @@ func TestAddChannelMember(t *testing.T) { Client.Logout() // Add a license - isLicensed := utils.IsLicensed() - license := utils.License() - defer func() { - utils.SetIsLicensed(isLicensed) - utils.SetLicense(license) - th.App.SetDefaultRolesBasedOnConfig() - }() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_ALL }) - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() + th.App.SetLicense(model.NewTestLicense()) // Check that a regular channel user can add other users. Client.Login(user2.Username, user2.Password) @@ -1875,10 +1804,6 @@ func TestAddChannelMember(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN }) - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() Client.Login(user2.Username, user2.Password) privateChannel = th.CreatePrivateChannel() @@ -1893,10 +1818,7 @@ func TestAddChannelMember(t *testing.T) { th.MakeUserChannelAdmin(user, privateChannel) th.App.InvalidateAllCaches() - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() + th.App.SetLicense(model.NewTestLicense()) Client.Login(user.Username, user.Password) _, resp = Client.AddChannelMember(privateChannel.Id, user3.Id) @@ -1907,10 +1829,6 @@ func TestAddChannelMember(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_TEAM_ADMIN }) - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() Client.Login(user2.Username, user2.Password) privateChannel = th.CreatePrivateChannel() @@ -1925,10 +1843,7 @@ func TestAddChannelMember(t *testing.T) { th.UpdateUserToTeamAdmin(user, team) th.App.InvalidateAllCaches() - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() + th.App.SetLicense(model.NewTestLicense()) Client.Login(user.Username, user.Password) _, resp = Client.AddChannelMember(privateChannel.Id, user3.Id) @@ -1939,10 +1854,6 @@ func TestAddChannelMember(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_SYSTEM_ADMIN }) - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() Client.Login(user2.Username, user2.Password) privateChannel = th.CreatePrivateChannel() @@ -2019,16 +1930,9 @@ func TestRemoveChannelMember(t *testing.T) { th.App.InvalidateAllCaches() // Test policy does not apply to TE. - restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelManageMembers - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { - *cfg.TeamSettings.RestrictPrivateChannelManageMembers = restrictPrivateChannel - }) - }() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN }) - th.App.SetDefaultRolesBasedOnConfig() privateChannel := th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE) _, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id) @@ -2040,18 +1944,8 @@ func TestRemoveChannelMember(t *testing.T) { CheckNoError(t, resp) // Add a license - isLicensed := utils.IsLicensed() - license := utils.License() - defer func() { - utils.SetIsLicensed(isLicensed) - utils.SetLicense(license) - th.App.SetDefaultRolesBasedOnConfig() - }() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_ALL }) - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() + th.App.SetLicense(model.NewTestLicense()) // Check that a regular channel user can remove other users. privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE) @@ -2067,10 +1961,6 @@ func TestRemoveChannelMember(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN }) - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE) _, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id) @@ -2083,9 +1973,7 @@ func TestRemoveChannelMember(t *testing.T) { th.MakeUserChannelAdmin(user1, privateChannel) th.App.InvalidateAllCaches() - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() + th.App.SetLicense(model.NewTestLicense()) _, resp = Client.RemoveUserFromChannel(privateChannel.Id, user2.Id) CheckNoError(t, resp) @@ -2094,10 +1982,6 @@ func TestRemoveChannelMember(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_TEAM_ADMIN }) - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE) _, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id) @@ -2110,9 +1994,7 @@ func TestRemoveChannelMember(t *testing.T) { th.UpdateUserToTeamAdmin(user1, team) th.App.InvalidateAllCaches() - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() + th.App.SetLicense(model.NewTestLicense()) _, resp = Client.RemoveUserFromChannel(privateChannel.Id, user2.Id) CheckNoError(t, resp) @@ -2121,10 +2003,6 @@ func TestRemoveChannelMember(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_SYSTEM_ADMIN }) - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE) _, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id) diff --git a/api4/context.go b/api4/context.go index e079428ac..df249f8de 100644 --- a/api4/context.go +++ b/api4/context.go @@ -449,6 +449,18 @@ func (c *Context) RequireFileId() *Context { return c } +func (c *Context) RequireFilename() *Context { + if c.Err != nil { + return c + } + + if len(c.Params.Filename) == 0 { + c.SetInvalidUrlParam("filename") + } + + return c +} + func (c *Context) RequirePluginId() *Context { if c.Err != nil { return c diff --git a/api4/file.go b/api4/file.go index 48ee281fe..0b0973b30 100644 --- a/api4/file.go +++ b/api4/file.go @@ -4,6 +4,7 @@ package api4 import ( + "io" "net/http" "net/url" "strconv" @@ -65,32 +66,62 @@ func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) { return } - if err := r.ParseMultipartForm(*c.App.Config().FileSettings.MaxFileSize); err != nil { + var resStruct *model.FileUploadResponse + var appErr *model.AppError + + if err := r.ParseMultipartForm(*c.App.Config().FileSettings.MaxFileSize); err != nil && err != http.ErrNotMultipart { http.Error(w, err.Error(), http.StatusInternalServerError) return - } + } else if err == http.ErrNotMultipart { + defer r.Body.Close() - m := r.MultipartForm + c.RequireChannelId() + c.RequireFilename() - props := m.Value - if len(props["channel_id"]) == 0 { - c.SetInvalidParam("channel_id") - return - } - channelId := props["channel_id"][0] - if len(channelId) == 0 { - c.SetInvalidParam("channel_id") - return - } + if c.Err != nil { + return + } - if !c.App.SessionHasPermissionToChannel(c.Session, channelId, model.PERMISSION_UPLOAD_FILE) { - c.SetPermissionError(model.PERMISSION_UPLOAD_FILE) - return + channelId := c.Params.ChannelId + filename := c.Params.Filename + + if !c.App.SessionHasPermissionToChannel(c.Session, channelId, model.PERMISSION_UPLOAD_FILE) { + c.SetPermissionError(model.PERMISSION_UPLOAD_FILE) + return + } + + resStruct, appErr = c.App.UploadFiles( + FILE_TEAM_ID, + channelId, + c.Session.UserId, + []io.ReadCloser{r.Body}, + []string{filename}, + []string{}, + ) + } else { + m := r.MultipartForm + + props := m.Value + if len(props["channel_id"]) == 0 { + c.SetInvalidParam("channel_id") + return + } + channelId := props["channel_id"][0] + if len(channelId) == 0 { + c.SetInvalidParam("channel_id") + return + } + + if !c.App.SessionHasPermissionToChannel(c.Session, channelId, model.PERMISSION_UPLOAD_FILE) { + c.SetPermissionError(model.PERMISSION_UPLOAD_FILE) + return + } + + resStruct, appErr = c.App.UploadMultipartFiles(FILE_TEAM_ID, channelId, c.Session.UserId, m.File["files"], m.Value["client_ids"]) } - resStruct, err := c.App.UploadFiles(FILE_TEAM_ID, channelId, c.Session.UserId, m.File["files"], m.Value["client_ids"]) - if err != nil { - c.Err = err + if appErr != nil { + c.Err = appErr return } @@ -281,13 +312,13 @@ func getPublicFile(c *Context, w http.ResponseWriter, r *http.Request) { if len(hash) == 0 { c.Err = model.NewAppError("getPublicFile", "api.file.get_file.public_invalid.app_error", nil, "", http.StatusBadRequest) - http.Redirect(w, r, c.GetSiteURLHeader()+"/error?message="+utils.T(c.Err.Message), http.StatusTemporaryRedirect) + utils.RenderWebAppError(w, r, c.Err, c.App.AsymmetricSigningKey()) return } if hash != app.GeneratePublicLinkHash(info.Id, *c.App.Config().FileSettings.PublicLinkSalt) { c.Err = model.NewAppError("getPublicFile", "api.file.get_file.public_invalid.app_error", nil, "", http.StatusBadRequest) - http.Redirect(w, r, c.GetSiteURLHeader()+"/error?message="+utils.T(c.Err.Message), http.StatusTemporaryRedirect) + utils.RenderWebAppError(w, r, c.Err, c.App.AsymmetricSigningKey()) return } diff --git a/api4/file_test.go b/api4/file_test.go index 7010b3039..a28420c76 100644 --- a/api4/file_test.go +++ b/api4/file_test.go @@ -14,7 +14,7 @@ import ( "github.com/mattermost/mattermost-server/store" ) -func TestUploadFile(t *testing.T) { +func TestUploadFileAsMultipart(t *testing.T) { th := Setup().InitBasic().InitSystemAdmin() defer th.TearDown() Client := th.Client @@ -119,7 +119,132 @@ func TestUploadFile(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnableFileAttachments = false }) _, resp = th.SystemAdminClient.UploadFile(data, channel.Id, "test.png") - if resp.StatusCode != http.StatusNotImplemented && resp.StatusCode != 0 { + if resp.StatusCode == 0 { + t.Log("file upload request failed completely") + } else if resp.StatusCode != http.StatusNotImplemented { + // This should return an HTTP 501, but it occasionally causes the http client itself to error + t.Fatalf("should've returned HTTP 501 or failed completely, got %v instead", resp.StatusCode) + } +} + +func TestUploadFileAsRequestBody(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + defer th.TearDown() + Client := th.Client + + user := th.BasicUser + channel := th.BasicChannel + + var uploadInfo *model.FileInfo + var data []byte + var err error + if data, err = readTestFile("test.png"); err != nil { + t.Fatal(err) + } else if fileResp, resp := Client.UploadFileAsRequestBody(data, channel.Id, "test.png"); resp.Error != nil { + t.Fatal(resp.Error) + } else if len(fileResp.FileInfos) != 1 { + t.Fatal("should've returned a single file infos") + } else { + uploadInfo = fileResp.FileInfos[0] + } + + // The returned file info from the upload call will be missing some fields that will be stored in the database + if uploadInfo.CreatorId != user.Id { + t.Fatal("file should be assigned to user") + } else if uploadInfo.PostId != "" { + t.Fatal("file shouldn't have a post") + } else if uploadInfo.Path != "" { + t.Fatal("file path should not be set on returned info") + } else if uploadInfo.ThumbnailPath != "" { + t.Fatal("file thumbnail path should not be set on returned info") + } else if uploadInfo.PreviewPath != "" { + t.Fatal("file preview path should not be set on returned info") + } + + var info *model.FileInfo + if result := <-th.App.Srv.Store.FileInfo().Get(uploadInfo.Id); result.Err != nil { + t.Fatal(result.Err) + } else { + info = result.Data.(*model.FileInfo) + } + + if info.Id != uploadInfo.Id { + t.Fatal("file id from response should match one stored in database") + } else if info.CreatorId != user.Id { + t.Fatal("file should be assigned to user") + } else if info.PostId != "" { + t.Fatal("file shouldn't have a post") + } else if info.Path == "" { + t.Fatal("file path should be set in database") + } else if info.ThumbnailPath == "" { + t.Fatal("file thumbnail path should be set in database") + } else if info.PreviewPath == "" { + t.Fatal("file preview path should be set in database") + } + + date := time.Now().Format("20060102") + + // This also makes sure that the relative path provided above is sanitized out + expectedPath := fmt.Sprintf("%v/teams/%v/channels/%v/users/%v/%v/test.png", date, FILE_TEAM_ID, channel.Id, user.Id, info.Id) + if info.Path != expectedPath { + t.Logf("file is saved in %v", info.Path) + t.Fatalf("file should've been saved in %v", expectedPath) + } + + expectedThumbnailPath := fmt.Sprintf("%v/teams/%v/channels/%v/users/%v/%v/test_thumb.jpg", date, FILE_TEAM_ID, channel.Id, user.Id, info.Id) + if info.ThumbnailPath != expectedThumbnailPath { + t.Logf("file thumbnail is saved in %v", info.ThumbnailPath) + t.Fatalf("file thumbnail should've been saved in %v", expectedThumbnailPath) + } + + expectedPreviewPath := fmt.Sprintf("%v/teams/%v/channels/%v/users/%v/%v/test_preview.jpg", date, FILE_TEAM_ID, channel.Id, user.Id, info.Id) + if info.PreviewPath != expectedPreviewPath { + t.Logf("file preview is saved in %v", info.PreviewPath) + t.Fatalf("file preview should've been saved in %v", expectedPreviewPath) + } + + // Wait a bit for files to ready + time.Sleep(2 * time.Second) + + if err := th.cleanupTestFile(info); err != nil { + t.Fatal(err) + } + + _, resp := Client.UploadFileAsRequestBody(data, model.NewId(), "test.png") + CheckForbiddenStatus(t, resp) + + _, resp = Client.UploadFileAsRequestBody(data, "../../junk", "test.png") + if resp.StatusCode == 0 { + t.Log("file upload request failed completely") + } else if resp.StatusCode != http.StatusBadRequest { + // This should return an HTTP 400, but it occasionally causes the http client itself to error + t.Fatalf("should've returned HTTP 400 or failed completely, got %v instead", resp.StatusCode) + } + + _, resp = th.SystemAdminClient.UploadFileAsRequestBody(data, model.NewId(), "test.png") + CheckForbiddenStatus(t, resp) + + _, resp = th.SystemAdminClient.UploadFileAsRequestBody(data, "../../junk", "test.png") + if resp.StatusCode == 0 { + t.Log("file upload request failed completely") + } else if resp.StatusCode != http.StatusBadRequest { + // This should return an HTTP 400, but it occasionally causes the http client itself to error + t.Fatalf("should've returned HTTP 400 or failed completely, got %v instead", resp.StatusCode) + } + + _, resp = th.SystemAdminClient.UploadFileAsRequestBody(data, channel.Id, "test.png") + CheckNoError(t, resp) + + enableFileAttachments := *th.App.Config().FileSettings.EnableFileAttachments + defer func() { + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnableFileAttachments = enableFileAttachments }) + }() + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnableFileAttachments = false }) + + _, resp = th.SystemAdminClient.UploadFileAsRequestBody(data, channel.Id, "test.png") + if resp.StatusCode == 0 { + t.Log("file upload request failed completely") + } else if resp.StatusCode != http.StatusNotImplemented { // This should return an HTTP 501, but it occasionally causes the http client itself to error t.Fatalf("should've returned HTTP 501 or failed completely, got %v instead", resp.StatusCode) } diff --git a/api4/oauth.go b/api4/oauth.go index 655adaaee..d0f43256a 100644 --- a/api4/oauth.go +++ b/api4/oauth.go @@ -313,7 +313,7 @@ func deauthorizeOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { func authorizeOAuthPage(c *Context, w http.ResponseWriter, r *http.Request) { if !c.App.Config().ServiceSettings.EnableOAuthServiceProvider { err := model.NewAppError("authorizeOAuth", "api.oauth.authorize_oauth.disabled.app_error", nil, "", http.StatusNotImplemented) - utils.RenderWebError(err, w, r) + utils.RenderWebAppError(w, r, err, c.App.AsymmetricSigningKey()) return } @@ -326,13 +326,13 @@ func authorizeOAuthPage(c *Context, w http.ResponseWriter, r *http.Request) { } if err := authRequest.IsValid(); err != nil { - utils.RenderWebError(err, w, r) + utils.RenderWebAppError(w, r, err, c.App.AsymmetricSigningKey()) return } oauthApp, err := c.App.GetOAuthApp(authRequest.ClientId) if err != nil { - utils.RenderWebError(err, w, r) + utils.RenderWebAppError(w, r, err, c.App.AsymmetricSigningKey()) return } @@ -343,7 +343,8 @@ func authorizeOAuthPage(c *Context, w http.ResponseWriter, r *http.Request) { } if !oauthApp.IsValidRedirectURL(authRequest.RedirectUri) { - utils.RenderWebError(model.NewAppError("authorizeOAuthPage", "api.oauth.allow_oauth.redirect_callback.app_error", nil, "", http.StatusBadRequest), w, r) + err := model.NewAppError("authorizeOAuthPage", "api.oauth.allow_oauth.redirect_callback.app_error", nil, "", http.StatusBadRequest) + utils.RenderWebAppError(w, r, err, c.App.AsymmetricSigningKey()) return } @@ -360,7 +361,7 @@ func authorizeOAuthPage(c *Context, w http.ResponseWriter, r *http.Request) { redirectUrl, err := c.App.AllowOAuthAppAccessToUser(c.Session.UserId, authRequest) if err != nil { - utils.RenderWebError(err, w, r) + utils.RenderWebAppError(w, r, err, c.App.AsymmetricSigningKey()) return } @@ -441,7 +442,10 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) { code := r.URL.Query().Get("code") if len(code) == 0 { - http.Redirect(w, r, c.GetSiteURLHeader()+"/error?type=oauth_missing_code&service="+strings.Title(service), http.StatusTemporaryRedirect) + utils.RenderWebError(w, r, http.StatusTemporaryRedirect, url.Values{ + "type": []string{"oauth_missing_code"}, + "service": []string{strings.Title(service)}, + }, c.App.AsymmetricSigningKey()) return } @@ -462,7 +466,7 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) { if action == model.OAUTH_ACTION_MOBILE { w.Write([]byte(err.ToJson())) } else { - http.Redirect(w, r, c.GetSiteURLHeader()+"/error?message="+url.QueryEscape(err.Message), http.StatusTemporaryRedirect) + utils.RenderWebAppError(w, r, err, c.App.AsymmetricSigningKey()) } return } @@ -474,7 +478,7 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) { if action == model.OAUTH_ACTION_MOBILE { w.Write([]byte(err.ToJson())) } else { - http.Redirect(w, r, c.GetSiteURLHeader()+"/error?message="+url.QueryEscape(err.Message), http.StatusTemporaryRedirect) + utils.RenderWebAppError(w, r, err, c.App.AsymmetricSigningKey()) } return } @@ -559,7 +563,9 @@ func signupWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) { } if !c.App.Config().TeamSettings.EnableUserCreation { - http.Redirect(w, r, c.GetSiteURLHeader()+"/error?message="+url.QueryEscape(utils.T("api.oauth.singup_with_oauth.disabled.app_error")), http.StatusTemporaryRedirect) + utils.RenderWebError(w, r, http.StatusBadRequest, url.Values{ + "message": []string{utils.T("api.oauth.singup_with_oauth.disabled.app_error")}, + }, c.App.AsymmetricSigningKey()) return } diff --git a/api4/oauth_test.go b/api4/oauth_test.go index 8dd602456..c871dafff 100644 --- a/api4/oauth_test.go +++ b/api4/oauth_test.go @@ -18,14 +18,7 @@ func TestCreateOAuthApp(t *testing.T) { Client := th.Client AdminClient := th.SystemAdminClient - enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider - adminOnly := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = adminOnly }) - }() th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) - th.App.SetDefaultRolesBasedOnConfig() oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}, IsTrusted: true} @@ -42,12 +35,10 @@ func TestCreateOAuthApp(t *testing.T) { } th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) - th.App.SetDefaultRolesBasedOnConfig() _, resp = Client.CreateOAuthApp(oapp) CheckForbiddenStatus(t, resp) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) - th.App.SetDefaultRolesBasedOnConfig() rapp, resp = Client.CreateOAuthApp(oapp) CheckNoError(t, resp) CheckCreatedStatus(t, resp) @@ -86,14 +77,7 @@ func TestUpdateOAuthApp(t *testing.T) { Client := th.Client AdminClient := th.SystemAdminClient - enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider - adminOnly := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = adminOnly }) - }() th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) - th.App.SetDefaultRolesBasedOnConfig() oapp := &model.OAuthApp{ Name: "oapp", @@ -172,7 +156,6 @@ func TestUpdateOAuthApp(t *testing.T) { th.LoginBasic() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) - th.App.SetDefaultRolesBasedOnConfig() _, resp = Client.UpdateOAuthApp(oapp) CheckForbiddenStatus(t, resp) @@ -199,15 +182,8 @@ func TestGetOAuthApps(t *testing.T) { Client := th.Client AdminClient := th.SystemAdminClient - enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider - adminOnly := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = adminOnly }) - }() th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) - th.App.SetDefaultRolesBasedOnConfig() oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}} @@ -251,7 +227,6 @@ func TestGetOAuthApps(t *testing.T) { } th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) - th.App.SetDefaultRolesBasedOnConfig() _, resp = Client.GetOAuthApps(0, 1000) CheckForbiddenStatus(t, resp) @@ -272,15 +247,8 @@ func TestGetOAuthApp(t *testing.T) { Client := th.Client AdminClient := th.SystemAdminClient - enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider - adminOnly := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = adminOnly }) - }() th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) - th.App.SetDefaultRolesBasedOnConfig() oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}} @@ -320,7 +288,6 @@ func TestGetOAuthApp(t *testing.T) { CheckForbiddenStatus(t, resp) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) - th.App.SetDefaultRolesBasedOnConfig() _, resp = Client.GetOAuthApp(rapp2.Id) CheckForbiddenStatus(t, resp) @@ -347,15 +314,8 @@ func TestGetOAuthAppInfo(t *testing.T) { Client := th.Client AdminClient := th.SystemAdminClient - enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider - adminOnly := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = adminOnly }) - }() th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) - th.App.SetDefaultRolesBasedOnConfig() oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}} @@ -395,7 +355,6 @@ func TestGetOAuthAppInfo(t *testing.T) { CheckNoError(t, resp) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) - th.App.SetDefaultRolesBasedOnConfig() _, resp = Client.GetOAuthAppInfo(rapp2.Id) CheckNoError(t, resp) @@ -422,15 +381,8 @@ func TestDeleteOAuthApp(t *testing.T) { Client := th.Client AdminClient := th.SystemAdminClient - enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider - adminOnly := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = adminOnly }) - }() th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) - th.App.SetDefaultRolesBasedOnConfig() oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}} @@ -465,7 +417,6 @@ func TestDeleteOAuthApp(t *testing.T) { CheckNoError(t, resp) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) - th.App.SetDefaultRolesBasedOnConfig() _, resp = Client.DeleteOAuthApp(rapp.Id) CheckForbiddenStatus(t, resp) @@ -490,15 +441,8 @@ func TestRegenerateOAuthAppSecret(t *testing.T) { Client := th.Client AdminClient := th.SystemAdminClient - enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider - adminOnly := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = adminOnly }) - }() th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) - th.App.SetDefaultRolesBasedOnConfig() oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}} @@ -537,7 +481,6 @@ func TestRegenerateOAuthAppSecret(t *testing.T) { CheckNoError(t, resp) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) - th.App.SetDefaultRolesBasedOnConfig() _, resp = Client.RegenerateOAuthAppSecret(rapp.Id) CheckForbiddenStatus(t, resp) @@ -622,12 +565,7 @@ func TestAuthorizeOAuthApp(t *testing.T) { Client := th.Client AdminClient := th.SystemAdminClient - enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth }) - }() th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) - th.App.SetDefaultRolesBasedOnConfig() oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}} diff --git a/api4/params.go b/api4/params.go index 30638578b..070efbbc6 100644 --- a/api4/params.go +++ b/api4/params.go @@ -27,6 +27,7 @@ type ApiParams struct { ChannelId string PostId string FileId string + Filename string PluginId string CommandId string HookId string @@ -54,6 +55,7 @@ func ApiParamsFromRequest(r *http.Request) *ApiParams { params := &ApiParams{} props := mux.Vars(r) + query := r.URL.Query() if val, ok := props["user_id"]; ok { params.UserId = val @@ -73,6 +75,8 @@ func ApiParamsFromRequest(r *http.Request) *ApiParams { if val, ok := props["channel_id"]; ok { params.ChannelId = val + } else { + params.ChannelId = query.Get("channel_id") } if val, ok := props["post_id"]; ok { @@ -83,6 +87,8 @@ func ApiParamsFromRequest(r *http.Request) *ApiParams { params.FileId = val } + params.Filename = query.Get("filename") + if val, ok := props["plugin_id"]; ok { params.PluginId = val } @@ -151,17 +157,17 @@ func ApiParamsFromRequest(r *http.Request) *ApiParams { params.ActionId = val } - if val, err := strconv.Atoi(r.URL.Query().Get("page")); err != nil || val < 0 { + if val, err := strconv.Atoi(query.Get("page")); err != nil || val < 0 { params.Page = PAGE_DEFAULT } else { params.Page = val } - if val, err := strconv.ParseBool(r.URL.Query().Get("permanent")); err != nil { + if val, err := strconv.ParseBool(query.Get("permanent")); err != nil { params.Permanent = val } - if val, err := strconv.Atoi(r.URL.Query().Get("per_page")); err != nil || val < 0 { + if val, err := strconv.Atoi(query.Get("per_page")); err != nil || val < 0 { params.PerPage = PER_PAGE_DEFAULT } else if val > PER_PAGE_MAXIMUM { params.PerPage = PER_PAGE_MAXIMUM @@ -169,7 +175,7 @@ func ApiParamsFromRequest(r *http.Request) *ApiParams { params.PerPage = val } - if val, err := strconv.Atoi(r.URL.Query().Get("logs_per_page")); err != nil || val < 0 { + if val, err := strconv.Atoi(query.Get("logs_per_page")); err != nil || val < 0 { params.LogsPerPage = LOGS_PER_PAGE_DEFAULT } else if val > LOGS_PER_PAGE_MAXIMUM { params.LogsPerPage = LOGS_PER_PAGE_MAXIMUM diff --git a/api4/post_test.go b/api4/post_test.go index 6f770b70a..257918525 100644 --- a/api4/post_test.go +++ b/api4/post_test.go @@ -17,7 +17,6 @@ import ( "github.com/mattermost/mattermost-server/app" "github.com/mattermost/mattermost-server/model" - "github.com/mattermost/mattermost-server/utils" ) func TestCreatePost(t *testing.T) { @@ -130,20 +129,8 @@ func testCreatePostWithOutgoingHook( team := th.BasicTeam channel := th.BasicChannel - enableOutgoingHooks := th.App.Config().ServiceSettings.EnableOutgoingWebhooks - enableAdminOnlyHooks := th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations - allowedInternalConnections := *th.App.Config().ServiceSettings.AllowedUntrustedInternalConnections - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = enableOutgoingHooks }) - th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks }) - th.App.SetDefaultRolesBasedOnConfig() - th.App.UpdateConfig(func(cfg *model.Config) { - cfg.ServiceSettings.AllowedUntrustedInternalConnections = &allowedInternalConnections - }) - }() th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) - th.App.SetDefaultRolesBasedOnConfig() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost 127.0.0.1" }) @@ -489,21 +476,8 @@ func TestUpdatePost(t *testing.T) { Client := th.Client channel := th.BasicChannel - isLicensed := utils.IsLicensed() - license := utils.License() - allowEditPost := *th.App.Config().ServiceSettings.AllowEditPost - defer func() { - utils.SetIsLicensed(isLicensed) - utils.SetLicense(license) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = allowEditPost }) - th.App.SetDefaultRolesBasedOnConfig() - }() - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - + th.App.SetLicense(model.NewTestLicense()) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = model.ALLOW_EDIT_POST_ALWAYS }) - th.App.SetDefaultRolesBasedOnConfig() post := &model.Post{ChannelId: channel.Id, Message: "zz" + model.NewId() + "a"} rpost, resp := Client.CreatePost(post) @@ -574,21 +548,8 @@ func TestPatchPost(t *testing.T) { Client := th.Client channel := th.BasicChannel - isLicensed := utils.IsLicensed() - license := utils.License() - allowEditPost := *th.App.Config().ServiceSettings.AllowEditPost - defer func() { - utils.SetIsLicensed(isLicensed) - utils.SetLicense(license) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = allowEditPost }) - th.App.SetDefaultRolesBasedOnConfig() - }() - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - + th.App.SetLicense(model.NewTestLicense()) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = model.ALLOW_EDIT_POST_ALWAYS }) - th.App.SetDefaultRolesBasedOnConfig() post := &model.Post{ ChannelId: channel.Id, diff --git a/api4/system.go b/api4/system.go index 43b941247..2355cb476 100644 --- a/api4/system.go +++ b/api4/system.go @@ -121,6 +121,9 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) { return } + // Do not allow plugin uploads to be toggled through the API + cfg.PluginSettings.EnableUploads = c.App.GetConfig().PluginSettings.EnableUploads + err := c.App.SaveConfig(cfg, true) if err != nil { c.Err = err @@ -266,7 +269,7 @@ func getClientLicense(c *Context, w http.ResponseWriter, r *http.Request) { return } - etag := utils.GetClientLicenseEtag(true) + etag := c.App.GetClientLicenseEtag(true) if c.HandleEtag(etag, "Get Client License", w, r) { return } @@ -274,9 +277,9 @@ func getClientLicense(c *Context, w http.ResponseWriter, r *http.Request) { var clientLicense map[string]string if c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) { - clientLicense = utils.ClientLicense() + clientLicense = c.App.ClientLicense() } else { - clientLicense = utils.GetSanitizedClientLicense() + clientLicense = c.App.GetSanitizedClientLicense() } w.Header().Set(model.HEADER_ETAG_SERVER, etag) diff --git a/api4/system_test.go b/api4/system_test.go index 1b2bb5d99..01b4934ae 100644 --- a/api4/system_test.go +++ b/api4/system_test.go @@ -7,6 +7,7 @@ import ( l4g "github.com/alecthomas/log4go" "github.com/mattermost/mattermost-server/model" + "github.com/stretchr/testify/assert" ) func TestGetPing(t *testing.T) { @@ -106,9 +107,10 @@ func TestUpdateConfig(t *testing.T) { defer th.TearDown() Client := th.Client - cfg := th.App.GetConfig() + cfg, resp := th.SystemAdminClient.GetConfig() + CheckNoError(t, resp) - _, resp := Client.UpdateConfig(cfg) + _, resp = Client.UpdateConfig(cfg) CheckForbiddenStatus(t, resp) SiteName := th.App.Config().TeamSettings.SiteName @@ -139,6 +141,22 @@ func TestUpdateConfig(t *testing.T) { t.Fatal() } } + + t.Run("Should not be able to modify PluginSettings.EnableUploads", func(t *testing.T) { + oldEnableUploads := *th.App.GetConfig().PluginSettings.EnableUploads + *cfg.PluginSettings.EnableUploads = !oldEnableUploads + + cfg, resp = th.SystemAdminClient.UpdateConfig(cfg) + CheckNoError(t, resp) + assert.Equal(t, oldEnableUploads, *cfg.PluginSettings.EnableUploads) + assert.Equal(t, oldEnableUploads, *th.App.GetConfig().PluginSettings.EnableUploads) + + cfg.PluginSettings.EnableUploads = nil + cfg, resp = th.SystemAdminClient.UpdateConfig(cfg) + CheckNoError(t, resp) + assert.Equal(t, oldEnableUploads, *cfg.PluginSettings.EnableUploads) + assert.Equal(t, oldEnableUploads, *th.App.GetConfig().PluginSettings.EnableUploads) + }) } func TestGetOldClientConfig(t *testing.T) { diff --git a/api4/team_test.go b/api4/team_test.go index d365fd686..faa90e511 100644 --- a/api4/team_test.go +++ b/api4/team_test.go @@ -68,13 +68,7 @@ func TestCreateTeam(t *testing.T) { CheckUnauthorizedStatus(t, resp) // Update permission - enableTeamCreation := th.App.Config().TeamSettings.EnableTeamCreation - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.EnableTeamCreation = enableTeamCreation }) - th.App.SetDefaultRolesBasedOnConfig() - }() th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.EnableTeamCreation = false }) - th.App.SetDefaultRolesBasedOnConfig() th.LoginBasic() _, resp = Client.CreateTeam(team) @@ -1292,20 +1286,8 @@ func TestAddTeamMember(t *testing.T) { Client.Logout() - // Check effects of config and license changes. - restrictTeamInvite := *th.App.Config().TeamSettings.RestrictTeamInvite - isLicensed := utils.IsLicensed() - license := utils.License() - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = restrictTeamInvite }) - utils.SetIsLicensed(isLicensed) - utils.SetLicense(license) - th.App.SetDefaultRolesBasedOnConfig() - }() - // Set the config so that only team admins can add a user to a team. th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN }) - th.App.SetDefaultRolesBasedOnConfig() th.LoginBasic() // Test without the EE license to see that the permission restriction is ignored. @@ -1313,10 +1295,7 @@ func TestAddTeamMember(t *testing.T) { CheckNoError(t, resp) // Add an EE license. - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() + th.App.SetLicense(model.NewTestLicense()) th.LoginBasic() // Check that a regular user can't add someone to the team. @@ -1327,10 +1306,7 @@ func TestAddTeamMember(t *testing.T) { th.UpdateUserToTeamAdmin(th.BasicUser, th.BasicTeam) th.App.InvalidateAllCaches() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN }) - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() + th.App.SetLicense(model.NewTestLicense()) th.LoginBasic() // Should work as a team admin. @@ -1339,7 +1315,6 @@ func TestAddTeamMember(t *testing.T) { // Change permission level to System Admin th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN }) - th.App.SetDefaultRolesBasedOnConfig() // Should not work as team admin. _, resp = Client.AddTeamMember(team.Id, otherUser.Id) @@ -1353,21 +1328,13 @@ func TestAddTeamMember(t *testing.T) { th.UpdateUserToNonTeamAdmin(th.BasicUser, th.BasicTeam) th.App.InvalidateAllCaches() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_ALL }) - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() + th.App.SetLicense(model.NewTestLicense()) th.LoginBasic() // Should work as a regular user. _, resp = Client.AddTeamMember(team.Id, otherUser.Id) CheckNoError(t, resp) - // Reset config and license. - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = restrictTeamInvite }) - utils.SetIsLicensed(isLicensed) - utils.SetLicense(license) - th.App.SetDefaultRolesBasedOnConfig() th.LoginBasic() // by hash and data @@ -1507,20 +1474,8 @@ func TestAddTeamMembers(t *testing.T) { Client.Logout() - // Check effects of config and license changes. - restrictTeamInvite := *th.App.Config().TeamSettings.RestrictTeamInvite - isLicensed := utils.IsLicensed() - license := utils.License() - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = restrictTeamInvite }) - utils.SetIsLicensed(isLicensed) - utils.SetLicense(license) - th.App.SetDefaultRolesBasedOnConfig() - }() - // Set the config so that only team admins can add a user to a team. th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN }) - th.App.SetDefaultRolesBasedOnConfig() th.LoginBasic() // Test without the EE license to see that the permission restriction is ignored. @@ -1528,10 +1483,7 @@ func TestAddTeamMembers(t *testing.T) { CheckNoError(t, resp) // Add an EE license. - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() + th.App.SetLicense(model.NewTestLicense()) th.LoginBasic() // Check that a regular user can't add someone to the team. @@ -1542,10 +1494,7 @@ func TestAddTeamMembers(t *testing.T) { th.UpdateUserToTeamAdmin(th.BasicUser, th.BasicTeam) th.App.InvalidateAllCaches() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN }) - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() + th.App.SetLicense(model.NewTestLicense()) th.LoginBasic() // Should work as a team admin. @@ -1554,7 +1503,6 @@ func TestAddTeamMembers(t *testing.T) { // Change permission level to System Admin th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN }) - th.App.SetDefaultRolesBasedOnConfig() // Should not work as team admin. _, resp = Client.AddTeamMembers(team.Id, userList) @@ -1568,10 +1516,7 @@ func TestAddTeamMembers(t *testing.T) { th.UpdateUserToNonTeamAdmin(th.BasicUser, th.BasicTeam) th.App.InvalidateAllCaches() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_ALL }) - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - th.App.SetDefaultRolesBasedOnConfig() + th.App.SetLicense(model.NewTestLicense()) th.LoginBasic() // Should work as a regular user. @@ -1930,10 +1875,6 @@ func TestInviteUsersToTeam(t *testing.T) { } } - restrictCreationToDomains := th.App.Config().TeamSettings.RestrictCreationToDomains - defer func() { - th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.RestrictCreationToDomains = restrictCreationToDomains }) - }() th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.RestrictCreationToDomains = "@example.com" }) err := th.App.InviteNewUsersToTeam(emailList, th.BasicTeam.Id, th.BasicUser.Id) diff --git a/api4/user.go b/api4/user.go index cfb2a5b3f..f82a6e3d5 100644 --- a/api4/user.go +++ b/api4/user.go @@ -13,7 +13,6 @@ import ( "github.com/mattermost/mattermost-server/app" "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/store" - "github.com/mattermost/mattermost-server/utils" ) func (api *API) InitUser() { @@ -894,7 +893,7 @@ func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) { return } - if sent, err := c.App.SendPasswordReset(email, utils.GetSiteURL()); err != nil { + if sent, err := c.App.SendPasswordReset(email, c.App.GetSiteURL()); err != nil { c.Err = err return } else if sent { @@ -1076,6 +1075,7 @@ func attachDeviceId(c *Context, w http.ResponseWriter, r *http.Request) { MaxAge: maxAge, Expires: expiresAt, HttpOnly: true, + Domain: c.App.GetCookieDomain(), Secure: secure, } diff --git a/api4/user_test.go b/api4/user_test.go index a7b7d297d..4613a8ea9 100644 --- a/api4/user_test.go +++ b/api4/user_test.go @@ -1566,18 +1566,7 @@ func TestUpdateUserMfa(t *testing.T) { defer th.TearDown() Client := th.Client - isLicensed := utils.IsLicensed() - license := utils.License() - enableMfa := *th.App.Config().ServiceSettings.EnableMultifactorAuthentication - defer func() { - utils.SetIsLicensed(isLicensed) - utils.SetLicense(license) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = enableMfa }) - }() - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - *utils.License().Features.MFA = true + th.App.SetLicense(model.NewTestLicense("mfa")) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = true }) session, _ := th.App.GetSession(Client.AuthToken) @@ -1612,18 +1601,7 @@ func TestCheckUserMfa(t *testing.T) { t.Fatal("should be false - mfa not active") } - isLicensed := utils.IsLicensed() - license := utils.License() - enableMfa := *th.App.Config().ServiceSettings.EnableMultifactorAuthentication - defer func() { - utils.SetIsLicensed(isLicensed) - utils.SetLicense(license) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = enableMfa }) - }() - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - *utils.License().Features.MFA = true + th.App.SetLicense(model.NewTestLicense("mfa")) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = true }) th.LoginBasic() @@ -1659,18 +1637,7 @@ func TestGenerateMfaSecret(t *testing.T) { _, resp = Client.GenerateMfaSecret("junk") CheckBadRequestStatus(t, resp) - isLicensed := utils.IsLicensed() - license := utils.License() - enableMfa := *th.App.Config().ServiceSettings.EnableMultifactorAuthentication - defer func() { - utils.SetIsLicensed(isLicensed) - utils.SetLicense(license) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = enableMfa }) - }() - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() - *utils.License().Features.MFA = true + th.App.SetLicense(model.NewTestLicense("mfa")) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = true }) _, resp = Client.GenerateMfaSecret(model.NewId()) @@ -2187,19 +2154,7 @@ func TestSwitchAccount(t *testing.T) { t.Fatal("bad link") } - isLicensed := utils.IsLicensed() - license := utils.License() - enableAuthenticationTransfer := *th.App.Config().ServiceSettings.ExperimentalEnableAuthenticationTransfer - defer func() { - utils.SetIsLicensed(isLicensed) - utils.SetLicense(license) - th.App.UpdateConfig(func(cfg *model.Config) { - *cfg.ServiceSettings.ExperimentalEnableAuthenticationTransfer = enableAuthenticationTransfer - }) - }() - utils.SetIsLicensed(true) - utils.SetLicense(&model.License{Features: &model.Features{}}) - utils.License().Features.SetDefaults() + th.App.SetLicense(model.NewTestLicense()) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ExperimentalEnableAuthenticationTransfer = false }) sr = &model.SwitchRequest{ diff --git a/api4/webhook.go b/api4/webhook.go index 90e32a891..e19f14704 100644 --- a/api4/webhook.go +++ b/api4/webhook.go @@ -8,7 +8,10 @@ import ( "net/http" "strings" + l4g "github.com/alecthomas/log4go" + "github.com/gorilla/mux" + "github.com/gorilla/schema" "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/utils" ) @@ -447,34 +450,40 @@ func incomingWebhook(c *Context, w http.ResponseWriter, r *http.Request) { r.ParseForm() - var payload io.Reader + var err *model.AppError + incomingWebhookPayload := &model.IncomingWebhookRequest{} contentType := r.Header.Get("Content-Type") if strings.Split(contentType, "; ")[0] == "application/x-www-form-urlencoded" { - payload = strings.NewReader(r.FormValue("payload")) - } else { - payload = r.Body - } + payload := strings.NewReader(r.FormValue("payload")) - if c.App.Config().LogSettings.EnableWebhookDebugging { - var err error - payload, err = utils.InfoReader( - payload, - utils.T("api.webhook.incoming.debug"), - ) + incomingWebhookPayload, err = decodePayload(payload) if err != nil { - c.Err = model.NewAppError("incomingWebhook", "api.webhook.incoming.debug.error", nil, err.Error(), http.StatusInternalServerError) + c.Err = err return } - } + } else if strings.HasPrefix(contentType, "multipart/form-data") { + r.ParseMultipartForm(0) - parsedRequest, decodeError := model.IncomingWebhookRequestFromJson(payload) + decoder := schema.NewDecoder() + err := decoder.Decode(incomingWebhookPayload, r.PostForm) - if decodeError != nil { - c.Err = decodeError - return + if err != nil { + c.Err = model.NewAppError("incomingWebhook", "api.webhook.incoming.error", nil, err.Error(), http.StatusBadRequest) + return + } + } else { + incomingWebhookPayload, err = decodePayload(r.Body) + if err != nil { + c.Err = err + return + } + } + + if c.App.Config().LogSettings.EnableWebhookDebugging { + l4g.Debug(utils.T("api.webhook.incoming.debug"), incomingWebhookPayload.ToJson()) } - err := c.App.HandleIncomingWebhook(id, parsedRequest) + err = c.App.HandleIncomingWebhook(id, incomingWebhookPayload) if err != nil { c.Err = err return @@ -499,3 +508,14 @@ func commandWebhook(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain") w.Write([]byte("ok")) } + +func decodePayload(payload io.Reader) (*model.IncomingWebhookRequest, *model.AppError) { + decodeError := &model.AppError{} + incomingWebhookPayload, decodeError := model.IncomingWebhookRequestFromJson(payload) + + if decodeError != nil { + return nil, decodeError + } + + return incomingWebhookPayload, nil +} |