diff options
author | bodqhrohro <bodqhrohro@gmail.com> | 2019-11-24 20:10:29 +0300 |
---|---|---|
committer | bodqhrohro <bodqhrohro@gmail.com> | 2019-11-24 20:10:29 +0300 |
commit | 653b1bde94b89d91862007a18b8730ff58673f59 (patch) | |
tree | 5b0c8674f918eb49dd27e53918ff10529c0ff55c /xmpp | |
parent | c0c21a35a4cfd326423ad530926a0e96c1b07dcf (diff) |
Telegram authorization
Diffstat (limited to 'xmpp')
-rw-r--r-- | xmpp/component.go | 36 | ||||
-rw-r--r-- | xmpp/gateway/gateway.go | 53 | ||||
-rw-r--r-- | xmpp/handlers.go | 64 |
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() { |