mirror of
https://dev.narayana.im/narayana/telegabber.git
synced 2026-08-05 04:07:07 +00:00
Room configuration form
This commit is contained in:
parent
cef56ca484
commit
f18fded3e9
3 changed files with 244 additions and 5 deletions
|
|
@ -2683,6 +2683,53 @@ func (c *Client) SetChatMemberStatus(chatID, userID int64, status ChatMemberStat
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetChatTitle is a handy wrapper for the following TDLib method
|
||||||
|
func (c *Client) SetChatTitle(chatID int64, title string) error {
|
||||||
|
_, err := c.client.SetChatTitle(&client.SetChatTitleRequest{
|
||||||
|
ChatId: chatID,
|
||||||
|
Title: title,
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetChatDescription is a handy wrapper for the following TDLib method
|
||||||
|
func (c *Client) SetChatDescription(chatID int64, description string) error {
|
||||||
|
_, err := c.client.SetChatDescription(&client.SetChatDescriptionRequest{
|
||||||
|
ChatId: chatID,
|
||||||
|
Description: description,
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetChatPermissions is a handy wrapper for the following TDLib method
|
||||||
|
func (c *Client) SetChatPermissions(chatID int64, permissions *client.ChatPermissions) error {
|
||||||
|
_, err := c.client.SetChatPermissions(&client.SetChatPermissionsRequest{
|
||||||
|
ChatId: chatID,
|
||||||
|
Permissions: permissions,
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloneChatPermissions makes a copy of ChatPermissions structure
|
||||||
|
func CloneChatPermissions(permissions *client.ChatPermissions) *client.ChatPermissions {
|
||||||
|
return &client.ChatPermissions{
|
||||||
|
CanSendBasicMessages: permissions.CanSendBasicMessages,
|
||||||
|
CanSendAudios: permissions.CanSendAudios,
|
||||||
|
CanSendDocuments: permissions.CanSendDocuments,
|
||||||
|
CanSendPhotos: permissions.CanSendPhotos,
|
||||||
|
CanSendVideos: permissions.CanSendVideos,
|
||||||
|
CanSendVideoNotes: permissions.CanSendVideoNotes,
|
||||||
|
CanSendVoiceNotes: permissions.CanSendVoiceNotes,
|
||||||
|
CanSendPolls: permissions.CanSendPolls,
|
||||||
|
CanSendOtherMessages: permissions.CanSendOtherMessages,
|
||||||
|
CanAddWebPagePreviews: permissions.CanAddWebPagePreviews,
|
||||||
|
CanChangeInfo: permissions.CanChangeInfo,
|
||||||
|
CanInviteUsers: permissions.CanInviteUsers,
|
||||||
|
CanPinMessages: permissions.CanPinMessages,
|
||||||
|
CanManageTopics: permissions.CanManageTopics,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) mucOccupantRolePresence(chatID, userID int64, status ChatMemberStatus, nickname string) {
|
func (c *Client) mucOccupantRolePresence(chatID, userID int64, status ChatMemberStatus, nickname string) {
|
||||||
args := []args.V{
|
args := []args.V{
|
||||||
gateway.SPFrom(gateway.MUCNODE(chatID)),
|
gateway.SPFrom(gateway.MUCNODE(chatID)),
|
||||||
|
|
|
||||||
|
|
@ -327,6 +327,7 @@ type QueryMucAdminItem struct {
|
||||||
// QueryMucOwner is from XEP-0045
|
// QueryMucOwner is from XEP-0045
|
||||||
type QueryMucOwner struct {
|
type QueryMucOwner struct {
|
||||||
XMLName xml.Name `xml:"http://jabber.org/protocol/muc#owner query"`
|
XMLName xml.Name `xml:"http://jabber.org/protocol/muc#owner query"`
|
||||||
|
Form *stanza.Form `xml:"jabber:x:data x`
|
||||||
ResultSet *stanza.ResultSet `xml:"set,omitempty"`
|
ResultSet *stanza.ResultSet `xml:"set,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
201
xmpp/handlers.go
201
xmpp/handlers.go
|
|
@ -26,6 +26,8 @@ const (
|
||||||
TypeVCard4
|
TypeVCard4
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const MUC_DEFAULT_HISTORY_LIMIT int32 = 20
|
||||||
|
|
||||||
func logPacketType(p stanza.Packet) {
|
func logPacketType(p stanza.Packet) {
|
||||||
log.Warnf("Ignoring packet: %T\n", p)
|
log.Warnf("Ignoring packet: %T\n", p)
|
||||||
}
|
}
|
||||||
|
|
@ -97,6 +99,11 @@ func HandleIq(s xmpp.Sender, p stanza.Packet) {
|
||||||
go handleSetQueryMucAdmin(s, iq, queryMucAdmin)
|
go handleSetQueryMucAdmin(s, iq, queryMucAdmin)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
queryMucOwner, ok := iq.Payload.(*extensions.QueryMucOwner)
|
||||||
|
if ok {
|
||||||
|
go handleSetQueryMucOwner(s, iq, queryMucOwner)
|
||||||
|
return
|
||||||
|
}
|
||||||
} else if iq.Type == stanza.IQTypeResult {
|
} else if iq.Type == stanza.IQTypeResult {
|
||||||
discoInfo, ok := iq.Payload.(*stanza.DiscoInfo)
|
discoInfo, ok := iq.Payload.(*stanza.DiscoInfo)
|
||||||
if ok {
|
if ok {
|
||||||
|
|
@ -603,7 +610,7 @@ func handleMUCPresence(s xmpp.Sender, p stanza.Presence, mucExt stanza.MucPresen
|
||||||
} else if !mucExt.History.Since.IsZero() {
|
} else if !mucExt.History.Since.IsZero() {
|
||||||
limit = telegram.NewMessageLimitSince(mucExt.History.Since.Unix())
|
limit = telegram.NewMessageLimitSince(mucExt.History.Since.Unix())
|
||||||
} else {
|
} else {
|
||||||
limit = telegram.NewMessageLimitMessages(20)
|
limit = telegram.NewMessageLimitMessages(MUC_DEFAULT_HISTORY_LIMIT)
|
||||||
}
|
}
|
||||||
session.JoinMUC(chatId, fromResource, limit)
|
session.JoinMUC(chatId, fromResource, limit)
|
||||||
}
|
}
|
||||||
|
|
@ -1181,6 +1188,12 @@ func handleGetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.Quer
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chat, _, err := session.GetContactByID(toID, nil)
|
||||||
|
if err != nil || !session.IsGroup(chat) {
|
||||||
|
iqAnswerSetError(answer, 405)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if len(query.Items) != 1 {
|
if len(query.Items) != 1 {
|
||||||
iqAnswerSetError(answer, 400)
|
iqAnswerSetError(answer, 400)
|
||||||
return
|
return
|
||||||
|
|
@ -1216,8 +1229,6 @@ func handleGetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.Quer
|
||||||
|
|
||||||
members, err := session.GetChatMembers(toID, false, "", membersList)
|
members, err := session.GetChatMembers(toID, false, "", membersList)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
chat, _, _ := session.GetContactByID(toID, nil)
|
|
||||||
|
|
||||||
for _, member := range members {
|
for _, member := range members {
|
||||||
senderId, nickname, affiliation, role := session.TgMemberToMUCOccupant(member, chat)
|
senderId, nickname, affiliation, role := session.TgMemberToMUCOccupant(member, chat)
|
||||||
if item.Role != "" && role != item.Role {
|
if item.Role != "" && role != item.Role {
|
||||||
|
|
@ -1241,8 +1252,69 @@ func handleGetQueryMucOwner(s xmpp.Sender, iq *stanza.IQ) {
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
iqAnswerSetError(answer, 405)
|
defer gateway.ResumableSend(component, answer)
|
||||||
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, 405)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chat, _, err := session.GetContactByID(toID, nil)
|
||||||
|
if err != nil || chat == nil || !session.IsGroup(chat) {
|
||||||
|
iqAnswerSetError(answer, 405)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
payload := &extensions.QueryMucOwner{}
|
||||||
|
answer.Payload = payload
|
||||||
|
|
||||||
|
dummyString := ""
|
||||||
|
changeSubject := "1"
|
||||||
|
if chat.Permissions != nil && !chat.Permissions.CanPinMessages {
|
||||||
|
changeSubject = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.Form = &stanza.Form{
|
||||||
|
Type: stanza.FormTypeForm,
|
||||||
|
Title: fmt.Sprintf("Configuration for \"%v\" room", chat.Title),
|
||||||
|
Fields: []*stanza.Field{
|
||||||
|
&stanza.Field{
|
||||||
|
Var: "FORM_TYPE",
|
||||||
|
Type: stanza.FieldTypeHidden,
|
||||||
|
ValuesList: []string{"http://jabber.org/protocol/muc#roominfo"},
|
||||||
|
},
|
||||||
|
&stanza.Field{
|
||||||
|
Var: "muc#roomconfig_roomname",
|
||||||
|
Label: "Group name",
|
||||||
|
Required: &dummyString,
|
||||||
|
ValuesList: []string{chat.Title},
|
||||||
|
},
|
||||||
|
&stanza.Field{
|
||||||
|
Var: "muc#roomconfig_roomdesc",
|
||||||
|
Label: "Description (optional)",
|
||||||
|
ValuesList: []string{session.GetChatDescription(chat)},
|
||||||
|
},
|
||||||
|
&stanza.Field{
|
||||||
|
Var: "muc#roomconfig_changesubject",
|
||||||
|
Label: "Allow Occupants to Change Subject?",
|
||||||
|
Type: stanza.FieldTypeBool,
|
||||||
|
ValuesList: []string{changeSubject},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleSetQueryRegister(s xmpp.Sender, iq *stanza.IQ, query *extensions.QueryRegister) {
|
func handleSetQueryRegister(s xmpp.Sender, iq *stanza.IQ, query *extensions.QueryRegister) {
|
||||||
|
|
@ -1796,6 +1868,113 @@ func handleSetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.Quer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleSetQueryMucOwner(s xmpp.Sender, iq *stanza.IQ, query *extensions.QueryMucOwner) {
|
||||||
|
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, 405)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chat, _, err := session.GetContactByID(toID, nil)
|
||||||
|
if err != nil || chat == nil || !session.IsGroup(chat) {
|
||||||
|
iqAnswerSetError(answer, 405)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if query.Form == nil {
|
||||||
|
iqAnswerSetError(answer, 400)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch query.Form.Type {
|
||||||
|
case stanza.FormTypeSubmit:
|
||||||
|
// okay, noop
|
||||||
|
case stanza.FormTypeCancel:
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
iqAnswerSetError(answer, 400)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = nil
|
||||||
|
for _, field := range query.Form.Fields {
|
||||||
|
switch field.Var {
|
||||||
|
case "muc#roomconfig_roomname", "muc#roomconfig_roomdesc", "muc#roomconfig_changesubject":
|
||||||
|
if len(field.ValuesList) != 1 {
|
||||||
|
iqAnswerSetError(answer, 400)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
value := field.ValuesList[0]
|
||||||
|
|
||||||
|
switch field.Var {
|
||||||
|
case "muc#roomconfig_roomname":
|
||||||
|
if value == "" {
|
||||||
|
iqAnswerSetError(answer, 400)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if value != chat.Title {
|
||||||
|
err = session.SetChatTitle(toID, value)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "muc#roomconfig_roomdesc":
|
||||||
|
if value != session.GetChatDescription(chat) {
|
||||||
|
err = session.SetChatDescription(toID, value)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "muc#roomconfig_changesubject":
|
||||||
|
b, ok := ToBool(value)
|
||||||
|
if !ok {
|
||||||
|
iqAnswerSetError(answer, 400)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
permissions := chat.Permissions
|
||||||
|
if permissions != nil && b != permissions.CanPinMessages {
|
||||||
|
newPermissions := telegram.CloneChatPermissions(permissions)
|
||||||
|
newPermissions.CanPinMessages = b
|
||||||
|
|
||||||
|
err = session.SetChatPermissions(toID, newPermissions)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
code, ok := telegram.GetErrorCode(err)
|
||||||
|
if !ok {
|
||||||
|
code = 500
|
||||||
|
}
|
||||||
|
iqAnswerSetError(answer, int(code))
|
||||||
|
answer.Error.Text = err.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func iqAnswerSetError(answer *stanza.IQ, code int) {
|
func iqAnswerSetError(answer *stanza.IQ, code int) {
|
||||||
iqAnswerSetErrorInternal(answer, code, false)
|
iqAnswerSetErrorInternal(answer, code, false)
|
||||||
}
|
}
|
||||||
|
|
@ -2124,3 +2303,15 @@ func makeVCardPayload(typ byte, id string, info telegram.VCardInfo, session *tel
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToBool returns bool, ok
|
||||||
|
func ToBool(b string) (bool, bool) {
|
||||||
|
switch b {
|
||||||
|
case "0", "false":
|
||||||
|
return false, true
|
||||||
|
case "1", "true":
|
||||||
|
return true, true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, false
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue