[GH-22254] check if bot user exists (#26545)

Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Anna Os 2024-04-10 10:06:08 +02:00 committed by GitHub
parent db2cfe953b
commit 1806ba2cc7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 94 additions and 17 deletions

View File

@ -33,15 +33,17 @@ func (a *App) EnsureBot(rctx request.CTX, pluginID string, bot *model.Bot) (stri
return "", errors.New("passed a bot with no username") return "", errors.New("passed a bot with no username")
} }
botIDBytes, err := a.GetPluginKey(pluginID, botUserKey) botIDBytes, appErr := a.GetPluginKey(pluginID, botUserKey)
if err != nil { if appErr != nil {
return "", err return "", appErr
} }
// If the bot has already been created, use it // If the bot has already been created, check whether it still exists and use it
if botIDBytes != nil { if botIDBytes != nil {
botID := string(botIDBytes) botID := string(botIDBytes)
if _, appErr = a.GetBot(rctx, botID, true); appErr != nil {
rctx.Logger().Debug("Unable to get bot.", mlog.String("bot_id", botID), mlog.Err(appErr))
} else {
// ensure existing bot is synced with what is being created // ensure existing bot is synced with what is being created
botPatch := &model.BotPatch{ botPatch := &model.BotPatch{
Username: &bot.Username, Username: &bot.Username,
@ -49,18 +51,19 @@ func (a *App) EnsureBot(rctx request.CTX, pluginID string, bot *model.Bot) (stri
Description: &bot.Description, Description: &bot.Description,
} }
if _, err = a.PatchBot(rctx, botID, botPatch); err != nil { if _, appErr = a.PatchBot(rctx, botID, botPatch); appErr != nil {
return "", fmt.Errorf("failed to patch bot: %w", err) return "", fmt.Errorf("failed to patch bot: %w", appErr)
} }
return botID, nil return botID, nil
} }
}
// Check for an existing bot user with that username. If one exists, then use that. // Check for an existing bot user with that username. If one exists, then use that.
if user, appErr := a.GetUserByUsername(bot.Username); appErr == nil && user != nil { if user, appErr := a.GetUserByUsername(bot.Username); appErr == nil && user != nil {
if user.IsBot { if user.IsBot {
if appErr := a.SetPluginKey(pluginID, botUserKey, []byte(user.Id)); appErr != nil { if appErr := a.SetPluginKey(pluginID, botUserKey, []byte(user.Id)); appErr != nil {
return "", fmt.Errorf("failed to set plugin key: %w", err) return "", fmt.Errorf("failed to set plugin key: %w", appErr)
} }
} else { } else {
rctx.Logger().Error("Plugin attempted to use an account that already exists. Convert user to a bot "+ rctx.Logger().Error("Plugin attempted to use an account that already exists. Convert user to a bot "+
@ -82,7 +85,7 @@ func (a *App) EnsureBot(rctx request.CTX, pluginID string, bot *model.Bot) (stri
} }
if appErr := a.SetPluginKey(pluginID, botUserKey, []byte(createdBot.UserId)); appErr != nil { if appErr := a.SetPluginKey(pluginID, botUserKey, []byte(createdBot.UserId)); appErr != nil {
return "", fmt.Errorf("failed to set plugin key: %w", err) return "", fmt.Errorf("failed to set plugin key: %w", appErr)
} }
return createdBot.UserId, nil return createdBot.UserId, nil

View File

@ -112,6 +112,80 @@ func TestCreateBot(t *testing.T) {
}) })
} }
func TestEnsureBot(t *testing.T) {
t.Run("ensure bot should pass if already exist bot user", func(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
pluginId := "pluginId"
appErr := th.App.SetPluginKey(pluginId, "key", []byte("test"))
require.Nil(t, appErr)
botID1, err := th.App.EnsureBot(th.Context, pluginId, &model.Bot{
Username: "username",
Description: "a bot",
OwnerId: th.BasicUser.Id,
})
require.NoError(t, err)
bot, appErr := th.App.GetBot(th.Context, botID1, true)
require.Nil(t, appErr)
assert.Equal(t, "username", bot.Username)
assert.Equal(t, "a bot", bot.Description)
botID2, err := th.App.EnsureBot(th.Context, pluginId, &model.Bot{
Username: "another_username",
Description: "another bot",
OwnerId: th.BasicUser.Id,
})
require.NoError(t, err)
assert.Equal(t, botID1, botID2)
bot, appErr = th.App.GetBot(th.Context, botID2, true)
require.Nil(t, appErr)
assert.Equal(t, "another_username", bot.Username)
assert.Equal(t, "another bot", bot.Description)
})
t.Run("ensure bot should pass even after delete bot user", func(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
pluginId := "pluginId"
appErr := th.App.SetPluginKey(pluginId, "key", []byte("test"))
require.Nil(t, appErr)
initialBot := model.Bot{
Username: "username",
Description: "a bot",
OwnerId: th.BasicUser.Id,
}
botID1, err := th.App.EnsureBot(th.Context, pluginId, &initialBot)
require.NoError(t, err)
bot, appErr := th.App.GetBot(th.Context, botID1, true)
require.Nil(t, appErr)
assert.Equal(t, "username", bot.Username)
assert.Equal(t, "a bot", bot.Description)
err = th.App.Srv().Store().User().PermanentDelete(initialBot.UserId)
require.NoError(t, err)
botID2, err := th.App.EnsureBot(th.Context, pluginId, &model.Bot{
Username: "another_username",
Description: "another bot",
OwnerId: th.BasicUser.Id,
})
require.NoError(t, err)
assert.NotEqual(t, botID1, botID2)
bot, appErr = th.App.GetBot(th.Context, botID2, true)
require.Nil(t, appErr)
assert.Equal(t, "another_username", bot.Username)
assert.Equal(t, "another bot", bot.Description)
})
}
func TestPatchBot(t *testing.T) { func TestPatchBot(t *testing.T) {
t.Run("invalid patch for user", func(t *testing.T) { t.Run("invalid patch for user", func(t *testing.T) {
th := Setup(t).InitBasic() th := Setup(t).InitBasic()