From 39ac09f82a43e9ed95133c3b05633d18305f062c Mon Sep 17 00:00:00 2001 From: eleksir Date: Sun, 20 Aug 2023 10:55:02 -0700 Subject: [PATCH] Implement ban by nick regexp (in MUCs) * Move ban action to separate function * Implement ban by nick regexp --- buny.go | 220 +++++++++++++++++++++---------------- data/sample_blacklist.json | 5 + types.go | 1 + 3 files changed, 133 insertions(+), 93 deletions(-) diff --git a/buny.go b/buny.go index b286d93..3b4af9a 100644 --- a/buny.go +++ b/buny.go @@ -11,7 +11,7 @@ import ( log "github.com/sirupsen/logrus" ) -func buny(v xmpp.Presence) error { //nolint:gocognit +func buny(v xmpp.Presence) error { //nolint:gocognit,gocyclo var err error // Если у presence-а есть JID и presence из одной из комнат, в которой мы есть и если его домен в чёрном @@ -54,6 +54,12 @@ func buny(v xmpp.Presence) error { //nolint:gocognit } evilJid := strings.SplitN(v.JID, "/", 2)[0] + evilNick := "" + evilNicks := strings.SplitN(v.From, "/", 2) + // Давайте-ка похэндлим нонсенс - когда у нас в строке нету разделителя + if len(evilNicks) > 1 { + evilNick = evilNicks[1] + } // Обрабатываем правила чёрного списка for _, cRoom := range roomsConnected { @@ -71,54 +77,34 @@ func buny(v xmpp.Presence) error { //nolint:gocognit } if re.MatchString(evilJid) { - log.Infof("Hammer falls on %s", v.JID) - - if config.Jabber.BanPhrasesEnable { - phrase := randomPhrase(config.Jabber.BanPhrases) - - if _, err := talk.Send( - xmpp.Chat{ //nolint:exhaustruct - Remote: room, - Text: phrase, - Type: v.Type, - }, - ); err != nil { - err := fmt.Errorf("unable to send phrase to room %s: %w", room, err) - gTomb.Kill(err) - - // Здесь возвращаем nil, т.к. за нас ошибку залоггирует код выше - return nil - } - } - - // https://xmpp.org/extensions/xep-0045.html#ban баним вот таким сообщением - ban := "" - - if bEntry.ReasonEnable { - var t = time.Now() - ban += fmt.Sprintf( - "autoban at %04d.%02d.%02d %02d:%02d:%02d", - t.Year(), - t.Month(), - t.Day(), - t.Hour(), - t.Minute(), - t.Second(), + if id, err := squash(room, evilJid, bEntry.ReasonEnable, v.Type); err != nil { + err := fmt.Errorf( + "unable to ban user: id=%s, err=%w", + id, + err, ) - } else { - ban += "" + + gTomb.Kill(err) + + continue } - ban += "" + return err + } + } - if id, err := talk.RawInformationQuery( - talk.JID(), - room, - "ban1", - xmpp.IQTypeSet, - "http://jabber.org/protocol/muc#admin", - ban, - ); err != nil { + for _, nickRegexp := range bEntry.NickRe { + re, err := regexp.Compile(nickRegexp) + + if err != nil { + log.Errorf("Incorrect regexp in blacklist: %s, skipping", nickRegexp) + + continue + } + + if re.MatchString(evilNick) { + // Баним именно jid + if id, err := squash(room, evilJid, bEntry.ReasonEnable, v.Type); err != nil { err := fmt.Errorf( "unable to ban user: id=%s, err=%w", id, @@ -149,54 +135,7 @@ func buny(v xmpp.Presence) error { //nolint:gocognit } if re.MatchString(evilJid) { - log.Infof("Hammer falls on %s", v.JID) - - if config.Jabber.BanPhrasesEnable { - phrase := randomPhrase(config.Jabber.BanPhrases) - - if _, err := talk.Send( - xmpp.Chat{ //nolint:exhaustruct - Remote: room, - Text: phrase, - Type: v.Type, - }, - ); err != nil { - err := fmt.Errorf("unable to send phrase to room %s: %w", room, err) - gTomb.Kill(err) - - // Здесь возвращаем nil, т.к. за нас ошибку залоггирует код выше - return nil - } - } - - // https://xmpp.org/extensions/xep-0045.html#ban баним вот таким сообщением - ban := "" - - if bEntry.ReasonEnable { - var t = time.Now() - ban += fmt.Sprintf( - "autoban at %04d.%02d.%02d %02d:%02d:%02d", - t.Year(), - t.Month(), - t.Day(), - t.Hour(), - t.Minute(), - t.Second(), - ) - } else { - ban += "" - } - - ban += "" - - if id, err := talk.RawInformationQuery( - talk.JID(), - room, - "ban1", - xmpp.IQTypeSet, - "http://jabber.org/protocol/muc#admin", - ban, - ); err != nil { + if id, err := squash(room, evilJid, bEntry.ReasonEnable, v.Type); err != nil { err := fmt.Errorf( "unable to ban user: id=%s, err=%w", id, @@ -212,6 +151,35 @@ func buny(v xmpp.Presence) error { //nolint:gocognit } } + if bEntry.RoomName == room { + for _, nickRegexp := range bEntry.NickRe { + re, err := regexp.Compile(nickRegexp) + + if err != nil { + log.Errorf("Incorrect regexp in blacklist: %s, skipping", nickRegexp) + + continue + } + + if re.MatchString(evilNick) { + // Баним именно jid + if id, err := squash(room, evilJid, bEntry.ReasonEnable, v.Type); err != nil { + err := fmt.Errorf( + "unable to ban user: id=%s, err=%w", + id, + err, + ) + + gTomb.Kill(err) + + continue + } + + return err + } + } + } + continue } } @@ -222,4 +190,70 @@ func buny(v xmpp.Presence) error { //nolint:gocognit return err } +// squash банит указанный jid в указанной комнате. +// reasonEnable указывает, надо ли писать дату автобана в банлисте в поле reason (это единственная причина, в которую +// умеет бот). +func squash(room, jid string, reasonEnable bool, vType string) (string, error) { + var ( + id string + err error + ) + + log.Infof("Hammer falls on %s", jid) + + if config.Jabber.BanPhrasesEnable { + phrase := randomPhrase(config.Jabber.BanPhrases) + + if _, err = talk.Send( + xmpp.Chat{ //nolint:exhaustruct + Remote: room, + Text: phrase, + Type: vType, + }, + ); err != nil { + err = fmt.Errorf("unable to send phrase to room %s: %w", room, err) + + // Здесь возвращаем nil, т.к. за нас ошибку залоггирует код выше + return id, err + } + } + + // https://xmpp.org/extensions/xep-0045.html#ban баним вот таким сообщением + ban := "" + + if reasonEnable { + var t = time.Now() + ban += fmt.Sprintf( + "autoban at %04d.%02d.%02d %02d:%02d:%02d", + t.Year(), + t.Month(), + t.Day(), + t.Hour(), + t.Minute(), + t.Second(), + ) + } else { + ban += "" + } + + ban += "" + + if id, err = talk.RawInformationQuery( + talk.JID(), + room, + "ban1", + xmpp.IQTypeSet, + "http://jabber.org/protocol/muc#admin", + ban, + ); err != nil { + err = fmt.Errorf( + "unable to ban user: id=%s, err=%w", + id, + err, + ) + } + + return id, err +} + /* vim: set ft=go noet ai ts=4 sw=4 sts=4: */ diff --git a/data/sample_blacklist.json b/data/sample_blacklist.json index 65340e9..2ee8810 100644 --- a/data/sample_blacklist.json +++ b/data/sample_blacklist.json @@ -12,6 +12,11 @@ "^[cC]hris(topher)?@", "^(his|her)_cat@sweet.home/.*$", "^(her|his)_dog@.*\\.street/.*" + ], + # Список регулярок nick-ов злодеев + "nick_re": [ + "^(Annoying_)?[F|f]ly$", + "^Buzzing_Wasp$" ] } ] diff --git a/types.go b/types.go index 453ebbb..1c885cc 100644 --- a/types.go +++ b/types.go @@ -53,6 +53,7 @@ type myBlackList struct { RoomName string `json:"room_name,omitempty"` ReasonEnable bool `json:"reason_enable,omitempty"` JidRe []string `json:"jid_re,omitempty"` + NickRe []string `json:"nick_re,omitempty"` } `json:"blacklist,omitempty"` }