feat(moderation): баны сервера, тайм-ауты и фильтры журнала аудита
Фаза 4 (AGENT.md 7.17, 7.18): модерация участников.
- миграция 00011: таблица `guild_bans` (бан переживает исключение участника);
- `PUT /guilds/{id}/bans/{user_id}` — бан с причиной и права `BAN_MEMBERS`:
исключает участника, отключает его от голосовой комнаты, пишет системное
сообщение, аудит и события `MEMBER_REMOVE`/`GUILD_DELETE`;
- `DELETE /guilds/{id}/bans/{user_id}` — снятие бана, `GET .../bans` — список
с автором и причиной (только модераторам);
- вход по приглашению для забаненного отклоняется с `guild.banned`;
- тайм-аут уже был в схеме, но не работал: кэш прав комнат не сбрасывался при
изменениях сервера, поэтому участник с тайм-аутом продолжал писать. Ключ
кэша комнат теперь включает сервер, `InvalidateGuild` чистит и его;
- тайм-аут уходит в `MEMBER_UPDATE` (и снимается событием), истёкшие
тайм-ауты не показываются в профиле участника;
- журнал аудита получил фильтры `action`, `actor_id`, `target_id`, `before_id`;
- тесты: полный цикл бана (включая запрет входа и разбан), права и иерархия,
блокировка сообщений тайм-аутом, запрет тайм-аута на себя, фильтры аудита.
This commit is contained in:
@@ -8,7 +8,7 @@ import (
|
||||
// Channel вычисляет права пользователя в конкретной комнате: базовые права
|
||||
// сервера, затем оверрайды ролей, затем оверрайд пользователя (AGENT.md 6.2).
|
||||
func (c *Calculator) Channel(ctx context.Context, guildID, channelID, userID uint64, instanceAdmin bool) (Resolved, error) {
|
||||
if cached, ok := c.cache.GetChannel(channelID, userID); ok {
|
||||
if cached, ok := c.cache.GetChannel(guildID, channelID, userID); ok {
|
||||
cached.IsInstanceAdmin = instanceAdmin
|
||||
return cached, nil
|
||||
}
|
||||
@@ -20,11 +20,11 @@ func (c *Calculator) Channel(ctx context.Context, guildID, channelID, userID uin
|
||||
resolved.Channel = resolved.Guild
|
||||
if !resolved.IsMember && !resolved.IsInstanceAdmin {
|
||||
// Не участник не видит ничего, даже если есть персональный оверрайд.
|
||||
c.cache.PutChannel(channelID, userID, resolved)
|
||||
c.cache.PutChannel(guildID, channelID, userID, resolved)
|
||||
return resolved, nil
|
||||
}
|
||||
if resolved.IsInstanceAdmin || resolved.Guild.Has(Administrator) {
|
||||
c.cache.PutChannel(channelID, userID, resolved)
|
||||
c.cache.PutChannel(guildID, channelID, userID, resolved)
|
||||
return resolved, nil
|
||||
}
|
||||
|
||||
@@ -78,6 +78,6 @@ func (c *Calculator) Channel(ctx context.Context, guildID, channelID, userID uin
|
||||
}
|
||||
}
|
||||
resolved.Channel = (computed &^ userDeny) | userAllow
|
||||
c.cache.PutChannel(channelID, userID, resolved)
|
||||
c.cache.PutChannel(guildID, channelID, userID, resolved)
|
||||
return resolved, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user