mirror of
https://dev.narayana.im/narayana/telegabber.git
synced 2026-08-05 12:17:06 +00:00
Support bulk muc#admin operations on occupantsu
This commit is contained in:
parent
cff81d227c
commit
b1ecfc29cd
3 changed files with 172 additions and 64 deletions
|
|
@ -85,10 +85,12 @@ const (
|
|||
type MembersList int
|
||||
|
||||
const (
|
||||
MembersListMembers MembersList = iota
|
||||
MembersListNone MembersList = iota
|
||||
MembersListMembers
|
||||
MembersListRestricted
|
||||
MembersListBanned
|
||||
MembersListBannedAndAdministrators
|
||||
MembersListAdministrators
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -621,9 +623,7 @@ func (c *Client) updateMUCMembers(mucState *MUCState, chatID int64, members []*c
|
|||
myRole := "participant"
|
||||
|
||||
for _, member := range members {
|
||||
senderId := c.GetSenderId(member.MemberId)
|
||||
nickname := c.GetMUCNickname(senderId)
|
||||
affiliation, role := c.memberStatusToAffiliationAndRole(member.Status)
|
||||
senderId, nickname, affiliation, role := c.TgMemberToMUCMember(member)
|
||||
mucState.Members[senderId] = &MUCMember{
|
||||
Nickname: nickname,
|
||||
Affiliation: affiliation,
|
||||
|
|
@ -2485,6 +2485,14 @@ func (c *Client) memberStatusToAffiliationAndRole(memberStatus client.ChatMember
|
|||
return "member", "participant"
|
||||
}
|
||||
|
||||
// TgMemberToMUCMember resolves useful data to generate a MUC member
|
||||
func (c *Client) TgMemberToMUCMember(member *client.ChatMember) (senderId int64, nickname, affiliation, role string) {
|
||||
senderId = c.GetSenderId(member.MemberId)
|
||||
nickname = c.GetMUCNickname(senderId)
|
||||
affiliation, role = c.memberStatusToAffiliationAndRole(member.Status)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Client) sendMessagesReverse(chatID int64, messages []*client.Message, plain bool, toJid string) {
|
||||
sChatId := gateway.CHATNODE(chatID)
|
||||
var mucJid string
|
||||
|
|
@ -2540,6 +2548,8 @@ func (c *Client) GetChatMembers(chatID int64, limited bool, query string, member
|
|||
filters = []client.ChatMembersFilter{&client.ChatMembersFilterBanned{}}
|
||||
case MembersListBannedAndAdministrators:
|
||||
filters = []client.ChatMembersFilter{&client.ChatMembersFilterBanned{}, &client.ChatMembersFilterAdministrators{}}
|
||||
case MembersListAdministrators:
|
||||
filters = []client.ChatMembersFilter{&client.ChatMembersFilterAdministrators{}}
|
||||
}
|
||||
|
||||
limit := int32(9999)
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ type EmptySubject struct {
|
|||
// QueryMucAdmin is from XEP-0045
|
||||
type QueryMucAdmin struct {
|
||||
XMLName xml.Name `xml:"http://jabber.org/protocol/muc#admin query"`
|
||||
Item QueryMucAdminItem `xml:"item"`
|
||||
Items []*QueryMucAdminItem `xml:"item"`
|
||||
ResultSet *stanza.ResultSet `xml:"set,omitempty"`
|
||||
}
|
||||
|
||||
|
|
|
|||
130
xmpp/handlers.go
130
xmpp/handlers.go
|
|
@ -71,6 +71,11 @@ func HandleIq(s xmpp.Sender, p stanza.Packet) {
|
|||
go handleGetQueryRegister(s, iq)
|
||||
return
|
||||
}
|
||||
queryMucAdmin, ok := iq.Payload.(*extensions.QueryMucAdmin)
|
||||
if ok {
|
||||
go handleGetQueryMucAdmin(s, iq, queryMucAdmin)
|
||||
return
|
||||
}
|
||||
} else if iq.Type == stanza.IQTypeSet {
|
||||
queryRegister, ok := iq.Payload.(*extensions.QueryRegister)
|
||||
if ok {
|
||||
|
|
@ -1147,6 +1152,84 @@ func handleGetQueryRegister(s xmpp.Sender, iq *stanza.IQ) {
|
|||
}
|
||||
}
|
||||
|
||||
func handleGetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.QueryMucAdmin) {
|
||||
component, answer, ok := iqResultStub(s, iq)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
defer gateway.ResumableSend(component, answer)
|
||||
|
||||
bare, _, fromOk := gateway.SplitJID(iq.From)
|
||||
if !fromOk {
|
||||
iqAnswerSetError(answer, 400)
|
||||
return
|
||||
}
|
||||
|
||||
session, sessionOk := sessions[bare]
|
||||
if !sessionOk || !session.Session.MUC {
|
||||
iqAnswerSetError(answer, 403)
|
||||
return
|
||||
}
|
||||
|
||||
toID, toOk, toIsGroup := toToID(iq.To)
|
||||
if !toOk || !toIsGroup {
|
||||
iqAnswerSetError(answer, 406)
|
||||
return
|
||||
}
|
||||
|
||||
if len(query.Items) != 1 {
|
||||
iqAnswerSetError(answer, 400)
|
||||
return
|
||||
}
|
||||
item := query.Items[0]
|
||||
|
||||
var membersList telegram.MembersList
|
||||
switch item.Role {
|
||||
case "moderator":
|
||||
membersList = telegram.MembersListAdministrators
|
||||
case "participant":
|
||||
membersList = telegram.MembersListMembers
|
||||
}
|
||||
switch item.Affiliation {
|
||||
case "owner":
|
||||
iqAnswerSetError(answer, 403)
|
||||
return
|
||||
case "admin":
|
||||
membersList = telegram.MembersListAdministrators
|
||||
case "member":
|
||||
membersList = telegram.MembersListMembers
|
||||
case "outcast":
|
||||
membersList = telegram.MembersListBanned
|
||||
}
|
||||
|
||||
if membersList == telegram.MembersListNone {
|
||||
iqAnswerSetError(answer, 400)
|
||||
return
|
||||
}
|
||||
|
||||
payload := &extensions.QueryMucAdmin{}
|
||||
answer.Payload = payload
|
||||
|
||||
members, err := session.GetChatMembers(toID, false, "", membersList)
|
||||
if err == nil {
|
||||
for _, member := range members {
|
||||
senderId, nickname, affiliation, role := session.TgMemberToMUCMember(member)
|
||||
if item.Role != "" && role != item.Role {
|
||||
continue
|
||||
}
|
||||
if item.Affiliation != "" && affiliation != item.Affiliation {
|
||||
continue
|
||||
}
|
||||
payload.Items = append(payload.Items, &extensions.QueryMucAdminItem{
|
||||
Jid: gateway.CHATJID(senderId, true),
|
||||
Nick: nickname,
|
||||
Role: role,
|
||||
Affiliation: affiliation,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleSetQueryRegister(s xmpp.Sender, iq *stanza.IQ, query *extensions.QueryRegister) {
|
||||
component, answer, ok := iqResultStub(s, iq)
|
||||
if !ok {
|
||||
|
|
@ -1620,27 +1703,36 @@ func handleSetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.Quer
|
|||
return
|
||||
}
|
||||
|
||||
// pre-bake all data to make it transactional as much as possible
|
||||
type Item struct {
|
||||
UserID int64
|
||||
Nick string
|
||||
Status telegram.ChatMemberStatus
|
||||
}
|
||||
|
||||
var items []Item
|
||||
for _, item := range query.Items {
|
||||
if item.Affiliation == "owner" {
|
||||
iqAnswerSetError(answer, 403)
|
||||
return
|
||||
}
|
||||
|
||||
var userID int64
|
||||
if query.Item.Jid != "" {
|
||||
userID, _, _ = toToID(query.Item.Jid)
|
||||
} else if query.Item.Nick != "" {
|
||||
userID = session.GetMUCMemberIdByNickname(toID, query.Item.Nick)
|
||||
if item.Jid != "" {
|
||||
userID, _, _ = toToID(item.Jid)
|
||||
} else if item.Nick != "" {
|
||||
userID = session.GetMUCMemberIdByNickname(toID, item.Nick)
|
||||
}
|
||||
if userID == 0 {
|
||||
iqAnswerSetError(answer, 404)
|
||||
return
|
||||
}
|
||||
|
||||
nick := query.Item.Nick
|
||||
if nick == "" {
|
||||
nick = session.GetMUCNickname(userID)
|
||||
}
|
||||
nick := session.GetMUCNickname(userID)
|
||||
|
||||
var status telegram.ChatMemberStatus
|
||||
var integerPayload int64
|
||||
var stringPayload string
|
||||
|
||||
switch query.Item.Role {
|
||||
switch item.Role {
|
||||
case "none":
|
||||
status = telegram.ChatMemberStatusKicked
|
||||
case "visitor":
|
||||
|
|
@ -1651,7 +1743,7 @@ func handleSetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.Quer
|
|||
status = telegram.ChatMemberStatusPromoted
|
||||
}
|
||||
// affiliations have a higher priority over roles
|
||||
switch query.Item.Affiliation {
|
||||
switch item.Affiliation {
|
||||
case "none":
|
||||
status = telegram.ChatMemberStatusKicked
|
||||
case "outcast":
|
||||
|
|
@ -1660,9 +1752,6 @@ func handleSetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.Quer
|
|||
status = telegram.ChatMemberStatusUnmuted
|
||||
case "admin":
|
||||
status = telegram.ChatMemberStatusPromoted
|
||||
case "owner":
|
||||
iqAnswerSetError(answer, 403)
|
||||
return
|
||||
}
|
||||
|
||||
// nothing has been detected
|
||||
|
|
@ -1671,7 +1760,15 @@ func handleSetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.Quer
|
|||
return
|
||||
}
|
||||
|
||||
err := session.SetChatMemberStatus(toID, userID, status, integerPayload, stringPayload, nick)
|
||||
items = append(items, Item{
|
||||
UserID: userID,
|
||||
Nick: nick,
|
||||
Status: status,
|
||||
})
|
||||
}
|
||||
|
||||
for _, item := range items {
|
||||
err := session.SetChatMemberStatus(toID, item.UserID, item.Status, 0, "", item.Nick)
|
||||
if err != nil {
|
||||
code, ok := telegram.GetErrorCode(err)
|
||||
if !ok {
|
||||
|
|
@ -1681,6 +1778,7 @@ func handleSetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.Quer
|
|||
answer.Error.Text = err.Error()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func iqAnswerSetError(answer *stanza.IQ, code int) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue