aboutsummaryrefslogtreecommitdiff
path: root/xmpp
diff options
context:
space:
mode:
authorbodqhrohro <bodqhrohro@gmail.com>2019-11-24 20:10:29 +0300
committerbodqhrohro <bodqhrohro@gmail.com>2019-11-24 20:10:29 +0300
commit653b1bde94b89d91862007a18b8730ff58673f59 (patch)
tree5b0c8674f918eb49dd27e53918ff10529c0ff55c /xmpp
parentc0c21a35a4cfd326423ad530926a0e96c1b07dcf (diff)
Telegram authorization
Diffstat (limited to 'xmpp')
-rw-r--r--xmpp/component.go36
-rw-r--r--xmpp/gateway/gateway.go53
-rw-r--r--xmpp/handlers.go64
3 files changed, 132 insertions, 21 deletions
diff --git a/xmpp/component.go b/xmpp/component.go
index fa1a650..7e2d16e 100644
--- a/xmpp/component.go
+++ b/xmpp/component.go
@@ -8,6 +8,7 @@ import (
"dev.narayana.im/narayana/telegabber/config"
"dev.narayana.im/narayana/telegabber/persistence"
"dev.narayana.im/narayana/telegabber/telegram"
+ "dev.narayana.im/narayana/telegabber/xmpp/gateway"
log "github.com/sirupsen/logrus"
"github.com/soheilhy/args"
@@ -17,9 +18,8 @@ import (
const pollingInterval time.Duration = 1e7
-var jid *xmpp.Jid
var tgConf config.TelegramConfig
-var sessions map[string]telegram.Client
+var sessions map[string]*telegram.Client
var queue map[string]*stanza.Presence
var db persistence.SessionsYamlDB
@@ -28,18 +28,13 @@ var db persistence.SessionsYamlDB
func NewComponent(conf config.XMPPConfig, tc config.TelegramConfig) (*xmpp.StreamManager, *xmpp.Component, error) {
var err error
- jid, err = xmpp.NewJid(conf.Jid)
+ gateway.Jid, err = xmpp.NewJid(conf.Jid)
if err != nil {
return nil, nil, err
}
tgConf = tc
- err = loadSessions(conf.Db)
- if err != nil {
- return nil, nil, err
- }
-
options := xmpp.ComponentOptions{
Address: conf.Host + ":" + conf.Port,
Domain: conf.Jid,
@@ -57,6 +52,11 @@ func NewComponent(conf config.XMPPConfig, tc config.TelegramConfig) (*xmpp.Strea
return nil, nil, err
}
+ err = loadSessions(conf.Db, component)
+ if err != nil {
+ return nil, nil, err
+ }
+
sm := xmpp.NewStreamManager(component, nil)
go heartbeat(component)
@@ -99,10 +99,10 @@ func heartbeat(component *xmpp.Component) {
}
}
-func loadSessions(dbPath string) error {
+func loadSessions(dbPath string, component *xmpp.Component) error {
var err error
- sessions = make(map[string]telegram.Client)
+ sessions = make(map[string]*telegram.Client)
db, err = persistence.LoadSessions(dbPath)
if err != nil {
@@ -111,7 +111,7 @@ func loadSessions(dbPath string) error {
db.Transaction(func() bool {
for jid, session := range db.Data.Sessions {
- getTelegramInstance(jid, &session)
+ getTelegramInstance(jid, &session, component)
}
return false
@@ -120,10 +120,11 @@ func loadSessions(dbPath string) error {
return nil
}
-func getTelegramInstance(jid string, savedSession *persistence.Session) (telegram.Client, bool) {
+func getTelegramInstance(jid string, savedSession *persistence.Session, component *xmpp.Component) (*telegram.Client, bool) {
+ var err error
session, ok := sessions[jid]
if !ok {
- session, err := telegram.NewClient(tgConf, jid, savedSession)
+ session, err = telegram.NewClient(tgConf, jid, component, savedSession)
if err != nil {
log.Error(errors.Wrap(err, "TDlib initialization failure"))
return session, false
@@ -195,7 +196,7 @@ func newPresence(bareJid string, to string, args ...args.V) stanza.Presence {
func sendPresence(component *xmpp.Component, to string, args ...args.V) error {
var logFrom string
- bareJid := jid.Bare()
+ bareJid := gateway.Jid.Bare()
if SPFrom.IsSet(args) {
logFrom = SPFrom.Get(args)
} else {
@@ -212,7 +213,12 @@ func sendPresence(component *xmpp.Component, to string, args ...args.V) error {
// explicit check, as marshalling is expensive
if log.GetLevel() == log.DebugLevel {
- log.Debug(xml.Marshal(presence))
+ xmlPresence, err := xml.Marshal(presence)
+ if err == nil {
+ log.Debug(string(xmlPresence))
+ } else {
+ log.Debugf("%#v", presence)
+ }
}
immed := SPImmed.Get(args)
diff --git a/xmpp/gateway/gateway.go b/xmpp/gateway/gateway.go
new file mode 100644
index 0000000..0c22677
--- /dev/null
+++ b/xmpp/gateway/gateway.go
@@ -0,0 +1,53 @@
+package gateway
+
+import (
+ "encoding/xml"
+
+ log "github.com/sirupsen/logrus"
+ "gosrc.io/xmpp"
+ "gosrc.io/xmpp/stanza"
+)
+
+// Jid stores the component's JID object
+var Jid *xmpp.Jid
+
+// SendMessage creates and sends a message stanza
+func SendMessage(to string, from string, body string, component *xmpp.Component) {
+ componentJid := Jid.Full()
+
+ var logFrom string
+ var messageFrom string
+ if from == "" {
+ logFrom = componentJid
+ messageFrom = componentJid
+ } else {
+ logFrom = from
+ messageFrom = from + "@" + componentJid
+ }
+
+ log.WithFields(log.Fields{
+ "from": logFrom,
+ "to": to,
+ }).Warn("Got message")
+
+ message := stanza.Message{
+ Attrs: stanza.Attrs{
+ From: messageFrom,
+ To: to,
+ Type: "chat",
+ },
+ Body: body,
+ }
+
+ // explicit check, as marshalling is expensive
+ if log.GetLevel() == log.DebugLevel {
+ xmlMessage, err := xml.Marshal(message)
+ if err == nil {
+ log.Debug(string(xmlMessage))
+ } else {
+ log.Debugf("%#v", message)
+ }
+ }
+
+ _ = component.Send(message)
+}
diff --git a/xmpp/handlers.go b/xmpp/handlers.go
index ba93a11..d3abeab 100644
--- a/xmpp/handlers.go
+++ b/xmpp/handlers.go
@@ -2,8 +2,11 @@ package xmpp
import (
"github.com/pkg/errors"
+ "strconv"
+ "strings"
"dev.narayana.im/narayana/telegabber/persistence"
+ "dev.narayana.im/narayana/telegabber/xmpp/gateway"
log "github.com/sirupsen/logrus"
"gosrc.io/xmpp"
@@ -33,9 +36,52 @@ func HandleMessage(s xmpp.Sender, p stanza.Packet) {
return
}
- log.Printf("Message: %#v\n", msg)
- reply := stanza.Message{Attrs: stanza.Attrs{To: msg.From}, Body: msg.Body}
- _ = s.Send(reply)
+ component, ok := s.(*xmpp.Component)
+ if !ok {
+ log.Error("Not a component")
+ return
+ }
+
+ if msg.Type != "error" && msg.Body != "" {
+ log.WithFields(log.Fields{
+ "from": msg.From,
+ "to": msg.To,
+ }).Warn("Message")
+ log.Debugf("%#v", msg)
+
+ fromJid, err := xmpp.NewJid(msg.From)
+ if err != nil {
+ log.Error("Invalid from JID!")
+ return
+ }
+
+ session, ok := sessions[fromJid.Bare()]
+ if !ok {
+ log.Error("Message from stranger")
+ return
+ }
+
+ toParts := strings.Split(msg.To, "@")
+ toID := toParts[0]
+ if len(toParts) > 1 {
+ toIDInt, err := strconv.Atoi(toID)
+ if err != nil {
+ session.ProcessOutgoingMessage(toIDInt, msg.Body, 0)
+ return
+ }
+ } else if toID == gateway.Jid.Bare() {
+ bodyFields := strings.Fields(msg.Body)
+ cmd := bodyFields[0]
+ if strings.HasPrefix(cmd, "/") {
+ response := session.ProcessTransportCommand(cmd[1:], bodyFields[1:])
+ if response != "" {
+ gateway.SendMessage(msg.From, "", response, component)
+ }
+ return
+ }
+ }
+ log.Warn("Unknown purpose of the message, skipping")
+ }
}
// HandlePresence processes an incoming XMPP presence
@@ -49,7 +95,7 @@ func HandlePresence(s xmpp.Sender, p stanza.Packet) {
if prs.Type == "subscribe" {
handleSubscription(s, prs)
}
- if prs.To == jid.Bare() {
+ if prs.To == gateway.Jid.Bare() {
handlePresence(s, prs)
}
}
@@ -77,6 +123,12 @@ func handlePresence(s xmpp.Sender, p stanza.Presence) {
presenceType = "online"
}
+ component, ok := s.(*xmpp.Component)
+ if !ok {
+ log.Error("Not a component")
+ return
+ }
+
log.WithFields(log.Fields{
"type": presenceType,
"from": p.From,
@@ -90,7 +142,7 @@ func handlePresence(s xmpp.Sender, p stanza.Presence) {
return
}
bareFromJid := fromJid.Bare()
- session, ok := getTelegramInstance(bareFromJid, &persistence.Session{})
+ session, ok := getTelegramInstance(bareFromJid, &persistence.Session{}, component)
if !ok {
return
}
@@ -101,7 +153,7 @@ func handlePresence(s xmpp.Sender, p stanza.Presence) {
delete(sessions, bareFromJid)
case "unavailable", "error":
session.Disconnect()
- case "":
+ case "", "online":
// due to the weird implentation of go-tdlib wrapper, it won't
// return the client instance until successful authorization
go func() {