Skip to content

Commit

Permalink
refactor(peers): move rights editing to members package
Browse files Browse the repository at this point in the history
  • Loading branch information
tdakkota committed Mar 9, 2022
1 parent 2ba8a0f commit 1f93a39
Show file tree
Hide file tree
Showing 17 changed files with 638 additions and 434 deletions.
67 changes: 0 additions & 67 deletions telegram/peers/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,71 +296,4 @@ func (c Channel) DisableReactions(ctx context.Context) error {
return c.m.editReactions(ctx, c.InputPeer())
}

// KickUser kicks user participant.
//
// Needed for parity with Chat to define common interface.
//
// If revokeHistory is set, will delete all messages from this participant.
func (c Channel) KickUser(ctx context.Context, participant tg.InputUserClass, revokeHistory bool) error {
p := convertInputUserToInputPeer(participant)
if revokeHistory {
if _, err := c.m.api.ChannelsDeleteParticipantHistory(ctx, &tg.ChannelsDeleteParticipantHistoryRequest{
Channel: c.InputChannel(),
Participant: p,
}); err != nil {
return errors.Wrap(err, "revoke history")
}
}
return c.KickParticipant(ctx, p)
}

// KickParticipant kicks participant.
func (c Channel) KickParticipant(ctx context.Context, participant tg.InputPeerClass) error {
return c.EditParticipantRights(ctx, participant, ParticipantRights{
DenyViewMessages: true,
})
}

// EditParticipantRights edits participant rights in this channel.
func (c Channel) EditParticipantRights(
ctx context.Context,
participant tg.InputPeerClass,
options ParticipantRights,
) error {
return c.editParticipantRights(ctx, participant, options)
}

func (c Channel) editParticipantRights(ctx context.Context, p tg.InputPeerClass, options ParticipantRights) error {
if _, err := c.m.api.ChannelsEditBanned(ctx, &tg.ChannelsEditBannedRequest{
Channel: c.InputChannel(),
Participant: p,
BannedRights: options.IntoChatBannedRights(),
}); err != nil {
return errors.Wrap(err, "edit participant rights")
}
return nil
}

// EditRights edits rights of all participants in this channel.
func (c Channel) EditRights(ctx context.Context, options ParticipantRights) error {
return c.m.editDefaultRights(ctx, c.InputPeer(), options)
}

// EditAdminRights edits admin rights of given user in this channel.
func (c Channel) EditAdminRights(
ctx context.Context,
admin tg.InputUserClass,
options AdminRights,
) error {
if _, err := c.m.api.ChannelsEditAdmin(ctx, &tg.ChannelsEditAdminRequest{
Channel: c.InputChannel(),
UserID: admin,
AdminRights: options.IntoChatAdminRights(),
Rank: options.Rank,
}); err != nil {
return errors.Wrap(err, "edit admin rights")
}
return nil
}

// TODO(tdakkota): add more getters, helpers and convertors
62 changes: 0 additions & 62 deletions telegram/peers/channel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,65 +188,3 @@ func TestChannel_Delete(t *testing.T) {
}).ThenResult(&tg.Updates{})
a.NoError(ch.Delete(ctx))
}

func TestChannel_KickUser(t *testing.T) {
a := require.New(t)
ctx := context.Background()
mock, m := testManager(t)

u := m.User(getTestUser())
ch := m.Channel(getTestChannel())
rights := tg.ChatBannedRights{
ViewMessages: true,
}
rights.SetFlags()

mock.ExpectCall(&tg.ChannelsEditBannedRequest{
Channel: ch.InputChannel(),
Participant: u.InputPeer(),
BannedRights: rights,
}).ThenRPCErr(getTestError())
a.Error(ch.KickUser(ctx, u.InputUser(), false))

mock.ExpectCall(&tg.ChannelsEditBannedRequest{
Channel: ch.InputChannel(),
Participant: u.InputPeer(),
BannedRights: rights,
}).ThenResult(&tg.Updates{})
a.NoError(ch.KickUser(ctx, u.InputUser(), false))
}

func TestChannel_EditAdminRights(t *testing.T) {
a := require.New(t)
ctx := context.Background()
mock, m := testManager(t)

u := m.User(getTestUser())
ch := m.Channel(getTestChannel())
rights := tg.ChatAdminRights{
AddAdmins: true,
}
rights.SetFlags()

mock.ExpectCall(&tg.ChannelsEditAdminRequest{
Channel: ch.InputChannel(),
UserID: u.InputUser(),
AdminRights: rights,
Rank: "rank",
}).ThenRPCErr(getTestError())
a.Error(ch.EditAdminRights(ctx, u.InputUser(), AdminRights{
Rank: "rank",
AddAdmins: true,
}))

mock.ExpectCall(&tg.ChannelsEditAdminRequest{
Channel: ch.InputChannel(),
UserID: u.InputUser(),
AdminRights: rights,
Rank: "rank",
}).ThenResult(&tg.Updates{})
a.NoError(ch.EditAdminRights(ctx, u.InputUser(), AdminRights{
Rank: "rank",
AddAdmins: true,
}))
}
24 changes: 0 additions & 24 deletions telegram/peers/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,28 +296,4 @@ func (c Chat) deleteUser(ctx context.Context, user tg.InputUserClass, revokeHist
return nil
}

// KickUser kicks user participant.
//
// If revokeHistory is set, will delete all messages from this participant.
func (c Chat) KickUser(ctx context.Context, participant tg.InputUserClass, revokeHistory bool) error {
return c.deleteUser(ctx, participant, revokeHistory)
}

// EditRights edits rights of all participants in this channel.
func (c Chat) EditRights(ctx context.Context, options ParticipantRights) error {
return c.m.editDefaultRights(ctx, c.InputPeer(), options)
}

// EditAdmin edits admin rights for given user.
func (c Chat) EditAdmin(ctx context.Context, user tg.InputUserClass, isAdmin bool) error {
if _, err := c.m.api.MessagesEditChatAdmin(ctx, &tg.MessagesEditChatAdminRequest{
ChatID: c.ID(),
UserID: user,
IsAdmin: isAdmin,
}); err != nil {
return errors.Wrap(err, "edit admin")
}
return nil
}

// TODO(tdakkota): add more getters, helpers and convertors
182 changes: 80 additions & 102 deletions telegram/peers/members/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,101 +16,6 @@ type ChannelMembers struct {
channel peers.Channel
}

// ChannelMember is channel Member.
type ChannelMember struct {
parent *ChannelMembers
creatorDate time.Time
user peers.User
inviter peers.User
raw tg.ChannelParticipantClass
}

// Status returns member Status.
func (c ChannelMember) Status() Status {
switch c.raw.(type) {
case *tg.ChannelParticipant:
return Plain
case *tg.ChannelParticipantSelf:
return Plain
case *tg.ChannelParticipantCreator:
return Creator
case *tg.ChannelParticipantAdmin:
return Admin
case *tg.ChannelParticipantBanned:
return Banned
case *tg.ChannelParticipantLeft:
return Left
default:
return -1
}
}

// Rank returns admin "rank".
func (c ChannelMember) Rank() (string, bool) {
switch p := c.raw.(type) {
case *tg.ChannelParticipant:
return "", false
case *tg.ChannelParticipantSelf:
return "", false
case *tg.ChannelParticipantCreator:
return p.GetRank()
case *tg.ChannelParticipantAdmin:
return p.GetRank()
case *tg.ChannelParticipantBanned:
return "", false
case *tg.ChannelParticipantLeft:
return "", false
default:
return "", false
}
}

// JoinDate returns member join date, if it is available.
func (c ChannelMember) JoinDate() (time.Time, bool) {
switch p := c.raw.(type) {
case *tg.ChannelParticipant:
return time.Unix(int64(p.Date), 0), true
case *tg.ChannelParticipantSelf:
return time.Unix(int64(p.Date), 0), true
case *tg.ChannelParticipantCreator:
return c.creatorDate, true
case *tg.ChannelParticipantAdmin:
return time.Unix(int64(p.Date), 0), true
case *tg.ChannelParticipantBanned:
return time.Unix(int64(p.Date), 0), true
case *tg.ChannelParticipantLeft:
return time.Time{}, false
default:
return time.Time{}, false
}
}

// InvitedBy returns user that invited this member.
func (c ChannelMember) InvitedBy() (peers.User, bool) {
switch p := c.raw.(type) {
case *tg.ChannelParticipant:
return peers.User{}, false
case *tg.ChannelParticipantSelf:
return c.inviter, true
case *tg.ChannelParticipantCreator:
return peers.User{}, false
case *tg.ChannelParticipantAdmin:
_, has := p.GetInviterID()
return c.inviter, has
case *tg.ChannelParticipantBanned:
return peers.User{}, false
case *tg.ChannelParticipantLeft:
return peers.User{}, false
default:
return peers.User{}, false
}
}

// User returns member User object.
func (c ChannelMember) User() peers.User {
return c.user
}

func (c *ChannelMembers) query(ctx context.Context, offset, limit int) (*tg.ChannelsChannelParticipants, error) {
raw := c.m.API()
p, err := raw.ChannelsGetParticipants(ctx, &tg.ChannelsGetParticipantsRequest{
Expand Down Expand Up @@ -158,13 +63,13 @@ func (c *ChannelMembers) ForEach(ctx context.Context, cb Callback) error {
if len(m.Participants) < 1 {
return nil
}
for i, participant := range m.Participants {
for i, member := range m.Participants {
var (
userID int64
inviterID int64
err error
)
switch p := participant.(type) {
switch p := member.(type) {
case *tg.ChannelParticipant:
userID = p.UserID
case *tg.ChannelParticipantSelf:
Expand Down Expand Up @@ -200,7 +105,7 @@ func (c *ChannelMembers) ForEach(ctx context.Context, cb Callback) error {
creatorDate: channelDate,
user: user,
inviter: peers.User{},
raw: participant,
raw: member,
}
if inviterID != 0 {
inviter, err := c.m.ResolveUserID(ctx, inviterID)
Expand Down Expand Up @@ -228,11 +133,84 @@ func (c *ChannelMembers) Count(ctx context.Context) (int, error) {
return m.Count, nil
}

// Peer returns chat object.
func (c *ChannelMembers) Peer() peers.Peer {
return c.channel
}

// Kick kicks user member.
//
// Needed for parity with ChatMembers to define common interface.
//
// If revokeHistory is set, will delete all messages from this member.
func (c *ChannelMembers) Kick(ctx context.Context, member tg.InputUserClass, revokeHistory bool) error {
p := convertInputUserToInputPeer(member)
if revokeHistory {
if _, err := c.m.API().ChannelsDeleteParticipantHistory(ctx, &tg.ChannelsDeleteParticipantHistoryRequest{
Channel: c.channel.InputChannel(),
Participant: p,
}); err != nil {
return errors.Wrap(err, "revoke history")
}
}
return c.KickMember(ctx, p)
}

// KickMember kicks member.
//
// Unlike Kick, KickMember can be used to kick chat member that uses send-as-channel mode.
func (c *ChannelMembers) KickMember(ctx context.Context, member tg.InputPeerClass) error {
return c.EditMemberRights(ctx, member, MemberRights{
DenyViewMessages: true,
})
}

// EditMemberRights edits member rights in this channel.
func (c *ChannelMembers) EditMemberRights(
ctx context.Context,
member tg.InputPeerClass,
options MemberRights,
) error {
return c.editMemberRights(ctx, member, options)
}

func (c *ChannelMembers) editMemberRights(ctx context.Context, p tg.InputPeerClass, options MemberRights) error {
if _, err := c.m.API().ChannelsEditBanned(ctx, &tg.ChannelsEditBannedRequest{
Channel: c.channel.InputChannel(),
Participant: p,
BannedRights: options.IntoChatBannedRights(),
}); err != nil {
return errors.Wrap(err, "edit member rights")
}
return nil
}

// EditRights edits rights of all members in this channel.
func (c *ChannelMembers) EditRights(ctx context.Context, options MemberRights) error {
return editDefaultRights(ctx, c.m.API(), c.channel.InputPeer(), options)
}

// EditAdminRights edits admin rights of given user in this channel.
func (c *ChannelMembers) EditAdminRights(
ctx context.Context,
admin tg.InputUserClass,
options AdminRights,
) error {
if _, err := c.m.API().ChannelsEditAdmin(ctx, &tg.ChannelsEditAdminRequest{
Channel: c.channel.InputChannel(),
UserID: admin,
AdminRights: options.IntoChatAdminRights(),
Rank: options.Rank,
}); err != nil {
return errors.Wrap(err, "edit admin rights")
}
return nil
}

// Channel returns recent channel members.
func Channel(ctx context.Context, channel peers.Channel) (*ChannelMembers, error) {
m := channel.Manager()
func Channel(channel peers.Channel) *ChannelMembers {
return &ChannelMembers{
m: m,
m: channel.Manager(),
channel: channel,
}, nil
}
}

0 comments on commit 1f93a39

Please sign in to comment.