chatinfo: handle forbidden channels/chats without panicking

Signed-off-by: Sumner Evans <sumner.evans@automattic.com>
This commit is contained in:
Sumner Evans
2024-10-24 10:45:32 -06:00
parent 4bdd415dbe
commit 229efdd487
2 changed files with 56 additions and 26 deletions
+22 -13
View File
@@ -6,6 +6,7 @@ import (
"time" "time"
"github.com/gotd/td/tg" "github.com/gotd/td/tg"
"github.com/rs/zerolog"
"go.mau.fi/util/ptr" "go.mau.fi/util/ptr"
"maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2"
"maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/database"
@@ -285,7 +286,7 @@ func (t *TelegramClient) GetChatInfo(ctx context.Context, portal *bridgev2.Porta
// TODO save emojiset? // TODO save emojiset?
chatInfo.Members.IsFull = false chatInfo.Members.IsFull = false
chatInfo.Members.PowerLevels = t.getGroupChatPowerLevels(fullChat.GetChats()[0]) chatInfo.Members.PowerLevels = t.getGroupChatPowerLevels(ctx, fullChat.GetChats()[0])
if !portal.Metadata.(*PortalMetadata).IsSuperGroup { if !portal.Metadata.(*PortalMetadata).IsSuperGroup {
// Add the channel user // Add the channel user
sender := ids.MakeChannelUserID(id) sender := ids.MakeChannelUserID(id)
@@ -387,22 +388,30 @@ func (t *TelegramClient) getDMPowerLevels(ghost *bridgev2.Ghost) *bridgev2.Power
return &plo return &plo
} }
func (t *TelegramClient) getGroupChatPowerLevels(entity tg.ChatClass) *bridgev2.PowerLevelOverrides { func (t *TelegramClient) getGroupChatPowerLevels(ctx context.Context, entity tg.ChatClass) *bridgev2.PowerLevelOverrides {
log := zerolog.Ctx(ctx).With().
Str("action", "get_group_chat_power_levels").
Logger()
dbrAble, ok := entity.(interface { dbrAble, ok := entity.(interface {
GetDefaultBannedRights() (tg.ChatBannedRights, bool) GetDefaultBannedRights() (tg.ChatBannedRights, bool)
}) })
if !ok { var dbr tg.ChatBannedRights
panic(fmt.Sprintf("unsupported chat type %T", entity)) if ok {
} dbr, ok = dbrAble.GetDefaultBannedRights()
dbr, ok := dbrAble.GetDefaultBannedRights() if !ok {
if !ok { dbr = tg.ChatBannedRights{
dbr = tg.ChatBannedRights{ InviteUsers: true,
InviteUsers: true, ChangeInfo: true,
ChangeInfo: true, PinMessages: true,
PinMessages: true, SendStickers: false,
SendStickers: false, SendMessages: false,
SendMessages: false, }
} }
} else {
log.Error().
Type("entity_type", entity).
Msg("couldn't get default banned rights from entity, assuming you don't have any rights")
} }
return t.getPowerLevelOverridesFromBannedRights(entity, dbr) return t.getPowerLevelOverridesFromBannedRights(entity, dbr)
} }
+34 -13
View File
@@ -110,7 +110,7 @@ func (t *TelegramClient) handleDialogs(ctx context.Context, dialogs tg.ModifiedM
UserLocal: &bridgev2.UserLocalPortalInfo{}, UserLocal: &bridgev2.UserLocalPortalInfo{},
Members: &bridgev2.ChatMemberList{ Members: &bridgev2.ChatMemberList{
MemberMap: map[networkid.UserID]bridgev2.ChatMember{ MemberMap: map[networkid.UserID]bridgev2.ChatMember{
t.userID: bridgev2.ChatMember{ t.userID: {
EventSender: t.mySender(), EventSender: t.mySender(),
Membership: event.MembershipJoin, Membership: event.MembershipJoin,
}, },
@@ -122,7 +122,7 @@ func (t *TelegramClient) handleDialogs(ctx context.Context, dialogs tg.ModifiedM
case *tg.PeerUser: case *tg.PeerUser:
userID := ids.MakeUserID(peer.UserID) userID := ids.MakeUserID(peer.UserID)
if users[userID].(*tg.User).GetDeleted() { if users[userID].(*tg.User).GetDeleted() {
log.Debug().Msg("Not syncing portal because user is deleted") log.Debug().Int64("user_id", peer.UserID).Msg("Not syncing portal because user is deleted")
continue continue
} }
chatInfo.Members.MemberMap[userID] = bridgev2.ChatMember{ chatInfo.Members.MemberMap[userID] = bridgev2.ChatMember{
@@ -130,31 +130,52 @@ func (t *TelegramClient) handleDialogs(ctx context.Context, dialogs tg.ModifiedM
Membership: event.MembershipJoin, Membership: event.MembershipJoin,
} }
case *tg.PeerChat: case *tg.PeerChat:
chatInfo.Members.PowerLevels = t.getGroupChatPowerLevels(chats[peer.ChatID]) chat := chats[peer.ChatID]
chatInfo.Name = &chats[peer.ChatID].(*tg.Chat).Title if chat.TypeID() == tg.ChatForbiddenTypeID {
case *tg.PeerChannel: log.Debug().
channel, ok := chats[peer.ChannelID].(*tg.Channel) Int64("chat_id", peer.ChatID).
if !ok { Msg("Not syncing portal because chat is forbidden")
log.Error().Type("channel", chats[peer.ChannelID]).Msg("Failed to cast chat to channel") continue
} else if chat.TypeID() != tg.ChatTypeID {
log.Debug().
Int64("chat_id", peer.ChatID).
Type("chat_type", chat).
Msg("Not syncing portal because chat type is unsupported")
continue continue
} }
chatInfo.Name = &channel.Title chatInfo.Members.PowerLevels = t.getGroupChatPowerLevels(ctx, chat)
chatInfo.Members.PowerLevels = t.getGroupChatPowerLevels(channel) chatInfo.Name = &chat.(*tg.Chat).Title
case *tg.PeerChannel:
channel := chats[peer.ChannelID]
if channel.TypeID() == tg.ChannelForbiddenTypeID {
log.Debug().
Int64("channel_id", peer.ChannelID).
Msg("Not syncing portal because channel is forbidden")
continue
} else if channel.TypeID() != tg.ChannelTypeID {
log.Debug().
Int64("channel_id", peer.ChannelID).
Type("channel_type", channel).
Msg("Not syncing portal because channel type is unsupported")
continue
}
chatInfo.Name = &channel.(*tg.Channel).Title
chatInfo.Members.PowerLevels = t.getGroupChatPowerLevels(ctx, channel)
if !portal.Metadata.(*PortalMetadata).IsSuperGroup { if !portal.Metadata.(*PortalMetadata).IsSuperGroup {
// Add the channel user // Add the channel user
sender := ids.MakeChannelUserID(peer.ChannelID) sender := ids.MakeChannelUserID(peer.ChannelID)
chatInfo.Members.MemberMap = map[networkid.UserID]bridgev2.ChatMember{ chatInfo.Members.MemberMap = map[networkid.UserID]bridgev2.ChatMember{
sender: bridgev2.ChatMember{ sender: {
EventSender: bridgev2.EventSender{Sender: sender}, EventSender: bridgev2.EventSender{Sender: sender},
Membership: event.MembershipJoin, Membership: event.MembershipJoin,
PowerLevel: superadminPowerLevel, PowerLevel: superadminPowerLevel,
}, },
} }
chatInfo.Members.MemberMap = map[networkid.UserID]bridgev2.ChatMember{ chatInfo.Members.MemberMap = map[networkid.UserID]bridgev2.ChatMember{
t.userID: bridgev2.ChatMember{ t.userID: {
EventSender: t.mySender(), EventSender: t.mySender(),
Membership: event.MembershipJoin, Membership: event.MembershipJoin,
PowerLevel: adminRightsToPowerLevel(channel.AdminRights), PowerLevel: adminRightsToPowerLevel(channel.(*tg.Channel).AdminRights),
}, },
} }
} }