diff --git a/api4/apitestlib.go b/api4/apitestlib.go index 9f2a91037d..9168983bbf 100644 --- a/api4/apitestlib.go +++ b/api4/apitestlib.go @@ -322,8 +322,8 @@ func SetupWithStoreMock(tb testing.TB) *TestHelper { return th } -func SetupEnterpriseWithStoreMock(tb testing.TB, options ...app.Option) *TestHelper { - th := setupTestHelper(testlib.GetMockStoreForSetupFunctions(), nil, true, false, nil, options) +func SetupEnterpriseWithStoreMock(tb testing.TB) *TestHelper { + th := setupTestHelper(testlib.GetMockStoreForSetupFunctions(), nil, true, false, nil, nil) statusMock := mocks.StatusStore{} statusMock.On("UpdateExpiredDNDStatuses").Return([]*model.Status{}, nil) statusMock.On("Get", "user1").Return(&model.Status{UserId: "user1", Status: model.StatusOnline}, nil) @@ -401,17 +401,17 @@ func (th *TestHelper) InitLogin() *TestHelper { // create users once and cache them because password hashing is slow initBasicOnce.Do(func() { th.SystemAdminUser = th.CreateUser() - th.App.UpdateUserRoles(th.SystemAdminUser.Id, model.SystemUserRoleId+" "+model.SystemAdminRoleId, false) + th.App.UpdateUserRoles(th.Context, th.SystemAdminUser.Id, model.SystemUserRoleId+" "+model.SystemAdminRoleId, false) th.SystemAdminUser, _ = th.App.GetUser(th.SystemAdminUser.Id) userCache.SystemAdminUser = th.SystemAdminUser.DeepCopy() th.SystemManagerUser = th.CreateUser() - th.App.UpdateUserRoles(th.SystemManagerUser.Id, model.SystemUserRoleId+" "+model.SystemManagerRoleId, false) + th.App.UpdateUserRoles(th.Context, th.SystemManagerUser.Id, model.SystemUserRoleId+" "+model.SystemManagerRoleId, false) th.SystemManagerUser, _ = th.App.GetUser(th.SystemManagerUser.Id) userCache.SystemManagerUser = th.SystemManagerUser.DeepCopy() th.TeamAdminUser = th.CreateUser() - th.App.UpdateUserRoles(th.TeamAdminUser.Id, model.SystemUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.TeamAdminUser.Id, model.SystemUserRoleId, false) th.TeamAdminUser, _ = th.App.GetUser(th.TeamAdminUser.Id) userCache.TeamAdminUser = th.TeamAdminUser.DeepCopy() @@ -476,7 +476,7 @@ func (th *TestHelper) InitBasic() *TestHelper { th.App.AddUserToChannel(th.Context, th.BasicUser2, th.BasicPrivateChannel, false) th.App.AddUserToChannel(th.Context, th.BasicUser, th.BasicDeletedChannel, false) th.App.AddUserToChannel(th.Context, th.BasicUser2, th.BasicDeletedChannel, false) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId, false) th.Client.DeleteChannel(th.BasicDeletedChannel.Id) th.LoginBasic() th.Group = th.CreateGroup() diff --git a/api4/bot.go b/api4/bot.go index fad11c8114..569d51b793 100644 --- a/api4/bot.go +++ b/api4/bot.go @@ -28,7 +28,7 @@ func createBot(c *Context, w http.ResponseWriter, r *http.Request) { var botPatch *model.BotPatch err := json.NewDecoder(r.Body).Decode(&botPatch) if err != nil { - c.SetInvalidParam("bot") + c.SetInvalidParamWithErr("bot", err) return } @@ -70,7 +70,7 @@ func createBot(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(createdBot); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -84,7 +84,7 @@ func patchBot(c *Context, w http.ResponseWriter, r *http.Request) { var botPatch *model.BotPatch err := json.NewDecoder(r.Body).Decode(&botPatch) if err != nil { - c.SetInvalidParam("bot") + c.SetInvalidParamWithErr("bot", err) return } @@ -109,7 +109,7 @@ func patchBot(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddEventObjectType("bot") if err := json.NewEncoder(w).Encode(updatedBot); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -150,7 +150,7 @@ func getBot(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(bot); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -268,7 +268,7 @@ func assignBot(c *Context, w http.ResponseWriter, _ *http.Request) { auditRec.AddEventObjectType("bot") if err := json.NewEncoder(w).Encode(bot); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -287,7 +287,7 @@ func convertBotToUser(c *Context, w http.ResponseWriter, r *http.Request) { var userPatch model.UserPatch jsonErr := json.NewDecoder(r.Body).Decode(&userPatch) if jsonErr != nil || userPatch.Password == nil || *userPatch.Password == "" { - c.SetInvalidParam("userPatch") + c.SetInvalidParamWithErr("userPatch", jsonErr) return } @@ -304,7 +304,7 @@ func convertBotToUser(c *Context, w http.ResponseWriter, r *http.Request) { return } - user, err := c.App.ConvertBotToUser(bot, &userPatch, systemAdmin) + user, err := c.App.ConvertBotToUser(c.AppContext, bot, &userPatch, systemAdmin) if err != nil { c.Err = err return @@ -315,6 +315,6 @@ func convertBotToUser(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddEventObjectType("user") if err := json.NewEncoder(w).Encode(user); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/bot_test.go b/api4/bot_test.go index b01dca609e..c5b7bc1413 100644 --- a/api4/bot_test.go +++ b/api4/bot_test.go @@ -37,7 +37,7 @@ func TestCreateBot(t *testing.T) { defer th.TearDown() th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.Config().ServiceSettings.EnableBotAccountCreation = model.NewBool(false) _, _, err := th.Client.CreateBot(&model.Bot{ @@ -55,7 +55,7 @@ func TestCreateBot(t *testing.T) { defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -81,7 +81,7 @@ func TestCreateBot(t *testing.T) { defer th.TearDown() th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -106,7 +106,7 @@ func TestCreateBot(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionEditOtherUsers.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) bot, resp, err := th.Client.CreateBot(&model.Bot{ Username: GenerateTestUsername(), @@ -116,7 +116,7 @@ func TestCreateBot(t *testing.T) { require.NoError(t, err) CheckCreatedStatus(t, resp) defer th.App.PermanentDeleteBot(bot.UserId) - th.App.UpdateUserRoles(bot.UserId, model.TeamUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, bot.UserId, model.TeamUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) rtoken, _, err := th.Client.CreateUserAccessToken(bot.UserId, "test token") require.NoError(t, err) @@ -152,7 +152,7 @@ func TestPatchBot(t *testing.T) { defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -234,7 +234,7 @@ func TestPatchBot(t *testing.T) { defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -258,7 +258,7 @@ func TestPatchBot(t *testing.T) { defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) th.AddPermissionToRole(model.PermissionManageOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -291,7 +291,7 @@ func TestPatchBot(t *testing.T) { th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionManageRoles.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) resp, err = th.Client.UpdateUserRoles(createdBot.UserId, model.SystemUserRoleId) require.NoError(t, err) @@ -310,7 +310,7 @@ func TestPatchBot(t *testing.T) { defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -341,7 +341,7 @@ func TestPatchBot(t *testing.T) { th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -372,7 +372,7 @@ func TestPatchBot(t *testing.T) { th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -408,7 +408,7 @@ func TestPatchBot(t *testing.T) { th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -444,7 +444,7 @@ func TestPatchBot(t *testing.T) { th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -513,7 +513,7 @@ func TestGetBot(t *testing.T) { CheckOKStatus(t, resp) th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -533,7 +533,7 @@ func TestGetBot(t *testing.T) { th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) _, resp, err := th.Client.GetBot(model.NewId(), "") require.Error(t, err) @@ -545,7 +545,7 @@ func TestGetBot(t *testing.T) { th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) bot, resp, err := th.Client.GetBot(bot1.UserId, "") require.NoError(t, err) @@ -561,7 +561,7 @@ func TestGetBot(t *testing.T) { th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) bot, resp, err := th.Client.GetBot(bot2.UserId, "") require.NoError(t, err) @@ -579,7 +579,7 @@ func TestGetBot(t *testing.T) { th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionManageOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) _, _, err := th.Client.GetBot(bot1.UserId, "") CheckErrorID(t, err, "store.sql_bot.get.missing.app_error") @@ -591,7 +591,7 @@ func TestGetBot(t *testing.T) { th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionManageOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) _, _, err := th.Client.GetBot(myBot.UserId, "") CheckErrorID(t, err, "store.sql_bot.get.missing.app_error") @@ -602,7 +602,7 @@ func TestGetBot(t *testing.T) { th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) _, resp, err := th.Client.GetBot(deletedBot.UserId, "") require.Error(t, err) @@ -614,7 +614,7 @@ func TestGetBot(t *testing.T) { th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) bot, resp, err := th.Client.GetBotIncludeDeleted(deletedBot.UserId, "") require.NoError(t, err) @@ -687,7 +687,7 @@ func TestGetBots(t *testing.T) { CheckOKStatus(t, resp) th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser2.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser2.Id, model.TeamUserRoleId, false) th.LoginBasic2() orphanedBot, resp, err := th.Client.CreateBot(&model.Bot{ Username: GenerateTestUsername(), @@ -710,7 +710,7 @@ func TestGetBots(t *testing.T) { th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) expectedBotList := []*model.Bot{bot1, bot2, bot3, orphanedBot} th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { @@ -730,7 +730,7 @@ func TestGetBots(t *testing.T) { th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) expectedBotList := []*model.Bot{bot1} th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { @@ -750,7 +750,7 @@ func TestGetBots(t *testing.T) { th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) expectedBotList := []*model.Bot{bot3, orphanedBot} th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { @@ -770,7 +770,7 @@ func TestGetBots(t *testing.T) { th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) expectedBotList := []*model.Bot{} th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { @@ -790,7 +790,7 @@ func TestGetBots(t *testing.T) { th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) expectedBotList := []*model.Bot{bot1, deletedBot1, bot2, bot3, deletedBot2, orphanedBot} th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { @@ -810,7 +810,7 @@ func TestGetBots(t *testing.T) { th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) expectedBotList := []*model.Bot{bot1} th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { @@ -830,7 +830,7 @@ func TestGetBots(t *testing.T) { th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) expectedBotList := []*model.Bot{bot2, bot3} th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { @@ -850,7 +850,7 @@ func TestGetBots(t *testing.T) { th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) expectedBotList := []*model.Bot{deletedBot2, orphanedBot} th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { @@ -870,7 +870,7 @@ func TestGetBots(t *testing.T) { th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) expectedBotList := []*model.Bot{orphanedBot} th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { @@ -891,7 +891,7 @@ func TestGetBots(t *testing.T) { th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionManageOthersBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) _, _, err := th.Client.GetBots(0, 10, "") CheckErrorID(t, err, "api.context.permissions.app_error") @@ -916,7 +916,7 @@ func TestDisableBot(t *testing.T) { defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -942,7 +942,7 @@ func TestDisableBot(t *testing.T) { th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -968,7 +968,7 @@ func TestDisableBot(t *testing.T) { th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -1021,7 +1021,7 @@ func TestEnableBot(t *testing.T) { defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -1051,7 +1051,7 @@ func TestEnableBot(t *testing.T) { th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -1081,7 +1081,7 @@ func TestEnableBot(t *testing.T) { th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -1288,7 +1288,7 @@ func TestConvertBotToUser(t *testing.T) { defer th.TearDown() th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) diff --git a/api4/channel.go b/api4/channel.go index c686bfd272..954ec5632e 100644 --- a/api4/channel.go +++ b/api4/channel.go @@ -82,7 +82,7 @@ func createChannel(c *Context, w http.ResponseWriter, r *http.Request) { var channel *model.Channel err := json.NewDecoder(r.Body).Decode(&channel) if err != nil { - c.SetInvalidParam("channel") + c.SetInvalidParamWithErr("channel", err) return } @@ -126,7 +126,7 @@ func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) { var channel *model.Channel err := json.NewDecoder(r.Body).Decode(&channel) if err != nil { - c.SetInvalidParam("channel") + c.SetInvalidParamWithErr("channel", err) return } @@ -303,7 +303,7 @@ func patchChannel(c *Context, w http.ResponseWriter, r *http.Request) { var patch *model.ChannelPatch err := json.NewDecoder(r.Body).Decode(&patch) if err != nil { - c.SetInvalidParam("channel") + c.SetInvalidParamWithErr("channel", err) return } @@ -482,7 +482,7 @@ func searchGroupChannels(c *Context, w http.ResponseWriter, r *http.Request) { var props *model.ChannelSearch err := json.NewDecoder(r.Body).Decode(&props) if err != nil { - c.SetInvalidParam("channel_search") + c.SetInvalidParamWithErr("channel_search", err) return } @@ -1057,7 +1057,7 @@ func searchChannelsForTeam(c *Context, w http.ResponseWriter, r *http.Request) { var props *model.ChannelSearch err := json.NewDecoder(r.Body).Decode(&props) if err != nil { - c.SetInvalidParam("channel_search") + c.SetInvalidParamWithErr("channel_search", err) return } @@ -1096,7 +1096,7 @@ func searchArchivedChannelsForTeam(c *Context, w http.ResponseWriter, r *http.Re var props *model.ChannelSearch err := json.NewDecoder(r.Body).Decode(&props) if err != nil { - c.SetInvalidParam("channel_search") + c.SetInvalidParamWithErr("channel_search", err) return } @@ -1130,7 +1130,7 @@ func searchAllChannels(c *Context, w http.ResponseWriter, r *http.Request) { var props *model.ChannelSearch err := json.NewDecoder(r.Body).Decode(&props) if err != nil { - c.SetInvalidParam("channel_search") + c.SetInvalidParamWithErr("channel_search", err) return } @@ -1470,7 +1470,7 @@ func viewChannel(c *Context, w http.ResponseWriter, r *http.Request) { var view model.ChannelView if jsonErr := json.NewDecoder(r.Body).Decode(&view); jsonErr != nil { - c.SetInvalidParam("channel_view") + c.SetInvalidParamWithErr("channel_view", jsonErr) return } @@ -1547,7 +1547,7 @@ func updateChannelMemberSchemeRoles(c *Context, w http.ResponseWriter, r *http.R var schemeRoles model.SchemeRoles if jsonErr := json.NewDecoder(r.Body).Decode(&schemeRoles); jsonErr != nil { - c.SetInvalidParam("scheme_roles") + c.SetInvalidParamWithErr("scheme_roles", jsonErr) return } @@ -1810,7 +1810,7 @@ func updateChannelScheme(c *Context, w http.ResponseWriter, r *http.Request) { var p model.SchemeIDPatch if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil || p.SchemeID == nil || !model.IsValidId(*p.SchemeID) { - c.SetInvalidParam("scheme_id") + c.SetInvalidParamWithErr("scheme_id", jsonErr) return } schemeID := p.SchemeID @@ -2013,7 +2013,7 @@ func patchChannelModerations(c *Context, w http.ResponseWriter, r *http.Request) var channelModerationsPatch []*model.ChannelModerationPatch err := json.NewDecoder(r.Body).Decode(&channelModerationsPatch) if err != nil { - c.Err = model.NewAppError("Api4.patchChannelModerations", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.patchChannelModerations", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } diff --git a/api4/channel_category.go b/api4/channel_category.go index fe9c0c0ef3..c92b3ff27b 100644 --- a/api4/channel_category.go +++ b/api4/channel_category.go @@ -55,7 +55,7 @@ func createCategoryForTeamForUser(c *Context, w http.ResponseWriter, r *http.Req var categoryCreateRequest model.SidebarCategoryWithChannels err := json.NewDecoder(r.Body).Decode(&categoryCreateRequest) if err != nil || c.Params.UserId != categoryCreateRequest.UserId || c.Params.TeamId != categoryCreateRequest.TeamId { - c.SetInvalidParam("category") + c.SetInvalidParamWithErr("category", err) return } @@ -177,7 +177,7 @@ func updateCategoriesForTeamForUser(c *Context, w http.ResponseWriter, r *http.R var categoriesUpdateRequest []*model.SidebarCategoryWithChannels err := json.NewDecoder(r.Body).Decode(&categoriesUpdateRequest) if err != nil { - c.SetInvalidParam("category") + c.SetInvalidParamWithErr("category", err) return } @@ -278,7 +278,7 @@ func updateCategoryForTeamForUser(c *Context, w http.ResponseWriter, r *http.Req var categoryUpdateRequest model.SidebarCategoryWithChannels err := json.NewDecoder(r.Body).Decode(&categoryUpdateRequest) if err != nil || categoryUpdateRequest.TeamId != c.Params.TeamId || categoryUpdateRequest.UserId != c.Params.UserId { - c.SetInvalidParam("category") + c.SetInvalidParamWithErr("category", err) return } diff --git a/api4/channel_local.go b/api4/channel_local.go index bb5286b44f..0c5da46a6c 100644 --- a/api4/channel_local.go +++ b/api4/channel_local.go @@ -41,7 +41,7 @@ func localCreateChannel(c *Context, w http.ResponseWriter, r *http.Request) { var channel *model.Channel err := json.NewDecoder(r.Body).Decode(&channel) if err != nil { - c.SetInvalidParam("channel") + c.SetInvalidParamWithErr("channel", err) return } @@ -284,7 +284,7 @@ func localPatchChannel(c *Context, w http.ResponseWriter, r *http.Request) { var patch *model.ChannelPatch err := json.NewDecoder(r.Body).Decode(&patch) if err != nil { - c.SetInvalidParam("channel") + c.SetInvalidParamWithErr("channel", err) return } diff --git a/api4/cloud.go b/api4/cloud.go index 0f833c8bdc..825db6d5bb 100644 --- a/api4/cloud.go +++ b/api4/cloud.go @@ -14,6 +14,7 @@ import ( "github.com/mattermost/mattermost-server/v6/audit" "github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/plugin" + "github.com/mattermost/mattermost-server/v6/shared/mlog" ) func (api *API) InitCloud() { @@ -57,7 +58,7 @@ func handleNotifyAdminToUpgrade(c *Context, w http.ResponseWriter, r *http.Reque var notifyAdminRequest *model.NotifyAdminToUpgradeRequest err := json.NewDecoder(r.Body).Decode(¬ifyAdminRequest) if err != nil { - c.SetInvalidParam("notifyAdminRequest") + c.SetInvalidParamWithErr("notifyAdminRequest", err) return } @@ -232,12 +233,19 @@ func validateBusinessEmail(c *Context, w http.ResponseWriter, r *http.Request) { return } - errValidatingEmail := c.App.Cloud().ValidateBusinessEmail(user.Id, emailToValidate.Email) - if errValidatingEmail != nil { - c.Err = model.NewAppError("Api4.valiateBusinessEmail", "api.cloud.request_error", nil, errValidatingEmail.Error(), http.StatusInternalServerError) + emailErr := c.App.Cloud().ValidateBusinessEmail(user.Id, emailToValidate.Email) + if emailErr != nil { + c.Err = model.NewAppError("Api4.validateBusinessEmail", "api.cloud.request_error", nil, emailErr.Error(), http.StatusForbidden) + emailResp := model.ValidateBusinessEmailResponse{IsValid: false} + if err := json.NewEncoder(w).Encode(emailResp); err != nil { + mlog.Warn("Error while writing response", mlog.Err(err)) + } return } - ReturnStatusOK(w) + emailResp := model.ValidateBusinessEmailResponse{IsValid: true} + if err := json.NewEncoder(w).Encode(emailResp); err != nil { + mlog.Warn("Error while writing response", mlog.Err(err)) + } } func validateWorkspaceBusinessEmail(c *Context, w http.ResponseWriter, r *http.Request) { @@ -263,20 +271,27 @@ func validateWorkspaceBusinessEmail(c *Context, w http.ResponseWriter, r *http.R c.Err = model.NewAppError("Api4.validateWorkspaceBusinessEmail", "api.cloud.request_error", nil, err.Error(), http.StatusInternalServerError) return } - errValidatingSystemEmail := c.App.Cloud().ValidateBusinessEmail(user.Id, cloudCustomer.Email) + emailErr := c.App.Cloud().ValidateBusinessEmail(user.Id, cloudCustomer.Email) // if the current workspace email is not a valid business email - if errValidatingSystemEmail != nil { + if emailErr != nil { // grab the current admin email and validate it errValidatingAdminEmail := c.App.Cloud().ValidateBusinessEmail(user.Id, user.Email) if errValidatingAdminEmail != nil { - c.Err = model.NewAppError("Api4.validateWorkspaceBusinessEmail", "api.cloud.request_error", nil, errValidatingAdminEmail.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.validateWorkspaceBusinessEmail", "api.cloud.request_error", nil, errValidatingAdminEmail.Error(), http.StatusForbidden) + emailResp := model.ValidateBusinessEmailResponse{IsValid: false} + if err := json.NewEncoder(w).Encode(emailResp); err != nil { + mlog.Warn("Error while writing response", mlog.Err(err)) + } return } } // if any of the emails is valid, return ok - ReturnStatusOK(w) + emailResp := model.ValidateBusinessEmailResponse{IsValid: true} + if err := json.NewEncoder(w).Encode(emailResp); err != nil { + mlog.Warn("Error while writing response", mlog.Err(err)) + } } func getCloudProducts(c *Context, w http.ResponseWriter, r *http.Request) { diff --git a/api4/cloud_test.go b/api4/cloud_test.go index b959998f32..a689c68a8e 100644 --- a/api4/cloud_test.go +++ b/api4/cloud_test.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "net/http" - "net/http/httptest" "os" "testing" "time" @@ -401,21 +400,19 @@ func TestNotifyAdminToUpgrade(t *testing.T) { }) } func Test_validateBusinessEmail(t *testing.T) { - t.Run("Initial request has invalid email", func(t *testing.T) { + t.Run("Returns forbidden for non admin executors", func(t *testing.T) { th := Setup(t).InitBasic() defer th.TearDown() th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) - validateBusinessEmail := model.ValidateBusinessEmailRequest{Email: ""} + invalidEmail := model.ValidateBusinessEmailRequest{Email: "invalid@gmail.com"} th.App.Srv().SetLicense(model.NewTestLicense("cloud")) cloud := mocks.CloudInterface{} - resp := httptest.NewRecorder() - - cloud.Mock.On("ValidateBusinessEmail", mock.Anything).Return(resp, nil) + cloud.Mock.On("ValidateBusinessEmail", th.SystemAdminUser.Id, invalidEmail.Email).Return(errors.New("invalid email")) cloudImpl := th.App.Srv().Cloud defer func() { @@ -423,8 +420,59 @@ func Test_validateBusinessEmail(t *testing.T) { }() th.App.Srv().Cloud = &cloud - _, err := th.Client.ValidateBusinessEmail(&validateBusinessEmail) + res, err := th.Client.ValidateBusinessEmail(&invalidEmail) require.Error(t, err) + require.Equal(t, http.StatusForbidden, res.StatusCode, "403") + }) + + t.Run("Returns forbidden for invalid business email", func(t *testing.T) { + th := Setup(t).InitBasic() + defer th.TearDown() + + th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) + + validBusinessEmail := model.ValidateBusinessEmailRequest{Email: "invalid@slacker.com"} + + th.App.Srv().SetLicense(model.NewTestLicense("cloud")) + + cloud := mocks.CloudInterface{} + + cloud.Mock.On("ValidateBusinessEmail", th.SystemAdminUser.Id, validBusinessEmail.Email).Return(errors.New("invalid email")) + + cloudImpl := th.App.Srv().Cloud + defer func() { + th.App.Srv().Cloud = cloudImpl + }() + th.App.Srv().Cloud = &cloud + + res, err := th.SystemAdminClient.ValidateBusinessEmail(&validBusinessEmail) + require.Error(t, err) + require.Equal(t, http.StatusForbidden, res.StatusCode, "403") + }) + + t.Run("Validate business email for admin", func(t *testing.T) { + th := Setup(t).InitBasic() + defer th.TearDown() + + th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) + + validBusinessEmail := model.ValidateBusinessEmailRequest{Email: "valid@mattermost.com"} + + th.App.Srv().SetLicense(model.NewTestLicense("cloud")) + + cloud := mocks.CloudInterface{} + + cloud.Mock.On("ValidateBusinessEmail", th.SystemAdminUser.Id, validBusinessEmail.Email).Return(nil) + + cloudImpl := th.App.Srv().Cloud + defer func() { + th.App.Srv().Cloud = cloudImpl + }() + th.App.Srv().Cloud = &cloud + + res, err := th.SystemAdminClient.ValidateBusinessEmail(&validBusinessEmail) + require.NoError(t, err) + require.Equal(t, http.StatusOK, res.StatusCode, "200") }) } diff --git a/api4/command.go b/api4/command.go index fa627b32d2..c267c869fc 100644 --- a/api4/command.go +++ b/api4/command.go @@ -32,7 +32,7 @@ func (api *API) InitCommand() { func createCommand(c *Context, w http.ResponseWriter, r *http.Request) { var cmd model.Command if jsonErr := json.NewDecoder(r.Body).Decode(&cmd); jsonErr != nil { - c.SetInvalidParam("command") + c.SetInvalidParamWithErr("command", jsonErr) return } @@ -62,7 +62,7 @@ func createCommand(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rcmd); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -74,7 +74,7 @@ func updateCommand(c *Context, w http.ResponseWriter, r *http.Request) { var cmd model.Command if jsonErr := json.NewDecoder(r.Body).Decode(&cmd); jsonErr != nil || cmd.Id != c.Params.CommandId { - c.SetInvalidParam("command") + c.SetInvalidParamWithErr("command", jsonErr) return } @@ -122,7 +122,7 @@ func updateCommand(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success") if err := json.NewEncoder(w).Encode(rcmd); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -134,7 +134,7 @@ func moveCommand(c *Context, w http.ResponseWriter, r *http.Request) { var cmr model.CommandMoveRequest if jsonErr := json.NewDecoder(r.Body).Decode(&cmr); jsonErr != nil { - c.SetInvalidParam("team_id") + c.SetInvalidParamWithErr("team_id", jsonErr) return } @@ -274,7 +274,7 @@ func listCommands(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(commands); err != nil { - mlog.Warn("Error writing response", mlog.Err(err)) + c.Logger.Warn("Error writing response", mlog.Err(err)) } } @@ -305,14 +305,14 @@ func getCommand(c *Context, w http.ResponseWriter, r *http.Request) { return } if err := json.NewEncoder(w).Encode(cmd); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) { var commandArgs model.CommandArgs if jsonErr := json.NewDecoder(r.Body).Decode(&commandArgs); jsonErr != nil { - c.SetInvalidParam("command_args") + c.SetInvalidParamWithErr("command_args", jsonErr) return } @@ -368,7 +368,7 @@ func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() if err := json.NewEncoder(w).Encode(response); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -390,7 +390,7 @@ func listAutocompleteCommands(c *Context, w http.ResponseWriter, r *http.Request } if err := json.NewEncoder(w).Encode(commands); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/command_local.go b/api4/command_local.go index cf22bb744a..216caa7773 100644 --- a/api4/command_local.go +++ b/api4/command_local.go @@ -25,7 +25,7 @@ func (api *API) InitCommandLocal() { func localCreateCommand(c *Context, w http.ResponseWriter, r *http.Request) { var cmd model.Command if jsonErr := json.NewDecoder(r.Body).Decode(&cmd); jsonErr != nil { - c.SetInvalidParam("command") + c.SetInvalidParamWithErr("command", jsonErr) return } @@ -47,6 +47,6 @@ func localCreateCommand(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rcmd); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/command_test.go b/api4/command_test.go index 3f493607ff..2f47a8dca6 100644 --- a/api4/command_test.go +++ b/api4/command_test.go @@ -646,7 +646,7 @@ func TestExecuteInvalidCommand(t *testing.T) { rc := &model.CommandResponse{} if err := json.NewEncoder(w).Encode(rc); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + th.TestLogger.Warn("Error while writing response", mlog.Err(err)) } })) defer ts.Close() @@ -732,7 +732,7 @@ func TestExecuteGetCommand(t *testing.T) { w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + th.TestLogger.Warn("Error while writing response", mlog.Err(err)) } })) defer ts.Close() @@ -792,7 +792,7 @@ func TestExecutePostCommand(t *testing.T) { w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + th.TestLogger.Warn("Error while writing response", mlog.Err(err)) } })) defer ts.Close() @@ -846,7 +846,7 @@ func TestExecuteCommandAgainstChannelOnAnotherTeam(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + th.TestLogger.Warn("Error while writing response", mlog.Err(err)) } })) defer ts.Close() @@ -898,7 +898,7 @@ func TestExecuteCommandAgainstChannelUserIsNotIn(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + th.TestLogger.Warn("Error while writing response", mlog.Err(err)) } })) defer ts.Close() @@ -958,7 +958,7 @@ func TestExecuteCommandInDirectMessageChannel(t *testing.T) { require.Equal(t, http.MethodPost, r.Method) w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + th.TestLogger.Warn("Error while writing response", mlog.Err(err)) } })) defer ts.Close() @@ -1025,7 +1025,7 @@ func TestExecuteCommandInTeamUserIsNotOn(t *testing.T) { w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + th.TestLogger.Warn("Error while writing response", mlog.Err(err)) } })) defer ts.Close() diff --git a/api4/compliance.go b/api4/compliance.go index f828a03c08..f7987e1b82 100644 --- a/api4/compliance.go +++ b/api4/compliance.go @@ -25,7 +25,7 @@ func (api *API) InitCompliance() { func createComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) { var job model.Compliance if jsonErr := json.NewDecoder(r.Body).Decode(&job); jsonErr != nil { - c.SetInvalidParam("compliance") + c.SetInvalidParamWithErr("compliance", jsonErr) return } @@ -55,7 +55,7 @@ func createComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rjob); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -76,7 +76,7 @@ func getComplianceReports(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() if err := json.NewEncoder(w).Encode(crs); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -106,7 +106,7 @@ func getComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddMeta("compliance_desc", job.Desc) if err := json.NewEncoder(w).Encode(job); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/config.go b/api4/config.go index e08cdccf55..c20e3e2912 100644 --- a/api4/config.go +++ b/api4/config.go @@ -78,7 +78,7 @@ func getConfig(c *Context, w http.ResponseWriter, r *http.Request) { return } if err := json.NewEncoder(w).Encode(cfg); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -220,7 +220,7 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(cfg); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -370,7 +370,7 @@ func patchConfig(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(cfg); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/config_local.go b/api4/config_local.go index b120e93bd7..baf019ecc9 100644 --- a/api4/config_local.go +++ b/api4/config_local.go @@ -30,7 +30,7 @@ func localGetConfig(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") if err := json.NewEncoder(w).Encode(cfg); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -82,7 +82,7 @@ func localUpdateConfig(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") if err := json.NewEncoder(w).Encode(newCfg); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -137,7 +137,7 @@ func localPatchConfig(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") if err := json.NewEncoder(w).Encode(c.App.GetSanitizedConfig()); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/data_retention.go b/api4/data_retention.go index 0749c1d5a5..0059e8ea89 100644 --- a/api4/data_retention.go +++ b/api4/data_retention.go @@ -111,7 +111,7 @@ func getPolicy(c *Context, w http.ResponseWriter, r *http.Request) { func createPolicy(c *Context, w http.ResponseWriter, r *http.Request) { var policy model.RetentionPolicyWithTeamAndChannelIDs if jsonErr := json.NewDecoder(r.Body).Decode(&policy); jsonErr != nil { - c.SetInvalidParam("policy") + c.SetInvalidParamWithErr("policy", jsonErr) return } auditRec := c.MakeAuditRecord("createPolicy", audit.Fail) @@ -144,7 +144,7 @@ func createPolicy(c *Context, w http.ResponseWriter, r *http.Request) { func patchPolicy(c *Context, w http.ResponseWriter, r *http.Request) { var patch model.RetentionPolicyWithTeamAndChannelIDs if jsonErr := json.NewDecoder(r.Body).Decode(&patch); jsonErr != nil { - c.SetInvalidParam("policy") + c.SetInvalidParamWithErr("policy", jsonErr) return } c.RequirePolicyId() @@ -233,7 +233,7 @@ func searchTeamsInPolicy(c *Context, w http.ResponseWriter, r *http.Request) { var props model.TeamSearch if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { - c.SetInvalidParam("team_search") + c.SetInvalidParamWithErr("team_search", jsonErr) return } @@ -261,7 +261,7 @@ func addTeamsToPolicy(c *Context, w http.ResponseWriter, r *http.Request) { var teamIDs []string jsonErr := json.NewDecoder(r.Body).Decode(&teamIDs) if jsonErr != nil { - c.SetInvalidParam("team_ids") + c.SetInvalidParamWithErr("team_ids", jsonErr) return } auditRec := c.MakeAuditRecord("addTeamsToPolicy", audit.Fail) @@ -289,7 +289,7 @@ func removeTeamsFromPolicy(c *Context, w http.ResponseWriter, r *http.Request) { var teamIDs []string jsonErr := json.NewDecoder(r.Body).Decode(&teamIDs) if jsonErr != nil { - c.SetInvalidParam("team_ids") + c.SetInvalidParamWithErr("team_ids", jsonErr) return } auditRec := c.MakeAuditRecord("removeTeamsFromPolicy", audit.Fail) @@ -342,7 +342,7 @@ func searchChannelsInPolicy(c *Context, w http.ResponseWriter, r *http.Request) var props *model.ChannelSearch err := json.NewDecoder(r.Body).Decode(&props) if err != nil { - c.SetInvalidParam("channel_search") + c.SetInvalidParamWithErr("channel_search", err) return } @@ -382,7 +382,7 @@ func addChannelsToPolicy(c *Context, w http.ResponseWriter, r *http.Request) { var channelIDs []string jsonErr := json.NewDecoder(r.Body).Decode(&channelIDs) if jsonErr != nil { - c.SetInvalidParam("channel_ids") + c.SetInvalidParamWithErr("channel_ids", jsonErr) return } auditRec := c.MakeAuditRecord("addChannelsToPolicy", audit.Fail) @@ -411,7 +411,7 @@ func removeChannelsFromPolicy(c *Context, w http.ResponseWriter, r *http.Request var channelIDs []string jsonErr := json.NewDecoder(r.Body).Decode(&channelIDs) if jsonErr != nil { - c.SetInvalidParam("channel_ids") + c.SetInvalidParamWithErr("channel_ids", jsonErr) return } auditRec := c.MakeAuditRecord("removeChannelsFromPolicy", audit.Fail) diff --git a/api4/emoji.go b/api4/emoji.go index 95fb682aae..52b1b017ce 100644 --- a/api4/emoji.go +++ b/api4/emoji.go @@ -98,7 +98,7 @@ func createEmoji(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() if err := json.NewEncoder(w).Encode(newEmoji); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -121,7 +121,7 @@ func getEmojiList(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(listEmoji); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -211,7 +211,7 @@ func getEmoji(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(emoji); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -228,7 +228,7 @@ func getEmojiByName(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(emoji); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -257,7 +257,7 @@ func getEmojiImage(c *Context, w http.ResponseWriter, r *http.Request) { func searchEmojis(c *Context, w http.ResponseWriter, r *http.Request) { var emojiSearch model.EmojiSearch if jsonErr := json.NewDecoder(r.Body).Decode(&emojiSearch); jsonErr != nil { - c.SetInvalidParam("term") + c.SetInvalidParamWithErr("term", jsonErr) return } @@ -273,7 +273,7 @@ func searchEmojis(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(emojis); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -292,6 +292,6 @@ func autocompleteEmojis(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(emojis); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/file.go b/api4/file.go index 6dc5ac04b0..1eadda69b8 100644 --- a/api4/file.go +++ b/api4/file.go @@ -150,7 +150,7 @@ func uploadFileStream(c *Context, w http.ResponseWriter, r *http.Request) { // Write the response values to the output upon return w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(fileUploadResponse); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -632,7 +632,7 @@ func getFileInfo(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set("Cache-Control", "max-age=2592000, private") if err := json.NewEncoder(w).Encode(info); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -759,7 +759,7 @@ func searchFiles(c *Context, w http.ResponseWriter, r *http.Request, teamID stri var params model.SearchParameter jsonErr := json.NewDecoder(r.Body).Decode(¶ms) if jsonErr != nil { - c.Err = model.NewAppError("searchFiles", "api.post.search_files.invalid_body.app_error", nil, jsonErr.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("searchFiles", "api.post.search_files.invalid_body.app_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) return } @@ -821,6 +821,6 @@ func searchFiles(c *Context, w http.ResponseWriter, r *http.Request, teamID stri w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") if err := json.NewEncoder(w).Encode(results); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/file_test.go b/api4/file_test.go index 276dfb4cef..dafb76110e 100644 --- a/api4/file_test.go +++ b/api4/file_test.go @@ -84,7 +84,7 @@ func testDoUploadFileRequest(t testing.TB, c *model.Client4, url string, blob [] var res model.FileUploadResponse if jsonErr := json.NewDecoder(resp.Body).Decode(&res); jsonErr != nil { - return nil, nil, model.NewAppError("doUploadFile", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + return nil, nil, model.NewAppError("doUploadFile", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(jsonErr) } return &res, model.BuildResponse(resp), nil } diff --git a/api4/graphql.go b/api4/graphql.go index 4edbc31c27..41208ec1d0 100644 --- a/api4/graphql.go +++ b/api4/graphql.go @@ -78,7 +78,7 @@ func (api *API) graphQL(c *Context, w http.ResponseWriter, r *http.Request) { defer func() { if response != nil { if err := json.NewEncoder(w).Encode(response); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } }() diff --git a/api4/graphql_client.go b/api4/graphql_client.go index 9a85e6a2fa..edc893eeee 100644 --- a/api4/graphql_client.go +++ b/api4/graphql_client.go @@ -44,7 +44,7 @@ func (c *graphQLClient) login(loginId string, password string) (*model.User, *mo var user model.User if jsonErr := json.NewDecoder(r.Body).Decode(&user); jsonErr != nil { - return nil, nil, model.NewAppError("login", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + return nil, nil, model.NewAppError("login", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(jsonErr) } return &user, model.BuildResponse(r), nil } diff --git a/api4/group.go b/api4/group.go index cf0046d213..9d13c18325 100644 --- a/api4/group.go +++ b/api4/group.go @@ -132,7 +132,7 @@ func getGroup(c *Context, w http.ResponseWriter, r *http.Request) { func createGroup(c *Context, w http.ResponseWriter, r *http.Request) { var group *model.GroupWithUserIds if jsonErr := json.NewDecoder(r.Body).Decode(&group); jsonErr != nil { - c.SetInvalidParam("group") + c.SetInvalidParamWithErr("group", jsonErr) return } @@ -215,7 +215,7 @@ func patchGroup(c *Context, w http.ResponseWriter, r *http.Request) { var groupPatch model.GroupPatch if jsonErr := json.NewDecoder(r.Body).Decode(&groupPatch); jsonErr != nil { - c.SetInvalidParam("group") + c.SetInvalidParamWithErr("group", jsonErr) return } @@ -1030,7 +1030,7 @@ func addGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { var newMembers *model.GroupModifyMembers if jsonErr := json.NewDecoder(r.Body).Decode(&newMembers); jsonErr != nil { - c.SetInvalidParam("addGroupMembers") + c.SetInvalidParamWithErr("addGroupMembers", jsonErr) return } @@ -1083,7 +1083,7 @@ func deleteGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { var deleteBody *model.GroupModifyMembers if jsonErr := json.NewDecoder(r.Body).Decode(&deleteBody); jsonErr != nil { - c.SetInvalidParam("deleteGroupMembers") + c.SetInvalidParamWithErr("deleteGroupMembers", jsonErr) return } diff --git a/api4/integration_action.go b/api4/integration_action.go index 474c1c93ff..aa7e5d7319 100644 --- a/api4/integration_action.go +++ b/api4/integration_action.go @@ -8,6 +8,7 @@ import ( "net/http" "github.com/mattermost/mattermost-server/v6/model" + "github.com/mattermost/mattermost-server/v6/shared/mlog" ) func (api *API) InitAction() { @@ -24,7 +25,10 @@ func doPostAction(c *Context, w http.ResponseWriter, r *http.Request) { } var actionRequest model.DoPostActionRequest - json.NewDecoder(r.Body).Decode(&actionRequest) + err := json.NewDecoder(r.Body).Decode(&actionRequest) + if err != nil { + c.Logger.Warn("Error decoding the action request", mlog.Err(err)) + } var cookie *model.PostActionCookie if actionRequest.Cookie != "" { @@ -68,7 +72,7 @@ func openDialog(c *Context, w http.ResponseWriter, r *http.Request) { var dialog model.OpenDialogRequest err := json.NewDecoder(r.Body).Decode(&dialog) if err != nil { - c.SetInvalidParam("dialog") + c.SetInvalidParamWithErr("dialog", err) return } @@ -90,7 +94,7 @@ func submitDialog(c *Context, w http.ResponseWriter, r *http.Request) { jsonErr := json.NewDecoder(r.Body).Decode(&submit) if jsonErr != nil { - c.SetInvalidParam("dialog") + c.SetInvalidParamWithErr("dialog", jsonErr) return } diff --git a/api4/job.go b/api4/job.go index 6e2ec56f82..b0622ae8e3 100644 --- a/api4/job.go +++ b/api4/job.go @@ -47,7 +47,7 @@ func getJob(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(job); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -106,7 +106,7 @@ func downloadJob(c *Context, w http.ResponseWriter, r *http.Request) { func createJob(c *Context, w http.ResponseWriter, r *http.Request) { var job model.Job if jsonErr := json.NewDecoder(r.Body).Decode(&job); jsonErr != nil { - c.SetInvalidParam("job") + c.SetInvalidParamWithErr("job", jsonErr) return } @@ -137,7 +137,7 @@ func createJob(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rjob); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/ldap.go b/api4/ldap.go index 4ee9c8cc1f..60cd176c65 100644 --- a/api4/ldap.go +++ b/api4/ldap.go @@ -10,6 +10,7 @@ import ( "github.com/mattermost/mattermost-server/v6/audit" "github.com/mattermost/mattermost-server/v6/model" + "github.com/mattermost/mattermost-server/v6/shared/mlog" ) type mixedUnlinkedGroup struct { @@ -51,7 +52,10 @@ func syncLdap(c *Context, w http.ResponseWriter, r *http.Request) { IncludeRemovedMembers bool `json:"include_removed_members"` } var opts LdapSyncOptions - json.NewDecoder(r.Body).Decode(&opts) + err := json.NewDecoder(r.Body).Decode(&opts) + if err != nil { + c.Logger.Warn("Error decoding LDAP sync options", mlog.Err(err)) + } auditRec := c.MakeAuditRecord("syncLdap", audit.Fail) defer c.LogAuditRec(auditRec) diff --git a/api4/license.go b/api4/license.go index f4b0d079f0..4e308a1a45 100644 --- a/api4/license.go +++ b/api4/license.go @@ -136,7 +136,7 @@ func addLicense(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success") if err := json.NewEncoder(w).Encode(license); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/license_local.go b/api4/license_local.go index 7dbb4e51f5..9634fe0488 100644 --- a/api4/license_local.go +++ b/api4/license_local.go @@ -73,7 +73,7 @@ func localAddLicense(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success") if err := json.NewEncoder(w).Encode(license); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/oauth.go b/api4/oauth.go index 2cb4c6cc26..96a7ae4586 100644 --- a/api4/oauth.go +++ b/api4/oauth.go @@ -27,7 +27,7 @@ func (api *API) InitOAuth() { func createOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { var oauthApp model.OAuthApp if jsonErr := json.NewDecoder(r.Body).Decode(&oauthApp); jsonErr != nil { - c.SetInvalidParam("oauth_app") + c.SetInvalidParamWithErr("oauth_app", jsonErr) return } @@ -60,7 +60,7 @@ func createOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rapp); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -82,7 +82,7 @@ func updateOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { var oauthApp model.OAuthApp if jsonErr := json.NewDecoder(r.Body).Decode(&oauthApp); jsonErr != nil { - c.SetInvalidParam("oauth_app") + c.SetInvalidParamWithErr("oauth_app", jsonErr) return } auditRec.AddEventParameter("oauth_app", oauthApp) @@ -121,7 +121,7 @@ func updateOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success") if err := json.NewEncoder(w).Encode(updatedOAuthApp); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -178,7 +178,7 @@ func getOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(oauthApp); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -196,7 +196,7 @@ func getOAuthAppInfo(c *Context, w http.ResponseWriter, r *http.Request) { oauthApp.Sanitize() if err := json.NewEncoder(w).Encode(oauthApp); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -280,7 +280,7 @@ func regenerateOAuthAppSecret(c *Context, w http.ResponseWriter, r *http.Request c.LogAudit("success") if err := json.NewEncoder(w).Encode(oauthApp); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/plugin.go b/api4/plugin.go index 43a744a070..1ab0aae92c 100644 --- a/api4/plugin.go +++ b/api4/plugin.go @@ -167,7 +167,7 @@ func installMarketplacePlugin(c *Context, w http.ResponseWriter, r *http.Request w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(manifest); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -189,7 +189,7 @@ func getPlugins(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(response); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -211,7 +211,7 @@ func getPluginStatuses(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(response); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -402,7 +402,7 @@ func installPlugin(c *Context, w http.ResponseWriter, plugin io.ReadSeeker, forc } w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(manifest); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -462,6 +462,6 @@ func getFirstAdminVisitMarketplaceStatus(c *Context, w http.ResponseWriter, r *h auditRec.Success() if err := json.NewEncoder(w).Encode(firstAdminVisitMarketplaceObj); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/post.go b/api4/post.go index 024bcdc873..7ae86bbc28 100644 --- a/api4/post.go +++ b/api4/post.go @@ -43,7 +43,7 @@ func (api *API) InitPost() { func createPost(c *Context, w http.ResponseWriter, r *http.Request) { var post model.Post if jsonErr := json.NewDecoder(r.Body).Decode(&post); jsonErr != nil { - c.SetInvalidParam("post") + c.SetInvalidParamWithErr("post", jsonErr) return } @@ -106,14 +106,19 @@ func createPost(c *Context, w http.ResponseWriter, r *http.Request) { // Note that rp has already had PreparePostForClient called on it by App.CreatePost if err := rp.EncodeJSON(w); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } func createEphemeralPost(c *Context, w http.ResponseWriter, r *http.Request) { ephRequest := model.PostEphemeral{} - json.NewDecoder(r.Body).Decode(&ephRequest) + jsonErr := json.NewDecoder(r.Body).Decode(&ephRequest) + if jsonErr != nil { + c.SetInvalidParamWithErr("body", jsonErr) + return + } + if ephRequest.UserID == "" { c.SetInvalidParam("user_id") return @@ -476,7 +481,7 @@ func getPostsByIds(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set(model.HeaderFirstInaccessiblePostTime, strconv.FormatInt(firstInaccessiblePostTime, 10)) if err := json.NewEncoder(w).Encode(posts); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -525,6 +530,35 @@ func getPostThread(c *Context, w http.ResponseWriter, r *http.Request) { return } + rPost, err := c.App.GetSinglePost(c.Params.PostId, false) + if err != nil { + c.Err = err + return + } + hasPermission := false + becauseCompliance := false + if c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), rPost.ChannelId, model.PermissionReadChannel) { + hasPermission = true + } else if channel, cErr := c.App.GetChannel(c.AppContext, rPost.ChannelId); cErr == nil { + if channel.Type == model.ChannelTypeOpen && + c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), channel.TeamId, model.PermissionReadPublicChannel) { + hasPermission = true + if *c.App.Config().MessageExportSettings.EnableExport { + hasPermission = false + becauseCompliance = true + } + } + } + + if !hasPermission { + if becauseCompliance { + c.Err = model.NewAppError("getPostThread", "api.post.compliance_enabled.join_channel_to_view_post", nil, "", http.StatusForbidden) + } else { + c.SetPermissionError(model.PermissionReadChannel) + } + return + } + // For now, by default we return all items unless it's set to maintain // backwards compatibility with mobile. But when the next ESR passes, we need to // change this to web.PerPageDefault. @@ -627,7 +661,7 @@ func searchPostsInAllTeams(c *Context, w http.ResponseWriter, r *http.Request) { func searchPosts(c *Context, w http.ResponseWriter, r *http.Request, teamId string) { var params model.SearchParameter if jsonErr := json.NewDecoder(r.Body).Decode(¶ms); jsonErr != nil { - c.Err = model.NewAppError("searchPosts", "api.post.search_posts.invalid_body.app_error", nil, jsonErr.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("searchPosts", "api.post.search_posts.invalid_body.app_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) return } @@ -710,7 +744,7 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) { var post model.Post if jsonErr := json.NewDecoder(r.Body).Decode(&post); jsonErr != nil { - c.SetInvalidParam("post") + c.SetInvalidParamWithErr("post", jsonErr) return } @@ -771,7 +805,7 @@ func patchPost(c *Context, w http.ResponseWriter, r *http.Request) { var post model.PostPatch if jsonErr := json.NewDecoder(r.Body).Decode(&post); jsonErr != nil { - c.SetInvalidParam("post") + c.SetInvalidParamWithErr("post", jsonErr) return } @@ -840,7 +874,7 @@ func setPostUnread(c *Context, w http.ResponseWriter, r *http.Request) { return } if err := json.NewEncoder(w).Encode(state); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -861,7 +895,7 @@ func setPostReminder(c *Context, w http.ResponseWriter, r *http.Request) { var reminder model.PostReminder if jsonErr := json.NewDecoder(r.Body).Decode(&reminder); jsonErr != nil { - c.SetInvalidParam("target_time") + c.SetInvalidParamWithErr("target_time", jsonErr) return } diff --git a/api4/post_test.go b/api4/post_test.go index a7550edffc..8e68db254d 100644 --- a/api4/post_test.go +++ b/api4/post_test.go @@ -25,6 +25,7 @@ import ( "github.com/mattermost/mattermost-server/v6/app" "github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/plugin/plugintest/mock" + "github.com/mattermost/mattermost-server/v6/shared/mlog" "github.com/mattermost/mattermost-server/v6/store/storetest/mocks" "github.com/mattermost/mattermost-server/v6/utils" "github.com/mattermost/mattermost-server/v6/utils/testutils" @@ -306,7 +307,10 @@ func testCreatePostWithOutgoingHook( if requestContentType == "application/json" { decoder := json.NewDecoder(r.Body) o := &model.OutgoingWebhookPayload{} - decoder.Decode(&o) + err := decoder.Decode(&o) + if err != nil { + th.TestLogger.Warn("Error decoding body", mlog.Err(err)) + } if !reflect.DeepEqual(expectedPayload, o) { t.Logf("JSON payload is %+v, should be %+v", o, expectedPayload) @@ -448,7 +452,7 @@ func TestCreatePostPublic(t *testing.T) { require.Error(t, err) CheckForbiddenStatus(t, resp) - th.App.UpdateUserRoles(ruser.Id, model.SystemUserRoleId+" "+model.SystemPostAllPublicRoleId, false) + th.App.UpdateUserRoles(th.Context, ruser.Id, model.SystemUserRoleId+" "+model.SystemPostAllPublicRoleId, false) th.App.Srv().InvalidateAllCaches() client.Login(user.Email, user.Password) @@ -461,7 +465,7 @@ func TestCreatePostPublic(t *testing.T) { require.Error(t, err) CheckForbiddenStatus(t, resp) - th.App.UpdateUserRoles(ruser.Id, model.SystemUserRoleId, false) + th.App.UpdateUserRoles(th.Context, ruser.Id, model.SystemUserRoleId, false) th.App.JoinUserToTeam(th.Context, th.BasicTeam, ruser, "") th.App.UpdateTeamMemberRoles(th.BasicTeam.Id, ruser.Id, model.TeamUserRoleId+" "+model.TeamPostAllPublicRoleId) th.App.Srv().InvalidateAllCaches() @@ -498,7 +502,7 @@ func TestCreatePostAll(t *testing.T) { require.Error(t, err) CheckForbiddenStatus(t, resp) - th.App.UpdateUserRoles(ruser.Id, model.SystemUserRoleId+" "+model.SystemPostAllRoleId, false) + th.App.UpdateUserRoles(th.Context, ruser.Id, model.SystemUserRoleId+" "+model.SystemPostAllRoleId, false) th.App.Srv().InvalidateAllCaches() client.Login(user.Email, user.Password) @@ -514,7 +518,7 @@ func TestCreatePostAll(t *testing.T) { _, _, err = client.CreatePost(post) require.NoError(t, err) - th.App.UpdateUserRoles(ruser.Id, model.SystemUserRoleId, false) + th.App.UpdateUserRoles(th.Context, ruser.Id, model.SystemUserRoleId, false) th.App.JoinUserToTeam(th.Context, th.BasicTeam, ruser, "") th.App.UpdateTeamMemberRoles(th.BasicTeam.Id, ruser.Id, model.TeamUserRoleId+" "+model.TeamPostAllRoleId) th.App.Srv().InvalidateAllCaches() @@ -924,7 +928,7 @@ func TestPatchPost(t *testing.T) { t.Run("invalid requests", func(t *testing.T) { r, err := client.DoAPIPut("/posts/"+post.Id+"/patch", "garbage") - require.EqualError(t, err, ": Invalid or missing post in request body., ") + require.EqualError(t, err, ": Invalid or missing post in request body.") require.Equal(t, http.StatusBadRequest, r.StatusCode, "wrong status code") patch := &model.PostPatch{} @@ -2191,10 +2195,26 @@ func TestGetPostThread(t *testing.T) { client.RemoveUserFromChannel(th.BasicChannel.Id, th.BasicUser.Id) - // Channel is public, should be able to read post + messageExportEnabled := *th.App.Config().MessageExportSettings.EnableExport + // Channel is public, and compliance export is OFF, should be able to read post + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.MessageExportSettings.EnableExport = false + }) _, _, err = client.GetPostThread(th.BasicPost.Id, "", false) require.NoError(t, err) + // channel is public, and compliance export is ON, should NOT be able to read post + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.MessageExportSettings.EnableExport = true + }) + _, resp, err = client.GetPostThread(th.BasicPost.Id, "", false) + require.Error(t, err) + CheckForbiddenStatus(t, resp) + + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.MessageExportSettings.EnableExport = messageExportEnabled + }) + privatePost := th.CreatePostWithClient(client, th.BasicPrivateChannel) _, _, err = client.GetPostThread(privatePost.Id, "", false) diff --git a/api4/preference.go b/api4/preference.go index 09a19f9834..79928f0320 100644 --- a/api4/preference.go +++ b/api4/preference.go @@ -38,7 +38,7 @@ func getPreferences(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(preferences); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -60,7 +60,7 @@ func getPreferencesByCategory(c *Context, w http.ResponseWriter, r *http.Request } if err := json.NewEncoder(w).Encode(preferences); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -82,7 +82,7 @@ func getPreferenceByCategoryAndName(c *Context, w http.ResponseWriter, r *http.R } if err := json.NewEncoder(w).Encode(preferences); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -102,7 +102,7 @@ func updatePreferences(c *Context, w http.ResponseWriter, r *http.Request) { var preferences model.Preferences if jsonErr := json.NewDecoder(r.Body).Decode(&preferences); jsonErr != nil { - c.SetInvalidParam("preferences") + c.SetInvalidParamWithErr("preferences", jsonErr) return } @@ -150,7 +150,7 @@ func deletePreferences(c *Context, w http.ResponseWriter, r *http.Request) { var preferences model.Preferences if jsonErr := json.NewDecoder(r.Body).Decode(&preferences); jsonErr != nil { - c.SetInvalidParam("preferences") + c.SetInvalidParamWithErr("preferences", jsonErr) return } diff --git a/api4/reaction.go b/api4/reaction.go index ac19502d92..da95d63f5b 100644 --- a/api4/reaction.go +++ b/api4/reaction.go @@ -21,7 +21,7 @@ func (api *API) InitReaction() { func saveReaction(c *Context, w http.ResponseWriter, r *http.Request) { var reaction model.Reaction if jsonErr := json.NewDecoder(r.Body).Decode(&reaction); jsonErr != nil { - c.SetInvalidParam("reaction") + c.SetInvalidParamWithErr("reaction", jsonErr) return } @@ -47,7 +47,7 @@ func saveReaction(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(re); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/remote_cluster.go b/api4/remote_cluster.go index a919beadb4..d0956a38a9 100644 --- a/api4/remote_cluster.go +++ b/api4/remote_cluster.go @@ -32,7 +32,7 @@ func remoteClusterPing(c *Context, w http.ResponseWriter, r *http.Request) { var frame model.RemoteClusterFrame if jsonErr := json.NewDecoder(r.Body).Decode(&frame); jsonErr != nil { - c.Err = model.NewAppError("remoteClusterPing", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("remoteClusterPing", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) return } @@ -78,7 +78,7 @@ func remoteClusterAcceptMessage(c *Context, w http.ResponseWriter, r *http.Reque var frame model.RemoteClusterFrame if jsonErr := json.NewDecoder(r.Body).Decode(&frame); jsonErr != nil { - c.Err = model.NewAppError("remoteClusterAcceptMessage", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("remoteClusterAcceptMessage", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) return } @@ -124,7 +124,7 @@ func remoteClusterConfirmInvite(c *Context, w http.ResponseWriter, r *http.Reque var frame model.RemoteClusterFrame if jsonErr := json.NewDecoder(r.Body).Decode(&frame); jsonErr != nil { - c.Err = model.NewAppError("remoteClusterConfirmInvite", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("remoteClusterConfirmInvite", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) return } @@ -216,7 +216,7 @@ func uploadRemoteData(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(info); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -269,7 +269,7 @@ func remoteSetProfileImage(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddMeta("user", user) imageData := imageArray[0] - if err := c.App.SetProfileImage(c.Params.UserId, imageData); err != nil { + if err := c.App.SetProfileImage(c.AppContext, c.Params.UserId, imageData); err != nil { c.Err = err return } diff --git a/api4/resolver_team.go b/api4/resolver_team.go index 7bf95a2685..b224d4c6e5 100644 --- a/api4/resolver_team.go +++ b/api4/resolver_team.go @@ -71,7 +71,7 @@ func getGraphQLTeams(c *web.Context, teamIDs []string) ([]*model.Team, error) { } } - if !c.App.SessionHasPermissionToTeams(c.AppContext, *c.AppContext.Session(), teamsToCheck, model.PermissionViewMembers) { + if !c.App.SessionHasPermissionToTeams(c.AppContext, *c.AppContext.Session(), teamsToCheck, model.PermissionViewTeam) { c.SetPermissionError(model.PermissionViewTeam) return nil, c.Err } diff --git a/api4/resolver_team_member_test.go b/api4/resolver_team_member_test.go index d8aa832317..2d740e1545 100644 --- a/api4/resolver_team_member_test.go +++ b/api4/resolver_team_member_test.go @@ -289,3 +289,123 @@ func TestGraphQLTeamMembers(t *testing.T) { assert.Len(t, q.TeamMembers, 1) }) } + +func TestGraphQLTeamMembersAsGuest(t *testing.T) { + os.Setenv("MM_FEATUREFLAGS_GRAPHQL", "true") + defer os.Unsetenv("MM_FEATUREFLAGS_GRAPHQL") + + th := Setup(t) + + id := model.NewId() + team := &model.Team{ + DisplayName: "dn_" + id, + Name: GenerateTestTeamName(), + Email: th.GenerateTestEmail(), + Type: model.TeamOpen, + AllowOpenInvite: true, + } + + var err error + team, _, err = th.Client.CreateTeam(team) + require.NoError(t, err) + th.BasicTeam = team + + th.BasicChannel = th.CreatePublicChannel() + th.LinkUserToTeam(th.BasicUser, th.BasicTeam) + th.App.AddUserToChannel(th.Context, th.BasicUser, th.BasicChannel, false) + th.LoginBasic() + + defer th.TearDown() + + require.Nil(t, th.App.DemoteUserToGuest(th.Context, th.BasicUser)) + + var q struct { + TeamMembers []struct { + User struct { + ID string `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + FirstName string `json:"firstName"` + LastName string `json:"lastName"` + NickName string `json:"nickname"` + } `json:"user"` + Team struct { + ID string `json:"id"` + DisplayName string `json:"displayName"` + Name string `json:"name"` + CreateAt float64 `json:"createAt"` + DeleteAt float64 `json:"deleteAt"` + SchemeId *string `json:"schemeId"` + PolicyId *string `json:"policyId"` + CloudLimitsArchived bool `json:"cloudLimitsArchived"` + } `json:"team"` + Roles []struct { + ID string `json:"id"` + Name string `json:"Name"` + Permissions []string `json:"permissions"` + SchemeManaged bool `json:"schemeManaged"` + BuiltIn bool `json:"builtIn"` + } `json:"roles"` + DeleteAt float64 `json:"deleteAt"` + SchemeGuest bool `json:"schemeGuest"` + SchemeUser bool `json:"schemeUser"` + SchemeAdmin bool `json:"schemeAdmin"` + } `json:"teamMembers"` + } + + t.Run("User", func(t *testing.T) { + input := graphQLInput{ + OperationName: "teamMembers", + Query: ` + query teamMembers($userId: String = "", $teamId: String = "") { + teamMembers(userId: $userId, teamId: $teamId) { + team { + id + displayName + } + user { + id + username + email + firstName + lastName + } + roles { + id + name + } + schemeGuest + schemeUser + schemeAdmin + } + } + `, + Variables: map[string]any{ + "userId": "me", + }, + } + + resp, err := th.MakeGraphQLRequest(&input) + require.NoError(t, err) + require.Len(t, resp.Errors, 0) + require.NoError(t, json.Unmarshal(resp.Data, &q)) + assert.Len(t, q.TeamMembers, 1) + + tm := q.TeamMembers[0] + assert.Equal(t, th.BasicTeam.Id, tm.Team.ID) + assert.Equal(t, th.BasicTeam.DisplayName, tm.Team.DisplayName) + + assert.Equal(t, th.BasicUser.Id, tm.User.ID) + assert.Equal(t, th.BasicUser.Username, tm.User.Username) + assert.Equal(t, th.BasicUser.Email, tm.User.Email) + assert.Equal(t, th.BasicUser.FirstName, tm.User.FirstName) + assert.Equal(t, th.BasicUser.LastName, tm.User.LastName) + + require.Len(t, tm.Roles, 1) + assert.NotEmpty(t, tm.Roles[0].ID) + assert.Equal(t, "team_guest", tm.Roles[0].Name) + assert.True(t, tm.SchemeGuest) + assert.False(t, tm.SchemeUser) + assert.False(t, tm.SchemeAdmin) + }) +} diff --git a/api4/resolver_user_test.go b/api4/resolver_user_test.go index c10176be2c..6328aec631 100644 --- a/api4/resolver_user_test.go +++ b/api4/resolver_user_test.go @@ -172,7 +172,7 @@ func TestGraphQLUser(t *testing.T) { t.Run("Update", func(t *testing.T) { th.BasicUser.Props = map[string]string{"testpropkey": "testpropvalue"} - th.App.UpdateUser(th.BasicUser, false) + th.App.UpdateUser(th.Context, th.BasicUser, false) input := graphQLInput{ OperationName: "user", diff --git a/api4/role.go b/api4/role.go index c9ebc5577d..f9ea2dda90 100644 --- a/api4/role.go +++ b/api4/role.go @@ -60,7 +60,7 @@ func getRole(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(role); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -77,7 +77,7 @@ func getRoleByName(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(role); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -117,7 +117,7 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) { var patch model.RolePatch if jsonErr := json.NewDecoder(r.Body).Decode(&patch); jsonErr != nil { - c.SetInvalidParam("role") + c.SetInvalidParamWithErr("role", jsonErr) return } @@ -214,6 +214,6 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("") if err := json.NewEncoder(w).Encode(role); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/saml.go b/api4/saml.go index 9305550c79..f102870be6 100644 --- a/api4/saml.go +++ b/api4/saml.go @@ -232,7 +232,7 @@ func getSamlCertificateStatus(c *Context, w http.ResponseWriter, r *http.Request status := c.App.GetSamlCertificateStatus() if err := json.NewEncoder(w).Encode(status); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -256,7 +256,7 @@ func getSamlMetadataFromIdp(c *Context, w http.ResponseWriter, r *http.Request) } if err := json.NewEncoder(w).Encode(metadata); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -273,7 +273,7 @@ func resetAuthDataToEmail(c *Context, w http.ResponseWriter, r *http.Request) { var params *ResetAuthDataParams jsonErr := json.NewDecoder(r.Body).Decode(¶ms) if jsonErr != nil { - c.Err = model.NewAppError("resetAuthDataToEmail", "model.utils.decode_json.app_error", nil, jsonErr.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("resetAuthDataToEmail", "model.utils.decode_json.app_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) return } numAffected, appErr := c.App.ResetSamlAuthDataToEmail(params.IncludeDeleted, params.DryRun, params.SpecifiedUserIDs) @@ -281,6 +281,14 @@ func resetAuthDataToEmail(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = appErr return } - b, _ := json.Marshal(map[string]any{"num_affected": numAffected}) - w.Write(b) + + n := struct { + NumAffected int `json:"num_affected"` + }{ + NumAffected: numAffected, + } + + if err := json.NewEncoder(w).Encode(n); err != nil { + c.Logger.Warn("Error writing response", mlog.Err(err)) + } } diff --git a/api4/scheme.go b/api4/scheme.go index 210b83fbe1..200d8f554d 100644 --- a/api4/scheme.go +++ b/api4/scheme.go @@ -25,7 +25,7 @@ func (api *API) InitScheme() { func createScheme(c *Context, w http.ResponseWriter, r *http.Request) { var scheme model.Scheme if jsonErr := json.NewDecoder(r.Body).Decode(&scheme); jsonErr != nil { - c.SetInvalidParam("scheme") + c.SetInvalidParamWithErr("scheme", jsonErr) return } @@ -55,7 +55,7 @@ func createScheme(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(returnedScheme); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -77,7 +77,7 @@ func getScheme(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(scheme); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -172,7 +172,7 @@ func getChannelsForScheme(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(channels); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -184,7 +184,7 @@ func patchScheme(c *Context, w http.ResponseWriter, r *http.Request) { var patch model.SchemePatch if jsonErr := json.NewDecoder(r.Body).Decode(&patch); jsonErr != nil { - c.SetInvalidParam("scheme") + c.SetInvalidParamWithErr("scheme", jsonErr) return } @@ -223,7 +223,7 @@ func patchScheme(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("") if err := json.NewEncoder(w).Encode(scheme); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/shared_channel_test.go b/api4/shared_channel_test.go index e26732d8f7..16796c73ac 100644 --- a/api4/shared_channel_test.go +++ b/api4/shared_channel_test.go @@ -163,7 +163,7 @@ func TestCreateDirectChannelWithRemoteUser(t *testing.T) { localUser := th.BasicUser remoteUser := th.CreateUser() remoteUser.RemoteId = model.NewString(model.NewId()) - remoteUser, appErr := th.App.UpdateUser(remoteUser, false) + remoteUser, appErr := th.App.UpdateUser(th.Context, remoteUser, false) require.Nil(t, appErr) dm, _, err := client.CreateDirectChannel(localUser.Id, remoteUser.Id) @@ -194,7 +194,7 @@ func TestCreateDirectChannelWithRemoteUser(t *testing.T) { require.Nil(t, appErr) remoteUser.RemoteId = model.NewString(rc.RemoteId) - remoteUser, appErr = th.App.UpdateUser(remoteUser, false) + remoteUser, appErr = th.App.UpdateUser(th.Context, remoteUser, false) require.Nil(t, appErr) dm, _, err := client.CreateDirectChannel(localUser.Id, remoteUser.Id) @@ -227,7 +227,7 @@ func TestCreateDirectChannelWithRemoteUser(t *testing.T) { require.Nil(t, appErr) remoteUser.RemoteId = model.NewString(rc.RemoteId) - remoteUser, appErr = th.App.UpdateUser(remoteUser, false) + remoteUser, appErr = th.App.UpdateUser(th.Context, remoteUser, false) require.Nil(t, appErr) dm, _, err := client.CreateDirectChannel(remoteUser.Id, localUser.Id) diff --git a/api4/status.go b/api4/status.go index e9fd83b2d8..5ecc754b9d 100644 --- a/api4/status.go +++ b/api4/status.go @@ -44,7 +44,7 @@ func getUserStatus(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(statusMap[0]); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -86,7 +86,7 @@ func updateUserStatus(c *Context, w http.ResponseWriter, r *http.Request) { var status model.Status if jsonErr := json.NewDecoder(r.Body).Decode(&status); jsonErr != nil { - c.SetInvalidParam("status") + c.SetInvalidParamWithErr("status", jsonErr) return } @@ -103,7 +103,7 @@ func updateUserStatus(c *Context, w http.ResponseWriter, r *http.Request) { currentStatus, err := c.App.GetStatus(c.Params.UserId) if err == nil && currentStatus.Status == model.StatusOutOfOffice && status.Status != model.StatusOutOfOffice { - c.App.DisableAutoResponder(c.Params.UserId, c.IsSystemAdmin()) + c.App.DisableAutoResponder(c.AppContext, c.Params.UserId, c.IsSystemAdmin()) } switch status.Status { @@ -137,7 +137,7 @@ func updateUserCustomStatus(c *Context, w http.ResponseWriter, r *http.Request) var customStatus model.CustomStatus jsonErr := json.NewDecoder(r.Body).Decode(&customStatus) if jsonErr != nil || (customStatus.Emoji == "" && customStatus.Text == "") || !customStatus.AreDurationAndExpirationTimeValid() { - c.SetInvalidParam("custom_status") + c.SetInvalidParamWithErr("custom_status", jsonErr) return } @@ -147,7 +147,7 @@ func updateUserCustomStatus(c *Context, w http.ResponseWriter, r *http.Request) } customStatus.PreSave() - err := c.App.SetCustomStatus(c.Params.UserId, &customStatus) + err := c.App.SetCustomStatus(c.AppContext, c.Params.UserId, &customStatus) if err != nil { c.Err = err return @@ -172,7 +172,7 @@ func removeUserCustomStatus(c *Context, w http.ResponseWriter, r *http.Request) return } - if err := c.App.RemoveCustomStatus(c.Params.UserId); err != nil { + if err := c.App.RemoveCustomStatus(c.AppContext, c.Params.UserId); err != nil { c.Err = err return } @@ -193,7 +193,7 @@ func removeUserRecentCustomStatus(c *Context, w http.ResponseWriter, r *http.Req var recentCustomStatus model.CustomStatus if jsonErr := json.NewDecoder(r.Body).Decode(&recentCustomStatus); jsonErr != nil { - c.SetInvalidParam("recent_custom_status") + c.SetInvalidParamWithErr("recent_custom_status", jsonErr) return } diff --git a/api4/system.go b/api4/system.go index 2617ed03e5..d35a2068c8 100644 --- a/api4/system.go +++ b/api4/system.go @@ -271,7 +271,7 @@ func getAudits(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddEventParameter("audits_per_page", c.Params.LogsPerPage) if err := json.NewEncoder(w).Encode(audits); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -410,7 +410,7 @@ func getAnalytics(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(rows); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -543,9 +543,9 @@ func pushNotificationAck(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = model.NewAppError("pushNotificationAck", "api.push_notifications_ack.message.parse.app_error", nil, - jsonErr.Error(), + "", http.StatusBadRequest, - ) + ).Wrap(jsonErr) return } @@ -586,7 +586,7 @@ func pushNotificationAck(c *Context, w http.ResponseWriter, r *http.Request) { return } if err2 := json.NewEncoder(w).Encode(msg); err2 != nil { - mlog.Warn("Error while writing response", mlog.Err(err2)) + c.Logger.Warn("Error while writing response", mlog.Err(err2)) } } @@ -814,7 +814,7 @@ func sendWarnMetricAckEmail(c *Context, w http.ResponseWriter, r *http.Request) var ack model.SendWarnMetricAck if jsonErr := json.NewDecoder(r.Body).Decode(&ack); jsonErr != nil { - c.SetInvalidParam("ack") + c.SetInvalidParamWithErr("ack", jsonErr) return } @@ -916,7 +916,7 @@ func getOnboarding(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() if err := json.NewEncoder(w).Encode(firstAdminCompleteSetupObj); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/system_test.go b/api4/system_test.go index 5058e89acd..13eced3f1f 100644 --- a/api4/system_test.go +++ b/api4/system_test.go @@ -967,7 +967,7 @@ func TestGetAppliedSchemaMigrations(t *testing.T) { }) t.Run("as a system manager role", func(t *testing.T) { - _, appErr := th.App.UpdateUserRoles(th.BasicUser2.Id, model.SystemManagerRoleId, false) + _, appErr := th.App.UpdateUserRoles(th.Context, th.BasicUser2.Id, model.SystemManagerRoleId, false) require.Nil(t, appErr) th.LoginBasic2() diff --git a/api4/team.go b/api4/team.go index 33ede5115b..fac2d489c3 100644 --- a/api4/team.go +++ b/api4/team.go @@ -80,7 +80,7 @@ func (api *API) InitTeam() { func createTeam(c *Context, w http.ResponseWriter, r *http.Request) { var team model.Team if jsonErr := json.NewDecoder(r.Body).Decode(&team); jsonErr != nil { - c.SetInvalidParam("team") + c.SetInvalidParamWithErr("team", jsonErr) return } team.Email = strings.ToLower(team.Email) @@ -131,7 +131,7 @@ func createTeam(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rteam); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -154,7 +154,7 @@ func getTeam(c *Context, w http.ResponseWriter, r *http.Request) { c.App.SanitizeTeam(*c.AppContext.Session(), team) if err := json.NewEncoder(w).Encode(team); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -177,7 +177,7 @@ func getTeamByName(c *Context, w http.ResponseWriter, r *http.Request) { c.App.SanitizeTeam(*c.AppContext.Session(), team) if err := json.NewEncoder(w).Encode(team); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -189,7 +189,7 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) { var team model.Team if jsonErr := json.NewDecoder(r.Body).Decode(&team); jsonErr != nil { - c.SetInvalidParam("team") + c.SetInvalidParamWithErr("team", jsonErr) return } @@ -222,7 +222,7 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) { c.App.SanitizeTeam(*c.AppContext.Session(), updatedTeam) if err := json.NewEncoder(w).Encode(updatedTeam); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -234,7 +234,7 @@ func patchTeam(c *Context, w http.ResponseWriter, r *http.Request) { var team model.TeamPatch if jsonErr := json.NewDecoder(r.Body).Decode(&team); jsonErr != nil { - c.SetInvalidParam("team") + c.SetInvalidParamWithErr("team", jsonErr) return } @@ -266,7 +266,7 @@ func patchTeam(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("") if err := json.NewEncoder(w).Encode(patchedTeam); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -325,7 +325,7 @@ func restoreTeam(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() if err := json.NewEncoder(w).Encode(team); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -380,7 +380,7 @@ func updateTeamPrivacy(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() if err := json.NewEncoder(w).Encode(team); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -413,7 +413,7 @@ func regenerateTeamInviteId(c *Context, w http.ResponseWriter, r *http.Request) c.LogAudit("") if err := json.NewEncoder(w).Encode(patchedTeam); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -559,7 +559,7 @@ func getTeamMember(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(team); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -687,7 +687,7 @@ func addTeamMember(c *Context, w http.ResponseWriter, r *http.Request) { var err *model.AppError var member model.TeamMember if jsonErr := json.NewDecoder(r.Body).Decode(&member); jsonErr != nil { - c.Err = model.NewAppError("addTeamMember", "api.team.add_team_member.invalid_body.app_error", nil, "Error in model.TeamMemberFromJSON()", http.StatusBadRequest) + c.Err = model.NewAppError("addTeamMember", "api.team.add_team_member.invalid_body.app_error", nil, "Error in model.TeamMemberFromJSON()", http.StatusBadRequest).Wrap(jsonErr) return } if member.TeamId != c.Params.TeamId { @@ -763,7 +763,7 @@ func addTeamMember(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(tm); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -803,7 +803,7 @@ func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request) w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(member); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -818,7 +818,7 @@ func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) { var err *model.AppError var members []*model.TeamMember if jsonErr := json.NewDecoder(r.Body).Decode(&members); jsonErr != nil { - c.SetInvalidParam("members") + c.SetInvalidParamWithErr("members", jsonErr) return } @@ -991,7 +991,7 @@ func getTeamUnread(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(unreadTeam); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -1019,7 +1019,7 @@ func getTeamStats(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(stats); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -1067,7 +1067,7 @@ func updateTeamMemberSchemeRoles(c *Context, w http.ResponseWriter, r *http.Requ var schemeRoles model.SchemeRoles if jsonErr := json.NewDecoder(r.Body).Decode(&schemeRoles); jsonErr != nil { - c.SetInvalidParam("scheme_roles") + c.SetInvalidParamWithErr("scheme_roles", jsonErr) return } @@ -1155,7 +1155,7 @@ func getAllTeams(c *Context, w http.ResponseWriter, r *http.Request) { func searchTeams(c *Context, w http.ResponseWriter, r *http.Request) { var props model.TeamSearch if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { - c.SetInvalidParam("team_search") + c.SetInvalidParamWithErr("team_search", jsonErr) return } // Only system managers may use the ExcludePolicyConstrained field @@ -1476,7 +1476,7 @@ func inviteGuestsToChannels(c *Context, w http.ResponseWriter, r *http.Request) var guestsInvite model.GuestsInvite if jsonErr := json.NewDecoder(r.Body).Decode(&guestsInvite); jsonErr != nil { - c.Err = model.NewAppError("Api4.inviteGuestsToChannels", "api.team.invite_guests_to_channels.invalid_body.app_error", nil, jsonErr.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("Api4.inviteGuestsToChannels", "api.team.invite_guests_to_channels.invalid_body.app_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) return } auditRec.AddEventParameter("guests_invite", guestsInvite) @@ -1695,7 +1695,7 @@ func updateTeamScheme(c *Context, w http.ResponseWriter, r *http.Request) { var p model.SchemeIDPatch if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil { - c.SetInvalidParam("scheme_id") + c.SetInvalidParamWithErr("scheme_id", jsonErr) return } diff --git a/api4/team_local.go b/api4/team_local.go index 2f6aa488fa..29a93c6c0e 100644 --- a/api4/team_local.go +++ b/api4/team_local.go @@ -244,7 +244,7 @@ func normalizeDomains(domains string) []string { func localCreateTeam(c *Context, w http.ResponseWriter, r *http.Request) { var team model.Team if jsonErr := json.NewDecoder(r.Body).Decode(&team); jsonErr != nil { - c.SetInvalidParam("team") + c.SetInvalidParamWithErr("team", jsonErr) return } @@ -268,6 +268,6 @@ func localCreateTeam(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rteam); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/terms_of_service.go b/api4/terms_of_service.go index 2de763f0a2..53c5a61ccb 100644 --- a/api4/terms_of_service.go +++ b/api4/terms_of_service.go @@ -26,7 +26,7 @@ func getLatestTermsOfService(c *Context, w http.ResponseWriter, r *http.Request) } if err := json.NewEncoder(w).Encode(termsOfService); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -67,11 +67,11 @@ func createTermsOfService(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(termsOfService); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } else { if err := json.NewEncoder(w).Encode(oldTermsOfService); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } auditRec.Success() diff --git a/api4/upload.go b/api4/upload.go index 312f468b6d..a96b1afc9e 100644 --- a/api4/upload.go +++ b/api4/upload.go @@ -31,7 +31,7 @@ func createUpload(c *Context, w http.ResponseWriter, r *http.Request) { var us model.UploadSession if jsonErr := json.NewDecoder(r.Body).Decode(&us); jsonErr != nil { - c.SetInvalidParam("upload") + c.SetInvalidParamWithErr("upload", jsonErr) return } @@ -74,7 +74,7 @@ func createUpload(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rus); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -96,7 +96,7 @@ func getUpload(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(us); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -152,7 +152,7 @@ func uploadData(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(info); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/user.go b/api4/user.go index 60145829fc..56323550f4 100644 --- a/api4/user.go +++ b/api4/user.go @@ -108,7 +108,7 @@ func (api *API) InitUser() { func createUser(c *Context, w http.ResponseWriter, r *http.Request) { var user model.User if jsonErr := json.NewDecoder(r.Body).Decode(&user); jsonErr != nil { - c.SetInvalidParam("user") + c.SetInvalidParamWithErr("user", jsonErr) return } @@ -167,7 +167,7 @@ func createUser(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(ruser); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -221,7 +221,7 @@ func getUser(c *Context, w http.ResponseWriter, r *http.Request) { c.App.UpdateLastActivityAtIfNeeded(*c.AppContext.Session()) w.Header().Set(model.HeaderEtagServer, etag) if err := json.NewEncoder(w).Encode(user); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -283,7 +283,7 @@ func getUserByUsername(c *Context, w http.ResponseWriter, r *http.Request) { } w.Header().Set(model.HeaderEtagServer, etag) if err := json.NewEncoder(w).Encode(user); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -334,7 +334,7 @@ func getUserByEmail(c *Context, w http.ResponseWriter, r *http.Request) { c.App.SanitizeProfile(user, c.IsSystemAdmin()) w.Header().Set(model.HeaderEtagServer, etag) if err := json.NewEncoder(w).Encode(user); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -479,7 +479,7 @@ func setProfileImage(c *Context, w http.ResponseWriter, r *http.Request) { } imageData := imageArray[0] - if err := c.App.SetProfileImage(c.Params.UserId, imageData); err != nil { + if err := c.App.SetProfileImage(c.AppContext, c.Params.UserId, imageData); err != nil { c.Err = err return } @@ -517,7 +517,7 @@ func setDefaultProfileImage(c *Context, w http.ResponseWriter, r *http.Request) } auditRec.AddMeta("user", user) - if err := c.App.SetDefaultProfileImage(user); err != nil { + if err := c.App.SetDefaultProfileImage(c.AppContext, user); err != nil { c.Err = err return } @@ -546,7 +546,7 @@ func getTotalUsersStats(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(stats); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -610,7 +610,7 @@ func getFilteredUsersStats(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(stats); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -970,7 +970,7 @@ func getKnownUsers(c *Context, w http.ResponseWriter, r *http.Request) { func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) { var props model.UserSearch if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { - c.SetInvalidParam("") + c.SetInvalidParamWithErr("props", jsonErr) return } @@ -1156,7 +1156,7 @@ func autocompleteUsers(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(autocomplete); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -1168,7 +1168,7 @@ func updateUser(c *Context, w http.ResponseWriter, r *http.Request) { var user model.User if jsonErr := json.NewDecoder(r.Body).Decode(&user); jsonErr != nil { - c.SetInvalidParam("user") + c.SetInvalidParamWithErr("user", jsonErr) return } @@ -1227,7 +1227,7 @@ func updateUser(c *Context, w http.ResponseWriter, r *http.Request) { } } - ruser, err := c.App.UpdateUserAsUser(&user, c.IsSystemAdmin()) + ruser, err := c.App.UpdateUserAsUser(c.AppContext, &user, c.IsSystemAdmin()) if err != nil { c.Err = err return @@ -1238,7 +1238,7 @@ func updateUser(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("") if err := json.NewEncoder(w).Encode(ruser); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -1250,7 +1250,7 @@ func patchUser(c *Context, w http.ResponseWriter, r *http.Request) { var patch model.UserPatch if jsonErr := json.NewDecoder(r.Body).Decode(&patch); jsonErr != nil { - c.SetInvalidParam("user") + c.SetInvalidParamWithErr("user", jsonErr) return } @@ -1306,7 +1306,7 @@ func patchUser(c *Context, w http.ResponseWriter, r *http.Request) { } } - ruser, err := c.App.PatchUser(c.Params.UserId, &patch, c.IsSystemAdmin()) + ruser, err := c.App.PatchUser(c.AppContext, c.Params.UserId, &patch, c.IsSystemAdmin()) if err != nil { c.Err = err return @@ -1319,7 +1319,7 @@ func patchUser(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("") if err := json.NewEncoder(w).Encode(ruser); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -1413,7 +1413,7 @@ func updateUserRoles(c *Context, w http.ResponseWriter, r *http.Request) { return } - user, err := c.App.UpdateUserRoles(c.Params.UserId, newRoles, true) + user, err := c.App.UpdateUserRoles(c.AppContext, c.Params.UserId, newRoles, true) if err != nil { c.Err = err return @@ -1515,7 +1515,7 @@ func updateUserAuth(c *Context, w http.ResponseWriter, r *http.Request) { var userAuth model.UserAuth if jsonErr := json.NewDecoder(r.Body).Decode(&userAuth); jsonErr != nil { - c.SetInvalidParam("user") + c.SetInvalidParamWithErr("user", jsonErr) return } @@ -1542,7 +1542,7 @@ func updateUserAuth(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit(fmt.Sprintf("updated user %s auth to service=%v", c.Params.UserId, user.AuthService)) if err := json.NewEncoder(w).Encode(user); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -1588,7 +1588,7 @@ func updateUserMfa(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("attempt") - if err := c.App.UpdateMfa(activate, c.Params.UserId, code); err != nil { + if err := c.App.UpdateMfa(c.AppContext, activate, c.Params.UserId, code); err != nil { c.Err = err return } @@ -1627,7 +1627,7 @@ func generateMfaSecret(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set("Pragma", "no-cache") w.Header().Set("Expires", "0") if err := json.NewEncoder(w).Encode(secret); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -1675,9 +1675,9 @@ func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) { return } - err = c.App.UpdatePasswordAsUser(c.Params.UserId, currentPassword, newPassword) + err = c.App.UpdatePasswordAsUser(c.AppContext, c.Params.UserId, currentPassword, newPassword) } else if canUpdatePassword { - err = c.App.UpdatePasswordByUserIdSendEmail(c.Params.UserId, newPassword, c.AppContext.T("api.user.reset_password.method")) + err = c.App.UpdatePasswordByUserIdSendEmail(c.AppContext, c.Params.UserId, newPassword, c.AppContext.T("api.user.reset_password.method")) } else { err = model.NewAppError("updatePassword", "api.user.update_password.context.app_error", nil, "", http.StatusForbidden) } @@ -1711,7 +1711,7 @@ func resetPassword(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddMeta("token", token) c.LogAudit("attempt - token=" + token) - if err := c.App.ResetPasswordFromToken(token, newPassword); err != nil { + if err := c.App.ResetPasswordFromToken(c.AppContext, token, newPassword); err != nil { c.LogAudit("fail - token=" + token) c.Err = err return @@ -1827,7 +1827,7 @@ func login(c *Context, w http.ResponseWriter, r *http.Request) { return } certPem, certSubject, certEmail := c.App.CheckForClientSideCert(r) - mlog.Debug("Client Cert", mlog.String("cert_subject", certSubject), mlog.String("cert_email", certEmail)) + c.Logger.Debug("Client Cert", mlog.String("cert_subject", certSubject), mlog.String("cert_email", certEmail)) if certPem == "" || certEmail == "" { c.Err = model.NewAppError("ClientSideCertMissing", "api.user.login.client_side_cert.certificate.app_error", nil, "", http.StatusBadRequest) @@ -1895,7 +1895,7 @@ func login(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() if err := json.NewEncoder(w).Encode(user); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -2170,7 +2170,7 @@ func getUserAudits(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddMeta("audits_per_page", c.Params.LogsPerPage) if err := json.NewEncoder(w).Encode(audits); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -2186,7 +2186,7 @@ func verifyUserEmail(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("verifyUserEmail", audit.Fail) defer c.LogAuditRec(auditRec) - if err := c.App.VerifyEmailFromToken(token); err != nil { + if err := c.App.VerifyEmailFromToken(c.AppContext, token); err != nil { c.Err = model.NewAppError("verifyUserEmail", "api.user.verify_email.bad_link.app_error", nil, err.Error(), http.StatusBadRequest) return } @@ -2235,7 +2235,7 @@ func sendVerificationEmail(c *Context, w http.ResponseWriter, r *http.Request) { func switchAccountType(c *Context, w http.ResponseWriter, r *http.Request) { var switchRequest model.SwitchRequest if jsonErr := json.NewDecoder(r.Body).Decode(&switchRequest); jsonErr != nil { - c.SetInvalidParam("switch_request") + c.SetInvalidParamWithErr("switch_request", jsonErr) return } @@ -2297,7 +2297,7 @@ func createUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { var accessToken model.UserAccessToken if jsonErr := json.NewDecoder(r.Body).Decode(&accessToken); jsonErr != nil { - c.SetInvalidParam("user_access_token") + c.SetInvalidParamWithErr("user_access_token", jsonErr) return } @@ -2332,7 +2332,7 @@ func createUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success - token_id=" + token.Id) if err := json.NewEncoder(w).Encode(token); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -2344,7 +2344,7 @@ func searchUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request) var props model.UserAccessTokenSearch if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { - c.SetInvalidParam("user_access_token_search") + c.SetInvalidParamWithErr("user_access_token_search", jsonErr) return } @@ -2443,7 +2443,7 @@ func getUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(accessToken); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -2628,7 +2628,7 @@ func getUserTermsOfService(c *Context, w http.ResponseWriter, r *http.Request) { return } if err := json.NewEncoder(w).Encode(result); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -2728,7 +2728,7 @@ func publishUserTyping(c *Context, w http.ResponseWriter, r *http.Request) { var typingRequest model.TypingRequest if jsonErr := json.NewDecoder(r.Body).Decode(&typingRequest); jsonErr != nil { - c.SetInvalidParam("typing_request") + c.SetInvalidParamWithErr("typing_request", jsonErr) return } @@ -2781,7 +2781,7 @@ func verifyUserEmailWithoutToken(c *Context, w http.ResponseWriter, r *http.Requ c.LogAudit("user verified") if err := json.NewEncoder(w).Encode(user); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -2871,7 +2871,7 @@ func getChannelMembersForUser(c *Context, w http.ResponseWriter, r *http.Request } if err := json.NewEncoder(w).Encode(members); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -3014,7 +3014,7 @@ func getThreadForUser(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(thread); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -3085,7 +3085,7 @@ func getThreadsForUser(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(threads); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -3113,7 +3113,7 @@ func updateReadStateThreadByUser(c *Context, w http.ResponseWriter, r *http.Requ } if err := json.NewEncoder(w).Encode(thread); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } auditRec.Success() @@ -3149,7 +3149,7 @@ func setUnreadThreadByPostId(c *Context, w http.ResponseWriter, r *http.Request) } if err := json.NewEncoder(w).Encode(thread); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } auditRec.Success() @@ -3285,6 +3285,6 @@ func getRecentSearches(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(searchParams); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/user_local.go b/api4/user_local.go index e093f2fdff..1b9c4fdf33 100644 --- a/api4/user_local.go +++ b/api4/user_local.go @@ -225,7 +225,7 @@ func localGetUser(c *Context, w http.ResponseWriter, r *http.Request) { c.App.SanitizeProfile(user, c.IsSystemAdmin()) w.Header().Set(model.HeaderEtagServer, etag) if err := json.NewEncoder(w).Encode(user); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -308,7 +308,7 @@ func localGetUserByUsername(c *Context, w http.ResponseWriter, r *http.Request) c.App.SanitizeProfile(user, c.IsSystemAdmin()) w.Header().Set(model.HeaderEtagServer, etag) if err := json.NewEncoder(w).Encode(user); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -339,7 +339,7 @@ func localGetUserByEmail(c *Context, w http.ResponseWriter, r *http.Request) { c.App.SanitizeProfile(user, c.IsSystemAdmin()) w.Header().Set(model.HeaderEtagServer, etag) if err := json.NewEncoder(w).Encode(user); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/user_test.go b/api4/user_test.go index 658ebf4d4b..733f6e0e27 100644 --- a/api4/user_test.go +++ b/api4/user_test.go @@ -643,7 +643,7 @@ func TestGetUser(t *testing.T) { user := th.CreateUser() user.Props = map[string]string{"testpropkey": "testpropvalue"} - th.App.UpdateUser(user, false) + th.App.UpdateUser(th.Context, user, false) th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { ruser, resp, err := client.GetUser(user.Id, "") @@ -699,7 +699,7 @@ func TestGetUserWithAcceptedTermsOfServiceForOtherUser(t *testing.T) { tos, _ := th.App.CreateTermsOfService("Dummy TOS", user.Id) - th.App.UpdateUser(user, false) + th.App.UpdateUser(th.Context, user, false) ruser, _, err := th.Client.GetUser(user.Id, "") require.NoError(t, err) @@ -785,7 +785,7 @@ func TestGetBotUser(t *testing.T) { defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true @@ -4038,7 +4038,7 @@ func TestCreateUserAccessToken(t *testing.T) { defer th.TearDown() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = false }) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { _, resp, err := client.CreateUserAccessToken(th.BasicUser.Id, "test token") @@ -4052,7 +4052,7 @@ func TestCreateUserAccessToken(t *testing.T) { defer th.TearDown() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) rtoken, _, err := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") require.NoError(t, err) @@ -4117,7 +4117,7 @@ func TestCreateUserAccessToken(t *testing.T) { defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionCreateUserAccessToken.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -4159,7 +4159,7 @@ func TestCreateUserAccessToken(t *testing.T) { th.AddPermissionToRole(model.PermissionCreateBot.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionCreateUserAccessToken.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -4219,7 +4219,7 @@ func TestGetUserAccessToken(t *testing.T) { defer th.TearDown() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) token, _, err := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") require.NoError(t, err) @@ -4239,7 +4239,7 @@ func TestGetUserAccessToken(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) token, _, err := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") require.NoError(t, err) @@ -4264,7 +4264,7 @@ func TestGetUserAccessToken(t *testing.T) { th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionCreateUserAccessToken.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadUserAccessToken.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -4312,7 +4312,7 @@ func TestGetUserAccessToken(t *testing.T) { th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionCreateUserAccessToken.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionReadUserAccessToken.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -4355,7 +4355,7 @@ func TestGetUserAccessTokensForUser(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) _, _, err := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") require.NoError(t, err) @@ -4380,7 +4380,7 @@ func TestGetUserAccessTokensForUser(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) _, _, err := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") require.NoError(t, err) @@ -4407,7 +4407,7 @@ func TestGetUserAccessTokens(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) _, resp, err := th.Client.GetUserAccessTokens(0, 100) require.Error(t, err) @@ -4420,7 +4420,7 @@ func TestGetUserAccessTokens(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) _, _, err := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token 2") require.NoError(t, err) @@ -4440,7 +4440,7 @@ func TestGetUserAccessTokens(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) _, _, err := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token 2") require.NoError(t, err) @@ -4463,7 +4463,7 @@ func TestSearchUserAccessToken(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) token, _, err := th.Client.CreateUserAccessToken(th.BasicUser.Id, testDescription) require.NoError(t, err) @@ -4499,7 +4499,7 @@ func TestRevokeUserAccessToken(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { token, _, err := client.CreateUserAccessToken(th.BasicUser.Id, "test token") require.NoError(t, err) @@ -4537,7 +4537,7 @@ func TestRevokeUserAccessToken(t *testing.T) { th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionCreateUserAccessToken.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionRevokeUserAccessToken.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -4581,7 +4581,7 @@ func TestRevokeUserAccessToken(t *testing.T) { th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionCreateUserAccessToken.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionRevokeUserAccessToken.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -4620,7 +4620,7 @@ func TestDisableUserAccessToken(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) token, _, err := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") require.NoError(t, err) assertToken(t, th, token, th.BasicUser.Id) @@ -4656,7 +4656,7 @@ func TestDisableUserAccessToken(t *testing.T) { th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionCreateUserAccessToken.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionRevokeUserAccessToken.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -4700,7 +4700,7 @@ func TestDisableUserAccessToken(t *testing.T) { th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionCreateUserAccessToken.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionRevokeUserAccessToken.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -4739,7 +4739,7 @@ func TestEnableUserAccessToken(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) token, _, err := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") require.NoError(t, err) assertToken(t, th, token, th.BasicUser.Id) @@ -4783,7 +4783,7 @@ func TestEnableUserAccessToken(t *testing.T) { th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionCreateUserAccessToken.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionRevokeUserAccessToken.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -4830,7 +4830,7 @@ func TestEnableUserAccessToken(t *testing.T) { th.AddPermissionToRole(model.PermissionManageBots.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionCreateUserAccessToken.Id, model.TeamUserRoleId) th.AddPermissionToRole(model.PermissionRevokeUserAccessToken.Id, model.TeamUserRoleId) - th.App.UpdateUserRoles(th.BasicUser.Id, model.TeamUserRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.TeamUserRoleId, false) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) @@ -4873,7 +4873,7 @@ func TestUserAccessTokenInactiveUser(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) token, _, err := th.Client.CreateUserAccessToken(th.BasicUser.Id, testDescription) require.NoError(t, err) @@ -4896,7 +4896,7 @@ func TestUserAccessTokenDisableConfig(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) - th.App.UpdateUserRoles(th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserRoleId+" "+model.SystemUserAccessTokenRoleId, false) token, _, err := th.Client.CreateUserAccessToken(th.BasicUser.Id, testDescription) require.NoError(t, err) @@ -5267,7 +5267,7 @@ func TestPromoteGuestToUser(t *testing.T) { th.App.Srv().SetLicense(model.NewTestLicense()) user := th.BasicUser - th.App.UpdateUserRoles(user.Id, model.SystemGuestRoleId, false) + th.App.UpdateUserRoles(th.Context, user.Id, model.SystemGuestRoleId, false) th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) { _, _, err := c.GetUser(user.Id, "") diff --git a/api4/webhook.go b/api4/webhook.go index 3f19313bf6..744fc38263 100644 --- a/api4/webhook.go +++ b/api4/webhook.go @@ -30,7 +30,7 @@ func (api *API) InitWebhook() { func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { var hook model.IncomingWebhook if jsonErr := json.NewDecoder(r.Body).Decode(&hook); jsonErr != nil { - c.SetInvalidParam("incoming_webhook") + c.SetInvalidParamWithErr("incoming_webhook", jsonErr) return } @@ -86,7 +86,7 @@ func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(incomingHook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -98,7 +98,7 @@ func updateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { var updatedHook model.IncomingWebhook if jsonErr := json.NewDecoder(r.Body).Decode(&updatedHook); jsonErr != nil { - c.SetInvalidParam("incoming_webhook") + c.SetInvalidParamWithErr("incoming_webhook", jsonErr) return } @@ -173,7 +173,7 @@ func updateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(incomingHook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -273,7 +273,7 @@ func getIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success") if err := json.NewEncoder(w).Encode(hook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -342,7 +342,7 @@ func updateOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { var updatedHook model.OutgoingWebhook if jsonErr := json.NewDecoder(r.Body).Decode(&updatedHook); jsonErr != nil { - c.SetInvalidParam("outgoing_webhook") + c.SetInvalidParamWithErr("outgoing_webhook", jsonErr) return } @@ -395,14 +395,14 @@ func updateOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success") if err := json.NewEncoder(w).Encode(rhook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { var hook model.OutgoingWebhook if jsonErr := json.NewDecoder(r.Body).Decode(&hook); jsonErr != nil { - c.SetInvalidParam("outgoing_webhook") + c.SetInvalidParamWithErr("outgoing_webhook", jsonErr) return } @@ -446,7 +446,7 @@ func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rhook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -545,7 +545,7 @@ func getOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success") if err := json.NewEncoder(w).Encode(hook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -592,7 +592,7 @@ func regenOutgoingHookToken(c *Context, w http.ResponseWriter, r *http.Request) c.LogAudit("success") if err := json.NewEncoder(w).Encode(rhook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/webhook_local.go b/api4/webhook_local.go index ae42ee4355..cadffbd41e 100644 --- a/api4/webhook_local.go +++ b/api4/webhook_local.go @@ -29,7 +29,7 @@ func (api *API) InitWebhookLocal() { func localCreateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { var hook model.IncomingWebhook if jsonErr := json.NewDecoder(r.Body).Decode(&hook); jsonErr != nil { - c.SetInvalidParam("incoming_webhook") + c.SetInvalidParamWithErr("incoming_webhook", jsonErr) return } @@ -68,14 +68,14 @@ func localCreateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(incomingHook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } func localCreateOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { var hook model.OutgoingWebhook if jsonErr := json.NewDecoder(r.Body).Decode(&hook); jsonErr != nil { - c.SetInvalidParam("outgoing_webhook") + c.SetInvalidParamWithErr("outgoing_webhook", jsonErr) return } @@ -109,6 +109,6 @@ func localCreateOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rhook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/app/app_iface.go b/app/app_iface.go index f078927cb4..d935543640 100644 --- a/app/app_iface.go +++ b/app/app_iface.go @@ -80,7 +80,7 @@ type AppIface interface { // Use GetLastAccessiblePostTime() to access the result. ComputeLastAccessiblePostTime() error // ConvertBotToUser converts a bot to user. - ConvertBotToUser(bot *model.Bot, userPatch *model.UserPatch, sysadmin bool) (*model.User, *model.AppError) + ConvertBotToUser(c request.CTX, bot *model.Bot, userPatch *model.UserPatch, sysadmin bool) (*model.User, *model.AppError) // ConvertUserToBot converts a user to bot. ConvertUserToBot(user *model.User) (*model.Bot, *model.AppError) // CreateBot creates the given bot and corresponding user. @@ -94,10 +94,10 @@ type AppIface interface { CreateDefaultMemberships(c *request.Context, since int64, includeRemovedMembers bool) error // CreateGuest creates a guest and sets several fields of the returned User struct to // their zero values. - CreateGuest(c *request.Context, user *model.User) (*model.User, *model.AppError) + CreateGuest(c request.CTX, user *model.User) (*model.User, *model.AppError) // CreateUser creates a user and sets several fields of the returned User struct to // their zero values. - CreateUser(c *request.Context, user *model.User) (*model.User, *model.AppError) + CreateUser(c request.CTX, user *model.User) (*model.User, *model.AppError) // Creates and stores FileInfos for a post created before the FileInfos table existed. MigrateFilenamesToFileInfos(post *model.Post) []*model.FileInfo // DefaultChannelNames returns the list of system-wide default channel names. @@ -381,10 +381,6 @@ type AppIface interface { // upload, returning a rejection error. In this case FileInfo would have // contained the last "good" FileInfo before the execution of that plugin. UploadFileX(c *request.Context, channelID, name string, input io.Reader, opts ...func(*UploadFileTask)) (*model.FileInfo, *model.AppError) - // Uploads some files to the given team and channel as the given user. files and filenames should have - // the same length. clientIds should either not be provided or have the same length as files and filenames. - // The provided files should be closed by the caller so that they are not leaked. - UploadFiles(c *request.Context, teamID string, channelID string, userID string, files []io.ReadCloser, filenames []string, clientIds []string, now time.Time) (*model.FileUploadResponse, *model.AppError) // UserIsInAdminRoleGroup returns true at least one of the user's groups are configured to set the members as // admins in the given syncable. UserIsInAdminRoleGroup(userID, syncableID string, syncableType model.GroupSyncableType) (bool, *model.AppError) @@ -500,10 +496,10 @@ type AppIface interface { CreateTermsOfService(text, userID string) (*model.TermsOfService, *model.AppError) CreateUploadSession(c request.CTX, us *model.UploadSession) (*model.UploadSession, *model.AppError) CreateUserAccessToken(token *model.UserAccessToken) (*model.UserAccessToken, *model.AppError) - CreateUserAsAdmin(c *request.Context, user *model.User, redirect string) (*model.User, *model.AppError) - CreateUserFromSignup(c *request.Context, user *model.User, redirect string) (*model.User, *model.AppError) - CreateUserWithInviteId(c *request.Context, user *model.User, inviteId, redirect string) (*model.User, *model.AppError) - CreateUserWithToken(c *request.Context, user *model.User, token *model.Token) (*model.User, *model.AppError) + CreateUserAsAdmin(c request.CTX, user *model.User, redirect string) (*model.User, *model.AppError) + CreateUserFromSignup(c request.CTX, user *model.User, redirect string) (*model.User, *model.AppError) + CreateUserWithInviteId(c request.CTX, user *model.User, inviteId, redirect string) (*model.User, *model.AppError) + CreateUserWithToken(c request.CTX, user *model.User, token *model.Token) (*model.User, *model.AppError) CreateWebhookPost(c request.CTX, userID string, channel *model.Channel, text, overrideUsername, overrideIconURL, overrideIconEmoji string, props model.StringInterface, postType string, postRootId string) (*model.Post, *model.AppError) DBHealthCheckDelete() error DBHealthCheckWrite() error @@ -537,7 +533,7 @@ type AppIface interface { DeleteSharedChannelRemote(id string) (bool, error) DeleteSidebarCategory(c request.CTX, userID, teamID, categoryId string) *model.AppError DeleteToken(token *model.Token) *model.AppError - DisableAutoResponder(userID string, asAdmin bool) *model.AppError + DisableAutoResponder(c request.CTX, userID string, asAdmin bool) *model.AppError DisableUserAccessToken(token *model.UserAccessToken) *model.AppError DoAppMigrations() DoCommandRequest(cmd *model.Command, p url.Values) (*model.Command, *model.CommandResponse, *model.AppError) @@ -875,7 +871,7 @@ type AppIface interface { IsUserSignUpAllowed() *model.AppError JoinChannel(c request.CTX, channel *model.Channel, userID string) *model.AppError JoinDefaultChannels(c request.CTX, teamID string, user *model.User, shouldBeAdmin bool, userRequestorId string) *model.AppError - JoinUserToTeam(c *request.Context, team *model.Team, user *model.User, userRequestorId string) (*model.TeamMember, *model.AppError) + JoinUserToTeam(c request.CTX, team *model.Team, user *model.User, userRequestorId string) (*model.TeamMember, *model.AppError) Ldap() einterfaces.LdapInterface LeaveChannel(c request.CTX, channelID string, userID string) *model.AppError LeaveTeam(c *request.Context, team *model.Team, user *model.User, requestorId string) *model.AppError @@ -913,7 +909,7 @@ type AppIface interface { PatchRole(role *model.Role, patch *model.RolePatch) (*model.Role, *model.AppError) PatchScheme(scheme *model.Scheme, patch *model.SchemePatch) (*model.Scheme, *model.AppError) PatchTeam(teamID string, patch *model.TeamPatch) (*model.Team, *model.AppError) - PatchUser(userID string, patch *model.UserPatch, asAdmin bool) (*model.User, *model.AppError) + PatchUser(c request.CTX, userID string, patch *model.UserPatch, asAdmin bool) (*model.User, *model.AppError) PermanentDeleteAllUsers(c *request.Context) *model.AppError PermanentDeleteChannel(c request.CTX, channel *model.Channel) *model.AppError PermanentDeleteTeam(c request.CTX, team *model.Team) *model.AppError @@ -947,7 +943,7 @@ type AppIface interface { RemoveAllDeactivatedMembersFromChannel(c request.CTX, channel *model.Channel) *model.AppError RemoveChannelsFromRetentionPolicy(policyID string, channelIDs []string) *model.AppError RemoveConfigListener(id string) - RemoveCustomStatus(userID string) *model.AppError + RemoveCustomStatus(c request.CTX, userID string) *model.AppError RemoveDirectory(path string) *model.AppError RemoveFile(path string) *model.AppError RemoveLdapPrivateCertificate() *model.AppError @@ -962,7 +958,7 @@ type AppIface interface { RemoveUserFromTeam(c *request.Context, teamID string, userID string, requestorId string) *model.AppError RemoveUsersFromChannelNotMemberOfTeam(c request.CTX, remover *model.User, channel *model.Channel, team *model.Team) *model.AppError RequestLicenseAndAckWarnMetric(c *request.Context, warnMetricId string, isBot bool) *model.AppError - ResetPasswordFromToken(userSuppliedTokenString, newPassword string) *model.AppError + ResetPasswordFromToken(c request.CTX, userSuppliedTokenString, newPassword string) *model.AppError ResetPermissionsSystem() *model.AppError ResetSamlAuthDataToEmail(includeDeleted bool, dryRun bool, userIDs []string) (numAffected int, appErr *model.AppError) RestoreChannel(c request.CTX, channel *model.Channel, userID string) (*model.Channel, *model.AppError) @@ -1037,16 +1033,16 @@ type AppIface interface { SetActiveChannel(c request.CTX, userID string, channelID string) *model.AppError SetAutoResponderStatus(user *model.User, oldNotifyProps model.StringMap) SetChannels(ch *Channels) - SetCustomStatus(userID string, cs *model.CustomStatus) *model.AppError - SetDefaultProfileImage(user *model.User) *model.AppError + SetCustomStatus(c request.CTX, userID string, cs *model.CustomStatus) *model.AppError + SetDefaultProfileImage(c request.CTX, user *model.User) *model.AppError SetPhase2PermissionsMigrationStatus(isComplete bool) error SetPluginKey(pluginID string, key string, value []byte) *model.AppError SetPluginKeyWithExpiry(pluginID string, key string, value []byte, expireInSeconds int64) *model.AppError SetPluginKeyWithOptions(pluginID string, key string, value []byte, options model.PluginKVSetOptions) (bool, *model.AppError) SetPostReminder(postID, userID string, targetTime int64) *model.AppError - SetProfileImage(userID string, imageData *multipart.FileHeader) *model.AppError - SetProfileImageFromFile(userID string, file io.Reader) *model.AppError - SetProfileImageFromMultiPartFile(userID string, file multipart.File) *model.AppError + SetProfileImage(c request.CTX, userID string, imageData *multipart.FileHeader) *model.AppError + SetProfileImageFromFile(c request.CTX, userID string, file io.Reader) *model.AppError + SetProfileImageFromMultiPartFile(c request.CTX, userID string, file multipart.File) *model.AppError SetRemoteClusterLastPingAt(remoteClusterId string) *model.AppError SetSamlIdpCertificateFromMetadata(data []byte) *model.AppError SetSearchEngine(se *searchengine.Broker) @@ -1096,15 +1092,15 @@ type AppIface interface { UpdateHashedPasswordByUserId(userID, newHashedPassword string) *model.AppError UpdateIncomingWebhook(oldHook, updatedHook *model.IncomingWebhook) (*model.IncomingWebhook, *model.AppError) UpdateLastActivityAtIfNeeded(session model.Session) - UpdateMfa(activate bool, userID, token string) *model.AppError + UpdateMfa(c request.CTX, activate bool, userID, token string) *model.AppError UpdateMobileAppBadge(userID string) UpdateOAuthApp(oldApp, updatedApp *model.OAuthApp) (*model.OAuthApp, *model.AppError) UpdateOAuthUserAttrs(userData io.Reader, user *model.User, provider einterfaces.OAuthProvider, service string, tokenUser *model.User) *model.AppError UpdateOutgoingWebhook(c request.CTX, oldHook, updatedHook *model.OutgoingWebhook) (*model.OutgoingWebhook, *model.AppError) UpdatePassword(user *model.User, newPassword string) *model.AppError - UpdatePasswordAsUser(userID, currentPassword, newPassword string) *model.AppError - UpdatePasswordByUserIdSendEmail(userID, newPassword, method string) *model.AppError - UpdatePasswordSendEmail(user *model.User, newPassword, method string) *model.AppError + UpdatePasswordAsUser(c request.CTX, userID, currentPassword, newPassword string) *model.AppError + UpdatePasswordByUserIdSendEmail(c request.CTX, userID, newPassword, method string) *model.AppError + UpdatePasswordSendEmail(c request.CTX, user *model.User, newPassword, method string) *model.AppError UpdatePost(c *request.Context, post *model.Post, safeUpdate bool) (*model.Post, *model.AppError) UpdatePreferences(userID string, preferences model.Preferences) *model.AppError UpdateRemoteCluster(rc *model.RemoteCluster) (*model.RemoteCluster, *model.AppError) @@ -1125,20 +1121,19 @@ type AppIface interface { UpdateThreadReadForUser(c request.CTX, currentSessionId, userID, teamID, threadID string, timestamp int64) (*model.ThreadResponse, *model.AppError) UpdateThreadReadForUserByPost(c request.CTX, currentSessionId, userID, teamID, threadID, postID string) (*model.ThreadResponse, *model.AppError) UpdateThreadsReadForUser(userID, teamID string) *model.AppError - UpdateUser(user *model.User, sendNotifications bool) (*model.User, *model.AppError) + UpdateUser(c request.CTX, user *model.User, sendNotifications bool) (*model.User, *model.AppError) UpdateUserActive(c *request.Context, userID string, active bool) *model.AppError - UpdateUserAsUser(user *model.User, asAdmin bool) (*model.User, *model.AppError) + UpdateUserAsUser(c request.CTX, user *model.User, asAdmin bool) (*model.User, *model.AppError) UpdateUserAuth(userID string, userAuth *model.UserAuth) (*model.UserAuth, *model.AppError) - UpdateUserRoles(userID string, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError) - UpdateUserRolesWithUser(user *model.User, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError) + UpdateUserRoles(c request.CTX, userID string, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError) + UpdateUserRolesWithUser(c request.CTX, user *model.User, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError) UploadData(c *request.Context, us *model.UploadSession, rd io.Reader) (*model.FileInfo, *model.AppError) UploadEmojiImage(id string, imageData *multipart.FileHeader) *model.AppError - UploadMultipartFiles(c *request.Context, teamID string, channelID string, userID string, fileHeaders []*multipart.FileHeader, clientIds []string, now time.Time) (*model.FileUploadResponse, *model.AppError) UpsertGroupMember(groupID string, userID string) (*model.GroupMember, *model.AppError) UpsertGroupMembers(groupID string, userIDs []string) ([]*model.GroupMember, *model.AppError) UpsertGroupSyncable(groupSyncable *model.GroupSyncable) (*model.GroupSyncable, *model.AppError) UserCanSeeOtherUser(userID string, otherUserId string) (bool, *model.AppError) - VerifyEmailFromToken(userSuppliedTokenString string) *model.AppError + VerifyEmailFromToken(c request.CTX, userSuppliedTokenString string) *model.AppError VerifyUserEmail(userID, email string) *model.AppError ViewChannel(c request.CTX, view *model.ChannelView, userID string, currentSessionId string, collapsedThreadsSupported bool) (map[string]int64, *model.AppError) WriteFile(fr io.Reader, path string) (int64, *model.AppError) diff --git a/app/authorization.go b/app/authorization.go index ee161ddbee..9945d5d6ce 100644 --- a/app/authorization.go +++ b/app/authorization.go @@ -59,6 +59,10 @@ func (a *App) SessionHasPermissionToTeam(session model.Session, teamID string, p // SessionHasPermissionToTeams returns true only if user has access to all teams. func (a *App) SessionHasPermissionToTeams(c request.CTX, session model.Session, teamIDs []string, permission *model.Permission) bool { + if len(teamIDs) == 0 { + return true + } + for _, teamID := range teamIDs { if teamID == "" { return false @@ -126,6 +130,10 @@ func (a *App) SessionHasPermissionToChannel(c request.CTX, session model.Session // SessionHasPermissionToChannels returns true only if user has access to all channels. func (a *App) SessionHasPermissionToChannels(c request.CTX, session model.Session, channelIDs []string, permission *model.Permission) bool { + if len(channelIDs) == 0 { + return true + } + for _, channelID := range channelIDs { if channelID == "" { return false diff --git a/app/auto_responder.go b/app/auto_responder.go index 90411ef419..9c5ffc5d75 100644 --- a/app/auto_responder.go +++ b/app/auto_responder.go @@ -98,7 +98,7 @@ func (a *App) SetAutoResponderStatus(user *model.User, oldNotifyProps model.Stri } } -func (a *App) DisableAutoResponder(userID string, asAdmin bool) *model.AppError { +func (a *App) DisableAutoResponder(c request.CTX, userID string, asAdmin bool) *model.AppError { user, err := a.GetUser(userID) if err != nil { return err @@ -111,7 +111,7 @@ func (a *App) DisableAutoResponder(userID string, asAdmin bool) *model.AppError patch.NotifyProps = user.NotifyProps patch.NotifyProps[model.AutoResponderActiveNotifyProp] = "false" - _, err := a.PatchUser(userID, patch, asAdmin) + _, err := a.PatchUser(c, userID, patch, asAdmin) if err != nil { return err } diff --git a/app/auto_responder_test.go b/app/auto_responder_test.go index 5593d11c4c..a7acc6eca1 100644 --- a/app/auto_responder_test.go +++ b/app/auto_responder_test.go @@ -27,7 +27,7 @@ func TestSetAutoResponderStatus(t *testing.T) { patch.NotifyProps["auto_responder_active"] = "true" patch.NotifyProps["auto_responder_message"] = "Hello, I'm unavailable today." - userUpdated1, _ := th.App.PatchUser(user.Id, patch, true) + userUpdated1, _ := th.App.PatchUser(th.Context, user.Id, patch, true) // autoResponder is enabled, status should be OOO th.App.SetAutoResponderStatus(userUpdated1, user.NotifyProps) @@ -41,7 +41,7 @@ func TestSetAutoResponderStatus(t *testing.T) { patch2.NotifyProps["auto_responder_active"] = "false" patch2.NotifyProps["auto_responder_message"] = "Hello, I'm unavailable today." - userUpdated2, _ := th.App.PatchUser(user.Id, patch2, true) + userUpdated2, _ := th.App.PatchUser(th.Context, user.Id, patch2, true) // autoResponder is disabled, status should be ONLINE th.App.SetAutoResponderStatus(userUpdated2, userUpdated1.NotifyProps) @@ -66,15 +66,15 @@ func TestDisableAutoResponder(t *testing.T) { patch.NotifyProps["auto_responder_active"] = "true" patch.NotifyProps["auto_responder_message"] = "Hello, I'm unavailable today." - th.App.PatchUser(user.Id, patch, true) + th.App.PatchUser(th.Context, user.Id, patch, true) - th.App.DisableAutoResponder(user.Id, true) + th.App.DisableAutoResponder(th.Context, user.Id, true) userUpdated1, err := th.App.GetUser(user.Id) require.Nil(t, err) assert.Equal(t, userUpdated1.NotifyProps["auto_responder_active"], "false") - th.App.DisableAutoResponder(user.Id, true) + th.App.DisableAutoResponder(th.Context, user.Id, true) userUpdated2, err := th.App.GetUser(user.Id) require.Nil(t, err) @@ -94,7 +94,7 @@ func TestSendAutoResponseIfNecessary(t *testing.T) { "auto_responder_message": "Hello, I'm unavailable today.", }, } - receiver, err := th.App.PatchUser(receiver.Id, patch, true) + receiver, err := th.App.PatchUser(th.Context, receiver.Id, patch, true) require.Nil(t, err) channel := th.CreateDmChannel(receiver) @@ -124,7 +124,7 @@ func TestSendAutoResponseIfNecessary(t *testing.T) { "auto_responder_message": "Hello, I'm unavailable today.", }, } - receiver, err := th.App.PatchUser(receiver.Id, patch, true) + receiver, err := th.App.PatchUser(th.Context, receiver.Id, patch, true) require.Nil(t, err) channel := th.CreateDmChannel(receiver) @@ -171,7 +171,7 @@ func TestSendAutoResponseIfNecessary(t *testing.T) { "auto_responder_message": "Hello, I'm unavailable today.", }, } - receiver, err := th.App.PatchUser(receiver.Id, patch, true) + receiver, err := th.App.PatchUser(th.Context, receiver.Id, patch, true) require.Nil(t, err) channel := th.CreateDmChannel(receiver) @@ -211,7 +211,7 @@ func TestSendAutoResponseIfNecessary(t *testing.T) { "auto_responder_message": "Hello, I'm unavailable today.", }, } - receiver, err := th.App.PatchUser(receiver.Id, patch, true) + receiver, err := th.App.PatchUser(th.Context, receiver.Id, patch, true) require.Nil(t, err) channel := th.CreateDmChannel(receiver) @@ -252,7 +252,7 @@ func TestSendAutoResponseSuccess(t *testing.T) { patch.NotifyProps["auto_responder_active"] = "true" patch.NotifyProps["auto_responder_message"] = "Hello, I'm unavailable today." - userUpdated1, err := th.App.PatchUser(user.Id, patch, true) + userUpdated1, err := th.App.PatchUser(th.Context, user.Id, patch, true) require.Nil(t, err) savedPost, _ := th.App.CreatePost(th.Context, &model.Post{ @@ -292,7 +292,7 @@ func TestSendAutoResponseSuccessOnThread(t *testing.T) { patch.NotifyProps["auto_responder_active"] = "true" patch.NotifyProps["auto_responder_message"] = "Hello, I'm unavailable today." - userUpdated1, err := th.App.PatchUser(user.Id, patch, true) + userUpdated1, err := th.App.PatchUser(th.Context, user.Id, patch, true) require.Nil(t, err) parentPost, _ := th.App.CreatePost(th.Context, &model.Post{ @@ -341,7 +341,7 @@ func TestSendAutoResponseFailure(t *testing.T) { patch.NotifyProps["auto_responder_active"] = "false" patch.NotifyProps["auto_responder_message"] = "Hello, I'm unavailable today." - userUpdated1, err := th.App.PatchUser(user.Id, patch, true) + userUpdated1, err := th.App.PatchUser(th.Context, user.Id, patch, true) require.Nil(t, err) savedPost, _ := th.App.CreatePost(th.Context, &model.Post{ diff --git a/app/bot_test.go b/app/bot_test.go index c491f9aca8..6b77b08fa0 100644 --- a/app/bot_test.go +++ b/app/bot_test.go @@ -606,7 +606,7 @@ func TestNotifySysadminsBotOwnerDisabled(t *testing.T) { Roles: model.SystemAdminRoleId + " " + model.SystemUserRoleId} _, err := th.App.CreateUser(th.Context, &sysadmin1) require.Nil(t, err, "failed to create user") - th.App.UpdateUserRoles(sysadmin1.Id, model.SystemUserRoleId+" "+model.SystemAdminRoleId, false) + th.App.UpdateUserRoles(th.Context, sysadmin1.Id, model.SystemUserRoleId+" "+model.SystemAdminRoleId, false) sysadmin2 := model.User{ Email: "sys2@example.com", @@ -616,7 +616,7 @@ func TestNotifySysadminsBotOwnerDisabled(t *testing.T) { Roles: model.SystemAdminRoleId + " " + model.SystemUserRoleId} _, err = th.App.CreateUser(th.Context, &sysadmin2) require.Nil(t, err, "failed to create user") - th.App.UpdateUserRoles(sysadmin2.Id, model.SystemUserRoleId+" "+model.SystemAdminRoleId, false) + th.App.UpdateUserRoles(th.Context, sysadmin2.Id, model.SystemUserRoleId+" "+model.SystemAdminRoleId, false) // create user to be disabled user1, err := th.App.CreateUser(th.Context, &model.User{ diff --git a/app/channel_test.go b/app/channel_test.go index d42d608f3c..50a6768ffe 100644 --- a/app/channel_test.go +++ b/app/channel_test.go @@ -1004,18 +1004,18 @@ func TestGetChannelMembersTimezones(t *testing.T) { user := th.BasicUser user.Timezone["useAutomaticTimezone"] = "false" user.Timezone["manualTimezone"] = "XOXO/BLABLA" - th.App.UpdateUser(user, false) + th.App.UpdateUser(th.Context, user, false) user2 := th.BasicUser2 user2.Timezone["automaticTimezone"] = "NoWhere/Island" - th.App.UpdateUser(user2, false) + th.App.UpdateUser(th.Context, user2, false) user3 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""} ruser, _ := th.App.CreateUser(th.Context, &user3) th.App.AddUserToChannel(th.Context, ruser, th.BasicChannel, false) ruser.Timezone["automaticTimezone"] = "NoWhere/Island" - th.App.UpdateUser(ruser, false) + th.App.UpdateUser(th.Context, ruser, false) user4 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""} ruser, _ = th.App.CreateUser(th.Context, &user4) diff --git a/app/config.go b/app/config.go index 9fb2d92af2..bbbc92ff44 100644 --- a/app/config.go +++ b/app/config.go @@ -82,9 +82,9 @@ func (w *configWrapper) SaveConfig(newCfg *model.Config, sendConfigChangeCluster if w.srv.Metrics != nil { w.srv.Metrics.Register() } - w.srv.platformService.RestartMetrics() // TODO: remove when this moved to the platform service + w.srv.SetupMetricsServer() } else { - w.srv.platformService.ShutdownMetrics() // TODO: remove when this moved to the platform service + w.srv.StopMetricsServer() } if w.srv.Cluster != nil { diff --git a/app/file.go b/app/file.go index 12c954de33..3ec52cb698 100644 --- a/app/file.go +++ b/app/file.go @@ -12,7 +12,6 @@ import ( "fmt" "image" "io" - "mime/multipart" "net/http" "net/url" "os" @@ -453,76 +452,6 @@ func GeneratePublicLinkHash(fileID, salt string) string { return base64.RawURLEncoding.EncodeToString(hash.Sum(nil)) } -func (a *App) UploadMultipartFiles(c *request.Context, teamID string, channelID string, userID string, fileHeaders []*multipart.FileHeader, clientIds []string, now time.Time) (*model.FileUploadResponse, *model.AppError) { - files := make([]io.ReadCloser, len(fileHeaders)) - filenames := make([]string, len(fileHeaders)) - - for i, fileHeader := range fileHeaders { - file, fileErr := fileHeader.Open() - if fileErr != nil { - return nil, model.NewAppError("UploadFiles", "api.file.upload_file.read_request.app_error", - map[string]any{"Filename": fileHeader.Filename}, fileErr.Error(), http.StatusBadRequest) - } - - // Will be closed after UploadFiles returns - defer file.Close() - - files[i] = file - filenames[i] = fileHeader.Filename - } - - return a.UploadFiles(c, teamID, channelID, userID, files, filenames, clientIds, now) -} - -// Uploads some files to the given team and channel as the given user. files and filenames should have -// the same length. clientIds should either not be provided or have the same length as files and filenames. -// The provided files should be closed by the caller so that they are not leaked. -func (a *App) UploadFiles(c *request.Context, teamID string, channelID string, userID string, files []io.ReadCloser, filenames []string, clientIds []string, now time.Time) (*model.FileUploadResponse, *model.AppError) { - if *a.Config().FileSettings.DriverName == "" { - return nil, model.NewAppError("UploadFiles", "api.file.upload_file.storage.app_error", nil, "", http.StatusNotImplemented) - } - - if len(filenames) != len(files) || (len(clientIds) > 0 && len(clientIds) != len(files)) { - return nil, model.NewAppError("UploadFiles", "api.file.upload_file.incorrect_number_of_files.app_error", nil, "", http.StatusBadRequest) - } - - resStruct := &model.FileUploadResponse{ - FileInfos: []*model.FileInfo{}, - ClientIds: []string{}, - } - - previewPathList := []string{} - thumbnailPathList := []string{} - imageDataList := [][]byte{} - - for i, file := range files { - buf := bytes.NewBuffer(nil) - io.Copy(buf, file) - data := buf.Bytes() - - info, data, err := a.DoUploadFileExpectModification(c, now, teamID, channelID, userID, filenames[i], data) - if err != nil { - return nil, err - } - - if info.PreviewPath != "" || info.ThumbnailPath != "" { - previewPathList = append(previewPathList, info.PreviewPath) - thumbnailPathList = append(thumbnailPathList, info.ThumbnailPath) - imageDataList = append(imageDataList, data) - } - - resStruct.FileInfos = append(resStruct.FileInfos, info) - - if len(clientIds) > 0 { - resStruct.ClientIds = append(resStruct.ClientIds, clientIds[i]) - } - } - - a.HandleImages(previewPathList, thumbnailPathList, imageDataList) - - return resStruct, nil -} - // UploadFile uploads a single file in form of a completely constructed byte array for a channel. func (a *App) UploadFile(c *request.Context, data []byte, channelID string, filename string) (*model.FileInfo, *model.AppError) { _, err := a.GetChannel(c, channelID) diff --git a/app/file_bench_test.go b/app/file_bench_test.go index 515f69cc03..608bd1eb31 100644 --- a/app/file_bench_test.go +++ b/app/file_bench_test.go @@ -9,8 +9,6 @@ import ( "image" "image/gif" "image/jpeg" - "io" - "io/ioutil" "math/rand" "testing" "time" @@ -130,21 +128,6 @@ func BenchmarkUploadFile(b *testing.B) { th.App.RemoveFile(info.Path) }, }, - { - title: "image UploadFiles", - f: func(b *testing.B, n int, data []byte, ext string) { - resp, err := th.App.UploadFiles(th.Context, teamID, channelID, userID, - []io.ReadCloser{ioutil.NopCloser(bytes.NewReader(data))}, - []string{fmt.Sprintf("BenchmarkDoUploadFiles-%d%s", n, ext)}, - []string{}, - time.Now()) - if err != nil { - b.Fatal(err) - } - th.App.Srv().Store.FileInfo().PermanentDelete(resp.FileInfos[0].Id) - th.App.RemoveFile(resp.FileInfos[0].Path) - }, - }, { title: "image UploadFileX Content-Length", f: func(b *testing.B, n int, data []byte, ext string) { diff --git a/app/helper_test.go b/app/helper_test.go index bb6b1cdee4..cafec901cf 100644 --- a/app/helper_test.go +++ b/app/helper_test.go @@ -222,7 +222,7 @@ func (th *TestHelper) InitBasic() *TestHelper { // create users once and cache them because password hashing is slow initBasicOnce.Do(func() { th.SystemAdminUser = th.CreateUser() - th.App.UpdateUserRoles(th.SystemAdminUser.Id, model.SystemUserRoleId+" "+model.SystemAdminRoleId, false) + th.App.UpdateUserRoles(th.Context, th.SystemAdminUser.Id, model.SystemUserRoleId+" "+model.SystemAdminRoleId, false) th.SystemAdminUser, _ = th.App.GetUser(th.SystemAdminUser.Id) userCache.SystemAdminUser = th.SystemAdminUser.DeepCopy() diff --git a/app/import_functions.go b/app/import_functions.go index 7ab16c3e50..75ec8ad364 100644 --- a/app/import_functions.go +++ b/app/import_functions.go @@ -527,12 +527,12 @@ func (a *App) importUser(c request.CTX, data *UserImportData, dryRun bool) *mode } else { var appErr *model.AppError if hasUserChanged { - if savedUser, appErr = a.UpdateUser(user, false); appErr != nil { + if savedUser, appErr = a.UpdateUser(c, user, false); appErr != nil { return appErr } } if hasUserRolesChanged { - if savedUser, appErr = a.UpdateUserRoles(user.Id, roles, false); appErr != nil { + if savedUser, appErr = a.UpdateUserRoles(c, user.Id, roles, false); appErr != nil { return appErr } } @@ -590,7 +590,7 @@ func (a *App) importUser(c request.CTX, data *UserImportData, dryRun bool) *mode if limitErr := checkImageLimits(file, *a.Config().FileSettings.MaxImageResolution); limitErr != nil { return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.check_image_limits.app_error", nil, "", http.StatusBadRequest) } - if err := a.SetProfileImageFromFile(savedUser.Id, file); err != nil { + if err := a.SetProfileImageFromFile(c, savedUser.Id, file); err != nil { mlog.Warn("Unable to set the profile image from a file.", mlog.Err(err)) } } diff --git a/app/login.go b/app/login.go index 25d3ede871..375d50d914 100644 --- a/app/login.go +++ b/app/login.go @@ -222,7 +222,7 @@ func (a *App) DoLogin(c *request.Context, w http.ResponseWriter, r *http.Request userVal := *user sessionVal := *session a.Srv().Go(func() { - a.Ldap().UpdateProfilePictureIfNecessary(userVal, sessionVal) + a.Ldap().UpdateProfilePictureIfNecessary(c, userVal, sessionVal) }) } diff --git a/app/notification_test.go b/app/notification_test.go index 4d482d9bba..4929244bb7 100644 --- a/app/notification_test.go +++ b/app/notification_test.go @@ -149,14 +149,14 @@ func TestSendNotifications(t *testing.T) { } th.BasicUser.NotifyProps[model.CommentsNotifyProp] = model.CommentsNotifyAny - th.BasicUser, appErr = th.App.UpdateUser(th.BasicUser, false) + th.BasicUser, appErr = th.App.UpdateUser(th.Context, th.BasicUser, false) require.Nil(t, appErr) t.Run("user wants notifications on all comments", func(t *testing.T) { testUserNotNotified(t, th.BasicUser) }) th.BasicUser.NotifyProps[model.CommentsNotifyProp] = model.CommentsNotifyRoot - th.BasicUser, appErr = th.App.UpdateUser(th.BasicUser, false) + th.BasicUser, appErr = th.App.UpdateUser(th.Context, th.BasicUser, false) require.Nil(t, appErr) t.Run("user wants notifications on root comment", func(t *testing.T) { testUserNotNotified(t, th.BasicUser) @@ -2723,13 +2723,13 @@ func TestReplyPostNotificationsWithCRT(t *testing.T) { oldValue := th.BasicUser2.NotifyProps[model.CommentsNotifyProp] newNotifyProps := th.BasicUser2.NotifyProps newNotifyProps[model.CommentsNotifyProp] = model.CommentsNotifyAny - u2, appErr := th.App.PatchUser(th.BasicUser2.Id, &model.UserPatch{NotifyProps: newNotifyProps}, false) + u2, appErr := th.App.PatchUser(th.Context, th.BasicUser2.Id, &model.UserPatch{NotifyProps: newNotifyProps}, false) require.Nil(t, appErr) require.Equal(t, model.CommentsNotifyAny, u2.NotifyProps[model.CommentsNotifyProp]) defer func() { newNotifyProps := th.BasicUser2.NotifyProps newNotifyProps[model.CommentsNotifyProp] = oldValue - _, nAppErr := th.App.PatchUser(th.BasicUser2.Id, &model.UserPatch{NotifyProps: newNotifyProps}, false) + _, nAppErr := th.App.PatchUser(th.Context, th.BasicUser2.Id, &model.UserPatch{NotifyProps: newNotifyProps}, false) require.Nil(t, nAppErr) }() diff --git a/app/opentracing/opentracing_layer.go b/app/opentracing/opentracing_layer.go index 67db2a962a..7cc9dd26b7 100644 --- a/app/opentracing/opentracing_layer.go +++ b/app/opentracing/opentracing_layer.go @@ -1791,7 +1791,7 @@ func (a *OpenTracingAppLayer) Config() *model.Config { return resultVar0 } -func (a *OpenTracingAppLayer) ConvertBotToUser(bot *model.Bot, userPatch *model.UserPatch, sysadmin bool) (*model.User, *model.AppError) { +func (a *OpenTracingAppLayer) ConvertBotToUser(c request.CTX, bot *model.Bot, userPatch *model.UserPatch, sysadmin bool) (*model.User, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.ConvertBotToUser") @@ -1803,7 +1803,7 @@ func (a *OpenTracingAppLayer) ConvertBotToUser(bot *model.Bot, userPatch *model. }() defer span.Finish() - resultVar0, resultVar1 := a.app.ConvertBotToUser(bot, userPatch, sysadmin) + resultVar0, resultVar1 := a.app.ConvertBotToUser(c, bot, userPatch, sysadmin) if resultVar1 != nil { span.LogFields(spanlog.Error(resultVar1)) @@ -2125,7 +2125,7 @@ func (a *OpenTracingAppLayer) CreateGroupWithUserIds(group *model.GroupWithUserI return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) CreateGuest(c *request.Context, user *model.User) (*model.User, *model.AppError) { +func (a *OpenTracingAppLayer) CreateGuest(c request.CTX, user *model.User) (*model.User, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CreateGuest") @@ -2565,7 +2565,7 @@ func (a *OpenTracingAppLayer) CreateUploadSession(c request.CTX, us *model.Uploa return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) CreateUser(c *request.Context, user *model.User) (*model.User, *model.AppError) { +func (a *OpenTracingAppLayer) CreateUser(c request.CTX, user *model.User) (*model.User, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CreateUser") @@ -2609,7 +2609,7 @@ func (a *OpenTracingAppLayer) CreateUserAccessToken(token *model.UserAccessToken return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) CreateUserAsAdmin(c *request.Context, user *model.User, redirect string) (*model.User, *model.AppError) { +func (a *OpenTracingAppLayer) CreateUserAsAdmin(c request.CTX, user *model.User, redirect string) (*model.User, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CreateUserAsAdmin") @@ -2631,7 +2631,7 @@ func (a *OpenTracingAppLayer) CreateUserAsAdmin(c *request.Context, user *model. return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) CreateUserFromSignup(c *request.Context, user *model.User, redirect string) (*model.User, *model.AppError) { +func (a *OpenTracingAppLayer) CreateUserFromSignup(c request.CTX, user *model.User, redirect string) (*model.User, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CreateUserFromSignup") @@ -2653,7 +2653,7 @@ func (a *OpenTracingAppLayer) CreateUserFromSignup(c *request.Context, user *mod return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) CreateUserWithInviteId(c *request.Context, user *model.User, inviteId string, redirect string) (*model.User, *model.AppError) { +func (a *OpenTracingAppLayer) CreateUserWithInviteId(c request.CTX, user *model.User, inviteId string, redirect string) (*model.User, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CreateUserWithInviteId") @@ -2675,7 +2675,7 @@ func (a *OpenTracingAppLayer) CreateUserWithInviteId(c *request.Context, user *m return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) CreateUserWithToken(c *request.Context, user *model.User, token *model.Token) (*model.User, *model.AppError) { +func (a *OpenTracingAppLayer) CreateUserWithToken(c request.CTX, user *model.User, token *model.Token) (*model.User, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CreateUserWithToken") @@ -3521,7 +3521,7 @@ func (a *OpenTracingAppLayer) DemoteUserToGuest(c request.CTX, user *model.User) return resultVar0 } -func (a *OpenTracingAppLayer) DisableAutoResponder(userID string, asAdmin bool) *model.AppError { +func (a *OpenTracingAppLayer) DisableAutoResponder(c request.CTX, userID string, asAdmin bool) *model.AppError { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.DisableAutoResponder") @@ -3533,7 +3533,7 @@ func (a *OpenTracingAppLayer) DisableAutoResponder(userID string, asAdmin bool) }() defer span.Finish() - resultVar0 := a.app.DisableAutoResponder(userID, asAdmin) + resultVar0 := a.app.DisableAutoResponder(c, userID, asAdmin) if resultVar0 != nil { span.LogFields(spanlog.Error(resultVar0)) @@ -11709,7 +11709,7 @@ func (a *OpenTracingAppLayer) JoinDefaultChannels(c request.CTX, teamID string, return resultVar0 } -func (a *OpenTracingAppLayer) JoinUserToTeam(c *request.Context, team *model.Team, user *model.User, userRequestorId string) (*model.TeamMember, *model.AppError) { +func (a *OpenTracingAppLayer) JoinUserToTeam(c request.CTX, team *model.Team, user *model.User, userRequestorId string) (*model.TeamMember, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.JoinUserToTeam") @@ -12657,7 +12657,7 @@ func (a *OpenTracingAppLayer) PatchTeam(teamID string, patch *model.TeamPatch) ( return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) PatchUser(userID string, patch *model.UserPatch, asAdmin bool) (*model.User, *model.AppError) { +func (a *OpenTracingAppLayer) PatchUser(c request.CTX, userID string, patch *model.UserPatch, asAdmin bool) (*model.User, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.PatchUser") @@ -12669,7 +12669,7 @@ func (a *OpenTracingAppLayer) PatchUser(userID string, patch *model.UserPatch, a }() defer span.Finish() - resultVar0, resultVar1 := a.app.PatchUser(userID, patch, asAdmin) + resultVar0, resultVar1 := a.app.PatchUser(c, userID, patch, asAdmin) if resultVar1 != nil { span.LogFields(spanlog.Error(resultVar1)) @@ -13444,7 +13444,7 @@ func (a *OpenTracingAppLayer) RemoveConfigListener(id string) { a.app.RemoveConfigListener(id) } -func (a *OpenTracingAppLayer) RemoveCustomStatus(userID string) *model.AppError { +func (a *OpenTracingAppLayer) RemoveCustomStatus(c request.CTX, userID string) *model.AppError { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.RemoveCustomStatus") @@ -13456,7 +13456,7 @@ func (a *OpenTracingAppLayer) RemoveCustomStatus(userID string) *model.AppError }() defer span.Finish() - resultVar0 := a.app.RemoveCustomStatus(userID) + resultVar0 := a.app.RemoveCustomStatus(c, userID) if resultVar0 != nil { span.LogFields(spanlog.Error(resultVar0)) @@ -13818,7 +13818,7 @@ func (a *OpenTracingAppLayer) RequestLicenseAndAckWarnMetric(c *request.Context, return resultVar0 } -func (a *OpenTracingAppLayer) ResetPasswordFromToken(userSuppliedTokenString string, newPassword string) *model.AppError { +func (a *OpenTracingAppLayer) ResetPasswordFromToken(c request.CTX, userSuppliedTokenString string, newPassword string) *model.AppError { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.ResetPasswordFromToken") @@ -13830,7 +13830,7 @@ func (a *OpenTracingAppLayer) ResetPasswordFromToken(userSuppliedTokenString str }() defer span.Finish() - resultVar0 := a.app.ResetPasswordFromToken(userSuppliedTokenString, newPassword) + resultVar0 := a.app.ResetPasswordFromToken(c, userSuppliedTokenString, newPassword) if resultVar0 != nil { span.LogFields(spanlog.Error(resultVar0)) @@ -15497,7 +15497,7 @@ func (a *OpenTracingAppLayer) SetChannels(ch *app.Channels) { a.app.SetChannels(ch) } -func (a *OpenTracingAppLayer) SetCustomStatus(userID string, cs *model.CustomStatus) *model.AppError { +func (a *OpenTracingAppLayer) SetCustomStatus(c request.CTX, userID string, cs *model.CustomStatus) *model.AppError { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SetCustomStatus") @@ -15509,7 +15509,7 @@ func (a *OpenTracingAppLayer) SetCustomStatus(userID string, cs *model.CustomSta }() defer span.Finish() - resultVar0 := a.app.SetCustomStatus(userID, cs) + resultVar0 := a.app.SetCustomStatus(c, userID, cs) if resultVar0 != nil { span.LogFields(spanlog.Error(resultVar0)) @@ -15519,7 +15519,7 @@ func (a *OpenTracingAppLayer) SetCustomStatus(userID string, cs *model.CustomSta return resultVar0 } -func (a *OpenTracingAppLayer) SetDefaultProfileImage(user *model.User) *model.AppError { +func (a *OpenTracingAppLayer) SetDefaultProfileImage(c request.CTX, user *model.User) *model.AppError { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SetDefaultProfileImage") @@ -15531,7 +15531,7 @@ func (a *OpenTracingAppLayer) SetDefaultProfileImage(user *model.User) *model.Ap }() defer span.Finish() - resultVar0 := a.app.SetDefaultProfileImage(user) + resultVar0 := a.app.SetDefaultProfileImage(c, user) if resultVar0 != nil { span.LogFields(spanlog.Error(resultVar0)) @@ -15651,7 +15651,7 @@ func (a *OpenTracingAppLayer) SetPostReminder(postID string, userID string, targ return resultVar0 } -func (a *OpenTracingAppLayer) SetProfileImage(userID string, imageData *multipart.FileHeader) *model.AppError { +func (a *OpenTracingAppLayer) SetProfileImage(c request.CTX, userID string, imageData *multipart.FileHeader) *model.AppError { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SetProfileImage") @@ -15663,7 +15663,7 @@ func (a *OpenTracingAppLayer) SetProfileImage(userID string, imageData *multipar }() defer span.Finish() - resultVar0 := a.app.SetProfileImage(userID, imageData) + resultVar0 := a.app.SetProfileImage(c, userID, imageData) if resultVar0 != nil { span.LogFields(spanlog.Error(resultVar0)) @@ -15673,7 +15673,7 @@ func (a *OpenTracingAppLayer) SetProfileImage(userID string, imageData *multipar return resultVar0 } -func (a *OpenTracingAppLayer) SetProfileImageFromFile(userID string, file io.Reader) *model.AppError { +func (a *OpenTracingAppLayer) SetProfileImageFromFile(c request.CTX, userID string, file io.Reader) *model.AppError { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SetProfileImageFromFile") @@ -15685,7 +15685,7 @@ func (a *OpenTracingAppLayer) SetProfileImageFromFile(userID string, file io.Rea }() defer span.Finish() - resultVar0 := a.app.SetProfileImageFromFile(userID, file) + resultVar0 := a.app.SetProfileImageFromFile(c, userID, file) if resultVar0 != nil { span.LogFields(spanlog.Error(resultVar0)) @@ -15695,7 +15695,7 @@ func (a *OpenTracingAppLayer) SetProfileImageFromFile(userID string, file io.Rea return resultVar0 } -func (a *OpenTracingAppLayer) SetProfileImageFromMultiPartFile(userID string, file multipart.File) *model.AppError { +func (a *OpenTracingAppLayer) SetProfileImageFromMultiPartFile(c request.CTX, userID string, file multipart.File) *model.AppError { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SetProfileImageFromMultiPartFile") @@ -15707,7 +15707,7 @@ func (a *OpenTracingAppLayer) SetProfileImageFromMultiPartFile(userID string, fi }() defer span.Finish() - resultVar0 := a.app.SetProfileImageFromMultiPartFile(userID, file) + resultVar0 := a.app.SetProfileImageFromMultiPartFile(c, userID, file) if resultVar0 != nil { span.LogFields(spanlog.Error(resultVar0)) @@ -16910,7 +16910,7 @@ func (a *OpenTracingAppLayer) UpdateLastActivityAtIfNeeded(session model.Session a.app.UpdateLastActivityAtIfNeeded(session) } -func (a *OpenTracingAppLayer) UpdateMfa(activate bool, userID string, token string) *model.AppError { +func (a *OpenTracingAppLayer) UpdateMfa(c request.CTX, activate bool, userID string, token string) *model.AppError { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdateMfa") @@ -16922,7 +16922,7 @@ func (a *OpenTracingAppLayer) UpdateMfa(activate bool, userID string, token stri }() defer span.Finish() - resultVar0 := a.app.UpdateMfa(activate, userID, token) + resultVar0 := a.app.UpdateMfa(c, activate, userID, token) if resultVar0 != nil { span.LogFields(spanlog.Error(resultVar0)) @@ -17035,7 +17035,7 @@ func (a *OpenTracingAppLayer) UpdatePassword(user *model.User, newPassword strin return resultVar0 } -func (a *OpenTracingAppLayer) UpdatePasswordAsUser(userID string, currentPassword string, newPassword string) *model.AppError { +func (a *OpenTracingAppLayer) UpdatePasswordAsUser(c request.CTX, userID string, currentPassword string, newPassword string) *model.AppError { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdatePasswordAsUser") @@ -17047,7 +17047,7 @@ func (a *OpenTracingAppLayer) UpdatePasswordAsUser(userID string, currentPasswor }() defer span.Finish() - resultVar0 := a.app.UpdatePasswordAsUser(userID, currentPassword, newPassword) + resultVar0 := a.app.UpdatePasswordAsUser(c, userID, currentPassword, newPassword) if resultVar0 != nil { span.LogFields(spanlog.Error(resultVar0)) @@ -17057,7 +17057,7 @@ func (a *OpenTracingAppLayer) UpdatePasswordAsUser(userID string, currentPasswor return resultVar0 } -func (a *OpenTracingAppLayer) UpdatePasswordByUserIdSendEmail(userID string, newPassword string, method string) *model.AppError { +func (a *OpenTracingAppLayer) UpdatePasswordByUserIdSendEmail(c request.CTX, userID string, newPassword string, method string) *model.AppError { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdatePasswordByUserIdSendEmail") @@ -17069,7 +17069,7 @@ func (a *OpenTracingAppLayer) UpdatePasswordByUserIdSendEmail(userID string, new }() defer span.Finish() - resultVar0 := a.app.UpdatePasswordByUserIdSendEmail(userID, newPassword, method) + resultVar0 := a.app.UpdatePasswordByUserIdSendEmail(c, userID, newPassword, method) if resultVar0 != nil { span.LogFields(spanlog.Error(resultVar0)) @@ -17079,7 +17079,7 @@ func (a *OpenTracingAppLayer) UpdatePasswordByUserIdSendEmail(userID string, new return resultVar0 } -func (a *OpenTracingAppLayer) UpdatePasswordSendEmail(user *model.User, newPassword string, method string) *model.AppError { +func (a *OpenTracingAppLayer) UpdatePasswordSendEmail(c request.CTX, user *model.User, newPassword string, method string) *model.AppError { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdatePasswordSendEmail") @@ -17091,7 +17091,7 @@ func (a *OpenTracingAppLayer) UpdatePasswordSendEmail(user *model.User, newPassw }() defer span.Finish() - resultVar0 := a.app.UpdatePasswordSendEmail(user, newPassword, method) + resultVar0 := a.app.UpdatePasswordSendEmail(c, user, newPassword, method) if resultVar0 != nil { span.LogFields(spanlog.Error(resultVar0)) @@ -17563,7 +17563,7 @@ func (a *OpenTracingAppLayer) UpdateThreadsReadForUser(userID string, teamID str return resultVar0 } -func (a *OpenTracingAppLayer) UpdateUser(user *model.User, sendNotifications bool) (*model.User, *model.AppError) { +func (a *OpenTracingAppLayer) UpdateUser(c request.CTX, user *model.User, sendNotifications bool) (*model.User, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdateUser") @@ -17575,7 +17575,7 @@ func (a *OpenTracingAppLayer) UpdateUser(user *model.User, sendNotifications boo }() defer span.Finish() - resultVar0, resultVar1 := a.app.UpdateUser(user, sendNotifications) + resultVar0, resultVar1 := a.app.UpdateUser(c, user, sendNotifications) if resultVar1 != nil { span.LogFields(spanlog.Error(resultVar1)) @@ -17607,7 +17607,7 @@ func (a *OpenTracingAppLayer) UpdateUserActive(c *request.Context, userID string return resultVar0 } -func (a *OpenTracingAppLayer) UpdateUserAsUser(user *model.User, asAdmin bool) (*model.User, *model.AppError) { +func (a *OpenTracingAppLayer) UpdateUserAsUser(c request.CTX, user *model.User, asAdmin bool) (*model.User, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdateUserAsUser") @@ -17619,7 +17619,7 @@ func (a *OpenTracingAppLayer) UpdateUserAsUser(user *model.User, asAdmin bool) ( }() defer span.Finish() - resultVar0, resultVar1 := a.app.UpdateUserAsUser(user, asAdmin) + resultVar0, resultVar1 := a.app.UpdateUserAsUser(c, user, asAdmin) if resultVar1 != nil { span.LogFields(spanlog.Error(resultVar1)) @@ -17651,7 +17651,7 @@ func (a *OpenTracingAppLayer) UpdateUserAuth(userID string, userAuth *model.User return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) UpdateUserRoles(userID string, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError) { +func (a *OpenTracingAppLayer) UpdateUserRoles(c request.CTX, userID string, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdateUserRoles") @@ -17663,7 +17663,7 @@ func (a *OpenTracingAppLayer) UpdateUserRoles(userID string, newRoles string, se }() defer span.Finish() - resultVar0, resultVar1 := a.app.UpdateUserRoles(userID, newRoles, sendWebSocketEvent) + resultVar0, resultVar1 := a.app.UpdateUserRoles(c, userID, newRoles, sendWebSocketEvent) if resultVar1 != nil { span.LogFields(spanlog.Error(resultVar1)) @@ -17673,7 +17673,7 @@ func (a *OpenTracingAppLayer) UpdateUserRoles(userID string, newRoles string, se return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) UpdateUserRolesWithUser(user *model.User, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError) { +func (a *OpenTracingAppLayer) UpdateUserRolesWithUser(c request.CTX, user *model.User, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdateUserRolesWithUser") @@ -17685,7 +17685,7 @@ func (a *OpenTracingAppLayer) UpdateUserRolesWithUser(user *model.User, newRoles }() defer span.Finish() - resultVar0, resultVar1 := a.app.UpdateUserRolesWithUser(user, newRoles, sendWebSocketEvent) + resultVar0, resultVar1 := a.app.UpdateUserRolesWithUser(c, user, newRoles, sendWebSocketEvent) if resultVar1 != nil { span.LogFields(spanlog.Error(resultVar1)) @@ -17835,50 +17835,6 @@ func (a *OpenTracingAppLayer) UploadFileX(c *request.Context, channelID string, return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) UploadFiles(c *request.Context, teamID string, channelID string, userID string, files []io.ReadCloser, filenames []string, clientIds []string, now time.Time) (*model.FileUploadResponse, *model.AppError) { - origCtx := a.ctx - span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UploadFiles") - - a.ctx = newCtx - a.app.Srv().Store.SetContext(newCtx) - defer func() { - a.app.Srv().Store.SetContext(origCtx) - a.ctx = origCtx - }() - - defer span.Finish() - resultVar0, resultVar1 := a.app.UploadFiles(c, teamID, channelID, userID, files, filenames, clientIds, now) - - if resultVar1 != nil { - span.LogFields(spanlog.Error(resultVar1)) - ext.Error.Set(span, true) - } - - return resultVar0, resultVar1 -} - -func (a *OpenTracingAppLayer) UploadMultipartFiles(c *request.Context, teamID string, channelID string, userID string, fileHeaders []*multipart.FileHeader, clientIds []string, now time.Time) (*model.FileUploadResponse, *model.AppError) { - origCtx := a.ctx - span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UploadMultipartFiles") - - a.ctx = newCtx - a.app.Srv().Store.SetContext(newCtx) - defer func() { - a.app.Srv().Store.SetContext(origCtx) - a.ctx = origCtx - }() - - defer span.Finish() - resultVar0, resultVar1 := a.app.UploadMultipartFiles(c, teamID, channelID, userID, fileHeaders, clientIds, now) - - if resultVar1 != nil { - span.LogFields(spanlog.Error(resultVar1)) - ext.Error.Set(span, true) - } - - return resultVar0, resultVar1 -} - func (a *OpenTracingAppLayer) UpsertGroupMember(groupID string, userID string) (*model.GroupMember, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpsertGroupMember") @@ -17989,7 +17945,7 @@ func (a *OpenTracingAppLayer) UserIsInAdminRoleGroup(userID string, syncableID s return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) VerifyEmailFromToken(userSuppliedTokenString string) *model.AppError { +func (a *OpenTracingAppLayer) VerifyEmailFromToken(c request.CTX, userSuppliedTokenString string) *model.AppError { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.VerifyEmailFromToken") @@ -18001,7 +17957,7 @@ func (a *OpenTracingAppLayer) VerifyEmailFromToken(userSuppliedTokenString strin }() defer span.Finish() - resultVar0 := a.app.VerifyEmailFromToken(userSuppliedTokenString) + resultVar0 := a.app.VerifyEmailFromToken(c, userSuppliedTokenString) if resultVar0 != nil { span.LogFields(spanlog.Error(resultVar0)) diff --git a/app/platform/config.go b/app/platform/config.go index 37e7286283..2713166849 100644 --- a/app/platform/config.go +++ b/app/platform/config.go @@ -3,28 +3,14 @@ package platform -import ( - "errors" - - "github.com/mattermost/mattermost-server/v6/config" - "github.com/mattermost/mattermost-server/v6/einterfaces" -) - // ServiceConfig is used to initialize the PlatformService. // The mandatory fields will be checked during the initialization of the service. type ServiceConfig struct { // Mandatory fields - ConfigStore *config.Store - StartMetrics bool // TODO: find an elegant way to start/stop metrics server by default // Optional fields - Metrics einterfaces.MetricsInterface - Cluster einterfaces.ClusterInterface } func (c *ServiceConfig) validate() error { // Mandatory fields need to be checked here - if c.ConfigStore == nil { - return errors.New("ConfigStore is required") - } return nil } diff --git a/app/platform/metrics.go b/app/platform/metrics.go deleted file mode 100644 index e5daef5457..0000000000 --- a/app/platform/metrics.go +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -package platform - -import ( - "context" - "net" - "net/http" - "net/http/pprof" - "runtime" - "sync" - "text/template" - "time" - - "github.com/gorilla/handlers" - "github.com/gorilla/mux" - "github.com/mattermost/mattermost-server/v6/einterfaces" - "github.com/mattermost/mattermost-server/v6/model" - "github.com/mattermost/mattermost-server/v6/shared/mlog" - "github.com/pkg/errors" -) - -const TimeToWaitForConnectionsToCloseOnServerShutdown = time.Second - -type platformMetrics struct { - server *http.Server - router *mux.Router - lock sync.Mutex - - metricsImpl einterfaces.MetricsInterface - - cfgFn func() *model.Config -} - -func newPlatformMetrics(metricsImpl einterfaces.MetricsInterface, cfgFn func() *model.Config) *platformMetrics { - if !*cfgFn().MetricsSettings.Enable { - return nil - } - - pm := &platformMetrics{ - cfgFn: cfgFn, - } - - pm.stopMetricsServer() - - if err := pm.initMetricsRouter(); err != nil { - mlog.Error("Error initiating metrics router.", mlog.Err(err)) - } - - if metricsImpl != nil { - metricsImpl.Register() - } - - pm.startMetricsServer() - - return pm -} - -func (pm *platformMetrics) stopMetricsServer() { - pm.lock.Lock() - defer pm.lock.Unlock() - - if pm.server != nil { - ctx, cancel := context.WithTimeout(context.Background(), TimeToWaitForConnectionsToCloseOnServerShutdown) - defer cancel() - - pm.server.Shutdown(ctx) - mlog.Info("Metrics and profiling server is stopping") - } -} - -func (pm *platformMetrics) startMetricsServer() { - var notify chan struct{} - pm.lock.Lock() - defer func() { - if notify != nil { - <-notify - } - pm.lock.Unlock() - }() - - l, err := net.Listen("tcp", *pm.cfgFn().MetricsSettings.ListenAddress) - if err != nil { - mlog.Error(err.Error()) - return - } - - notify = make(chan struct{}) - pm.server = &http.Server{ - Handler: handlers.RecoveryHandler(handlers.PrintRecoveryStack(true))(pm.router), - ReadTimeout: time.Duration(*pm.cfgFn().ServiceSettings.ReadTimeout) * time.Second, - WriteTimeout: time.Duration(*pm.cfgFn().ServiceSettings.WriteTimeout) * time.Second, - } - - go func() { - close(notify) - if err := pm.server.Serve(l); err != nil && err != http.ErrServerClosed { - mlog.Critical(err.Error()) - } - }() - - mlog.Info("Metrics and profiling server is started", mlog.String("address", l.Addr().String())) -} - -func (pm *platformMetrics) initMetricsRouter() error { - pm.router = mux.NewRouter() - runtime.SetBlockProfileRate(*pm.cfgFn().MetricsSettings.BlockProfileRate) - - metricsPage := ` - - {{if .}} -
Metrics
{{end}} -
Profiling Root
-
Profiling Command Line
-
Profiling Symbols
-
Profiling Goroutines
-
Profiling Heap
-
Profiling Threads
-
Profiling Blocking
-
Profiling Execution Trace
-
Profiling CPU
- - - ` - metricsPageTmpl, err := template.New("page").Parse(metricsPage) - if err != nil { - return errors.Wrap(err, "failed to create template") - } - - rootHandler := func(w http.ResponseWriter, r *http.Request) { - metricsPageTmpl.Execute(w, pm.metricsImpl != nil) - } - - pm.router.HandleFunc("/", rootHandler) - pm.router.StrictSlash(true) - - pm.router.Handle("/debug", http.RedirectHandler("/", http.StatusMovedPermanently)) - pm.router.HandleFunc("/debug/pprof/", pprof.Index) - pm.router.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) - pm.router.HandleFunc("/debug/pprof/profile", pprof.Profile) - pm.router.HandleFunc("/debug/pprof/symbol", pprof.Symbol) - pm.router.HandleFunc("/debug/pprof/trace", pprof.Trace) - - // Manually add support for paths linked to by index page at /debug/pprof/ - pm.router.Handle("/debug/pprof/goroutine", pprof.Handler("goroutine")) - pm.router.Handle("/debug/pprof/heap", pprof.Handler("heap")) - pm.router.Handle("/debug/pprof/threadcreate", pprof.Handler("threadcreate")) - pm.router.Handle("/debug/pprof/block", pprof.Handler("block")) - - return nil -} - -func (ps *PlatformService) HandleMetrics(route string, h http.Handler) { - if ps.metrics.router != nil { - ps.metrics.router.Handle(route, h) - } -} - -func (ps *PlatformService) RestartMetrics() { - ps.metrics = newPlatformMetrics(ps.serviceConfig.Metrics, ps.serviceConfig.ConfigStore.Get) -} diff --git a/app/platform/service.go b/app/platform/service.go index 7524a3a491..a9eda866f7 100644 --- a/app/platform/service.go +++ b/app/platform/service.go @@ -3,42 +3,17 @@ package platform -import ( - "github.com/mattermost/mattermost-server/v6/config" - "github.com/mattermost/mattermost-server/v6/einterfaces" -) - // PlatformService is the service for the platform related tasks. It is // responsible for non-entity related functionalities that are required // by a product such as database access, configuration access, licensing etc. type PlatformService struct { - serviceConfig ServiceConfig - configStore *config.Store - - metrics *platformMetrics - - cluster einterfaces.ClusterInterface } // New creates a new PlatformService. -func New(sc ServiceConfig) (*PlatformService, error) { - if err := sc.validate(); err != nil { +func New(c ServiceConfig) (*PlatformService, error) { + if err := c.validate(); err != nil { return nil, err } - ps := &PlatformService{ - serviceConfig: sc, - configStore: sc.ConfigStore, - cluster: sc.Cluster, - } - - ps.metrics = newPlatformMetrics(sc.Metrics, ps.configStore.Get) - - return ps, nil -} - -func (ps *PlatformService) ShutdownMetrics() { - if ps.metrics != nil { - ps.metrics.stopMetricsServer() - } + return &PlatformService{}, nil } diff --git a/app/plugin_api.go b/app/plugin_api.go index 0b1187d250..d42d08613d 100644 --- a/app/plugin_api.go +++ b/app/plugin_api.go @@ -318,7 +318,7 @@ func (api *PluginAPI) RevokeUserAccessToken(tokenID string) *model.AppError { } func (api *PluginAPI) UpdateUser(user *model.User) (*model.User, *model.AppError) { - return api.app.UpdateUser(user, true) + return api.app.UpdateUser(api.ctx, user, true) } func (api *PluginAPI) UpdateUserActive(userID string, active bool) *model.AppError { @@ -359,11 +359,11 @@ func (api *PluginAPI) SetUserStatusTimedDND(userID string, endTime int64) (*mode } func (api *PluginAPI) UpdateUserCustomStatus(userID string, customStatus *model.CustomStatus) *model.AppError { - return api.app.SetCustomStatus(userID, customStatus) + return api.app.SetCustomStatus(api.ctx, userID, customStatus) } func (api *PluginAPI) RemoveUserCustomStatus(userID string) *model.AppError { - return api.app.RemoveCustomStatus(userID) + return api.app.RemoveCustomStatus(api.ctx, userID) } func (api *PluginAPI) GetUserCustomStatus(userID string) (*model.CustomStatus, *model.AppError) { @@ -738,7 +738,7 @@ func (api *PluginAPI) SetProfileImage(userID string, data []byte) *model.AppErro return err } - return api.app.SetProfileImageFromFile(userID, bytes.NewReader(data)) + return api.app.SetProfileImageFromFile(api.ctx, userID, bytes.NewReader(data)) } func (api *PluginAPI) GetEmojiList(sortBy string, page, perPage int) ([]*model.Emoji, *model.AppError) { diff --git a/app/plugin_api_test.go b/app/plugin_api_test.go index 00b61d1976..03cfce39bb 100644 --- a/app/plugin_api_test.go +++ b/app/plugin_api_test.go @@ -547,7 +547,7 @@ func TestPluginAPIUserCustomStatus(t *testing.T) { custom.Text = "" err = api.UpdateUserCustomStatus(user1.Id, custom) assert.NotNil(t, err) - assert.Equal(t, err.Error(), "SetCustomStatus: Failed to update the custom status. Please add either emoji or custom text status or both., ") + assert.Equal(t, err.Error(), "SetCustomStatus: Failed to update the custom status. Please add either emoji or custom text status or both.") // Remove custom status err = api.RemoveUserCustomStatus(user1.Id) @@ -889,7 +889,7 @@ func TestPluginAPIInstallPlugin(t *testing.T) { _, appErr := api.InstallPlugin(bytes.NewReader(tarData), true) assert.NotNil(t, appErr, "should not allow upload if upload disabled") - assert.Equal(t, appErr.Error(), "installPlugin: Plugins and/or plugin uploads have been disabled., ") + assert.Equal(t, appErr.Error(), "installPlugin: Plugins and/or plugin uploads have been disabled.") th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PluginSettings.Enable = true diff --git a/app/plugin_hooks_test.go b/app/plugin_hooks_test.go index 32945cfed7..e4eaa4d23e 100644 --- a/app/plugin_hooks_test.go +++ b/app/plugin_hooks_test.go @@ -462,15 +462,12 @@ func TestHookFileWillBeUploaded(t *testing.T) { }, th.App, func(*model.Manifest) plugin.API { return &mockAPI }) defer tearDown() - _, err := th.App.UploadFiles(th.Context, - "noteam", + _, err := th.App.UploadFile(th.Context, + []byte("inputfile"), th.BasicChannel.Id, - th.BasicUser.Id, - []io.ReadCloser{ioutil.NopCloser(bytes.NewBufferString("inputfile"))}, - []string{"testhook.txt"}, - []string{}, - time.Now(), + "testhook.txt", ) + if assert.NotNil(t, err) { assert.Equal(t, "File rejected by plugin. rejected", err.Message) } @@ -515,15 +512,12 @@ func TestHookFileWillBeUploaded(t *testing.T) { }, th.App, func(*model.Manifest) plugin.API { return &mockAPI }) defer tearDown() - _, err := th.App.UploadFiles(th.Context, - "noteam", + _, err := th.App.UploadFile(th.Context, + []byte("inputfile"), th.BasicChannel.Id, - th.BasicUser.Id, - []io.ReadCloser{ioutil.NopCloser(bytes.NewBufferString("inputfile"))}, - []string{"testhook.txt"}, - []string{}, - time.Now(), + "testhook.txt", ) + if assert.NotNil(t, err) { assert.Equal(t, "File rejected by plugin. rejected", err.Message) } @@ -562,20 +556,16 @@ func TestHookFileWillBeUploaded(t *testing.T) { }, th.App, func(*model.Manifest) plugin.API { return &mockAPI }) defer tearDown() - response, err := th.App.UploadFiles(th.Context, - "noteam", + response, err := th.App.UploadFile(th.Context, + []byte("inputfile"), th.BasicChannel.Id, - th.BasicUser.Id, - []io.ReadCloser{ioutil.NopCloser(bytes.NewBufferString("inputfile"))}, - []string{"testhook.txt"}, - []string{}, - time.Now(), + "testhook.txt", ) + assert.Nil(t, err) assert.NotNil(t, response) - assert.Equal(t, 1, len(response.FileInfos)) - fileID := response.FileInfos[0].Id + fileID := response.Id fileInfo, err := th.App.GetFileInfo(fileID) assert.Nil(t, err) assert.NotNil(t, fileInfo) @@ -638,19 +628,14 @@ func TestHookFileWillBeUploaded(t *testing.T) { }, th.App, func(*model.Manifest) plugin.API { return &mockAPI }) defer tearDown() - response, err := th.App.UploadFiles(th.Context, - "noteam", + response, err := th.App.UploadFile(th.Context, + []byte("inputfile"), th.BasicChannel.Id, - th.BasicUser.Id, - []io.ReadCloser{ioutil.NopCloser(bytes.NewBufferString("inputfile"))}, - []string{"testhook.txt"}, - []string{}, - time.Now(), + "testhook.txt", ) assert.Nil(t, err) assert.NotNil(t, response) - assert.Equal(t, 1, len(response.FileInfos)) - fileID := response.FileInfos[0].Id + fileID := response.Id fileInfo, err := th.App.GetFileInfo(fileID) assert.Nil(t, err) diff --git a/app/plugin_test.go b/app/plugin_test.go index a5346e270f..d5b21aefe5 100644 --- a/app/plugin_test.go +++ b/app/plugin_test.go @@ -453,7 +453,7 @@ func TestGetPluginStatusesDisabled(t *testing.T) { _, err := th.App.GetPluginStatuses() require.NotNil(t, err) - require.EqualError(t, err, "GetPluginStatuses: Plugins have been disabled. Please check your logs for details., ") + require.EqualError(t, err, "GetPluginStatuses: Plugins have been disabled. Please check your logs for details.") } func TestGetPluginStatuses(t *testing.T) { diff --git a/app/server.go b/app/server.go index fddb9ef1c5..e363e76ca6 100644 --- a/app/server.go +++ b/app/server.go @@ -9,8 +9,10 @@ import ( "crypto/tls" "fmt" "hash/maphash" + "html/template" "net" "net/http" + "net/http/pprof" "net/url" "os" "os/exec" @@ -25,6 +27,7 @@ import ( "github.com/getsentry/sentry-go" sentryhttp "github.com/getsentry/sentry-go/http" + "github.com/gorilla/handlers" "github.com/gorilla/mux" "github.com/pkg/errors" "github.com/rs/cors" @@ -32,7 +35,6 @@ import ( "github.com/mattermost/mattermost-server/v6/app/email" "github.com/mattermost/mattermost-server/v6/app/featureflag" - "github.com/mattermost/mattermost-server/v6/app/platform" "github.com/mattermost/mattermost-server/v6/app/request" "github.com/mattermost/mattermost-server/v6/app/teams" "github.com/mattermost/mattermost-server/v6/app/users" @@ -129,6 +131,10 @@ type Server struct { localModeServer *http.Server + metricsServer *http.Server + metricsRouter *mux.Router + metricsLock sync.Mutex + didFinishListen chan struct{} goroutineCount int32 @@ -171,7 +177,6 @@ type Server struct { configStore *configWrapper filestore filestore.FileBackend - platformService *platform.PlatformService telemetryService *telemetry.TelemetryService userService *users.UserService teamService *teams.TeamService @@ -251,17 +256,6 @@ func NewServer(options ...Option) (*Server, error) { s.configStore = &configWrapper{srv: s, Store: configStore} } - ps, sErr := platform.New(platform.ServiceConfig{ - ConfigStore: s.configStore.Store, - StartMetrics: s.startMetrics, - Metrics: s.Metrics, - Cluster: s.Cluster, - }) - if sErr != nil { - return nil, errors.Wrap(sErr, "failed to initialize platform") - } - s.platformService = ps - // Step 2: Logging if err := s.initLogging(); err != nil { mlog.Error("Could not initiate logging", mlog.Err(err)) @@ -625,6 +619,10 @@ func NewServer(options ...Option) (*Server, error) { s.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableDeveloper = true }) } + if s.startMetrics { + s.SetupMetricsServer() + } + s.AddLicenseListener(func(oldLicense, newLicense *model.License) { if (oldLicense == nil && newLicense == nil) || !s.startMetrics { return @@ -634,7 +632,7 @@ func NewServer(options ...Option) (*Server, error) { return } - s.platformService.RestartMetrics() // TODO: remove when this moved to the platform service + s.SetupMetricsServer() }) s.SearchEngine.UpdateConfig(s.Config()) @@ -703,6 +701,24 @@ func NewServer(options ...Option) (*Server, error) { return s, nil } +func (s *Server) SetupMetricsServer() { + if !*s.Config().MetricsSettings.Enable { + return + } + + s.StopMetricsServer() + + if err := s.InitMetricsRouter(); err != nil { + mlog.Error("Error initiating metrics router.", mlog.Err(err)) + } + + if s.Metrics != nil { + s.Metrics.Register() + } + + s.startMetricsServer() +} + func maxInt(a, b int) int { if a > b { return a @@ -1030,7 +1046,7 @@ func (s *Server) Shutdown() { s.Cluster.StopInterNodeCommunication() } - s.platformService.ShutdownMetrics() + s.StopMetricsServer() // This must be done after the cluster is stopped. if s.Jobs != nil { @@ -1614,9 +1630,104 @@ func doConfigCleanup(s *Server) { } } -// TODO: remove this method when we switch to using platform service. +func (s *Server) StopMetricsServer() { + s.metricsLock.Lock() + defer s.metricsLock.Unlock() + + if s.metricsServer != nil { + ctx, cancel := context.WithTimeout(context.Background(), TimeToWaitForConnectionsToCloseOnServerShutdown) + defer cancel() + + s.metricsServer.Shutdown(ctx) + s.Log.Info("Metrics and profiling server is stopping") + } +} + func (s *Server) HandleMetrics(route string, h http.Handler) { - s.platformService.HandleMetrics(route, h) + if s.metricsRouter != nil { + s.metricsRouter.Handle(route, h) + } +} + +func (s *Server) InitMetricsRouter() error { + s.metricsRouter = mux.NewRouter() + runtime.SetBlockProfileRate(*s.Config().MetricsSettings.BlockProfileRate) + + metricsPage := ` + + {{if .}} +
Metrics
{{end}} +
Profiling Root
+
Profiling Command Line
+
Profiling Symbols
+
Profiling Goroutines
+
Profiling Heap
+
Profiling Threads
+
Profiling Blocking
+
Profiling Execution Trace
+
Profiling CPU
+ + + ` + metricsPageTmpl, err := template.New("page").Parse(metricsPage) + if err != nil { + return errors.Wrap(err, "failed to create template") + } + + rootHandler := func(w http.ResponseWriter, r *http.Request) { + metricsPageTmpl.Execute(w, s.Metrics != nil) + } + + s.metricsRouter.HandleFunc("/", rootHandler) + s.metricsRouter.StrictSlash(true) + + s.metricsRouter.Handle("/debug", http.RedirectHandler("/", http.StatusMovedPermanently)) + s.metricsRouter.HandleFunc("/debug/pprof/", pprof.Index) + s.metricsRouter.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) + s.metricsRouter.HandleFunc("/debug/pprof/profile", pprof.Profile) + s.metricsRouter.HandleFunc("/debug/pprof/symbol", pprof.Symbol) + s.metricsRouter.HandleFunc("/debug/pprof/trace", pprof.Trace) + + // Manually add support for paths linked to by index page at /debug/pprof/ + s.metricsRouter.Handle("/debug/pprof/goroutine", pprof.Handler("goroutine")) + s.metricsRouter.Handle("/debug/pprof/heap", pprof.Handler("heap")) + s.metricsRouter.Handle("/debug/pprof/threadcreate", pprof.Handler("threadcreate")) + s.metricsRouter.Handle("/debug/pprof/block", pprof.Handler("block")) + + return nil +} + +func (s *Server) startMetricsServer() { + var notify chan struct{} + s.metricsLock.Lock() + defer func() { + if notify != nil { + <-notify + } + s.metricsLock.Unlock() + }() + + l, err := net.Listen("tcp", *s.Config().MetricsSettings.ListenAddress) + if err != nil { + mlog.Error(err.Error()) + return + } + + notify = make(chan struct{}) + s.metricsServer = &http.Server{ + Handler: handlers.RecoveryHandler(handlers.PrintRecoveryStack(true))(s.metricsRouter), + ReadTimeout: time.Duration(*s.Config().ServiceSettings.ReadTimeout) * time.Second, + WriteTimeout: time.Duration(*s.Config().ServiceSettings.WriteTimeout) * time.Second, + } + + go func() { + close(notify) + if err := s.metricsServer.Serve(l); err != nil && err != http.ErrServerClosed { + mlog.Critical(err.Error()) + } + }() + + s.Log.Info("Metrics and profiling server is started", mlog.String("address", l.Addr().String())) } func (s *Server) sendLicenseUpForRenewalEmail(users map[string]*model.User, license *model.License) *model.AppError { diff --git a/app/slashcommands/command_custom_status.go b/app/slashcommands/command_custom_status.go index 4f50614c8d..74749b5f85 100644 --- a/app/slashcommands/command_custom_status.go +++ b/app/slashcommands/command_custom_status.go @@ -48,7 +48,7 @@ func (*CustomStatusProvider) DoCommand(a *app.App, c *request.Context, args *mod message = strings.TrimSpace(message) if message == CmdCustomStatusClear { - if err := a.RemoveCustomStatus(args.UserId); err != nil { + if err := a.RemoveCustomStatus(c, args.UserId); err != nil { mlog.Debug(err.Error()) return &model.CommandResponse{Text: args.T("api.command_custom_status.clear.app_error"), ResponseType: model.CommandResponseTypeEphemeral} } @@ -61,7 +61,7 @@ func (*CustomStatusProvider) DoCommand(a *app.App, c *request.Context, args *mod customStatus := GetCustomStatus(message) customStatus.PreSave() - if err := a.SetCustomStatus(args.UserId, customStatus); err != nil { + if err := a.SetCustomStatus(c, args.UserId, customStatus); err != nil { mlog.Debug(err.Error()) return &model.CommandResponse{Text: args.T("api.command_custom_status.app_error"), ResponseType: model.CommandResponseTypeEphemeral} } diff --git a/app/slashcommands/helper_test.go b/app/slashcommands/helper_test.go index 2435c71feb..32d9d4c4ce 100644 --- a/app/slashcommands/helper_test.go +++ b/app/slashcommands/helper_test.go @@ -165,7 +165,7 @@ func (th *TestHelper) initBasic() *TestHelper { // create users once and cache them because password hashing is slow initBasicOnce.Do(func() { th.SystemAdminUser = th.createUser() - th.App.UpdateUserRoles(th.SystemAdminUser.Id, model.SystemUserRoleId+" "+model.SystemAdminRoleId, false) + th.App.UpdateUserRoles(th.Context, th.SystemAdminUser.Id, model.SystemUserRoleId+" "+model.SystemAdminRoleId, false) th.SystemAdminUser, _ = th.App.GetUser(th.SystemAdminUser.Id) userCache.SystemAdminUser = th.SystemAdminUser.DeepCopy() diff --git a/app/status.go b/app/status.go index 7ec9c304f5..374e3477de 100644 --- a/app/status.go +++ b/app/status.go @@ -8,6 +8,7 @@ import ( "errors" "net/http" + "github.com/mattermost/mattermost-server/v6/app/request" "github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/shared/mlog" "github.com/mattermost/mattermost-server/v6/store" @@ -405,7 +406,7 @@ func (a *App) UpdateDNDStatusOfUsers() { } } -func (a *App) SetCustomStatus(userID string, cs *model.CustomStatus) *model.AppError { +func (a *App) SetCustomStatus(c request.CTX, userID string, cs *model.CustomStatus) *model.AppError { if cs == nil || (cs.Emoji == "" && cs.Text == "") { return model.NewAppError("SetCustomStatus", "api.custom_status.set_custom_statuses.update.app_error", nil, "", http.StatusBadRequest) } @@ -416,26 +417,26 @@ func (a *App) SetCustomStatus(userID string, cs *model.CustomStatus) *model.AppE } user.SetCustomStatus(cs) - _, updateErr := a.UpdateUser(user, true) + _, updateErr := a.UpdateUser(c, user, true) if updateErr != nil { return updateErr } if err := a.addRecentCustomStatus(userID, cs); err != nil { - a.Log().Error("Can't add recent custom status for", mlog.String("userID", userID), mlog.Err(err)) + c.Logger().Error("Can't add recent custom status for", mlog.String("userID", userID), mlog.Err(err)) } return nil } -func (a *App) RemoveCustomStatus(userID string) *model.AppError { +func (a *App) RemoveCustomStatus(c request.CTX, userID string) *model.AppError { user, err := a.GetUser(userID) if err != nil { return err } user.ClearCustomStatus() - _, updateErr := a.UpdateUser(user, true) + _, updateErr := a.UpdateUser(c, user, true) if updateErr != nil { return updateErr } diff --git a/app/status_test.go b/app/status_test.go index 74d82f5153..e56ef60728 100644 --- a/app/status_test.go +++ b/app/status_test.go @@ -53,14 +53,14 @@ func TestCustomStatus(t *testing.T) { Text: "honk!", } - err := th.App.SetCustomStatus(user.Id, cs) + err := th.App.SetCustomStatus(th.Context, user.Id, cs) require.Nil(t, err, "failed to set custom status %v", err) csSaved, err := th.App.GetCustomStatus(user.Id) require.Nil(t, err, "failed to get custom status after save %v", err) require.Equal(t, cs, csSaved) - err = th.App.RemoveCustomStatus(user.Id) + err = th.App.RemoveCustomStatus(th.Context, user.Id) require.Nil(t, err, "failed to to clear custom status %v", err) var csClear *model.CustomStatus @@ -117,9 +117,9 @@ func TestCustomStatusErrors(t *testing.T) { var appErr *model.AppError switch tc.customStatus { case "set": - appErr = th.App.SetCustomStatus(fakeUserID, cs) + appErr = th.App.SetCustomStatus(th.Context, fakeUserID, cs) case "remove": - appErr = th.App.RemoveCustomStatus(fakeUserID) + appErr = th.App.RemoveCustomStatus(th.Context, fakeUserID) } require.NotNil(t, appErr) diff --git a/app/syncables_test.go b/app/syncables_test.go index c996546f80..6947af7342 100644 --- a/app/syncables_test.go +++ b/app/syncables_test.go @@ -337,7 +337,7 @@ func TestCreateDefaultMemberships(t *testing.T) { t.Run("Team with restricted domains skips over members that do not match the allowed domains", func(t *testing.T) { restrictedUser := th.CreateUser() restrictedUser.Email = "restricted@mattermost.org" - _, err = th.App.UpdateUser(restrictedUser, false) + _, err = th.App.UpdateUser(th.Context, restrictedUser, false) require.Nil(t, err) _, err = th.App.UpsertGroupMember(scienceGroup.Id, restrictedUser.Id) require.Nil(t, err) diff --git a/app/team.go b/app/team.go index 94c25aae79..6240f4b932 100644 --- a/app/team.go +++ b/app/team.go @@ -763,7 +763,7 @@ func (a *App) AddUserToTeamByInviteId(c *request.Context, inviteId string, userI return team, teamMember, nil } -func (a *App) JoinUserToTeam(c *request.Context, team *model.Team, user *model.User, userRequestorId string) (*model.TeamMember, *model.AppError) { +func (a *App) JoinUserToTeam(c request.CTX, team *model.Team, user *model.User, userRequestorId string) (*model.TeamMember, *model.AppError) { teamMember, alreadyAdded, err := a.ch.srv.teamService.JoinUserToTeam(team, user) if err != nil { var appErr *model.AppError diff --git a/app/user.go b/app/user.go index 89dabb2f82..edeef970ff 100644 --- a/app/user.go +++ b/app/user.go @@ -43,7 +43,7 @@ const ( ImageProfilePixelDimension = 128 ) -func (a *App) CreateUserWithToken(c *request.Context, user *model.User, token *model.Token) (*model.User, *model.AppError) { +func (a *App) CreateUserWithToken(c request.CTX, user *model.User, token *model.Token) (*model.User, *model.AppError) { if err := a.IsUserSignUpAllowed(); err != nil { return nil, err } @@ -104,19 +104,19 @@ func (a *App) CreateUserWithToken(c *request.Context, user *model.User, token *m for _, channel := range channels { _, err := a.AddChannelMember(c, ruser.Id, channel, ChannelMemberOpts{}) if err != nil { - mlog.Warn("Failed to add channel member", mlog.Err(err)) + c.Logger().Warn("Failed to add channel member", mlog.Err(err)) } } } if err := a.DeleteToken(token); err != nil { - mlog.Warn("Error while deleting token", mlog.Err(err)) + c.Logger().Warn("Error while deleting token", mlog.Err(err)) } return ruser, nil } -func (a *App) CreateUserWithInviteId(c *request.Context, user *model.User, inviteId, redirect string) (*model.User, *model.AppError) { +func (a *App) CreateUserWithInviteId(c request.CTX, user *model.User, inviteId, redirect string) (*model.User, *model.AppError) { if err := a.IsUserSignUpAllowed(); err != nil { return nil, err } @@ -154,26 +154,26 @@ func (a *App) CreateUserWithInviteId(c *request.Context, user *model.User, invit a.AddDirectChannels(c, team.Id, ruser) if err := a.Srv().EmailService.SendWelcomeEmail(ruser.Id, ruser.Email, ruser.EmailVerified, ruser.DisableWelcomeEmail, ruser.Locale, a.GetSiteURL(), redirect); err != nil { - mlog.Warn("Failed to send welcome email on create user with inviteId", mlog.Err(err)) + c.Logger().Warn("Failed to send welcome email on create user with inviteId", mlog.Err(err)) } return ruser, nil } -func (a *App) CreateUserAsAdmin(c *request.Context, user *model.User, redirect string) (*model.User, *model.AppError) { +func (a *App) CreateUserAsAdmin(c request.CTX, user *model.User, redirect string) (*model.User, *model.AppError) { ruser, err := a.CreateUser(c, user) if err != nil { return nil, err } if err := a.Srv().EmailService.SendWelcomeEmail(ruser.Id, ruser.Email, ruser.EmailVerified, ruser.DisableWelcomeEmail, ruser.Locale, a.GetSiteURL(), redirect); err != nil { - mlog.Warn("Failed to send welcome email to the new user, created by system admin", mlog.Err(err)) + c.Logger().Warn("Failed to send welcome email to the new user, created by system admin", mlog.Err(err)) } return ruser, nil } -func (a *App) CreateUserFromSignup(c *request.Context, user *model.User, redirect string) (*model.User, *model.AppError) { +func (a *App) CreateUserFromSignup(c request.CTX, user *model.User, redirect string) (*model.User, *model.AppError) { if err := a.IsUserSignUpAllowed(); err != nil { return nil, err } @@ -191,7 +191,7 @@ func (a *App) CreateUserFromSignup(c *request.Context, user *model.User, redirec } if err := a.Srv().EmailService.SendWelcomeEmail(ruser.Id, ruser.Email, ruser.EmailVerified, ruser.DisableWelcomeEmail, ruser.Locale, a.GetSiteURL(), redirect); err != nil { - mlog.Warn("Failed to send welcome email on create user from signup", mlog.Err(err)) + c.Logger().Warn("Failed to send welcome email on create user from signup", mlog.Err(err)) } return ruser, nil @@ -211,17 +211,17 @@ func (a *App) IsFirstUserAccount() bool { // CreateUser creates a user and sets several fields of the returned User struct to // their zero values. -func (a *App) CreateUser(c *request.Context, user *model.User) (*model.User, *model.AppError) { +func (a *App) CreateUser(c request.CTX, user *model.User) (*model.User, *model.AppError) { return a.createUserOrGuest(c, user, false) } // CreateGuest creates a guest and sets several fields of the returned User struct to // their zero values. -func (a *App) CreateGuest(c *request.Context, user *model.User) (*model.User, *model.AppError) { +func (a *App) CreateGuest(c request.CTX, user *model.User) (*model.User, *model.AppError) { return a.createUserOrGuest(c, user, true) } -func (a *App) createUserOrGuest(c *request.Context, user *model.User, guest bool) (*model.User, *model.AppError) { +func (a *App) createUserOrGuest(c request.CTX, user *model.User, guest bool) (*model.User, *model.AppError) { if err := a.isUniqueToGroupNames(user.Username); err != nil { err.Where = "createUserOrGuest" return nil, err @@ -285,7 +285,7 @@ func (a *App) createUserOrGuest(c *request.Context, user *model.User, guest bool } if err := a.Srv().Store.Preference().Save(preferences); err != nil { - mlog.Warn("Encountered error saving user preferences", mlog.Err(err)) + c.Logger().Warn("Encountered error saving user preferences", mlog.Err(err)) } go a.UpdateViewedProductNoticesForNewUser(ruser.Id) @@ -347,7 +347,7 @@ func (a *App) CreateOAuthUser(c *request.Context, service string, userData io.Re if provider.IsSameUser(userByEmail, user) { if _, err := a.Srv().Store.User().UpdateAuthData(userByEmail.Id, user.AuthService, user.AuthData, "", false); err != nil { // if the user is not updated, write a warning to the log, but don't prevent user login - mlog.Warn("Error attempting to update user AuthData", mlog.Err(err)) + c.Logger().Warn("Error attempting to update user AuthData", mlog.Err(err)) } return userByEmail, nil } @@ -369,7 +369,7 @@ func (a *App) CreateOAuthUser(c *request.Context, service string, userData io.Re err = a.AddDirectChannels(c, teamID, user) if err != nil { - mlog.Warn("Failed to add direct channels", mlog.Err(err)) + c.Logger().Warn("Failed to add direct channels", mlog.Err(err)) } } @@ -759,7 +759,7 @@ func (a *App) GetDefaultProfileImage(user *model.User) ([]byte, *model.AppError) return a.ch.srv.GetDefaultProfileImage(user) } -func (a *App) SetDefaultProfileImage(user *model.User) *model.AppError { +func (a *App) SetDefaultProfileImage(c request.CTX, user *model.User) *model.AppError { img, appErr := a.GetDefaultProfileImage(user) if appErr != nil { return appErr @@ -771,14 +771,14 @@ func (a *App) SetDefaultProfileImage(user *model.User) *model.AppError { } if err := a.Srv().Store.User().ResetLastPictureUpdate(user.Id); err != nil { - mlog.Warn("Failed to reset last picture update", mlog.Err(err)) + c.Logger().Warn("Failed to reset last picture update", mlog.Err(err)) } a.InvalidateCacheForUser(user.Id) updatedUser, appErr := a.GetUser(user.Id) if appErr != nil { - mlog.Warn("Error in getting users profile forcing logout", mlog.String("user_id", user.Id), mlog.Err(appErr)) + c.Logger().Warn("Error in getting users profile forcing logout", mlog.String("user_id", user.Id), mlog.Err(appErr)) return nil } @@ -792,21 +792,21 @@ func (a *App) SetDefaultProfileImage(user *model.User) *model.AppError { return nil } -func (a *App) SetProfileImage(userID string, imageData *multipart.FileHeader) *model.AppError { +func (a *App) SetProfileImage(c request.CTX, userID string, imageData *multipart.FileHeader) *model.AppError { file, err := imageData.Open() if err != nil { return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.open.app_error", nil, err.Error(), http.StatusBadRequest) } defer file.Close() - return a.SetProfileImageFromMultiPartFile(userID, file) + return a.SetProfileImageFromMultiPartFile(c, userID, file) } -func (a *App) SetProfileImageFromMultiPartFile(userID string, file multipart.File) *model.AppError { +func (a *App) SetProfileImageFromMultiPartFile(c request.CTX, userID string, file multipart.File) *model.AppError { if limitErr := checkImageLimits(file, *a.Config().FileSettings.MaxImageResolution); limitErr != nil { return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.check_image_limits.app_error", nil, "", http.StatusBadRequest) } - return a.SetProfileImageFromFile(userID, file) + return a.SetProfileImageFromFile(c, userID, file) } func (a *App) AdjustImage(file io.Reader) (*bytes.Buffer, *model.AppError) { @@ -831,7 +831,7 @@ func (a *App) AdjustImage(file io.Reader) (*bytes.Buffer, *model.AppError) { return buf, nil } -func (a *App) SetProfileImageFromFile(userID string, file io.Reader) *model.AppError { +func (a *App) SetProfileImageFromFile(c request.CTX, userID string, file io.Reader) *model.AppError { buf, err := a.AdjustImage(file) if err != nil { return err @@ -847,7 +847,7 @@ func (a *App) SetProfileImageFromFile(userID string, file io.Reader) *model.AppE } if err := a.Srv().Store.User().UpdateLastPictureUpdate(userID); err != nil { - mlog.Warn("Error with updating last picture update", mlog.Err(err)) + c.Logger().Warn("Error with updating last picture update", mlog.Err(err)) } a.invalidateUserCacheAndPublish(userID) a.onUserProfileChange(userID) @@ -855,7 +855,7 @@ func (a *App) SetProfileImageFromFile(userID string, file io.Reader) *model.AppE return nil } -func (a *App) UpdatePasswordAsUser(userID, currentPassword, newPassword string) *model.AppError { +func (a *App) UpdatePasswordAsUser(c request.CTX, userID, currentPassword, newPassword string) *model.AppError { user, err := a.GetUser(userID) if err != nil { return err @@ -880,7 +880,7 @@ func (a *App) UpdatePasswordAsUser(userID, currentPassword, newPassword string) T := i18n.GetUserTranslations(user.Locale) - return a.UpdatePasswordSendEmail(user, newPassword, T("api.user.update_password.menu")) + return a.UpdatePasswordSendEmail(c, user, newPassword, T("api.user.update_password.menu")) } func (a *App) userDeactivated(c *request.Context, userID string) *model.AppError { @@ -999,8 +999,8 @@ func (a *App) SanitizeProfile(user *model.User, asAdmin bool) { user.SanitizeProfile(options) } -func (a *App) UpdateUserAsUser(user *model.User, asAdmin bool) (*model.User, *model.AppError) { - updatedUser, err := a.UpdateUser(user, true) +func (a *App) UpdateUserAsUser(c request.CTX, user *model.User, asAdmin bool) (*model.User, *model.AppError) { + updatedUser, err := a.UpdateUser(c, user, true) if err != nil { return nil, err } @@ -1039,7 +1039,7 @@ func (a *App) CheckProviderAttributes(user *model.User, patch *model.UserPatch) return conflictField } -func (a *App) PatchUser(userID string, patch *model.UserPatch, asAdmin bool) (*model.User, *model.AppError) { +func (a *App) PatchUser(c request.CTX, userID string, patch *model.UserPatch, asAdmin bool) (*model.User, *model.AppError) { user, err := a.GetUser(userID) if err != nil { return nil, err @@ -1047,7 +1047,7 @@ func (a *App) PatchUser(userID string, patch *model.UserPatch, asAdmin bool) (*m user.Patch(patch) - updatedUser, err := a.UpdateUser(user, true) + updatedUser, err := a.UpdateUser(c, user, true) if err != nil { return nil, err } @@ -1112,7 +1112,7 @@ func (a *App) isUniqueToGroupNames(val string) *model.AppError { return nil } -func (a *App) UpdateUser(user *model.User, sendNotifications bool) (*model.User, *model.AppError) { +func (a *App) UpdateUser(c request.CTX, user *model.User, sendNotifications bool) (*model.User, *model.AppError) { prev, err := a.ch.srv.userService.GetUser(user.Id) if err != nil { var nfErr *store.ErrNotFound @@ -1192,13 +1192,13 @@ func (a *App) UpdateUser(user *model.User, sendNotifications bool) (*model.User, if *a.Config().EmailSettings.RequireEmailVerification { a.Srv().Go(func() { if err := a.SendEmailVerification(userUpdate.New, newEmail, ""); err != nil { - mlog.Error("Failed to send email verification", mlog.Err(err)) + c.Logger().Error("Failed to send email verification", mlog.Err(err)) } }) } else { a.Srv().Go(func() { if err := a.Srv().EmailService.SendEmailChangeEmail(userUpdate.Old.Email, userUpdate.New.Email, userUpdate.New.Locale, a.GetSiteURL()); err != nil { - mlog.Error("Failed to send email change email", mlog.Err(err)) + c.Logger().Error("Failed to send email change email", mlog.Err(err)) } }) } @@ -1207,7 +1207,7 @@ func (a *App) UpdateUser(user *model.User, sendNotifications bool) (*model.User, if userUpdate.New.Username != userUpdate.Old.Username { a.Srv().Go(func() { if err := a.Srv().EmailService.SendChangeUsernameEmail(userUpdate.New.Username, userUpdate.New.Email, userUpdate.New.Locale, a.GetSiteURL()); err != nil { - mlog.Error("Failed to send change username email", mlog.Err(err)) + c.Logger().Error("Failed to send change username email", mlog.Err(err)) } }) } @@ -1251,7 +1251,7 @@ func (a *App) updateUserNotifyProps(userID string, props map[string]string) *mod return nil } -func (a *App) UpdateMfa(activate bool, userID, token string) *model.AppError { +func (a *App) UpdateMfa(c request.CTX, activate bool, userID, token string) *model.AppError { if activate { if err := a.ActivateMfa(userID, token); err != nil { return err @@ -1265,25 +1265,25 @@ func (a *App) UpdateMfa(activate bool, userID, token string) *model.AppError { a.Srv().Go(func() { user, err := a.GetUser(userID) if err != nil { - mlog.Error("Failed to get user", mlog.Err(err)) + c.Logger().Error("Failed to get user", mlog.Err(err)) return } if err := a.Srv().EmailService.SendMfaChangeEmail(user.Email, activate, user.Locale, a.GetSiteURL()); err != nil { - mlog.Error("Failed to send mfa change email", mlog.Err(err)) + c.Logger().Error("Failed to send mfa change email", mlog.Err(err)) } }) return nil } -func (a *App) UpdatePasswordByUserIdSendEmail(userID, newPassword, method string) *model.AppError { +func (a *App) UpdatePasswordByUserIdSendEmail(c request.CTX, userID, newPassword, method string) *model.AppError { user, err := a.GetUser(userID) if err != nil { return err } - return a.UpdatePasswordSendEmail(user, newPassword, method) + return a.UpdatePasswordSendEmail(c, user, newPassword, method) } func (a *App) UpdatePassword(user *model.User, newPassword string) *model.AppError { @@ -1302,14 +1302,14 @@ func (a *App) UpdatePassword(user *model.User, newPassword string) *model.AppErr return nil } -func (a *App) UpdatePasswordSendEmail(user *model.User, newPassword, method string) *model.AppError { +func (a *App) UpdatePasswordSendEmail(c request.CTX, user *model.User, newPassword, method string) *model.AppError { if err := a.UpdatePassword(user, newPassword); err != nil { return err } a.Srv().Go(func() { if err := a.Srv().EmailService.SendPasswordChangeEmail(user.Email, method, user.Locale, a.GetSiteURL()); err != nil { - mlog.Error("Failed to send password change email", mlog.Err(err)) + c.Logger().Error("Failed to send password change email", mlog.Err(err)) } }) @@ -1335,11 +1335,11 @@ func (a *App) UpdateHashedPassword(user *model.User, newHashedPassword string) * return nil } -func (a *App) ResetPasswordFromToken(userSuppliedTokenString, newPassword string) *model.AppError { - return a.resetPasswordFromToken(userSuppliedTokenString, newPassword, model.GetMillis()) +func (a *App) ResetPasswordFromToken(c request.CTX, userSuppliedTokenString, newPassword string) *model.AppError { + return a.resetPasswordFromToken(c, userSuppliedTokenString, newPassword, model.GetMillis()) } -func (a *App) resetPasswordFromToken(userSuppliedTokenString, newPassword string, nowMilli int64) *model.AppError { +func (a *App) resetPasswordFromToken(c request.CTX, userSuppliedTokenString, newPassword string, nowMilli int64) *model.AppError { token, err := a.GetPasswordRecoveryToken(userSuppliedTokenString) if err != nil { return err @@ -1373,12 +1373,12 @@ func (a *App) resetPasswordFromToken(userSuppliedTokenString, newPassword string T := i18n.GetUserTranslations(user.Locale) - if err := a.UpdatePasswordSendEmail(user, newPassword, T("api.user.reset_password.method")); err != nil { + if err := a.UpdatePasswordSendEmail(c, user, newPassword, T("api.user.reset_password.method")); err != nil { return err } if err := a.DeleteToken(token); err != nil { - mlog.Warn("Failed to delete token", mlog.Err(err)) + c.Logger().Warn("Failed to delete token", mlog.Err(err)) } return nil @@ -1474,17 +1474,17 @@ func (a *App) DeleteToken(token *model.Token) *model.AppError { return nil } -func (a *App) UpdateUserRoles(userID string, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError) { +func (a *App) UpdateUserRoles(c request.CTX, userID string, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError) { user, err := a.GetUser(userID) if err != nil { err.StatusCode = http.StatusBadRequest return nil, err } - return a.UpdateUserRolesWithUser(user, newRoles, sendWebSocketEvent) + return a.UpdateUserRolesWithUser(c, user, newRoles, sendWebSocketEvent) } -func (a *App) UpdateUserRolesWithUser(user *model.User, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError) { +func (a *App) UpdateUserRolesWithUser(c request.CTX, user *model.User, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError) { if err := a.CheckRolesExist(strings.Fields(newRoles)); err != nil { return nil, err @@ -1522,7 +1522,7 @@ func (a *App) UpdateUserRolesWithUser(user *model.User, newRoles string, sendWeb if result := <-schan; result.NErr != nil { // soft error since the user roles were still updated - mlog.Warn("Failed during updating user roles", mlog.Err(result.NErr)) + c.Logger().Warn("Failed during updating user roles", mlog.Err(result.NErr)) } a.InvalidateCacheForUser(user.Id) @@ -1539,9 +1539,9 @@ func (a *App) UpdateUserRolesWithUser(user *model.User, newRoles string, sendWeb } func (a *App) PermanentDeleteUser(c *request.Context, user *model.User) *model.AppError { - mlog.Warn("Attempting to permanently delete account", mlog.String("user_id", user.Id), mlog.String("user_email", user.Email)) + c.Logger().Warn("Attempting to permanently delete account", mlog.String("user_id", user.Id), mlog.String("user_email", user.Email)) if user.IsInRole(model.SystemAdminRoleId) { - mlog.Warn("You are deleting a user that is a system administrator. You may need to set another account as the system administrator using the command line tools.", mlog.String("user_email", user.Email)) + c.Logger().Warn("You are deleting a user that is a system administrator. You may need to set another account as the system administrator using the command line tools.", mlog.String("user_email", user.Email)) } if _, err := a.UpdateActive(c, user, false); err != nil { @@ -1600,13 +1600,13 @@ func (a *App) PermanentDeleteUser(c *request.Context, user *model.User) *model.A infos, err := a.Srv().Store.FileInfo().GetForUser(user.Id) if err != nil { - mlog.Warn("Error getting file list for user from FileInfoStore", mlog.Err(err)) + c.Logger().Warn("Error getting file list for user from FileInfoStore", mlog.Err(err)) } for _, info := range infos { res, err := a.FileExists(info.Path) if err != nil { - mlog.Warn( + c.Logger().Warn( "Error checking existence of file", mlog.String("path", info.Path), mlog.Err(err), @@ -1615,14 +1615,14 @@ func (a *App) PermanentDeleteUser(c *request.Context, user *model.User) *model.A } if !res { - mlog.Warn("File not found", mlog.String("path", info.Path)) + c.Logger().Warn("File not found", mlog.String("path", info.Path)) continue } err = a.RemoveFile(info.Path) if err != nil { - mlog.Warn( + c.Logger().Warn( "Unable to remove file", mlog.String("path", info.Path), mlog.Err(err), @@ -1646,7 +1646,7 @@ func (a *App) PermanentDeleteUser(c *request.Context, user *model.User) *model.A return model.NewAppError("PermanentDeleteUser", "app.team.remove_member.app_error", nil, err.Error(), http.StatusInternalServerError) } - mlog.Warn("Permanently deleted account", mlog.String("user_email", user.Email), mlog.String("user_id", user.Id)) + c.Logger().Warn("Permanently deleted account", mlog.String("user_email", user.Email), mlog.String("user_id", user.Id)) return nil } @@ -1693,7 +1693,7 @@ func (a *App) SendEmailVerification(user *model.User, newEmail, redirect string) return nil } -func (a *App) VerifyEmailFromToken(userSuppliedTokenString string) *model.AppError { +func (a *App) VerifyEmailFromToken(c request.CTX, userSuppliedTokenString string) *model.AppError { token, err := a.GetVerifyEmailToken(userSuppliedTokenString) if err != nil { return err @@ -1731,7 +1731,7 @@ func (a *App) VerifyEmailFromToken(userSuppliedTokenString string) *model.AppErr } if err := a.DeleteToken(token); err != nil { - mlog.Warn("Failed to delete token", mlog.Err(err)) + c.Logger().Warn("Failed to delete token", mlog.Err(err)) } return nil @@ -2163,23 +2163,23 @@ func (a *App) PromoteGuestToUser(c *request.Context, user *model.User, requestor for _, team := range userTeams { // Soft error if there is an issue joining the default channels if err := a.JoinDefaultChannels(c, team.Id, user, false, requestorId); err != nil { - mlog.Warn("Failed to join default channels", mlog.String("user_id", user.Id), mlog.String("team_id", team.Id), mlog.String("requestor_id", requestorId), mlog.Err(err)) + c.Logger().Warn("Failed to join default channels", mlog.String("user_id", user.Id), mlog.String("team_id", team.Id), mlog.String("requestor_id", requestorId), mlog.Err(err)) } } promotedUser, err := a.GetUser(user.Id) if err != nil { - mlog.Warn("Failed to get user on promote guest to user", mlog.Err(err)) + c.Logger().Warn("Failed to get user on promote guest to user", mlog.Err(err)) } else { a.sendUpdatedUserEvent(*promotedUser) if uErr := a.ch.srv.userService.UpdateSessionsIsGuest(promotedUser.Id, promotedUser.IsGuest()); uErr != nil { - mlog.Warn("Unable to update user sessions", mlog.String("user_id", promotedUser.Id), mlog.Err(uErr)) + c.Logger().Warn("Unable to update user sessions", mlog.String("user_id", promotedUser.Id), mlog.Err(uErr)) } } teamMembers, err := a.GetTeamMembersForUser(user.Id, "", true) if err != nil { - mlog.Warn("Failed to get team members for user on promote guest to user", mlog.Err(err)) + c.Logger().Warn("Failed to get team members for user on promote guest to user", mlog.Err(err)) } for _, member := range teamMembers { @@ -2187,7 +2187,7 @@ func (a *App) PromoteGuestToUser(c *request.Context, user *model.User, requestor channelMembers, err := a.GetChannelMembersForUser(c, member.TeamId, user.Id) if err != nil { - mlog.Warn("Failed to get channel members for user on promote guest to user", mlog.Err(err)) + c.Logger().Warn("Failed to get channel members for user on promote guest to user", mlog.Err(err)) } for _, member := range channelMembers { @@ -2196,7 +2196,7 @@ func (a *App) PromoteGuestToUser(c *request.Context, user *model.User, requestor evt := model.NewWebSocketEvent(model.WebsocketEventChannelMemberUpdated, "", "", user.Id, nil) memberJSON, jsonErr := json.Marshal(member) if jsonErr != nil { - mlog.Warn("Failed to encode channel member to JSON", mlog.Err(jsonErr)) + c.Logger().Warn("Failed to encode channel member to JSON", mlog.Err(jsonErr)) } evt.Add("channelMember", string(memberJSON)) a.Publish(evt) @@ -2218,12 +2218,12 @@ func (a *App) DemoteUserToGuest(c request.CTX, user *model.User) *model.AppError a.sendUpdatedUserEvent(*demotedUser) if uErr := a.ch.srv.userService.UpdateSessionsIsGuest(demotedUser.Id, demotedUser.IsGuest()); uErr != nil { - mlog.Warn("Unable to update user sessions", mlog.String("user_id", demotedUser.Id), mlog.Err(uErr)) + c.Logger().Warn("Unable to update user sessions", mlog.String("user_id", demotedUser.Id), mlog.Err(uErr)) } teamMembers, err := a.GetTeamMembersForUser(user.Id, "", true) if err != nil { - mlog.Warn("Failed to get team members for users on demote user to guest", mlog.Err(err)) + c.Logger().Warn("Failed to get team members for users on demote user to guest", mlog.Err(err)) } for _, member := range teamMembers { @@ -2231,7 +2231,7 @@ func (a *App) DemoteUserToGuest(c request.CTX, user *model.User) *model.AppError channelMembers, err := a.GetChannelMembersForUser(c, member.TeamId, user.Id) if err != nil { - mlog.Warn("Failed to get channel members for users on demote user to guest", mlog.Err(err)) + c.Logger().Warn("Failed to get channel members for users on demote user to guest", mlog.Err(err)) continue } @@ -2241,7 +2241,7 @@ func (a *App) DemoteUserToGuest(c request.CTX, user *model.User) *model.AppError evt := model.NewWebSocketEvent(model.WebsocketEventChannelMemberUpdated, "", "", user.Id, nil) memberJSON, jsonErr := json.Marshal(member) if jsonErr != nil { - mlog.Warn("Failed to encode channel member to JSON", mlog.Err(jsonErr)) + c.Logger().Warn("Failed to encode channel member to JSON", mlog.Err(jsonErr)) } evt.Add("channelMember", string(memberJSON)) a.Publish(evt) @@ -2295,8 +2295,8 @@ func (a *App) GetKnownUsers(userID string) ([]string, *model.AppError) { } // ConvertBotToUser converts a bot to user. -func (a *App) ConvertBotToUser(bot *model.Bot, userPatch *model.UserPatch, sysadmin bool) (*model.User, *model.AppError) { - user, nErr := a.Srv().Store.User().Get(context.Background(), bot.UserId) +func (a *App) ConvertBotToUser(c request.CTX, bot *model.Bot, userPatch *model.UserPatch, sysadmin bool) (*model.User, *model.AppError) { + user, nErr := a.Srv().Store.User().Get(c.Context(), bot.UserId) if nErr != nil { var nfErr *store.ErrNotFound switch { @@ -2308,7 +2308,7 @@ func (a *App) ConvertBotToUser(bot *model.Bot, userPatch *model.UserPatch, sysad } if sysadmin && !user.IsInRole(model.SystemAdminRoleId) { - _, appErr := a.UpdateUserRoles( + _, appErr := a.UpdateUserRoles(c, user.Id, fmt.Sprintf("%s %s", user.Roles, model.SystemAdminRoleId), false) @@ -2319,7 +2319,7 @@ func (a *App) ConvertBotToUser(bot *model.Bot, userPatch *model.UserPatch, sysad user.Patch(userPatch) - user, err := a.UpdateUser(user, false) + user, err := a.UpdateUser(c, user, false) if err != nil { return nil, err } @@ -2518,7 +2518,7 @@ func (a *App) UpdateThreadFollowForUserFromChannelAdd(c request.CTX, userID, tea payload, jsonErr := json.Marshal(userThread) if jsonErr != nil { - mlog.Warn("Failed to encode thread to JSON") + c.Logger().Warn("Failed to encode thread to JSON") } message.Add("thread", string(payload)) message.Add("previous_unread_replies", int64(0)) diff --git a/app/user_test.go b/app/user_test.go index ad4786e52c..4d545f894f 100644 --- a/app/user_test.go +++ b/app/user_test.go @@ -88,7 +88,7 @@ func TestSetDefaultProfileImage(t *testing.T) { th := Setup(t).InitBasic() defer th.TearDown() - err := th.App.SetDefaultProfileImage(&model.User{ + err := th.App.SetDefaultProfileImage(th.Context, &model.User{ Id: model.NewId(), Username: "notvaliduser", }) @@ -97,7 +97,7 @@ func TestSetDefaultProfileImage(t *testing.T) { user := th.BasicUser - err = th.App.SetDefaultProfileImage(user) + err = th.App.SetDefaultProfileImage(th.Context, user) require.Nil(t, err) user = getUserFromDB(th.App, user.Id, t) @@ -140,11 +140,11 @@ func TestUpdateUserToRestrictedDomain(t *testing.T) { *cfg.TeamSettings.RestrictCreationToDomains = "foo.com" }) - _, err := th.App.UpdateUser(user, false) + _, err := th.App.UpdateUser(th.Context, user, false) assert.Nil(t, err) user.Email = "asdf@ghjk.l" - _, err = th.App.UpdateUser(user, false) + _, err = th.App.UpdateUser(th.Context, user, false) assert.NotNil(t, err) t.Run("Restricted Domains must be ignored for guest users", func(t *testing.T) { @@ -156,7 +156,7 @@ func TestUpdateUserToRestrictedDomain(t *testing.T) { }) guest.Email = "asdf@bar.com" - updatedGuest, err := th.App.UpdateUser(guest, false) + updatedGuest, err := th.App.UpdateUser(th.Context, guest, false) require.Nil(t, err) require.Equal(t, guest.Email, updatedGuest.Email) }) @@ -170,11 +170,11 @@ func TestUpdateUserToRestrictedDomain(t *testing.T) { }) guest.Email = "asdf@bar.com" - _, err := th.App.UpdateUser(guest, false) + _, err := th.App.UpdateUser(th.Context, guest, false) require.NotNil(t, err) guest.Email = "asdf@foo.com" - updatedGuest, err := th.App.UpdateUser(guest, false) + updatedGuest, err := th.App.UpdateUser(th.Context, guest, false) require.Nil(t, err) require.Equal(t, guest.Email, updatedGuest.Email) }) @@ -189,7 +189,7 @@ func TestUpdateUser(t *testing.T) { t.Run("fails if the username matches a group name", func(t *testing.T) { user.Username = *group.Name - u, err := th.App.UpdateUser(user, false) + u, err := th.App.UpdateUser(th.Context, user, false) require.NotNil(t, err) require.Equal(t, "app.user.group_name_conflict", err.Id) require.Nil(t, u) @@ -215,7 +215,7 @@ func TestUpdateUserMissingFields(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { - _, err := th.App.UpdateUser(tc.input, false) + _, err := th.App.UpdateUser(th.Context, tc.input, false) if name == "no missing fields" { assert.Nil(t, err) @@ -517,7 +517,7 @@ func TestUpdateUserEmail(t *testing.T) { newEmail := th.MakeEmail() user.Email = newEmail - user2, appErr := th.App.UpdateUser(user, false) + user2, appErr := th.App.UpdateUser(th.Context, user, false) assert.Nil(t, appErr) assert.Equal(t, currentEmail, user2.Email) assert.True(t, user2.EmailVerified) @@ -525,7 +525,7 @@ func TestUpdateUserEmail(t *testing.T) { token, err := th.App.Srv().EmailService.CreateVerifyEmailToken(user2.Id, newEmail) assert.NoError(t, err) - appErr = th.App.VerifyEmailFromToken(token.Token) + appErr = th.App.VerifyEmailFromToken(th.Context, token.Token) assert.Nil(t, appErr) user2, appErr = th.App.GetUser(user2.Id) @@ -544,7 +544,7 @@ func TestUpdateUserEmail(t *testing.T) { newBotEmail := th.MakeEmail() botuser.Email = newBotEmail - botuser2, appErr := th.App.UpdateUser(&botuser, false) + botuser2, appErr := th.App.UpdateUser(th.Context, &botuser, false) assert.Nil(t, appErr) assert.Equal(t, botuser2.Email, newBotEmail) @@ -559,7 +559,7 @@ func TestUpdateUserEmail(t *testing.T) { newEmail := user2.Email user.Email = newEmail - user3, err := th.App.UpdateUser(user, false) + user3, err := th.App.UpdateUser(th.Context, user, false) require.NotNil(t, err) assert.Equal(t, err.Id, "app.user.save.email_exists.app_error") assert.Nil(t, user3) @@ -573,7 +573,7 @@ func TestUpdateUserEmail(t *testing.T) { newEmail := th.MakeEmail() user.Email = newEmail - user2, err := th.App.UpdateUser(user, false) + user2, err := th.App.UpdateUser(th.Context, user, false) assert.Nil(t, err) assert.Equal(t, newEmail, user2.Email) @@ -588,7 +588,7 @@ func TestUpdateUserEmail(t *testing.T) { newBotEmail := th.MakeEmail() botuser.Email = newBotEmail - botuser2, err := th.App.UpdateUser(&botuser, false) + botuser2, err := th.App.UpdateUser(th.Context, &botuser, false) assert.Nil(t, err) assert.Equal(t, botuser2.Email, newBotEmail) }) @@ -602,7 +602,7 @@ func TestUpdateUserEmail(t *testing.T) { newEmail := user2.Email user.Email = newEmail - user3, err := th.App.UpdateUser(user, false) + user3, err := th.App.UpdateUser(th.Context, user, false) require.NotNil(t, err) assert.Equal(t, err.Id, "app.user.save.email_exists.app_error") assert.Nil(t, user3) @@ -616,7 +616,7 @@ func TestUpdateUserEmail(t *testing.T) { // we update the email a first time and update. The first // token is sent with the email user.Email = th.MakeEmail() - _, appErr := th.App.UpdateUser(user, true) + _, appErr := th.App.UpdateUser(th.Context, user, true) require.Nil(t, appErr) tokens := []*model.Token{} @@ -632,7 +632,7 @@ func TestUpdateUserEmail(t *testing.T) { // time and another token gets sent. The first one should not // work anymore and the second should work properly user.Email = th.MakeEmail() - _, appErr = th.App.UpdateUser(user, true) + _, appErr = th.App.UpdateUser(th.Context, user, true) require.Nil(t, appErr) require.Eventually(t, func() bool { @@ -649,9 +649,9 @@ func TestUpdateUserEmail(t *testing.T) { _, err := th.App.Srv().Store.Token().GetByToken(firstToken.Token) require.Error(t, err) - require.NotNil(t, th.App.VerifyEmailFromToken(firstToken.Token)) - require.Nil(t, th.App.VerifyEmailFromToken(secondToken.Token)) - require.NotNil(t, th.App.VerifyEmailFromToken(firstToken.Token)) + require.NotNil(t, th.App.VerifyEmailFromToken(th.Context, firstToken.Token)) + require.Nil(t, th.App.VerifyEmailFromToken(th.Context, secondToken.Token)) + require.NotNil(t, th.App.VerifyEmailFromToken(th.Context, firstToken.Token)) }) } @@ -1096,7 +1096,7 @@ func TestPasswordRecovery(t *testing.T) { assert.Equal(t, th.BasicUser.Id, tokenData.UserId) assert.Equal(t, th.BasicUser.Email, tokenData.Email) - err = th.App.ResetPasswordFromToken(token.Token, "abcdefgh") + err = th.App.ResetPasswordFromToken(th.Context, token.Token, "abcdefgh") assert.Nil(t, err) }) @@ -1109,10 +1109,10 @@ func TestPasswordRecovery(t *testing.T) { }) th.BasicUser.Email = th.MakeEmail() - _, err = th.App.UpdateUser(th.BasicUser, false) + _, err = th.App.UpdateUser(th.Context, th.BasicUser, false) assert.Nil(t, err) - err = th.App.ResetPasswordFromToken(token.Token, "abcdefgh") + err = th.App.ResetPasswordFromToken(th.Context, token.Token, "abcdefgh") assert.NotNil(t, err) }) @@ -1120,7 +1120,7 @@ func TestPasswordRecovery(t *testing.T) { token, err := th.App.CreatePasswordRecoveryToken(th.BasicUser.Id, th.BasicUser.Email) assert.Nil(t, err) - err = th.App.resetPasswordFromToken(token.Token, "abcdefgh", model.GetMillis()) + err = th.App.resetPasswordFromToken(th.Context, token.Token, "abcdefgh", model.GetMillis()) assert.Nil(t, err) }) @@ -1128,7 +1128,7 @@ func TestPasswordRecovery(t *testing.T) { token, err := th.App.CreatePasswordRecoveryToken(th.BasicUser.Id, th.BasicUser.Email) assert.Nil(t, err) - err = th.App.resetPasswordFromToken(token.Token, "abcdefgh", model.GetMillisForTime(time.Now().Add(25*time.Hour))) + err = th.App.resetPasswordFromToken(th.Context, token.Token, "abcdefgh", model.GetMillisForTime(time.Now().Add(25*time.Hour))) assert.NotNil(t, err) }) @@ -1604,12 +1604,12 @@ func TestUpdateUserRolesWithUser(t *testing.T) { assert.Equal(t, user.Roles, model.SystemUserRoleId) // Upgrade to sysadmin. - user, err := th.App.UpdateUserRolesWithUser(user, model.SystemUserRoleId+" "+model.SystemAdminRoleId, false) + user, err := th.App.UpdateUserRolesWithUser(th.Context, user, model.SystemUserRoleId+" "+model.SystemAdminRoleId, false) require.Nil(t, err) assert.Equal(t, user.Roles, model.SystemUserRoleId+" "+model.SystemAdminRoleId) // Test bad role. - _, err = th.App.UpdateUserRolesWithUser(user, "does not exist", false) + _, err = th.App.UpdateUserRolesWithUser(th.Context, user, "does not exist", false) require.NotNil(t, err) } @@ -1636,7 +1636,7 @@ func TestPatchUser(t *testing.T) { defer th.App.PermanentDeleteUser(th.Context, testUser) t.Run("Patch with a username already exists", func(t *testing.T) { - _, err := th.App.PatchUser(testUser.Id, &model.UserPatch{ + _, err := th.App.PatchUser(th.Context, testUser.Id, &model.UserPatch{ Username: model.NewString(th.BasicUser.Username), }, true) @@ -1645,7 +1645,7 @@ func TestPatchUser(t *testing.T) { }) t.Run("Patch with a email already exists", func(t *testing.T) { - _, err := th.App.PatchUser(testUser.Id, &model.UserPatch{ + _, err := th.App.PatchUser(th.Context, testUser.Id, &model.UserPatch{ Email: model.NewString(th.BasicUser.Email), }, true) @@ -1654,7 +1654,7 @@ func TestPatchUser(t *testing.T) { }) t.Run("Patch username with a new username", func(t *testing.T) { - _, err := th.App.PatchUser(testUser.Id, &model.UserPatch{ + _, err := th.App.PatchUser(th.Context, testUser.Id, &model.UserPatch{ Username: model.NewString(model.NewId()), }, true) diff --git a/app/user_viewmembers_test.go b/app/user_viewmembers_test.go index 1c3e4309aa..055151b95a 100644 --- a/app/user_viewmembers_test.go +++ b/app/user_viewmembers_test.go @@ -20,23 +20,23 @@ func TestRestrictedViewMembers(t *testing.T) { user1 := th.CreateUser() user1.Nickname = "test user1" user1.Username = "test-user-1" - th.App.UpdateUser(user1, false) + th.App.UpdateUser(th.Context, user1, false) user2 := th.CreateUser() user2.Username = "test-user-2" user2.Nickname = "test user2" - th.App.UpdateUser(user2, false) + th.App.UpdateUser(th.Context, user2, false) user3 := th.CreateUser() user3.Username = "test-user-3" user3.Nickname = "test user3" - th.App.UpdateUser(user3, false) + th.App.UpdateUser(th.Context, user3, false) user4 := th.CreateUser() user4.Username = "test-user-4" user4.Nickname = "test user4" - th.App.UpdateUser(user4, false) + th.App.UpdateUser(th.Context, user4, false) user5 := th.CreateUser() user5.Username = "test-user-5" user5.Nickname = "test user5" - th.App.UpdateUser(user5, false) + th.App.UpdateUser(th.Context, user5, false) // user1 is member of all the channels and teams because is the creator th.BasicUser = user1 diff --git a/einterfaces/ldap.go b/einterfaces/ldap.go index 990a4fd98a..23e38405af 100644 --- a/einterfaces/ldap.go +++ b/einterfaces/ldap.go @@ -23,7 +23,7 @@ type LdapInterface interface { GetGroup(groupUID string) (*model.Group, *model.AppError) GetAllGroupsPage(page int, perPage int, opts model.LdapGroupSearchOpts) ([]*model.Group, int, *model.AppError) FirstLoginSync(c *request.Context, user *model.User, userAuthService, userAuthData, email string) *model.AppError - UpdateProfilePictureIfNecessary(model.User, model.Session) + UpdateProfilePictureIfNecessary(request.CTX, model.User, model.Session) GetADLdapIdFromSAMLId(authData string) string GetSAMLIdFromADLdapId(authData string) string GetVendorNameAndVendorVersion() (string, string) diff --git a/einterfaces/mocks/LdapInterface.go b/einterfaces/mocks/LdapInterface.go index cb3a3850a8..6c4b1ad25a 100644 --- a/einterfaces/mocks/LdapInterface.go +++ b/einterfaces/mocks/LdapInterface.go @@ -354,7 +354,7 @@ func (_m *LdapInterface) SwitchToLdap(userID string, ldapID string, ldapPassword return r0 } -// UpdateProfilePictureIfNecessary provides a mock function with given fields: _a0, _a1 -func (_m *LdapInterface) UpdateProfilePictureIfNecessary(_a0 model.User, _a1 model.Session) { - _m.Called(_a0, _a1) +// UpdateProfilePictureIfNecessary provides a mock function with given fields: _a0, _a1, _a2 +func (_m *LdapInterface) UpdateProfilePictureIfNecessary(_a0 request.CTX, _a1 model.User, _a2 model.Session) { + _m.Called(_a0, _a1, _a2) } diff --git a/i18n/en.json b/i18n/en.json index 6f1abff888..2cc65b6ab7 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -1857,10 +1857,6 @@ "id": "api.file.upload_file.incorrect_number_of_client_ids.app_error", "translation": "Unable to upload file(s). Have {{.NumClientIds}} client_ids for {{.NumFiles}} files." }, - { - "id": "api.file.upload_file.incorrect_number_of_files.app_error", - "translation": "Unable to upload files. Incorrect number of files specified." - }, { "id": "api.file.upload_file.large_image.app_error", "translation": "File above maximum dimensions could not be uploaded: {{.Filename}}" @@ -2237,6 +2233,10 @@ "id": "api.post.check_for_out_of_channel_mentions.message.one", "translation": "@{{.Username}} did not get notified by this mention because they are not in the channel." }, + { + "id": "api.post.compliance_enabled.join_channel_to_view_post", + "translation": "Due to compliance rules configured on this instance the channel must be joined before its posts can be read." + }, { "id": "api.post.create_post.can_not_post_to_deleted.error", "translation": "Can not post to deleted channel." @@ -5917,7 +5917,7 @@ }, { "id": "app.post_reminder_dm", - "translation": "Hi there, you asked me to remind you about {{.SiteURL}}/{{.TeamName}}/pl/{{.PostId}} by @{{.Username}}" + "translation": "Hi there, here's your reminder about this message from @{{.Username}}: {{.SiteURL}}/{{.TeamName}}/pl/{{.PostId}}" }, { "id": "app.preference.delete.app_error", diff --git a/model/cloud.go b/model/cloud.go index 46d7b7baad..d000c2a73b 100644 --- a/model/cloud.go +++ b/model/cloud.go @@ -105,6 +105,10 @@ type ValidateBusinessEmailRequest struct { Email string `json:"email"` } +type ValidateBusinessEmailResponse struct { + IsValid bool `json:"is_valid"` +} + // CloudCustomerInfo represents editable info of a customer. type CloudCustomerInfo struct { Name string `json:"name"` diff --git a/model/utils.go b/model/utils.go index 82c5e0953a..8d93015c57 100644 --- a/model/utils.go +++ b/model/utils.go @@ -10,7 +10,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "net" "net/http" "net/mail" @@ -218,10 +217,32 @@ type AppError struct { Where string `json:"-"` // The function where it happened in the form of Struct.Func IsOAuth bool `json:"is_oauth,omitempty"` // Whether the error is OAuth specific params map[string]any + wrapped error } func (er *AppError) Error() string { - return er.Where + ": " + er.Message + ", " + er.DetailedError + var sb strings.Builder + + // render the error information + sb.WriteString(er.Where) + sb.WriteString(": ") + sb.WriteString(er.Message) + + // only render the detailed error when it's present + if er.DetailedError != "" { + sb.WriteString(", ") + sb.WriteString(er.DetailedError) + } + + // render all wrapped errors + err := er.wrapped + for err != nil { + sb.WriteString(", ") + sb.WriteString(err.Error()) + err = errors.Unwrap(err) + } + + return sb.String() } func (er *AppError) Translate(T i18n.TranslateFunc) { @@ -249,10 +270,19 @@ func (er *AppError) ToJSON() string { return string(b) } +func (er *AppError) Unwrap() error { + return er.wrapped +} + +func (er *AppError) Wrap(err error) *AppError { + er.wrapped = err + return er +} + // AppErrorFromJSON will decode the input and return an AppError func AppErrorFromJSON(data io.Reader) *AppError { str := "" - bytes, rerr := ioutil.ReadAll(data) + bytes, rerr := io.ReadAll(data) if rerr != nil { str = rerr.Error() } else { @@ -269,14 +299,15 @@ func AppErrorFromJSON(data io.Reader) *AppError { } func NewAppError(where string, id string, params map[string]any, details string, status int) *AppError { - ap := &AppError{} - ap.Id = id - ap.params = params - ap.Message = id - ap.Where = where - ap.DetailedError = details - ap.StatusCode = status - ap.IsOAuth = false + ap := &AppError{ + Id: id, + params: params, + Message: id, + Where: where, + DetailedError: details, + StatusCode: status, + IsOAuth: false, + } ap.Translate(translateFunc) return ap } diff --git a/model/utils_test.go b/model/utils_test.go index b81556d9d5..9ac33e39c1 100644 --- a/model/utils_test.go +++ b/model/utils_test.go @@ -85,6 +85,33 @@ func TestAppErrorJunk(t *testing.T) { require.Equal(t, "body: This is a broken test", rerr.DetailedError) } +func TestAppErrorRender(t *testing.T) { + t.Run("Minimal", func(t *testing.T) { + aerr := NewAppError("here", "message", nil, "", http.StatusTeapot) + assert.EqualError(t, aerr, "here: message") + }) + + t.Run("Detailed", func(t *testing.T) { + aerr := NewAppError("here", "message", nil, "details", http.StatusTeapot) + assert.EqualError(t, aerr, "here: message, details") + }) + + t.Run("Wrapped", func(t *testing.T) { + aerr := NewAppError("here", "message", nil, "", http.StatusTeapot).Wrap(fmt.Errorf("my error")) + assert.EqualError(t, aerr, "here: message, my error") + }) + + t.Run("WrappedMultiple", func(t *testing.T) { + aerr := NewAppError("here", "message", nil, "", http.StatusTeapot).Wrap(fmt.Errorf("my error (%w)", fmt.Errorf("inner error"))) + assert.EqualError(t, aerr, "here: message, my error (inner error), inner error") + }) + + t.Run("DetailedWrappedMultiple", func(t *testing.T) { + aerr := NewAppError("here", "message", nil, "details", http.StatusTeapot).Wrap(fmt.Errorf("my error (%w)", fmt.Errorf("inner error"))) + assert.EqualError(t, aerr, "here: message, details, my error (inner error), inner error") + }) +} + func TestCopyStringMap(t *testing.T) { itemKey := "item1" originalMap := make(map[string]string) diff --git a/product/api.go b/product/api.go index 539b497a31..33da6c5899 100644 --- a/product/api.go +++ b/product/api.go @@ -80,7 +80,7 @@ type LicenseService interface { // The service shall be registered via app.UserKey service key. type UserService interface { GetUser(userID string) (*model.User, *model.AppError) - UpdateUser(user *model.User, sendNotifications bool) (*model.User, *model.AppError) + UpdateUser(c request.CTX, user *model.User, sendNotifications bool) (*model.User, *model.AppError) GetUserByEmail(email string) (*model.User, *model.AppError) GetUserByUsername(username string) (*model.User, *model.AppError) GetUsersFromProfiles(options *model.UserGetOptions) ([]*model.User, *model.AppError) diff --git a/shared/filestore/s3store.go b/shared/filestore/s3store.go index 229c3537a5..06d6bec7ed 100644 --- a/shared/filestore/s3store.go +++ b/shared/filestore/s3store.go @@ -4,6 +4,7 @@ package filestore import ( + "bytes" "context" "crypto/tls" "io" @@ -365,7 +366,13 @@ func (b *S3FileBackend) WriteFile(fr io.Reader, path string) (int64, error) { ctx, cancel := context.WithTimeout(context.Background(), b.timeout) defer cancel() options := s3PutOptions(b.encrypt, contentType) - info, err := b.client.PutObject(ctx, b.bucket, path, fr, -1, options) + + objSize := -1 + if buf, ok := fr.(*bytes.Buffer); ok { + objSize = buf.Len() + } + + info, err := b.client.PutObject(ctx, b.bucket, path, fr, int64(objSize), options) if err != nil { return info.Size, errors.Wrapf(err, "unable write the data in the file %s", path) } @@ -393,7 +400,11 @@ func (b *S3FileBackend) AppendFile(fr io.Reader, path string) (int64, error) { partName := fp + ".part" ctx2, cancel2 := context.WithTimeout(context.Background(), b.timeout) defer cancel2() - info, err := b.client.PutObject(ctx2, b.bucket, partName, fr, -1, options) + objSize := -1 + if buf, ok := fr.(*bytes.Buffer); ok { + objSize = buf.Len() + } + info, err := b.client.PutObject(ctx2, b.bucket, partName, fr, int64(objSize), options) if err != nil { return 0, errors.Wrapf(err, "unable append the data in the file %s", path) } diff --git a/shared/mail/inbucket.go b/shared/mail/inbucket.go index 42805f69a6..3bd8134ba6 100644 --- a/shared/mail/inbucket.go +++ b/shared/mail/inbucket.go @@ -74,11 +74,8 @@ func GetMailBox(email string) (results JSONMessageHeaderInbucket, err error) { var record JSONMessageHeaderInbucket err = json.NewDecoder(resp.Body).Decode(&record) - switch { - case err == io.EOF: - return nil, fmt.Errorf("error: %s", err) - case err != nil: - return nil, fmt.Errorf("error: %s", err) + if err != nil { + return nil, fmt.Errorf("error: %w", err) } if len(record) == 0 { return nil, fmt.Errorf("no mailbox") diff --git a/store/storetest/team_store.go b/store/storetest/team_store.go index 3df3096336..ad9bcb4f6a 100644 --- a/store/storetest/team_store.go +++ b/store/storetest/team_store.go @@ -1385,7 +1385,7 @@ func testTeamSaveMember(t *testing.T, ss store.Store) { member := &model.TeamMember{TeamId: "wrong", UserId: u1.Id} _, nErr := ss.Team().SaveMember(member, -1) require.Error(t, nErr) - require.Equal(t, "TeamMember.IsValid: model.team_member.is_valid.team_id.app_error, ", nErr.Error()) + require.Equal(t, "TeamMember.IsValid: model.team_member.is_valid.team_id.app_error", nErr.Error()) }) t.Run("too many members", func(t *testing.T) { @@ -1726,7 +1726,7 @@ func testTeamSaveMultipleMembers(t *testing.T, ss store.Store) { m2 := &model.TeamMember{TeamId: model.NewId(), UserId: u2.Id} _, nErr := ss.Team().SaveMultipleMembers([]*model.TeamMember{m1, m2}, -1) require.Error(t, nErr) - require.Equal(t, "TeamMember.IsValid: model.team_member.is_valid.team_id.app_error, ", nErr.Error()) + require.Equal(t, "TeamMember.IsValid: model.team_member.is_valid.team_id.app_error", nErr.Error()) }) t.Run("too many members in one team", func(t *testing.T) { diff --git a/testlib/assertions.go b/testlib/assertions.go index 5b6afd7a97..a7ec27cdaa 100644 --- a/testlib/assertions.go +++ b/testlib/assertions.go @@ -20,6 +20,7 @@ func AssertLog(t *testing.T, logs io.Reader, level, message string) { if err := dec.Decode(&log); err == io.EOF { break } else if err != nil { + t.Logf("Error decoding log entry: %s", err) continue } @@ -42,6 +43,7 @@ func AssertNoLog(t *testing.T, logs io.Reader, level, message string) { if err := dec.Decode(&log); err == io.EOF { break } else if err != nil { + t.Logf("Error decoding log entry: %s", err) continue } diff --git a/web/context.go b/web/context.go index c573e8c105..de02d18c03 100644 --- a/web/context.go +++ b/web/context.go @@ -221,6 +221,10 @@ func (c *Context) SetInvalidParam(parameter string) { c.Err = NewInvalidParamError(parameter) } +func (c *Context) SetInvalidParamWithErr(parameter string, err error) { + c.Err = NewInvalidParamError(parameter).Wrap(err) +} + func (c *Context) SetInvalidURLParam(parameter string) { c.Err = NewInvalidURLParamError(parameter) } @@ -269,10 +273,12 @@ func NewInvalidParamError(parameter string) *model.AppError { err := model.NewAppError("Context", "api.context.invalid_body_param.app_error", map[string]any{"Name": parameter}, "", http.StatusBadRequest) return err } + func NewInvalidURLParamError(parameter string) *model.AppError { err := model.NewAppError("Context", "api.context.invalid_url_param.app_error", map[string]any{"Name": parameter}, "", http.StatusBadRequest) return err } + func NewServerBusyError() *model.AppError { err := model.NewAppError("Context", "api.context.server_busy.app_error", nil, "", http.StatusServiceUnavailable) return err