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
|
type MembersList int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MembersListMembers MembersList = iota
|
MembersListNone MembersList = iota
|
||||||
|
MembersListMembers
|
||||||
MembersListRestricted
|
MembersListRestricted
|
||||||
MembersListBanned
|
MembersListBanned
|
||||||
MembersListBannedAndAdministrators
|
MembersListBannedAndAdministrators
|
||||||
|
MembersListAdministrators
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -621,9 +623,7 @@ func (c *Client) updateMUCMembers(mucState *MUCState, chatID int64, members []*c
|
||||||
myRole := "participant"
|
myRole := "participant"
|
||||||
|
|
||||||
for _, member := range members {
|
for _, member := range members {
|
||||||
senderId := c.GetSenderId(member.MemberId)
|
senderId, nickname, affiliation, role := c.TgMemberToMUCMember(member)
|
||||||
nickname := c.GetMUCNickname(senderId)
|
|
||||||
affiliation, role := c.memberStatusToAffiliationAndRole(member.Status)
|
|
||||||
mucState.Members[senderId] = &MUCMember{
|
mucState.Members[senderId] = &MUCMember{
|
||||||
Nickname: nickname,
|
Nickname: nickname,
|
||||||
Affiliation: affiliation,
|
Affiliation: affiliation,
|
||||||
|
|
@ -2485,6 +2485,14 @@ func (c *Client) memberStatusToAffiliationAndRole(memberStatus client.ChatMember
|
||||||
return "member", "participant"
|
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) {
|
func (c *Client) sendMessagesReverse(chatID int64, messages []*client.Message, plain bool, toJid string) {
|
||||||
sChatId := gateway.CHATNODE(chatID)
|
sChatId := gateway.CHATNODE(chatID)
|
||||||
var mucJid string
|
var mucJid string
|
||||||
|
|
@ -2540,6 +2548,8 @@ func (c *Client) GetChatMembers(chatID int64, limited bool, query string, member
|
||||||
filters = []client.ChatMembersFilter{&client.ChatMembersFilterBanned{}}
|
filters = []client.ChatMembersFilter{&client.ChatMembersFilterBanned{}}
|
||||||
case MembersListBannedAndAdministrators:
|
case MembersListBannedAndAdministrators:
|
||||||
filters = []client.ChatMembersFilter{&client.ChatMembersFilterBanned{}, &client.ChatMembersFilterAdministrators{}}
|
filters = []client.ChatMembersFilter{&client.ChatMembersFilterBanned{}, &client.ChatMembersFilterAdministrators{}}
|
||||||
|
case MembersListAdministrators:
|
||||||
|
filters = []client.ChatMembersFilter{&client.ChatMembersFilterAdministrators{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
limit := int32(9999)
|
limit := int32(9999)
|
||||||
|
|
|
||||||
|
|
@ -310,7 +310,7 @@ type EmptySubject struct {
|
||||||
// QueryMucAdmin is from XEP-0045
|
// QueryMucAdmin is from XEP-0045
|
||||||
type QueryMucAdmin struct {
|
type QueryMucAdmin struct {
|
||||||
XMLName xml.Name `xml:"http://jabber.org/protocol/muc#admin query"`
|
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"`
|
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)
|
go handleGetQueryRegister(s, iq)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
queryMucAdmin, ok := iq.Payload.(*extensions.QueryMucAdmin)
|
||||||
|
if ok {
|
||||||
|
go handleGetQueryMucAdmin(s, iq, queryMucAdmin)
|
||||||
|
return
|
||||||
|
}
|
||||||
} else if iq.Type == stanza.IQTypeSet {
|
} else if iq.Type == stanza.IQTypeSet {
|
||||||
queryRegister, ok := iq.Payload.(*extensions.QueryRegister)
|
queryRegister, ok := iq.Payload.(*extensions.QueryRegister)
|
||||||
if ok {
|
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) {
|
func handleSetQueryRegister(s xmpp.Sender, iq *stanza.IQ, query *extensions.QueryRegister) {
|
||||||
component, answer, ok := iqResultStub(s, iq)
|
component, answer, ok := iqResultStub(s, iq)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -1620,27 +1703,36 @@ func handleSetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.Quer
|
||||||
return
|
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
|
var userID int64
|
||||||
if query.Item.Jid != "" {
|
if item.Jid != "" {
|
||||||
userID, _, _ = toToID(query.Item.Jid)
|
userID, _, _ = toToID(item.Jid)
|
||||||
} else if query.Item.Nick != "" {
|
} else if item.Nick != "" {
|
||||||
userID = session.GetMUCMemberIdByNickname(toID, query.Item.Nick)
|
userID = session.GetMUCMemberIdByNickname(toID, item.Nick)
|
||||||
}
|
}
|
||||||
if userID == 0 {
|
if userID == 0 {
|
||||||
iqAnswerSetError(answer, 404)
|
iqAnswerSetError(answer, 404)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nick := query.Item.Nick
|
nick := session.GetMUCNickname(userID)
|
||||||
if nick == "" {
|
|
||||||
nick = session.GetMUCNickname(userID)
|
|
||||||
}
|
|
||||||
|
|
||||||
var status telegram.ChatMemberStatus
|
var status telegram.ChatMemberStatus
|
||||||
var integerPayload int64
|
|
||||||
var stringPayload string
|
|
||||||
|
|
||||||
switch query.Item.Role {
|
switch item.Role {
|
||||||
case "none":
|
case "none":
|
||||||
status = telegram.ChatMemberStatusKicked
|
status = telegram.ChatMemberStatusKicked
|
||||||
case "visitor":
|
case "visitor":
|
||||||
|
|
@ -1651,7 +1743,7 @@ func handleSetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.Quer
|
||||||
status = telegram.ChatMemberStatusPromoted
|
status = telegram.ChatMemberStatusPromoted
|
||||||
}
|
}
|
||||||
// affiliations have a higher priority over roles
|
// affiliations have a higher priority over roles
|
||||||
switch query.Item.Affiliation {
|
switch item.Affiliation {
|
||||||
case "none":
|
case "none":
|
||||||
status = telegram.ChatMemberStatusKicked
|
status = telegram.ChatMemberStatusKicked
|
||||||
case "outcast":
|
case "outcast":
|
||||||
|
|
@ -1660,9 +1752,6 @@ func handleSetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.Quer
|
||||||
status = telegram.ChatMemberStatusUnmuted
|
status = telegram.ChatMemberStatusUnmuted
|
||||||
case "admin":
|
case "admin":
|
||||||
status = telegram.ChatMemberStatusPromoted
|
status = telegram.ChatMemberStatusPromoted
|
||||||
case "owner":
|
|
||||||
iqAnswerSetError(answer, 403)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// nothing has been detected
|
// nothing has been detected
|
||||||
|
|
@ -1671,7 +1760,15 @@ func handleSetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.Quer
|
||||||
return
|
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 {
|
if err != nil {
|
||||||
code, ok := telegram.GetErrorCode(err)
|
code, ok := telegram.GetErrorCode(err)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -1681,6 +1778,7 @@ func handleSetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.Quer
|
||||||
answer.Error.Text = err.Error()
|
answer.Error.Text = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func iqAnswerSetError(answer *stanza.IQ, code int) {
|
func iqAnswerSetError(answer *stanza.IQ, code int) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue