sum7
/
yaja
Archived
1
0
Fork 0
This repository has been archived on 2020-09-27. You can view files and clone it, but cannot push or open issues or pull requests.
yaja/daemon/tester/bot.go

191 lines
5.3 KiB
Go
Raw Normal View History

2018-02-10 13:34:42 +01:00
package tester
import (
"fmt"
2018-02-10 13:34:42 +01:00
"strings"
log "github.com/sirupsen/logrus"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
2018-02-10 13:34:42 +01:00
)
func (t *Tester) StartBot(status *Status) {
2018-02-11 22:03:58 +01:00
logger := log.New()
logger.SetLevel(t.LoggingBots)
logCTX := logger.WithFields(log.Fields{
"type": "bot",
"jid": status.client.JID.Full(),
})
2018-02-10 13:34:42 +01:00
for {
element, err := status.client.Read()
if err != nil {
status.Disconnect(fmt.Sprintf("could not read any more data from socket: %s", err))
2018-02-10 13:34:42 +01:00
return
}
errMSG := &xmpp.StreamError{}
2018-02-11 22:03:58 +01:00
err = status.client.Decode(errMSG, element)
2018-02-11 11:15:11 +01:00
if err == nil {
status.Disconnect(fmt.Sprintf("recv stream error: %s: %s -> %s", errMSG.Text, xmpp.XMLChildrenString(errMSG.StreamErrorGroup), xmpp.XMLChildrenString(errMSG.Other)))
2018-02-11 11:15:11 +01:00
return
}
iq := &xmpp.IQClient{}
2018-02-11 22:03:58 +01:00
err = status.client.Decode(iq, element)
2018-02-10 13:34:42 +01:00
if err == nil {
if iq.Ping != nil {
logCTX.Debug("answer ping")
iq.Type = xmpp.IQTypeResult
2018-02-10 13:34:42 +01:00
iq.To = iq.From
iq.From = status.client.JID
2018-02-11 22:03:58 +01:00
status.client.Send(iq)
2018-02-10 13:34:42 +01:00
} else {
logCTX.Warnf("recv iq unsupport: %s", xmpp.XMLChildrenString(iq))
2018-02-10 13:34:42 +01:00
}
continue
}
pres := &xmpp.PresenceClient{}
2018-02-11 22:03:58 +01:00
err = status.client.Decode(pres, element)
2018-02-10 13:34:42 +01:00
if err == nil {
sender := pres.From
logPres := logCTX.WithField("from", sender.Full())
if pres.Type == xmpp.PresenceTypeSubscribe {
2018-02-11 19:35:32 +01:00
logPres.Debugf("recv presence subscribe")
pres.Type = xmpp.PresenceTypeSubscribed
pres.To = sender
pres.From = nil
2018-02-11 22:03:58 +01:00
status.client.Send(pres)
logPres.Debugf("accept new subscribe")
pres.Type = xmpp.PresenceTypeSubscribe
2018-02-11 19:35:32 +01:00
pres.ID = ""
2018-02-11 22:03:58 +01:00
status.client.Send(pres)
logPres.Info("request also subscribe")
} else if pres.Type == xmpp.PresenceTypeSubscribed {
2018-02-11 19:35:32 +01:00
logPres.Info("recv presence accepted subscribe")
} else if pres.Type == xmpp.PresenceTypeUnsubscribe {
2018-02-11 19:35:32 +01:00
logPres.Info("recv presence remove subscribe")
} else if pres.Type == xmpp.PresenceTypeUnsubscribed {
2018-02-11 19:35:32 +01:00
logPres.Info("recv presence removed subscribe")
} else if pres.Type == xmpp.PresenceTypeUnavailable {
2018-02-11 19:35:32 +01:00
logPres.Debug("recv presence unavailable")
2018-02-10 13:34:42 +01:00
} else {
logCTX.Warnf("recv presence unsupported: %s -> %s", pres.Type, xmpp.XMLChildrenString(pres))
2018-02-10 13:34:42 +01:00
}
continue
}
msg := &xmpp.MessageClient{}
2018-02-11 22:03:58 +01:00
err = status.client.Decode(msg, element)
2018-02-10 13:34:42 +01:00
if err != nil {
2018-02-11 11:15:11 +01:00
logCTX.Warnf("unsupport xml recv: %s <-> %v", err, element)
2018-02-10 13:34:42 +01:00
continue
}
2018-02-11 11:15:11 +01:00
logCTX = logCTX.WithField("from", msg.From.Full()).WithField("msg-recv", msg.Body)
2018-02-10 13:34:42 +01:00
if msg.Error != nil {
2018-02-11 19:35:32 +01:00
if msg.Error.Type == "auth" {
status.Disconnect("recv msg with error not auth")
2018-02-11 19:35:32 +01:00
return
}
logCTX.Debugf("recv msg with error %s[%s]: %s -> %s -> %s", msg.Error.Code, msg.Error.Type, msg.Error.Text, xmpp.XMLChildrenString(msg.Error.StanzaErrorGroup), xmpp.XMLChildrenString(msg.Error.Other))
2018-02-10 13:34:42 +01:00
continue
}
msgText := strings.SplitN(msg.Body, " ", 2)
switch msgText[0] {
case "ping":
status.client.Send(xmpp.MessageClient{Type: msg.Type, To: msg.From, Body: "pong"})
case "admin":
if len(msgText) == 2 {
botAdmin(strings.SplitN(msgText[1], " ", 2), logCTX, status, msg.From, botAllowed(t.Admins, status.account.Admins))
} else {
status.client.Send(xmpp.MessageClient{Type: msg.Type, To: msg.From, Body: "list, add JID-BARE, del JID-BARE"})
}
2018-02-11 22:03:58 +01:00
case "disconnect":
first := true
allAdmins := ""
isAdmin := false
2018-02-15 22:03:49 +01:00
fromBare := msg.From
for _, jid := range botAllowed(t.Admins, status.account.Admins) {
2018-02-11 22:03:58 +01:00
if first {
first = false
} else {
2018-02-15 22:03:49 +01:00
allAdmins += ", "
2018-02-11 22:03:58 +01:00
}
2018-02-15 22:03:49 +01:00
allAdmins += jid.Bare().String()
if jid.Bare().IsEqual(fromBare) {
2018-02-11 22:03:58 +01:00
isAdmin = true
2018-02-15 22:03:49 +01:00
status.client.Send(xmpp.MessageClient{Type: msg.Type, To: jid, Body: "last message, disconnect requested by " + fromBare.String()})
2018-02-11 22:03:58 +01:00
}
}
if isAdmin {
2018-02-15 22:03:49 +01:00
status.Disconnect(fmt.Sprintf("disconnect by admin '%s'", fromBare.String()))
2018-02-11 22:03:58 +01:00
return
}
status.client.Send(xmpp.MessageClient{Type: msg.Type, To: msg.From, Body: "not allowed, ask " + allAdmins})
2018-02-11 22:03:58 +01:00
2018-02-10 13:34:42 +01:00
case "checkmsg":
if len(msgText) == 2 {
t.UpdateConnectionStatus(msg.From, status.client.JID, msgText[1])
} else {
logCTX.Debug("undetect")
}
default:
logCTX.Debug("undetect")
}
}
}
func botAllowed(list []*xmppbase.JID, toConvert map[string]interface{}) []*xmppbase.JID {
alist := list
for jid := range toConvert {
alist = append(alist, xmppbase.NewJID(jid))
}
return alist
}
func botAdmin(cmd []string, log *log.Entry, status *Status, from *xmppbase.JID, allowed []*xmppbase.JID) {
msg := ""
if len(cmd) == 2 {
isAdmin := false
for _, jid := range allowed {
if jid.Bare() == from.Bare() {
isAdmin = true
}
}
if status.account.Admins == nil {
status.account.Admins = make(map[string]interface{})
}
if !isAdmin {
msg = "not allowed"
} else if cmd[0] == "add" {
status.account.Admins[cmd[1]] = true
msg = "ack"
} else if cmd[0] == "del" {
delete(status.account.Admins, cmd[1])
msg = "ack"
} else {
msg = "unknown command"
}
} else {
if len(cmd) == 1 && cmd[0] == "list" {
for jid := range status.account.Admins {
if msg == "" {
msg += "admins are: " + jid
} else {
msg += ", " + jid
}
}
} else {
msg = "unknown command"
}
}
status.client.Send(xmpp.MessageClient{Type: xmpp.MessageTypeChat, To: from, Body: msg})
}