diff options
Diffstat (limited to 'xmpp/handlers.go')
-rw-r--r-- | xmpp/handlers.go | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/xmpp/handlers.go b/xmpp/handlers.go index 6f51427..a1f6d74 100644 --- a/xmpp/handlers.go +++ b/xmpp/handlers.go @@ -287,6 +287,12 @@ func HandlePresence(s xmpp.Sender, p stanza.Packet) { } if prs.To == gateway.Jid.Bare() { handlePresence(s, prs) + return + } + var mucExt stanza.MucPresence + prs.Get(&mucExt) + if mucExt.XMLName.Space != "" { + handleMUCPresence(s, prs) } } @@ -397,6 +403,64 @@ func handlePresence(s xmpp.Sender, p stanza.Presence) { } } +func handleMUCPresence(s xmpp.Sender, p stanza.Presence) { + log.WithFields(log.Fields{ + "type": p.Type, + "from": p.From, + "to": p.To, + }).Warn("MUC presence") + log.Debugf("%#v", p) + + if p.Type == "" { + toBare, nickname, ok := gateway.SplitJID(p.To) + if ok { + component, ok := s.(*xmpp.Component) + if !ok { + log.Error("Not a component") + return + } + + reply := stanza.Presence{Attrs: stanza.Attrs{ + From: toBare, + To: p.From, + Id: p.Id, + }} + defer gateway.ResumableSend(component, reply) + + if nickname == "" { + presenceReplySetError(&reply, 400) + return + } + + chatId, ok := toToID(toBare) + if !ok { + presenceReplySetError(&reply, 404) + return + } + + fromBare, _, ok := gateway.SplitJID(p.From) + if !ok { + presenceReplySetError(&reply, 400) + return + } + + session, ok := sessions[fromBare] + if !ok || !session.Session.MUC { + presenceReplySetError(&reply, 401) + return + } + + chat, _, err := session.GetContactByID(chatId, nil) + if err != nil || !session.IsGroup(chat) { + presenceReplySetError(&reply, 404) + return + } + + session.SendMUCStatuses(chatId) + } + } +} + func handleGetVcardIq(s xmpp.Sender, iq *stanza.IQ, typ byte) { log.WithFields(log.Fields{ "from": iq.From, @@ -711,6 +775,28 @@ func iqAnswerSetError(answer *stanza.IQ, payload *extensions.QueryRegister, code } } +func presenceReplySetError(reply *stanza.Presence, code int) { + reply.Type = stanza.PresenceTypeError + reply.Error = stanza.Err{ + Code: code, + } + switch code { + case 400: + reply.Error.Type = stanza.ErrorTypeModify + reply.Error.Reason = "jid-malformed" + case 401: + reply.Error.Type = stanza.ErrorTypeAuth + reply.Error.Reason = "not-authorized" + case 404: + reply.Error.Type = stanza.ErrorTypeCancel + reply.Error.Reason = "item-not-found" + default: + log.Error("Unknown error code, falling back with empty reason") + reply.Error.Type = stanza.ErrorTypeCancel + reply.Error.Reason = "undefined-condition" + } +} + func toToID(to string) (int64, bool) { toParts := strings.Split(to, "@") if len(toParts) < 2 { |