Files
mattermost/server
44c0490c7c Prevent system-owned bots from being disabled (#37200)
* Prevent system-owned bots from being disabled

System-owned bots (system-bot, content-review) could be disabled either
directly via the API or via the owner-deactivation path when
DisableBotsWhenOwnerIsDeactivated=true. Once disabled, they never
self-healed, silently breaking post reminders, reports, and channel
notifications.

- Add model.ProtectedBotUsernames and remove the dead
  BotWarnMetricBotUsername constant.
- Guard UpdateBotActive so protected bots cannot be disabled (403),
  covering both the API and disableUserBots paths.
- Auto-heal the system bot in GetOrCreateSystemOwnedBot by fetching
  including deleted and re-enabling if disabled.
- Hide the Edit and Disable controls for protected bots in the System
  Console bot list.

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Strengthen tests for protected system bots

- Parameterize the app-layer guard test over both protected usernames
  (system-bot and content-review).
- Assert the underlying user is also reactivated by the auto-heal path.
- Drive the owner-deactivation test through the real UpdateActive path and
  add a non-protected bot to prove the batch keeps disabling other bots.
- Add an API-layer test asserting a 403 when disabling the system bot.
- Make the webapp recovery test click Enable and assert the action fires.

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Address CodeRabbit feedback on protected bot reactivation

- Add reactivateProtectedBot to bypass active-user limit checks when
  auto-healing or re-enabling disabled system-owned bots
- Fail closed on bot store lookup errors in UpdateBotActive before
  mutating user state

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Fix govet shadow lint in reactivateProtectedBot

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Update unknown bot test for bot-first lookup in UpdateBotActive

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Address PR feedback: DRY protected bot reactivation, range over ProtectedBotUsernames, label system bots as Managed by Mattermost

* Refactor UpdateActive to share inner updateActive with protected bot reactivation

* Address PR feedback: remove user-limit bypass for bot activation

Bot accounts are excluded from the active-user/license counts (User().Count
defaults to IncludeBotAccounts=false), so the dedicated bypass path was guarding
a case that cannot occur. Revert the UpdateActive/updateActive split and the
protected-bot branch in UpdateBotActive; bot (re)activation goes through the
normal UpdateActive path again.

* Replace hardcoded webapp protected-bot list with server-driven system_owned field

Addresses marianunez's review comment: the webapp kept its own copy of the
protected bot usernames (system-bot, content-review), duplicating
model.ProtectedBotUsernames and risking silent drift if a new system-owned
bot is added server-side without updating the client list.

model.Bot now computes IsSystemOwned() from ProtectedBotUsernames and
serializes it as system_owned via a custom MarshalJSON, so the webapp reads
it directly off the bot instead of matching usernames itself.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2026-08-15 08:12:58 +02:00
..
2023-03-22 17:22:27 -04:00
2023-03-22 17:22:27 -04:00
2023-03-22 17:22:27 -04:00
2023-03-22 17:22:27 -04:00
2024-05-15 12:05:13 -03:00