diff --git a/component/threema/account.go b/component/threema/account.go index bfeaed0..cf3b51d 100644 --- a/component/threema/account.go +++ b/component/threema/account.go @@ -21,9 +21,9 @@ type Account struct { readedMSG map[uint64]string } -func (t *Threema) getAccount(jid *models.JID) *Account { +func (t *Threema) getAccount(jid *models.JID) (*Account, error) { if a, ok := t.accountJID[jid.String()]; ok { - return a + return a, nil } account := models.AccountThreema{} @@ -36,28 +36,27 @@ func (t *Threema) getAccount(jid *models.JID) *Account { var lsk [32]byte copy(lsk[:], account.LSK[:]) tid, err := o3.NewThreemaID(string(account.TID), lsk, o3.AddressBook{}) - // TODO error handling if err != nil { - return nil + return nil, err } tid.Nick = o3.NewPubNick("xmpp:" + jid.String()) a := &Account{AccountThreema: account} - a.XMPP = *jid a.Session = o3.NewSessionContext(tid) a.send, a.recieve, err = a.Session.Run() + + if err != nil { + return nil, err + } + + a.XMPP = *jid a.deliveredMSG = make(map[uint64]string) a.readedMSG = make(map[uint64]string) - // TODO error handling - if err != nil { - return nil - } - go a.reciever(t.out) t.accountJID[jid.String()] = a - return a + return a, nil } func (a *Account) reciever(out chan<- xmpp.Packet) { diff --git a/component/threema/bot.go b/component/threema/bot.go index 7edcc61..6bd9ddc 100644 --- a/component/threema/bot.go +++ b/component/threema/bot.go @@ -22,8 +22,8 @@ func (t *Threema) Bot(from *models.JID, request string) string { case "generate": // test if account already exists - account := t.getAccount(from) - if account != nil { + account, err := t.getAccount(from) + if err == nil { return fmt.Sprintf("you already has the threema account with id: %s", string(account.TID)) } @@ -48,7 +48,7 @@ func (t *Threema) Bot(from *models.JID, request string) string { database.Write.Create(&a) // fetch account and connect - account = t.getAccount(from) + account, err = t.getAccount(from) tid := string(account.TID) if tid != "" { logger.WithField("threema", tid).Info("generate") diff --git a/component/threema/main.go b/component/threema/main.go index 0ff49e8..8996748 100644 --- a/component/threema/main.go +++ b/component/threema/main.go @@ -29,15 +29,23 @@ func (t *Threema) Connect() (chan xmpp.Packet, error) { var jids []*models.JID database.Read.Find(&jids) for _, jid := range jids { - a := t.getAccount(jid) - log.WithFields(map[string]interface{}{ - "jid": jid.String(), - "threema": string(a.TID), - }).Info("connected") + logger := log.WithField("jid", jid.String()) + a, err := t.getAccount(jid) + if err != nil { + logger.Warnf("unable to connect%s", err) + continue + } + logger = logger.WithField("threema", string(a.TID)) + logger.Info("connected") } return t.out, nil } func (t *Threema) Send(packet xmpp.Packet) { + if p := t.send(packet); p != nil { + t.out <- p + } +} +func (t *Threema) send(packet xmpp.Packet) xmpp.Packet { switch p := packet.(type) { case xmpp.Message: from := models.ParseJID(p.PacketAttrs.From) @@ -46,27 +54,26 @@ func (t *Threema) Send(packet xmpp.Packet) { if to.IsDomain() { msg := xmpp.NewMessage("chat", "", from.String(), "", "en") msg.Body = t.Bot(from, p.Body) - t.out <- msg - return + return msg } - account := t.getAccount(from) - if account == nil { + account, err := t.getAccount(from) + if err != nil { msg := xmpp.NewMessage("chat", "", from.String(), "", "en") msg.Body = "It was not possible to send, becouse we have no account for you.\nPlease generate one, by sending `generate` to this gateway" - t.out <- msg - return + return msg } threemaID := strings.ToUpper(to.Local) if err := account.Send(threemaID, p); err != nil { msg := xmpp.NewMessage("chat", "", from.String(), "", "en") msg.Body = err.Error() - t.out <- msg + return msg } default: log.Warnf("unkown package%v", p) } + return nil } func init() { diff --git a/component/threema/main_test.go b/component/threema/main_test.go index a53b305..322abcb 100644 --- a/component/threema/main_test.go +++ b/component/threema/main_test.go @@ -1 +1,117 @@ package threema + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "gosrc.io/xmpp" + + "dev.sum7.eu/genofire/golang-lib/database" + "dev.sum7.eu/genofire/thrempp/models" +) + +func TestThreema(t *testing.T) { + assert := assert.New(t) + + c, err := NewThreema(map[string]interface{}{}) + assert.NoError(err) + assert.NotNil(c) + + database.Open(database.Config{ + Type: "sqlite3", + Connection: "file::memory:?mode=memory", + }) + defer database.Close() + + jid := models.JID{ + Local: "a", + Domain: "example.org", + } + database.Write.Create(&jid) + database.Write.Create(&models.AccountThreema{ + TID: []byte("12345678"), + LSK: []byte("b"), + XMPPID: jid.ID, + }) + + //broken + jid = models.JID{ + Local: "b", + Domain: "example.org", + } + database.Write.Create(&jid) + database.Write.Create(&models.AccountThreema{ + TID: []byte("123"), + LSK: []byte("b"), + XMPPID: jid.ID, + }) + + ch, err := c.Connect() + assert.NoError(err) + assert.NotNil(ch) +} +func TestSend(t *testing.T) { + assert := assert.New(t) + + // test channel + out := make(chan xmpp.Packet) + tr := Threema{ + out: out, + accountJID: make(map[string]*Account), + } + go func() { + tr.Send(xmpp.Message{ + PacketAttrs: xmpp.PacketAttrs{From: "a@example.org"}, + }) + }() + p := <-out + assert.NotNil(p) + // no account. generate one + msg := p.(xmpp.Message) + assert.Contains(msg.Body, "generate") + + // test no answer + p = tr.send(xmpp.IQ{}) + assert.Nil(p) + + // chat with bot + p = tr.send(xmpp.Message{ + PacketAttrs: xmpp.PacketAttrs{To: "example.org"}, + }) + assert.NotNil(p) + msg = p.(xmpp.Message) + assert.Equal("command not supported", msg.Body) + + // chat with delivier error + database.Open(database.Config{ + Type: "sqlite3", + Connection: "file::memory:?mode=memory", + }) + defer database.Close() + + jid := models.JID{ + Local: "a", + Domain: "example.org", + } + database.Write.Create(&jid) + database.Write.Create(&models.AccountThreema{ + TID: []byte("12345678"), + LSK: []byte("b"), + XMPPID: jid.ID, + }) + + /* TODO manipulate account to no sendpipe + _, err := tr.getAccount(&jid) + assert.NoError(err) + + p = tr.send(xmpp.Message{ + PacketAttrs: xmpp.PacketAttrs{ + From: "a@example.org", + To: "12345678@threema.example.org", + }, + }) + assert.NotNil(p) + msg = p.(xmpp.Message) + assert.Equal("command not supported", msg.Body) + */ +}