diff --git a/server/channels/api4/user_test.go b/server/channels/api4/user_test.go index 127aa75a9ed..b553ab747d9 100644 --- a/server/channels/api4/user_test.go +++ b/server/channels/api4/user_test.go @@ -6906,6 +6906,34 @@ func TestDemoteUserToGuest(t *testing.T) { require.NoError(t, err) }) + t.Run("cannot demote bot account", func(t *testing.T) { + th.App.Srv().SetLicense(model.NewTestLicense("guest_accounts")) + + prevBotCreation := *th.App.Config().ServiceSettings.EnableBotAccountCreation + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.ServiceSettings.EnableBotAccountCreation = true + }) + defer th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.ServiceSettings.EnableBotAccountCreation = prevBotCreation + }) + + createdBot, resp, err := th.SystemAdminClient.CreateBot(context.Background(), &model.Bot{ + Username: "botdemote" + model.NewId(), + DisplayName: "Demote Test Bot", + Description: "test", + }) + require.NoError(t, err) + CheckCreatedStatus(t, resp) + defer func() { + appErr := th.App.PermanentDeleteBot(th.Context, createdBot.UserId) + require.Nil(t, appErr) + }() + + demoteResp, err := th.SystemAdminClient.DemoteUserToGuest(context.Background(), createdBot.UserId) + CheckBadRequestStatus(t, demoteResp) + CheckErrorID(t, err, "api.user.demote_user_to_guest.bot_not_allowed.app_error") + }) + th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) { _, _, err := c.GetUser(context.Background(), user.Id, "") require.NoError(t, err) diff --git a/server/channels/app/user.go b/server/channels/app/user.go index 325e3bdd1a1..22060540f07 100644 --- a/server/channels/app/user.go +++ b/server/channels/app/user.go @@ -2742,6 +2742,10 @@ func (a *App) PromoteGuestToUser(rctx request.CTX, user *model.User, requestorId // DemoteUserToGuest Convert user's roles and all his membership's roles from // regular user roles to guest roles. func (a *App) DemoteUserToGuest(rctx request.CTX, user *model.User) *model.AppError { + if user.IsBot { + return model.NewAppError("DemoteUserToGuest", "api.user.demote_user_to_guest.bot_not_allowed.app_error", nil, "", http.StatusBadRequest) + } + demotedUser, nErr := a.ch.srv.userService.DemoteUserToGuest(user) a.InvalidateCacheForUser(user.Id) if nErr != nil { diff --git a/server/channels/app/user_test.go b/server/channels/app/user_test.go index 88b7b19461e..f82cd9915c6 100644 --- a/server/channels/app/user_test.go +++ b/server/channels/app/user_test.go @@ -2012,6 +2012,18 @@ func TestDemoteUserToGuest(t *testing.T) { mainHelper.Parallel(t) th := Setup(t).InitBasic(t) + t.Run("Must reject bot user", func(t *testing.T) { + bot := th.CreateBot(t) + user, err := th.App.GetUser(bot.UserId) + require.Nil(t, err) + require.True(t, user.IsBot) + + appErr := th.App.DemoteUserToGuest(th.Context, user) + require.NotNil(t, appErr) + assert.Equal(t, "api.user.demote_user_to_guest.bot_not_allowed.app_error", appErr.Id) + assert.Equal(t, http.StatusBadRequest, appErr.StatusCode) + }) + t.Run("Must invalidate channel stats cache when demoting a user", func(t *testing.T) { user := th.CreateUser(t) require.Equal(t, "system_user", user.Roles) diff --git a/server/i18n/en.json b/server/i18n/en.json index 6959216da71..1f58855805c 100644 --- a/server/i18n/en.json +++ b/server/i18n/en.json @@ -4654,6 +4654,10 @@ "id": "api.user.demote_user_to_guest.already_guest.app_error", "translation": "Unable to convert the user to guest because is already a guest." }, + { + "id": "api.user.demote_user_to_guest.bot_not_allowed.app_error", + "translation": "Bot accounts cannot be converted to guest accounts." + }, { "id": "api.user.email_to_ldap.not_available.app_error", "translation": "AD/LDAP not available on this server."