fix(gateway): READY отдаёт права участника вместо пустого списка
Снапшот READY инициализировал my_permissions пустым списком и нигде его не заполнял, поэтому у всех — включая владельца сервера — клиент выключал композер («В эту комнату нельзя писать»), прятал шестерёнку, приглашения и кнопку саундборда: состав прав в снапшоте не совпадал с REST (GET /users/@me/guilds отдавал полный список). Права считает тот же движок и тот же кэш, что REST (permissions.Calculator, переданный в NewSnapshot), а инстанс-админ получает максимальный набор даже на чужом сервере, где он не участник (AGENT.md 7.19, 11.6). Тесты: TestReadyCarriesMyPermissions (непустые права роли по умолчанию, VIEW_CHANNEL/SEND_MESSAGES и согласие с can_send комнаты) и TestReadyGivesInstanceAdminAllPermissions.
This commit is contained in:
@@ -140,7 +140,7 @@ func (s *Snapshot) buildGuild(ctx context.Context, guild store.Guild, user *stor
|
||||
Roles: []ReadyRole{},
|
||||
MemberIDs: []string{},
|
||||
MyRoles: []string{},
|
||||
MyPerms: []string{},
|
||||
MyPerms: readyPermissions(resolved),
|
||||
Emojis: []ReadyEmoji{},
|
||||
VoiceStates: []ReadyVoiceState{},
|
||||
Sounds: []ReadySound{},
|
||||
@@ -257,6 +257,18 @@ func (s *Snapshot) buildGuild(ctx context.Context, guild store.Guild, user *stor
|
||||
return readyGuild, nil
|
||||
}
|
||||
|
||||
// readyPermissions отдаёт права пользователя на сервере списком имён — тем же
|
||||
// движком и в том же виде, что REST (`permissions.Names`). Без них клиент
|
||||
// выключал композер и прятал управление сервером (AGENT.md 11.6).
|
||||
func readyPermissions(resolved permissions.Resolved) []string {
|
||||
// У инстанс-админа права максимальные на любом сервере, включая чужой, где
|
||||
// он не участник (AGENT.md 7.19): в маске прав роли их нет.
|
||||
if resolved.IsInstanceAdmin {
|
||||
return permissions.Names(permissions.AllPermissions)
|
||||
}
|
||||
return permissions.Names(resolved.Guild)
|
||||
}
|
||||
|
||||
func channelPayload(channel store.Channel, canSend, canConnect bool) ReadyChannel {
|
||||
payload := ReadyChannel{
|
||||
ID: formatID(channel.ID),
|
||||
|
||||
Reference in New Issue
Block a user