aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBohdan Horbeshko <bodqhrohro@gmail.com>2022-06-29 02:34:14 +0300
committerBohdan Horbeshko <bodqhrohro@gmail.com>2022-06-29 02:34:14 +0300
commit76ac66236612315860538a73334e6c7d10c7c4b4 (patch)
tree8de3c83e7a736fbd4bd15944a1ec52104b7b131b
parent3a43c6223f7f4f21dda0a484ef3ec858102c836c (diff)
Support vCard4 via PubSub
-rw-r--r--xmpp/extensions/extensions.go2
-rw-r--r--xmpp/handlers.go139
2 files changed, 129 insertions, 12 deletions
diff --git a/xmpp/extensions/extensions.go b/xmpp/extensions/extensions.go
index 284dd91..878770a 100644
--- a/xmpp/extensions/extensions.go
+++ b/xmpp/extensions/extensions.go
@@ -119,7 +119,7 @@ func (c IqVcardTemp) Namespace() string {
return c.XMLName.Space
}
-// Namespace is a namespace!
+// GetSet getsets!
func (c IqVcardTemp) GetSet() *stanza.ResultSet {
return c.ResultSet
}
diff --git a/xmpp/handlers.go b/xmpp/handlers.go
index 870a292..06bc02b 100644
--- a/xmpp/handlers.go
+++ b/xmpp/handlers.go
@@ -3,6 +3,7 @@ package xmpp
import (
"bytes"
"encoding/base64"
+ "encoding/xml"
"github.com/pkg/errors"
"io"
"strconv"
@@ -17,6 +18,12 @@ import (
"gosrc.io/xmpp/stanza"
)
+const (
+ TypeVCardTemp byte = iota
+ TypeVCard4
+)
+const NodeVCard4 string = "urn:xmpp:vcard4"
+
func logPacketType(p stanza.Packet) {
log.Warnf("Ignoring packet: %T\n", p)
}
@@ -33,9 +40,16 @@ func HandleIq(s xmpp.Sender, p stanza.Packet) {
if iq.Type == "get" {
_, ok := iq.Payload.(*extensions.IqVcardTemp)
if ok {
- go handleGetVcardTempIq(s, iq)
+ go handleGetVcardIq(s, iq, TypeVCardTemp)
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)
if ok {
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{
"from": iq.From,
"to": iq.To,
@@ -246,9 +260,9 @@ func handleGetVcardTempIq(s xmpp.Sender, iq *stanza.IQ) {
return
}
- vcard := extensions.IqVcardTemp{}
+ var fn, photo, nickname, given, family, tel string
if chat != nil {
- vcard.Fn.Text = chat.Title
+ fn = chat.Title
if chat.Photo != nil {
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)
binval.Close()
if err == nil {
- vcard.Photo.Type.Text = "image/jpeg"
- vcard.Photo.Binval.Text = buf.String()
+ photo = buf.String()
} else {
log.Errorf("Error calculating base64: %v", path)
}
@@ -273,10 +286,10 @@ func handleGetVcardTempIq(s xmpp.Sender, iq *stanza.IQ) {
}
}
if user != nil {
- vcard.Nickname.Text = user.Username
- vcard.N.Given.Text = user.FirstName
- vcard.N.Family.Text = user.LastName
- vcard.Tel.Number.Text = user.PhoneNumber
+ nickname = user.Username
+ given = user.FirstName
+ family = user.LastName
+ tel = user.PhoneNumber
}
answer := stanza.IQ{
@@ -286,7 +299,7 @@ func handleGetVcardTempIq(s xmpp.Sender, iq *stanza.IQ) {
Id: iq.Id,
Type: "result",
},
- Payload: vcard,
+ Payload: makeVCardPayload(typ, iq.To, fn, photo, nickname, given, family, tel),
}
log.Debugf("%#v", answer)
@@ -357,3 +370,107 @@ func toToID(to string) (int64, bool) {
}
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
+}