|
|
|
@ -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 {
|
|
|
|
|