fix: sync linked discussion guest support
This commit is contained in:
parent
5f7c0b9804
commit
9f73dc20da
27 changed files with 1004 additions and 30 deletions
|
|
@ -25,6 +25,77 @@ func (s *ChannelStore) getChannelForMember(ctx context.Context, db sqlcgen.DBTX,
|
|||
return ch, member, nil
|
||||
}
|
||||
|
||||
func (s *ChannelStore) getChannelForMemberOrLinkedGuest(ctx context.Context, db sqlcgen.DBTX, viewerUserID, channelID int64) (domain.Channel, domain.ChannelMember, error) {
|
||||
channel, member, err := s.getChannelForMember(ctx, db, viewerUserID, channelID)
|
||||
if !errors.Is(err, domain.ErrChannelPrivate) {
|
||||
return channel, member, err
|
||||
}
|
||||
target, targetErr := s.channelByID(ctx, db, channelID)
|
||||
if targetErr != nil {
|
||||
return domain.Channel{}, domain.ChannelMember{}, targetErr
|
||||
}
|
||||
guest, allowed, guestErr := s.getLinkedDiscussionGuest(ctx, db, viewerUserID, target)
|
||||
if guestErr != nil {
|
||||
return domain.Channel{}, domain.ChannelMember{}, guestErr
|
||||
}
|
||||
if !allowed {
|
||||
return domain.Channel{}, domain.ChannelMember{}, err
|
||||
}
|
||||
return target, guest, nil
|
||||
}
|
||||
|
||||
// getLinkedDiscussionGuest authorizes a private discussion group through an
|
||||
// active membership in its bidirectionally linked broadcast. The returned
|
||||
// member is computed only and must never be persisted. An explicit target ban
|
||||
// or kick takes precedence over the source-channel membership.
|
||||
func (s *ChannelStore) getLinkedDiscussionGuest(ctx context.Context, db sqlcgen.DBTX, viewerUserID int64, target domain.Channel) (domain.ChannelMember, bool, error) {
|
||||
if target.Broadcast || !target.Megagroup || target.LinkedChatID == 0 {
|
||||
return domain.ChannelMember{}, false, nil
|
||||
}
|
||||
existing, err := s.getChannelMember(ctx, db, target.ID, viewerUserID)
|
||||
if err == nil {
|
||||
if existing.Status == domain.ChannelMemberBanned || existing.Status == domain.ChannelMemberKicked || existing.BannedRights.ViewMessages {
|
||||
return domain.ChannelMember{}, false, domain.ErrChannelUserBanned
|
||||
}
|
||||
if existing.Status == domain.ChannelMemberActive {
|
||||
return existing, false, nil
|
||||
}
|
||||
} else if !errors.Is(err, domain.ErrChannelPrivate) {
|
||||
return domain.ChannelMember{}, false, err
|
||||
}
|
||||
source, err := s.channelByID(ctx, db, target.LinkedChatID)
|
||||
if err != nil {
|
||||
if errors.Is(err, domain.ErrChannelInvalid) {
|
||||
return domain.ChannelMember{}, false, nil
|
||||
}
|
||||
return domain.ChannelMember{}, false, err
|
||||
}
|
||||
if !source.Broadcast || source.LinkedChatID != target.ID {
|
||||
return domain.ChannelMember{}, false, nil
|
||||
}
|
||||
sourceMember, err := s.getChannelMember(ctx, db, source.ID, viewerUserID)
|
||||
if err != nil {
|
||||
if errors.Is(err, domain.ErrChannelPrivate) {
|
||||
return domain.ChannelMember{}, false, nil
|
||||
}
|
||||
return domain.ChannelMember{}, false, err
|
||||
}
|
||||
if err := validateChannelMemberVisible(sourceMember); err != nil {
|
||||
return domain.ChannelMember{}, false, err
|
||||
}
|
||||
guest := domain.ChannelMember{
|
||||
ChannelID: target.ID,
|
||||
UserID: viewerUserID,
|
||||
Status: domain.ChannelMemberLeft,
|
||||
Role: domain.ChannelRoleMember,
|
||||
Guest: true,
|
||||
}
|
||||
if s.memberCacheActive(db) {
|
||||
s.memberCache.put(guest)
|
||||
}
|
||||
return guest, true, nil
|
||||
}
|
||||
|
||||
func (s *ChannelStore) getPublicPreviewMember(ctx context.Context, db sqlcgen.DBTX, viewerUserID int64, ch domain.Channel) (domain.ChannelMember, error) {
|
||||
member, err := s.getChannelMember(ctx, db, ch.ID, viewerUserID)
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue