mirror of
https://dev.narayana.im/narayana/telegabber.git
synced 2026-08-05 12:17:06 +00:00
Reflect MUC member affiliation/role changes in Telegram
This commit is contained in:
parent
26eafbba3d
commit
ebdf180ce5
6 changed files with 234 additions and 102 deletions
|
|
@ -31,6 +31,7 @@ type MUCState struct {
|
||||||
type MUCMember struct {
|
type MUCMember struct {
|
||||||
Nickname string
|
Nickname string
|
||||||
Affiliation string
|
Affiliation string
|
||||||
|
Role string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMUCState() *MUCState {
|
func NewMUCState() *MUCState {
|
||||||
|
|
|
||||||
|
|
@ -855,7 +855,7 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool,
|
||||||
return "Contact not found", true, false
|
return "Contact not found", true, false
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.Kick(chatID, contact.Id, "")
|
err = c.SetChatMemberStatus(chatID, contact.Id, ChatMemberStatusKicked, 0, "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), true, false
|
return err.Error(), true, false
|
||||||
}
|
}
|
||||||
|
|
@ -878,15 +878,7 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = c.client.SetChatMemberStatus(&client.SetChatMemberStatusRequest{
|
err = c.SetChatMemberStatus(chatID, contact.Id, ChatMemberStatusMuted, hours, "", "")
|
||||||
ChatId: chatID,
|
|
||||||
MemberId: &client.MessageSenderUser{UserId: contact.Id},
|
|
||||||
Status: &client.ChatMemberStatusRestricted{
|
|
||||||
IsMember: true,
|
|
||||||
RestrictedUntilDate: c.formatBantime(hours),
|
|
||||||
Permissions: &permissionsReadonly,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), true, false
|
return err.Error(), true, false
|
||||||
}
|
}
|
||||||
|
|
@ -907,15 +899,7 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool,
|
||||||
return "Contact not found", true, false
|
return "Contact not found", true, false
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = c.client.SetChatMemberStatus(&client.SetChatMemberStatusRequest{
|
err = c.SetChatMemberStatus(chatID, contact.Id, ChatMemberStatusUnmuted, 0, "", "")
|
||||||
ChatId: chatID,
|
|
||||||
MemberId: &client.MessageSenderUser{UserId: contact.Id},
|
|
||||||
Status: &client.ChatMemberStatusRestricted{
|
|
||||||
IsMember: true,
|
|
||||||
RestrictedUntilDate: 0,
|
|
||||||
Permissions: &permissionsMember,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), true, false
|
return err.Error(), true, false
|
||||||
}
|
}
|
||||||
|
|
@ -943,13 +927,7 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = c.client.SetChatMemberStatus(&client.SetChatMemberStatusRequest{
|
err = c.SetChatMemberStatus(chatID, contact.Id, ChatMemberStatusBanned, hours, "", "")
|
||||||
ChatId: chatID,
|
|
||||||
MemberId: &client.MessageSenderUser{UserId: contact.Id},
|
|
||||||
Status: &client.ChatMemberStatusBanned{
|
|
||||||
BannedUntilDate: c.formatBantime(hours),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), true, false
|
return err.Error(), true, false
|
||||||
}
|
}
|
||||||
|
|
@ -963,11 +941,7 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool,
|
||||||
return "Contact not found", true, false
|
return "Contact not found", true, false
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = c.client.SetChatMemberStatus(&client.SetChatMemberStatusRequest{
|
err = c.SetChatMemberStatus(chatID, contact.Id, ChatMemberStatusUnbanned, 0, "", "")
|
||||||
ChatId: chatID,
|
|
||||||
MemberId: &client.MessageSenderUser{UserId: contact.Id},
|
|
||||||
Status: &client.ChatMemberStatusMember{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), true, false
|
return err.Error(), true, false
|
||||||
}
|
}
|
||||||
|
|
@ -981,21 +955,13 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool,
|
||||||
return "Contact not found", true, false
|
return "Contact not found", true, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// clone the permissions
|
var customTitle string
|
||||||
status := client.ChatMemberStatusAdministrator{
|
|
||||||
CanBeEdited: true,
|
|
||||||
Rights: &permissionsAdmin,
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) > 1 {
|
if len(args) > 1 {
|
||||||
status.CustomTitle = args[1]
|
customTitle = args[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = c.client.SetChatMemberStatus(&client.SetChatMemberStatusRequest{
|
// clone the permissions
|
||||||
ChatId: chatID,
|
err = c.SetChatMemberStatus(chatID, contact.Id, ChatMemberStatusPromoted, 0, customTitle, "")
|
||||||
MemberId: &client.MessageSenderUser{UserId: contact.Id},
|
|
||||||
Status: &status,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), true, false
|
return err.Error(), true, false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,17 @@ func NewMessageLimitSince(since int64) *MessageLimit {
|
||||||
|
|
||||||
const AVATAR_SIZE_LIMIT int64 = 128 * 1024
|
const AVATAR_SIZE_LIMIT int64 = 128 * 1024
|
||||||
|
|
||||||
|
const (
|
||||||
|
ChatMemberStatusIllegal = iota
|
||||||
|
ChatMemberStatusKicked
|
||||||
|
ChatMemberStatusMuted
|
||||||
|
ChatMemberStatusUnmuted
|
||||||
|
ChatMemberStatusBanned
|
||||||
|
ChatMemberStatusUnbanned
|
||||||
|
ChatMemberStatusPromoted
|
||||||
|
)
|
||||||
|
type ChatMemberStatus int
|
||||||
|
|
||||||
// GetContactByUsername resolves username to user id retrieves user and chat information
|
// GetContactByUsername resolves username to user id retrieves user and chat information
|
||||||
func (c *Client) GetContactByUsername(username string) (*client.Chat, *client.User, error) {
|
func (c *Client) GetContactByUsername(username string) (*client.Chat, *client.User, error) {
|
||||||
if !c.Online() {
|
if !c.Online() {
|
||||||
|
|
@ -512,6 +523,7 @@ func (c *Client) ProcessStatusUpdate(chatID int64, status string, show string, o
|
||||||
gateway.SPFrom(gateway.MUCNODE(mucId)),
|
gateway.SPFrom(gateway.MUCNODE(mucId)),
|
||||||
gateway.SPResource(member.Nickname),
|
gateway.SPResource(member.Nickname),
|
||||||
gateway.SPMUCAffiliation(member.Affiliation),
|
gateway.SPMUCAffiliation(member.Affiliation),
|
||||||
|
gateway.SPMUCRole(member.Role),
|
||||||
gateway.SPMUCJid(chatJid),
|
gateway.SPMUCJid(chatJid),
|
||||||
)
|
)
|
||||||
err := c.sendPresence(newMucArgs...)
|
err := c.sendPresence(newMucArgs...)
|
||||||
|
|
@ -597,6 +609,7 @@ func (c *Client) sendMUCStatuses(chatID int64) {
|
||||||
myNickname = c.getFullName(c.me)
|
myNickname = c.getFullName(c.me)
|
||||||
}
|
}
|
||||||
myAffiliation := "member"
|
myAffiliation := "member"
|
||||||
|
myRole := "participant"
|
||||||
|
|
||||||
members, err := c.client.SearchChatMembers(&client.SearchChatMembersRequest{
|
members, err := c.client.SearchChatMembers(&client.SearchChatMembersRequest{
|
||||||
ChatId: chatID,
|
ChatId: chatID,
|
||||||
|
|
@ -616,15 +629,17 @@ func (c *Client) sendMUCStatuses(chatID int64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
nickname := c.GetMUCNickname(senderId)
|
nickname := c.GetMUCNickname(senderId)
|
||||||
affiliation := c.memberStatusToAffiliation(member.Status)
|
affiliation, role := c.memberStatusToAffiliationAndRole(member.Status)
|
||||||
mucState.Members[senderId] = &MUCMember{
|
mucState.Members[senderId] = &MUCMember{
|
||||||
Nickname: nickname,
|
Nickname: nickname,
|
||||||
Affiliation: affiliation,
|
Affiliation: affiliation,
|
||||||
|
Role: role,
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.me != nil && senderId == c.me.Id {
|
if c.me != nil && senderId == c.me.Id {
|
||||||
myNickname = nickname
|
myNickname = nickname
|
||||||
myAffiliation = affiliation
|
myAffiliation = affiliation
|
||||||
|
myRole = role
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -633,6 +648,7 @@ func (c *Client) sendMUCStatuses(chatID int64) {
|
||||||
gateway.SPResource(nickname),
|
gateway.SPResource(nickname),
|
||||||
gateway.SPImmed(true),
|
gateway.SPImmed(true),
|
||||||
gateway.SPMUCAffiliation(affiliation),
|
gateway.SPMUCAffiliation(affiliation),
|
||||||
|
gateway.SPMUCRole(affiliation),
|
||||||
gateway.SPMUCJid(gateway.CHATJID(senderId, true)),
|
gateway.SPMUCJid(gateway.CHATJID(senderId, true)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -644,6 +660,7 @@ func (c *Client) sendMUCStatuses(chatID int64) {
|
||||||
gateway.SPResource(myNickname),
|
gateway.SPResource(myNickname),
|
||||||
gateway.SPImmed(true),
|
gateway.SPImmed(true),
|
||||||
gateway.SPMUCAffiliation(myAffiliation),
|
gateway.SPMUCAffiliation(myAffiliation),
|
||||||
|
gateway.SPMUCRole(myRole),
|
||||||
gateway.SPMUCStatusCodes([]uint16{100, 110, 210}),
|
gateway.SPMUCStatusCodes([]uint16{100, 110, 210}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -660,7 +677,7 @@ func (c *Client) mucCacheHasMember(mucID int64, memberID int64) bool {
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) addMUCMember(mucID int64, memberID int64, affiliation string) bool {
|
func (c *Client) addMUCMember(mucID int64, memberID int64, affiliation, role string) bool {
|
||||||
c.locks.mucCacheLock.Lock()
|
c.locks.mucCacheLock.Lock()
|
||||||
defer c.locks.mucCacheLock.Unlock()
|
defer c.locks.mucCacheLock.Unlock()
|
||||||
mucState, ok := c.mucCache[mucID]
|
mucState, ok := c.mucCache[mucID]
|
||||||
|
|
@ -675,6 +692,7 @@ func (c *Client) addMUCMember(mucID int64, memberID int64, affiliation string) b
|
||||||
gateway.SPResource(nickname),
|
gateway.SPResource(nickname),
|
||||||
gateway.SPImmed(true),
|
gateway.SPImmed(true),
|
||||||
gateway.SPMUCAffiliation(affiliation),
|
gateway.SPMUCAffiliation(affiliation),
|
||||||
|
gateway.SPMUCRole(role),
|
||||||
gateway.SPMUCJid(gateway.CHATJID(memberID, true)),
|
gateway.SPMUCJid(gateway.CHATJID(memberID, true)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -682,6 +700,7 @@ func (c *Client) addMUCMember(mucID int64, memberID int64, affiliation string) b
|
||||||
mucState.Members[memberID] = &MUCMember{
|
mucState.Members[memberID] = &MUCMember{
|
||||||
Nickname: nickname,
|
Nickname: nickname,
|
||||||
Affiliation: affiliation,
|
Affiliation: affiliation,
|
||||||
|
Role: role,
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -747,6 +766,7 @@ func (c *Client) updateMUCsNickname(memberID int64, newNickname string) {
|
||||||
gateway.SPResource(oldMember.Nickname),
|
gateway.SPResource(oldMember.Nickname),
|
||||||
gateway.SPImmed(true),
|
gateway.SPImmed(true),
|
||||||
gateway.SPMUCAffiliation(oldMember.Affiliation),
|
gateway.SPMUCAffiliation(oldMember.Affiliation),
|
||||||
|
gateway.SPMUCRole(oldMember.Role),
|
||||||
gateway.SPMUCNick(newNickname),
|
gateway.SPMUCNick(newNickname),
|
||||||
gateway.SPMUCStatusCodes(unavailableStatusCodes),
|
gateway.SPMUCStatusCodes(unavailableStatusCodes),
|
||||||
gateway.SPMUCJid(realJid),
|
gateway.SPMUCJid(realJid),
|
||||||
|
|
@ -756,6 +776,7 @@ func (c *Client) updateMUCsNickname(memberID int64, newNickname string) {
|
||||||
gateway.SPResource(newNickname),
|
gateway.SPResource(newNickname),
|
||||||
gateway.SPImmed(true),
|
gateway.SPImmed(true),
|
||||||
gateway.SPMUCAffiliation(oldMember.Affiliation),
|
gateway.SPMUCAffiliation(oldMember.Affiliation),
|
||||||
|
gateway.SPMUCRole(oldMember.Role),
|
||||||
gateway.SPMUCStatusCodes(availableStatusCodes),
|
gateway.SPMUCStatusCodes(availableStatusCodes),
|
||||||
gateway.SPMUCJid(realJid),
|
gateway.SPMUCJid(realJid),
|
||||||
)
|
)
|
||||||
|
|
@ -1618,7 +1639,7 @@ func (c *Client) ProcessIncomingMessage(chatId int64, message *client.Message) {
|
||||||
if c.Session.MUC && c.IsGroup(chat) {
|
if c.Session.MUC && c.IsGroup(chat) {
|
||||||
if message.Content.MessageContentType() == client.TypeMessageChatDeleteMember {
|
if message.Content.MessageContentType() == client.TypeMessageChatDeleteMember {
|
||||||
deleteMember, _ := message.Content.(*client.MessageChatDeleteMember)
|
deleteMember, _ := message.Content.(*client.MessageChatDeleteMember)
|
||||||
c.kickMemberFromMUC(chatId, deleteMember.UserId, c.GetMUCNickname(deleteMember.UserId))
|
c.mucMemberRolePresence(chatId, deleteMember.UserId, ChatMemberStatusKicked, c.GetMUCNickname(deleteMember.UserId))
|
||||||
}
|
}
|
||||||
|
|
||||||
senderId := c.getMessageSenderId(message)
|
senderId := c.getMessageSenderId(message)
|
||||||
|
|
@ -1636,7 +1657,8 @@ func (c *Client) ProcessIncomingMessage(chatId int64, message *client.Message) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
status = chatMember.Status
|
status = chatMember.Status
|
||||||
}
|
}
|
||||||
safeToSend = c.addMUCMember(chatId, senderId, c.memberStatusToAffiliation(status))
|
affiliation, role := c.memberStatusToAffiliationAndRole(status)
|
||||||
|
safeToSend = c.addMUCMember(chatId, senderId, affiliation, role)
|
||||||
}
|
}
|
||||||
|
|
||||||
groupChatFrom = gateway.MUCJID(chatId) + "/" + c.GetMUCNickname(senderId)
|
groupChatFrom = gateway.MUCJID(chatId) + "/" + c.GetMUCNickname(senderId)
|
||||||
|
|
@ -2441,24 +2463,28 @@ func (c *Client) usernamesToString(usernames []string) string {
|
||||||
return strings.Join(atUsernames, ", ")
|
return strings.Join(atUsernames, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) memberStatusToAffiliation(memberStatus client.ChatMemberStatus) string {
|
func (c *Client) memberStatusToAffiliationAndRole(memberStatus client.ChatMemberStatus) (string, string) {
|
||||||
if memberStatus != nil {
|
if memberStatus != nil {
|
||||||
switch memberStatus.ChatMemberStatusType() {
|
switch memberStatus.ChatMemberStatusType() {
|
||||||
case client.TypeChatMemberStatusCreator:
|
case client.TypeChatMemberStatusCreator:
|
||||||
return "owner"
|
return "owner", "moderator"
|
||||||
case client.TypeChatMemberStatusAdministrator:
|
case client.TypeChatMemberStatusAdministrator:
|
||||||
return "admin"
|
return "admin", "moderator"
|
||||||
case client.TypeChatMemberStatusMember:
|
case client.TypeChatMemberStatusMember:
|
||||||
return "member"
|
return "member", "participant"
|
||||||
case client.TypeChatMemberStatusRestricted:
|
case client.TypeChatMemberStatusRestricted:
|
||||||
return "outcast"
|
restricted, _ := memberStatus.(*client.ChatMemberStatusRestricted)
|
||||||
|
if restricted.Permissions != nil && !restricted.Permissions.CanSendBasicMessages {
|
||||||
|
return "member", "visitor"
|
||||||
|
}
|
||||||
|
return "member", "participant"
|
||||||
case client.TypeChatMemberStatusLeft:
|
case client.TypeChatMemberStatusLeft:
|
||||||
return "none"
|
return "none", "none"
|
||||||
case client.TypeChatMemberStatusBanned:
|
case client.TypeChatMemberStatusBanned:
|
||||||
return "outcast"
|
return "outcast", "none"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "member"
|
return "member", "participant"
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
|
@ -2598,38 +2624,114 @@ func (c *Client) MigrateToMUCs() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kick kicks
|
// SetChatMemberStatus is a handy wrapper for the following TDLib method
|
||||||
func (c *Client) Kick(chatID, userID int64, nickname string) error {
|
func (c *Client) SetChatMemberStatus(chatID, userID int64, status ChatMemberStatus, numericPayload int64, stringPayload, nickname string) error {
|
||||||
|
var chatMemberStatus client.ChatMemberStatus
|
||||||
|
switch status {
|
||||||
|
case ChatMemberStatusKicked:
|
||||||
|
chatMemberStatus = &client.ChatMemberStatusLeft{}
|
||||||
|
case ChatMemberStatusMuted:
|
||||||
|
chatMemberStatus = &client.ChatMemberStatusRestricted{
|
||||||
|
IsMember: true,
|
||||||
|
RestrictedUntilDate: c.formatBantime(numericPayload),
|
||||||
|
Permissions: &permissionsReadonly,
|
||||||
|
}
|
||||||
|
case ChatMemberStatusUnmuted:
|
||||||
|
chatMemberStatus = &client.ChatMemberStatusRestricted{
|
||||||
|
IsMember: true,
|
||||||
|
RestrictedUntilDate: 0,
|
||||||
|
Permissions: &permissionsMember,
|
||||||
|
}
|
||||||
|
case ChatMemberStatusBanned:
|
||||||
|
chatMemberStatus = &client.ChatMemberStatusBanned{
|
||||||
|
BannedUntilDate: c.formatBantime(numericPayload),
|
||||||
|
}
|
||||||
|
case ChatMemberStatusUnbanned:
|
||||||
|
chatMemberStatus = &client.ChatMemberStatusMember{}
|
||||||
|
case ChatMemberStatusPromoted:
|
||||||
|
chatMemberStatus = &client.ChatMemberStatusAdministrator{
|
||||||
|
CanBeEdited: true,
|
||||||
|
Rights: &permissionsAdmin,
|
||||||
|
CustomTitle: stringPayload,
|
||||||
|
}
|
||||||
|
}
|
||||||
_, err := c.client.SetChatMemberStatus(&client.SetChatMemberStatusRequest{
|
_, err := c.client.SetChatMemberStatus(&client.SetChatMemberStatusRequest{
|
||||||
ChatId: chatID,
|
ChatId: chatID,
|
||||||
MemberId: &client.MessageSenderUser{UserId: userID},
|
MemberId: &client.MessageSenderUser{UserId: userID},
|
||||||
Status: &client.ChatMemberStatusLeft{},
|
Status: chatMemberStatus,
|
||||||
})
|
})
|
||||||
if err != nil && nickname != "" {
|
if err == nil && nickname != "" {
|
||||||
c.kickMemberFromMUC(chatID, userID, nickname)
|
c.mucMemberRolePresence(chatID, userID, status, nickname)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) kickMemberFromMUC(chatID, userID int64, nickname string) {
|
func (c *Client) mucMemberRolePresence(chatID, userID int64, status ChatMemberStatus, nickname string) {
|
||||||
unavailableStatusCodes := []uint16{307}
|
args := []args.V{
|
||||||
if c.me != nil && userID == c.me.Id {
|
|
||||||
unavailableStatusCodes = append(unavailableStatusCodes, 110)
|
|
||||||
}
|
|
||||||
c.sendPresence(
|
|
||||||
gateway.SPType("unavailable"),
|
|
||||||
gateway.SPFrom(gateway.MUCNODE(chatID)),
|
gateway.SPFrom(gateway.MUCNODE(chatID)),
|
||||||
gateway.SPResource(nickname),
|
gateway.SPResource(nickname),
|
||||||
gateway.SPImmed(true),
|
gateway.SPImmed(true),
|
||||||
gateway.SPMUCAffiliation("none"),
|
|
||||||
gateway.SPMUCStatusCodes(unavailableStatusCodes),
|
|
||||||
gateway.SPMUCJid(gateway.CHATJID(userID, true)),
|
gateway.SPMUCJid(gateway.CHATJID(userID, true)),
|
||||||
|
}
|
||||||
|
var statusCodes []uint16
|
||||||
|
var newAffiliation, newRole string
|
||||||
|
|
||||||
|
switch status {
|
||||||
|
case ChatMemberStatusKicked:
|
||||||
|
args = append(args, gateway.SPType("unavailable"))
|
||||||
|
newAffiliation = "none"
|
||||||
|
newRole = "none"
|
||||||
|
|
||||||
|
statusCodes = append(statusCodes, 307)
|
||||||
|
if c.me != nil && userID == c.me.Id {
|
||||||
|
statusCodes = append(statusCodes, 110)
|
||||||
|
}
|
||||||
|
case ChatMemberStatusMuted:
|
||||||
|
newAffiliation = "member"
|
||||||
|
newRole = "visitor"
|
||||||
|
case ChatMemberStatusUnmuted, ChatMemberStatusUnbanned:
|
||||||
|
newAffiliation = "member"
|
||||||
|
newRole = "participant"
|
||||||
|
case ChatMemberStatusBanned:
|
||||||
|
args = append(args, gateway.SPType("unavailable"))
|
||||||
|
newAffiliation = "outcast"
|
||||||
|
newRole = "none"
|
||||||
|
statusCodes = append(statusCodes, 301)
|
||||||
|
case ChatMemberStatusPromoted:
|
||||||
|
newAffiliation = "admin"
|
||||||
|
newRole = "moderator"
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(
|
||||||
|
args,
|
||||||
|
gateway.SPMUCAffiliation(newAffiliation),
|
||||||
|
gateway.SPMUCRole(newRole),
|
||||||
|
gateway.SPMUCStatusCodes(statusCodes),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
c.sendPresence(args...)
|
||||||
|
|
||||||
c.locks.mucCacheLock.Lock()
|
c.locks.mucCacheLock.Lock()
|
||||||
mucState, ok := c.mucCache[chatID]
|
mucState, ok := c.mucCache[chatID]
|
||||||
if ok && mucState != nil {
|
if ok && mucState != nil {
|
||||||
delete(mucState.Members, userID)
|
if status == ChatMemberStatusKicked || status == ChatMemberStatusBanned {
|
||||||
|
delete(mucState.Members, userID)
|
||||||
|
} else {
|
||||||
|
member, ok := mucState.Members[userID]
|
||||||
|
if ok {
|
||||||
|
member.Affiliation = newAffiliation
|
||||||
|
member.Role = newRole
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c.locks.mucCacheLock.Unlock()
|
c.locks.mucCacheLock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetErrorCode obtains an error code from a Telegram response error
|
||||||
|
func GetErrorCode(err error) (int32, bool) {
|
||||||
|
responseError, ok := err.(client.ResponseError)
|
||||||
|
if !ok || responseError.Err == nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return responseError.Err.Code, true
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -316,10 +316,12 @@ type QueryMucAdmin struct {
|
||||||
|
|
||||||
// QueryMucAdminItem is a child element from XEP-0045
|
// QueryMucAdminItem is a child element from XEP-0045
|
||||||
type QueryMucAdminItem struct {
|
type QueryMucAdminItem struct {
|
||||||
XMLName xml.Name `xml:"item"`
|
XMLName xml.Name `xml:"item"`
|
||||||
Nick string `xml:"nick,attr"`
|
Jid string `xml:"jid,attr,omitempty"`
|
||||||
Role string `xml:"role,attr"`
|
Nick string `xml:"nick,attr,omitempty"`
|
||||||
Reason string `xml:"reason,omitempty"`
|
Role string `xml:"role,attr,omitempty"`
|
||||||
|
Affiliation string `xml:"affiliation,attr,omitempty"`
|
||||||
|
Reason string `xml:"reason,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Namespace is a namespace!
|
// Namespace is a namespace!
|
||||||
|
|
|
||||||
|
|
@ -438,6 +438,9 @@ var SPImmed = args.NewBool(args.Default(true))
|
||||||
// SPMUCAffiliation is a XEP-0045 MUC affiliation
|
// SPMUCAffiliation is a XEP-0045 MUC affiliation
|
||||||
var SPMUCAffiliation = args.NewString()
|
var SPMUCAffiliation = args.NewString()
|
||||||
|
|
||||||
|
// SPMUCRole is a XEP-0045 MUC role
|
||||||
|
var SPMUCRole = args.NewString()
|
||||||
|
|
||||||
// SPMUCNick is a XEP-0045 MUC user nick
|
// SPMUCNick is a XEP-0045 MUC user nick
|
||||||
var SPMUCNick = args.NewString()
|
var SPMUCNick = args.NewString()
|
||||||
|
|
||||||
|
|
@ -505,10 +508,16 @@ func newPresence(bareJid string, to string, args ...args.V) stanza.Presence {
|
||||||
if SPMUCAffiliation.IsSet(args) {
|
if SPMUCAffiliation.IsSet(args) {
|
||||||
affiliation := SPMUCAffiliation.Get(args)
|
affiliation := SPMUCAffiliation.Get(args)
|
||||||
if affiliation != "" {
|
if affiliation != "" {
|
||||||
|
var role string
|
||||||
|
if SPMUCRole.IsSet(args) {
|
||||||
|
role = SPMUCRole.Get(args)
|
||||||
|
} else {
|
||||||
|
role = affiliationToRole(affiliation)
|
||||||
|
}
|
||||||
userExt := extensions.PresenceXMucUserExtension{
|
userExt := extensions.PresenceXMucUserExtension{
|
||||||
Item: extensions.PresenceXMucUserItem{
|
Item: extensions.PresenceXMucUserItem{
|
||||||
Affiliation: affiliation,
|
Affiliation: affiliation,
|
||||||
Role: affilationToRole(affiliation),
|
Role: role,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if SPMUCNick.IsSet(args) {
|
if SPMUCNick.IsSet(args) {
|
||||||
|
|
@ -625,7 +634,7 @@ func SplitJID(from string) (string, string, bool) {
|
||||||
return fromJid.Bare(), fromJid.Resource, true
|
return fromJid.Bare(), fromJid.Resource, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func affilationToRole(affilation string) string {
|
func affiliationToRole(affilation string) string {
|
||||||
switch affilation {
|
switch affilation {
|
||||||
case "owner", "admin":
|
case "owner", "admin":
|
||||||
return "moderator"
|
return "moderator"
|
||||||
|
|
|
||||||
104
xmpp/handlers.go
104
xmpp/handlers.go
|
|
@ -1602,37 +1602,84 @@ func handleSetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.Quer
|
||||||
}
|
}
|
||||||
defer gateway.ResumableSend(component, answer)
|
defer gateway.ResumableSend(component, answer)
|
||||||
|
|
||||||
if query.Item.Role == "none" {
|
bare, _, fromOk := gateway.SplitJID(iq.From)
|
||||||
bare, _, fromOk := gateway.SplitJID(iq.From)
|
if !fromOk {
|
||||||
if !fromOk {
|
iqAnswerSetError(answer, 400)
|
||||||
iqAnswerSetError(answer, 400)
|
return
|
||||||
return
|
}
|
||||||
}
|
|
||||||
|
|
||||||
session, sessionOk := sessions[bare]
|
session, sessionOk := sessions[bare]
|
||||||
if !sessionOk || !session.Session.MUC {
|
if !sessionOk || !session.Session.MUC {
|
||||||
iqAnswerSetError(answer, 401)
|
iqAnswerSetError(answer, 403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
toID, toOk, toIsGroup := toToID(iq.To)
|
toID, toOk, toIsGroup := toToID(iq.To)
|
||||||
if !toOk || !toIsGroup {
|
if !toOk || !toIsGroup {
|
||||||
iqAnswerSetError(answer, 406)
|
iqAnswerSetError(answer, 406)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userID := session.GetMUCMemberIdByNickname(toID, query.Item.Nick)
|
var userID int64
|
||||||
if userID == 0 {
|
if query.Item.Jid != "" {
|
||||||
iqAnswerSetError(answer, 404)
|
userID, _, _ = toToID(query.Item.Jid)
|
||||||
return
|
} else if query.Item.Nick != "" {
|
||||||
}
|
userID = session.GetMUCMemberIdByNickname(toID, query.Item.Nick)
|
||||||
|
}
|
||||||
|
if userID == 0 {
|
||||||
|
iqAnswerSetError(answer, 404)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
err := session.Kick(toID, userID, query.Item.Nick)
|
nick := query.Item.Nick
|
||||||
if err != nil {
|
if nick == "" {
|
||||||
iqAnswerSetError(answer, 500)
|
nick = session.GetMUCNickname(userID)
|
||||||
answer.Error.Text = err.Error()
|
}
|
||||||
return
|
|
||||||
|
var status telegram.ChatMemberStatus
|
||||||
|
var integerPayload int64
|
||||||
|
var stringPayload string
|
||||||
|
|
||||||
|
switch query.Item.Role {
|
||||||
|
case "none":
|
||||||
|
status = telegram.ChatMemberStatusKicked
|
||||||
|
case "visitor":
|
||||||
|
status = telegram.ChatMemberStatusMuted
|
||||||
|
case "participant":
|
||||||
|
status = telegram.ChatMemberStatusUnmuted
|
||||||
|
case "moderator":
|
||||||
|
status = telegram.ChatMemberStatusPromoted
|
||||||
|
}
|
||||||
|
// affiliations have a higher priority over roles
|
||||||
|
switch query.Item.Affiliation {
|
||||||
|
case "none":
|
||||||
|
status = telegram.ChatMemberStatusKicked
|
||||||
|
case "outcast":
|
||||||
|
status = telegram.ChatMemberStatusBanned
|
||||||
|
case "member":
|
||||||
|
status = telegram.ChatMemberStatusUnmuted
|
||||||
|
case "admin":
|
||||||
|
status = telegram.ChatMemberStatusPromoted
|
||||||
|
case "owner":
|
||||||
|
iqAnswerSetError(answer, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// nothing has been detected
|
||||||
|
if status == telegram.ChatMemberStatusIllegal {
|
||||||
|
iqAnswerSetError(answer, 400)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := session.SetChatMemberStatus(toID, userID, status, integerPayload, stringPayload, nick)
|
||||||
|
if err != nil {
|
||||||
|
code, ok := telegram.GetErrorCode(err)
|
||||||
|
if !ok {
|
||||||
|
code = 500
|
||||||
}
|
}
|
||||||
|
iqAnswerSetError(answer, int(code))
|
||||||
|
answer.Error.Text = err.Error()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1658,6 +1705,11 @@ func iqAnswerSetErrorInternal(answer *stanza.IQ, code int, registerMode bool) {
|
||||||
Type: stanza.ErrorTypeAuth,
|
Type: stanza.ErrorTypeAuth,
|
||||||
Reason: "not-authorized",
|
Reason: "not-authorized",
|
||||||
}
|
}
|
||||||
|
case 403:
|
||||||
|
answer.Error = &stanza.Err{
|
||||||
|
Type: stanza.ErrorTypeAuth,
|
||||||
|
Reason: "forbidden",
|
||||||
|
}
|
||||||
case 404:
|
case 404:
|
||||||
answer.Error = &stanza.Err{
|
answer.Error = &stanza.Err{
|
||||||
Type: stanza.ErrorTypeCancel,
|
Type: stanza.ErrorTypeCancel,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue