|
|
@ -3,6 +3,7 @@ package xmpp
|
|
|
|
import (
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"bytes"
|
|
|
|
"encoding/base64"
|
|
|
|
"encoding/base64"
|
|
|
|
|
|
|
|
"encoding/xml"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"io"
|
|
|
|
"io"
|
|
|
|
"strconv"
|
|
|
|
"strconv"
|
|
|
@ -17,6 +18,12 @@ import (
|
|
|
|
"gosrc.io/xmpp/stanza"
|
|
|
|
"gosrc.io/xmpp/stanza"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
|
|
|
TypeVCardTemp byte = iota
|
|
|
|
|
|
|
|
TypeVCard4
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
const NodeVCard4 string = "urn:xmpp:vcard4"
|
|
|
|
|
|
|
|
|
|
|
|
func logPacketType(p stanza.Packet) {
|
|
|
|
func logPacketType(p stanza.Packet) {
|
|
|
|
log.Warnf("Ignoring packet: %T\n", p)
|
|
|
|
log.Warnf("Ignoring packet: %T\n", p)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -33,9 +40,16 @@ func HandleIq(s xmpp.Sender, p stanza.Packet) {
|
|
|
|
if iq.Type == "get" {
|
|
|
|
if iq.Type == "get" {
|
|
|
|
_, ok := iq.Payload.(*extensions.IqVcardTemp)
|
|
|
|
_, ok := iq.Payload.(*extensions.IqVcardTemp)
|
|
|
|
if ok {
|
|
|
|
if ok {
|
|
|
|
go handleGetVcardTempIq(s, iq)
|
|
|
|
go handleGetVcardIq(s, iq, TypeVCardTemp)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pubsub, ok := iq.Payload.(*stanza.PubSubGeneric)
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
|
|
|
if pubsub.Items != nil && pubsub.Items.Node == NodeVCard4 {
|
|
|
|
|
|
|
|
go handleGetVcardIq(s, iq, TypeVCard4)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
_, ok = iq.Payload.(*stanza.DiscoInfo)
|
|
|
|
_, ok = iq.Payload.(*stanza.DiscoInfo)
|
|
|
|
if ok {
|
|
|
|
if ok {
|
|
|
|
go handleGetDiscoInfo(s, iq)
|
|
|
|
go handleGetDiscoInfo(s, iq)
|
|
|
@ -216,7 +230,7 @@ func handlePresence(s xmpp.Sender, p stanza.Presence) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func handleGetVcardTempIq(s xmpp.Sender, iq *stanza.IQ) {
|
|
|
|
func handleGetVcardIq(s xmpp.Sender, iq *stanza.IQ, typ byte) {
|
|
|
|
log.WithFields(log.Fields{
|
|
|
|
log.WithFields(log.Fields{
|
|
|
|
"from": iq.From,
|
|
|
|
"from": iq.From,
|
|
|
|
"to": iq.To,
|
|
|
|
"to": iq.To,
|
|
|
@ -246,9 +260,9 @@ func handleGetVcardTempIq(s xmpp.Sender, iq *stanza.IQ) {
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vcard := extensions.IqVcardTemp{}
|
|
|
|
var fn, photo, nickname, given, family, tel string
|
|
|
|
if chat != nil {
|
|
|
|
if chat != nil {
|
|
|
|
vcard.Fn.Text = chat.Title
|
|
|
|
fn = chat.Title
|
|
|
|
|
|
|
|
|
|
|
|
if chat.Photo != nil {
|
|
|
|
if chat.Photo != nil {
|
|
|
|
file, path, err := session.OpenPhotoFile(chat.Photo.Small, 32)
|
|
|
|
file, path, err := session.OpenPhotoFile(chat.Photo.Small, 32)
|
|
|
@ -260,8 +274,7 @@ func handleGetVcardTempIq(s xmpp.Sender, iq *stanza.IQ) {
|
|
|
|
_, err = io.Copy(binval, file)
|
|
|
|
_, err = io.Copy(binval, file)
|
|
|
|
binval.Close()
|
|
|
|
binval.Close()
|
|
|
|
if err == nil {
|
|
|
|
if err == nil {
|
|
|
|
vcard.Photo.Type.Text = "image/jpeg"
|
|
|
|
photo = buf.String()
|
|
|
|
vcard.Photo.Binval.Text = buf.String()
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
log.Errorf("Error calculating base64: %v", path)
|
|
|
|
log.Errorf("Error calculating base64: %v", path)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -273,10 +286,10 @@ func handleGetVcardTempIq(s xmpp.Sender, iq *stanza.IQ) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if user != nil {
|
|
|
|
if user != nil {
|
|
|
|
vcard.Nickname.Text = user.Username
|
|
|
|
nickname = user.Username
|
|
|
|
vcard.N.Given.Text = user.FirstName
|
|
|
|
given = user.FirstName
|
|
|
|
vcard.N.Family.Text = user.LastName
|
|
|
|
family = user.LastName
|
|
|
|
vcard.Tel.Number.Text = user.PhoneNumber
|
|
|
|
tel = user.PhoneNumber
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
answer := stanza.IQ{
|
|
|
|
answer := stanza.IQ{
|
|
|
@ -286,7 +299,7 @@ func handleGetVcardTempIq(s xmpp.Sender, iq *stanza.IQ) {
|
|
|
|
Id: iq.Id,
|
|
|
|
Id: iq.Id,
|
|
|
|
Type: "result",
|
|
|
|
Type: "result",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Payload: vcard,
|
|
|
|
Payload: makeVCardPayload(typ, iq.To, fn, photo, nickname, given, family, tel),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.Debugf("%#v", answer)
|
|
|
|
log.Debugf("%#v", answer)
|
|
|
|
|
|
|
|
|
|
|
@ -357,3 +370,107 @@ func toToID(to string) (int64, bool) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return toID, true
|
|
|
|
return toID, true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func makeVCardPayload(typ byte, id string, fn string, photo string, nickname string, given string, family string, tel string) stanza.IQPayload {
|
|
|
|
|
|
|
|
if typ == TypeVCardTemp {
|
|
|
|
|
|
|
|
vcard := &extensions.IqVcardTemp{}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vcard.Fn.Text = fn
|
|
|
|
|
|
|
|
if photo != "" {
|
|
|
|
|
|
|
|
vcard.Photo.Type.Text = "image/jpeg"
|
|
|
|
|
|
|
|
vcard.Photo.Binval.Text = photo
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
vcard.Nickname.Text = nickname
|
|
|
|
|
|
|
|
vcard.N.Given.Text = given
|
|
|
|
|
|
|
|
vcard.N.Family.Text = family
|
|
|
|
|
|
|
|
vcard.Tel.Number.Text = tel
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return vcard
|
|
|
|
|
|
|
|
} else if typ == TypeVCard4 {
|
|
|
|
|
|
|
|
nodes := []stanza.Node{}
|
|
|
|
|
|
|
|
if fn != "" {
|
|
|
|
|
|
|
|
nodes = append(nodes, stanza.Node{
|
|
|
|
|
|
|
|
XMLName: xml.Name{Local: "fn"},
|
|
|
|
|
|
|
|
Nodes: []stanza.Node{
|
|
|
|
|
|
|
|
stanza.Node{
|
|
|
|
|
|
|
|
XMLName: xml.Name{Local: "text"},
|
|
|
|
|
|
|
|
Content: fn,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if photo != "" {
|
|
|
|
|
|
|
|
nodes = append(nodes, stanza.Node{
|
|
|
|
|
|
|
|
XMLName: xml.Name{Local: "photo"},
|
|
|
|
|
|
|
|
Nodes: []stanza.Node{
|
|
|
|
|
|
|
|
stanza.Node{
|
|
|
|
|
|
|
|
XMLName: xml.Name{Local: "uri"},
|
|
|
|
|
|
|
|
Content: "data:image/jpeg;base64," + photo,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if nickname != "" {
|
|
|
|
|
|
|
|
nodes = append(nodes, stanza.Node{
|
|
|
|
|
|
|
|
XMLName: xml.Name{Local: "nickname"},
|
|
|
|
|
|
|
|
Nodes: []stanza.Node{
|
|
|
|
|
|
|
|
stanza.Node{
|
|
|
|
|
|
|
|
XMLName: xml.Name{Local: "text"},
|
|
|
|
|
|
|
|
Content: nickname,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if family != "" || given != "" {
|
|
|
|
|
|
|
|
nodes = append(nodes, stanza.Node{
|
|
|
|
|
|
|
|
XMLName: xml.Name{Local: "n"},
|
|
|
|
|
|
|
|
Nodes: []stanza.Node{
|
|
|
|
|
|
|
|
stanza.Node{
|
|
|
|
|
|
|
|
XMLName: xml.Name{Local: "surname"},
|
|
|
|
|
|
|
|
Content: family,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
stanza.Node{
|
|
|
|
|
|
|
|
XMLName: xml.Name{Local: "given"},
|
|
|
|
|
|
|
|
Content: given,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if tel != "" {
|
|
|
|
|
|
|
|
nodes = append(nodes, stanza.Node{
|
|
|
|
|
|
|
|
XMLName: xml.Name{Local: "tel"},
|
|
|
|
|
|
|
|
Nodes: []stanza.Node{
|
|
|
|
|
|
|
|
stanza.Node{
|
|
|
|
|
|
|
|
XMLName: xml.Name{Local: "uri"},
|
|
|
|
|
|
|
|
Content: "tel:" + tel,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pubsub := &stanza.PubSubGeneric{
|
|
|
|
|
|
|
|
Items: &stanza.Items{
|
|
|
|
|
|
|
|
Node: NodeVCard4,
|
|
|
|
|
|
|
|
List: []stanza.Item{
|
|
|
|
|
|
|
|
stanza.Item{
|
|
|
|
|
|
|
|
Id: id,
|
|
|
|
|
|
|
|
Any: &stanza.Node{
|
|
|
|
|
|
|
|
XMLName: xml.Name{Local: "vcard"},
|
|
|
|
|
|
|
|
Attrs: []xml.Attr{
|
|
|
|
|
|
|
|
xml.Attr{
|
|
|
|
|
|
|
|
Name: xml.Name{Local: "xmlns"},
|
|
|
|
|
|
|
|
Value: "urn:ietf:params:xml:ns:vcard-4.0",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
Nodes: nodes,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return pubsub
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
|
|
}
|
|
|
|