aboutsummaryrefslogtreecommitdiff
path: root/xmpp
diff options
context:
space:
mode:
authorbodqhrohro <bodqhrohro@gmail.com>2019-12-10 21:34:55 +0300
committerbodqhrohro <bodqhrohro@gmail.com>2019-12-10 21:34:55 +0300
commit416c70890950f76ce6f5ce902ea9a70165239f56 (patch)
tree2f9889d6d9448e3f7226cfa51d9bbe2e5fcde752 /xmpp
parentae2470dcb70c302bd3fbcd53ffa7384f526435bd (diff)
vCard support
Diffstat (limited to 'xmpp')
-rw-r--r--xmpp/extensions/extensions.go90
-rw-r--r--xmpp/handlers.go84
2 files changed, 173 insertions, 1 deletions
diff --git a/xmpp/extensions/extensions.go b/xmpp/extensions/extensions.go
index ec94837..594140f 100644
--- a/xmpp/extensions/extensions.go
+++ b/xmpp/extensions/extensions.go
@@ -24,6 +24,85 @@ type PresenceXVCardUpdatePhoto struct {
Text string `xml:",chardata"`
}
+// IqVcardTemp is from XEP-0054
+type IqVcardTemp struct {
+ XMLName xml.Name `xml:"vcard-temp vCard"`
+ Fn IqVcardFn
+ Nickname IqVcardNickname
+ N IqVcardN
+ Tel IqVcardTel
+ Photo IqVcardPhoto
+}
+
+// IqVcardFn is vCard/FN
+type IqVcardFn struct {
+ XMLName xml.Name `xml:"FN"`
+ Text string `xml:",chardata"`
+}
+
+// IqVcardNickname is vCard/NICKNAME
+type IqVcardNickname struct {
+ XMLName xml.Name `xml:"NICKNAME"`
+ Text string `xml:",chardata"`
+}
+
+// IqVcardN is vCard/N
+type IqVcardN struct {
+ XMLName xml.Name `xml:"N"`
+ Family IqVcardNFamily
+ Given IqVcardNGiven
+ Middle IqVcardNMiddle
+}
+
+// IqVcardNFamily is vCard/N/FAMILY
+type IqVcardNFamily struct {
+ XMLName xml.Name `xml:"FAMILY"`
+ Text string `xml:",chardata"`
+}
+
+// IqVcardNGiven is vCard/N/GIVEN
+type IqVcardNGiven struct {
+ XMLName xml.Name `xml:"GIVEN"`
+ Text string `xml:",chardata"`
+}
+
+// IqVcardNMiddle is vCard/N/MIDDLE
+type IqVcardNMiddle struct {
+ XMLName xml.Name `xml:"MIDDLE"`
+ Text string `xml:",chardata"`
+}
+
+// IqVcardTel is vCard/TEL
+type IqVcardTel struct {
+ XMLName xml.Name `xml:"TEL"`
+ Number IqVcardTelNumber
+}
+
+// IqVcardTelNumber is vCard/TEL/NUMBER
+type IqVcardTelNumber struct {
+ XMLName xml.Name `xml:"NUMBER"`
+ Text string `xml:",chardata"`
+}
+
+// IqVcardPhoto is vCard/PHOTO
+type IqVcardPhoto struct {
+ XMLName xml.Name `xml:"PHOTO"`
+ Type IqVcardPhotoType
+ Binval IqVcardPhotoBinval
+}
+
+// IqVcardPhotoType is vCard/PHOTO/TYPE
+type IqVcardPhotoType struct {
+ XMLName xml.Name `xml:"TYPE"`
+ Text string `xml:",chardata"`
+}
+
+// IqVcardPhotoBinval is vCard/PHOTO/BINVAL
+type IqVcardPhotoBinval struct {
+ XMLName xml.Name `xml:"BINVAL"`
+ Text string `xml:",chardata"`
+}
+
// Namespace is a namespace!
func (c PresenceNickExtension) Namespace() string {
return c.XMLName.Space
@@ -34,6 +113,11 @@ func (c PresenceXVCardUpdateExtension) Namespace() string {
return c.XMLName.Space
}
+// Namespace is a namespace!
+func (c IqVcardTemp) Namespace() string {
+ return c.XMLName.Space
+}
+
func init() {
// presence nick
stanza.TypeRegistry.MapExtension(stanza.PKTPresence, xml.Name{
@@ -46,4 +130,10 @@ func init() {
"vcard-temp:x:update",
"x",
}, PresenceXVCardUpdateExtension{})
+
+ // iq vcard request
+ stanza.TypeRegistry.MapExtension(stanza.PKTIQ, xml.Name{
+ "vcard-temp",
+ "vCard",
+ }, IqVcardTemp{})
}
diff --git a/xmpp/handlers.go b/xmpp/handlers.go
index 5635f10..31c2b27 100644
--- a/xmpp/handlers.go
+++ b/xmpp/handlers.go
@@ -1,11 +1,16 @@
package xmpp
import (
+ "bytes"
+ "encoding/base64"
"github.com/pkg/errors"
+ "io"
+ "os"
"strconv"
"strings"
"dev.narayana.im/narayana/telegabber/persistence"
+ "dev.narayana.im/narayana/telegabber/xmpp/extensions"
"dev.narayana.im/narayana/telegabber/xmpp/gateway"
log "github.com/sirupsen/logrus"
@@ -25,7 +30,84 @@ func HandleIq(s xmpp.Sender, p stanza.Packet) {
return
}
- log.Printf("Iq: %#v\n", iq)
+ log.Debugf("%#v", iq)
+ if iq.Type == "get" {
+ _, ok := iq.Payload.(*extensions.IqVcardTemp)
+ if ok {
+ log.WithFields(log.Fields{
+ "from": iq.From,
+ "to": iq.To,
+ }).Warn("VCard request")
+
+ fromJid, err := xmpp.NewJid(iq.From)
+ if err != nil {
+ log.Error("Invalid from JID!")
+ return
+ }
+
+ session, ok := sessions[fromJid.Bare()]
+ if !ok {
+ log.Error("IQ from stranger")
+ return
+ }
+
+ toParts := strings.Split(iq.To, "@")
+ toID, err := strconv.ParseInt(toParts[0], 10, 64)
+ if err != nil {
+ log.Error("Invalid IQ to")
+ return
+ }
+ chat, user, err := session.GetContactByID(toID, nil)
+ if err != nil {
+ log.Error(err)
+ return
+ }
+
+ vcard := extensions.IqVcardTemp{}
+ if chat != nil {
+ vcard.Fn.Text = chat.Title
+
+ if chat.Photo != nil {
+ path := chat.Photo.Small.Local.Path
+ file, err := os.Open(path)
+ if err == nil {
+ defer file.Close()
+
+ buf := new(bytes.Buffer)
+ binval := base64.NewEncoder(base64.StdEncoding, buf)
+ _, err = io.Copy(binval, file)
+ if err == nil {
+ vcard.Photo.Type.Text = "image/jpeg"
+ vcard.Photo.Binval.Text = buf.String()
+ } else {
+ log.Errorf("Error calculating hash: %v", path)
+ }
+ } else if path != "" {
+ log.Errorf("Photo does not exist: %v", path)
+ }
+ }
+ }
+ 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
+ }
+
+ answer := stanza.IQ{
+ Attrs: stanza.Attrs{
+ From: iq.To,
+ To: iq.From,
+ Id: iq.Id,
+ Type: "result",
+ },
+ Payload: vcard,
+ }
+ log.Debugf("%#v", answer)
+
+ _ = s.Send(answer)
+ }
+ }
}
// HandleMessage processes an incoming XMPP message