aboutsummaryrefslogtreecommitdiff
path: root/xmpp/handlers.go
diff options
context:
space:
mode:
Diffstat (limited to 'xmpp/handlers.go')
-rw-r--r--xmpp/handlers.go86
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 {