Fully implement ban of vilians when bot entered infested room, fix a bit MUC ping
This commit is contained in:
@@ -61,8 +61,3 @@ Cуществует несколько видов пинга:
|
|||||||
------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------
|
||||||
Причину бана можно только включить или выключить в конфиге на per-chat основе. Фразу настроить невозможно. (не хотелось
|
Причину бана можно только включить или выключить в конфиге на per-chat основе. Фразу настроить невозможно. (не хотелось
|
||||||
реализовывать парсинг темплейтов, как минимум даты-времени)
|
реализовывать парсинг темплейтов, как минимум даты-времени)
|
||||||
|
|
||||||
|
|
||||||
Парсинг списка и бан здобеев на моменте входа в комнату
|
|
||||||
------------------------------------------------------------------------------------------------------------------------
|
|
||||||
Бан реализован только для real jid-ов, но не для nick-ов. Пока непонятно, как изящно хранить и то и другое.
|
|
||||||
|
|||||||
16
buny.go
16
buny.go
@@ -58,6 +58,7 @@ func buny(v xmpp.Presence) error { //nolint:gocognit,gocyclo
|
|||||||
evilJid := strings.SplitN(v.JID, "/", 2)[0]
|
evilJid := strings.SplitN(v.JID, "/", 2)[0]
|
||||||
evilNick := ""
|
evilNick := ""
|
||||||
evilNicks := strings.SplitN(v.From, "/", 2)
|
evilNicks := strings.SplitN(v.From, "/", 2)
|
||||||
|
|
||||||
// Давайте-ка похэндлим нонсенс - когда у нас в строке нету разделителя
|
// Давайте-ка похэндлим нонсенс - когда у нас в строке нету разделителя
|
||||||
if len(evilNicks) > 1 {
|
if len(evilNicks) > 1 {
|
||||||
evilNick = evilNicks[1]
|
evilNick = evilNicks[1]
|
||||||
@@ -77,11 +78,13 @@ func buny(v xmpp.Presence) error { //nolint:gocognit,gocyclo
|
|||||||
re, err := regexp.Compile(jidRegexp)
|
re, err := regexp.Compile(jidRegexp)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Incorrect regexp in blacklist: %s, skipping", jidRegexp)
|
log.Errorf("Incorrect regexp in global blacklist: %s, skipping", jidRegexp)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debugf("Checking jid %s vs global blacklist regex %s", evilJid, jidRegexp)
|
||||||
|
|
||||||
if re.MatchString(evilJid) {
|
if re.MatchString(evilJid) {
|
||||||
if id, err := squash(room, evilJid, bEntry.ReasonEnable, v.Type); err != nil {
|
if id, err := squash(room, evilJid, bEntry.ReasonEnable, v.Type); err != nil {
|
||||||
err := fmt.Errorf(
|
err := fmt.Errorf(
|
||||||
@@ -107,11 +110,13 @@ func buny(v xmpp.Presence) error { //nolint:gocognit,gocyclo
|
|||||||
re, err := regexp.Compile(nickRegexp)
|
re, err := regexp.Compile(nickRegexp)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Incorrect regexp in blacklist: %s, skipping", nickRegexp)
|
log.Errorf("Incorrect regexp in global blacklist: %s, skipping", nickRegexp)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debugf("Checking nick %s vs global blacklist regex %s", evilNick, nickRegexp)
|
||||||
|
|
||||||
if re.MatchString(evilNick) {
|
if re.MatchString(evilNick) {
|
||||||
// Баним именно jid
|
// Баним именно jid
|
||||||
if id, err := squash(room, evilJid, bEntry.ReasonEnable, v.Type); err != nil {
|
if id, err := squash(room, evilJid, bEntry.ReasonEnable, v.Type); err != nil {
|
||||||
@@ -143,11 +148,13 @@ func buny(v xmpp.Presence) error { //nolint:gocognit,gocyclo
|
|||||||
re, err := regexp.Compile(jidRegexp)
|
re, err := regexp.Compile(jidRegexp)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Incorrect regexp in blacklist: %s, skipping", jidRegexp)
|
log.Errorf("Incorrect regexp in room %s blacklist: %s, skipping", room, jidRegexp)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debugf("Checking jid %s vs room %s blacklist regex %s", evilJid, room, jidRegexp)
|
||||||
|
|
||||||
if re.MatchString(evilJid) {
|
if re.MatchString(evilJid) {
|
||||||
if id, err := squash(room, evilJid, bEntry.ReasonEnable, v.Type); err != nil {
|
if id, err := squash(room, evilJid, bEntry.ReasonEnable, v.Type); err != nil {
|
||||||
err := fmt.Errorf(
|
err := fmt.Errorf(
|
||||||
@@ -174,11 +181,12 @@ func buny(v xmpp.Presence) error { //nolint:gocognit,gocyclo
|
|||||||
re, err := regexp.Compile(nickRegexp)
|
re, err := regexp.Compile(nickRegexp)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Incorrect regexp in blacklist: %s, skipping", nickRegexp)
|
log.Errorf("Incorrect regexp in room %s blacklist: %s, skipping", room, nickRegexp)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debugf("Checking nick %s vs room %s blacklist regex %s", evilJid, room, nickRegexp)
|
||||||
if re.MatchString(evilNick) {
|
if re.MatchString(evilNick) {
|
||||||
// Баним именно jid
|
// Баним именно jid
|
||||||
if id, err := squash(room, evilJid, bEntry.ReasonEnable, v.Type); err != nil {
|
if id, err := squash(room, evilJid, bEntry.ReasonEnable, v.Type); err != nil {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
@@ -490,7 +491,7 @@ func parseEvent(e interface{}) { //nolint:maintidx,gocognit,gocyclo
|
|||||||
// Однако, это не значит, что такую ситуацию мы не должны корректным образом обрабатывать.
|
// Однако, это не значит, что такую ситуацию мы не должны корректным образом обрабатывать.
|
||||||
if v.Type == "unavailable" {
|
if v.Type == "unavailable" {
|
||||||
// Считаем, что мы больше не в комнате, поэтому не знаем, кто там есть
|
// Считаем, что мы больше не в комнате, поэтому не знаем, кто там есть
|
||||||
roomPresencesJid.Delete(v.From)
|
roomPresences.Delete(v.From)
|
||||||
|
|
||||||
log.Error("Presence notification - looks like another instance of client leaves room")
|
log.Error("Presence notification - looks like another instance of client leaves room")
|
||||||
|
|
||||||
@@ -530,34 +531,35 @@ func parseEvent(e interface{}) { //nolint:maintidx,gocognit,gocyclo
|
|||||||
switch v.Role {
|
switch v.Role {
|
||||||
// Участник ушёл
|
// Участник ушёл
|
||||||
case "none":
|
case "none":
|
||||||
if namesInterface, present := roomPresencesJid.Get(room); present {
|
if presenceJSONInterface, present := roomPresences.Get(room); present {
|
||||||
var newNames []string
|
presenceJSONStrings := interfaceToStringSlice(presenceJSONInterface)
|
||||||
names := interfaceToStringSlice(namesInterface)
|
var newPresenceJSONStrings []string
|
||||||
|
|
||||||
for _, name := range names {
|
for _, presenceJSONstring := range presenceJSONStrings {
|
||||||
if name != v.JID {
|
var p xmpp.Presence
|
||||||
newNames = append(newNames, name)
|
_ = json.Unmarshal([]byte(presenceJSONstring), &p)
|
||||||
}
|
|
||||||
|
if p.JID == v.JID {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(newNames) == 0 {
|
newPresenceJSONStrings = append(newPresenceJSONStrings, presenceJSONstring)
|
||||||
roomPresencesJid.Delete(room)
|
|
||||||
} else {
|
|
||||||
roomPresencesJid.Set(room, newNames)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
roomPresences.Set(room, newPresenceJSONStrings)
|
||||||
}
|
}
|
||||||
// Участник пришёл
|
// Участник пришёл
|
||||||
default:
|
default:
|
||||||
var newNames []string
|
var presenceJSONStrings []string
|
||||||
|
var presenceJSONBytes []byte
|
||||||
|
|
||||||
if namesInterface, present := roomPresencesJid.Get(room); present {
|
if presenceJSONInterface, present := roomPresences.Get(room); present {
|
||||||
names := interfaceToStringSlice(namesInterface)
|
presenceJSONStrings = interfaceToStringSlice(presenceJSONInterface)
|
||||||
names = append(names, v.JID)
|
|
||||||
roomPresencesJid.Set(room, names)
|
|
||||||
} else {
|
|
||||||
newNames = append(newNames, v.JID)
|
|
||||||
roomPresencesJid.Set(room, newNames)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
presenceJSONBytes, _ = json.Marshal(v)
|
||||||
|
presenceJSONStrings = append(presenceJSONStrings, string(presenceJSONBytes))
|
||||||
|
roomPresences.Set(room, presenceJSONStrings)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Проверяем, а не злодей ли зашёл? Сделать это мы можем, только если мы находимся в комнате.
|
// Проверяем, а не злодей ли зашёл? Сделать это мы можем, только если мы находимся в комнате.
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ var serverPingTimestampRx int64
|
|||||||
// Объектик для хранения стейта утилизатора горутинок.
|
// Объектик для хранения стейта утилизатора горутинок.
|
||||||
var gTomb tomb.Tomb
|
var gTomb tomb.Tomb
|
||||||
|
|
||||||
// sync.Map-ка со списком участников конференций.
|
// sync.Map-ка со списком участников конференций (в json-формате, согласно структуре xmpp.Presence, "room".[]json).
|
||||||
var roomPresencesJid *Collection
|
var roomPresences *Collection
|
||||||
|
|
||||||
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||||
|
|||||||
18
lib.go
18
lib.go
@@ -583,28 +583,19 @@ func joinMuc(room string) {
|
|||||||
go RotateStatus(room)
|
go RotateStatus(room)
|
||||||
|
|
||||||
// Время прoверить участников на предмет злобности
|
// Время прoверить участников на предмет злобности
|
||||||
namesInterface, present := roomPresencesJid.Get(room)
|
namesInterface, present := roomPresences.Get(room)
|
||||||
|
|
||||||
// Если room есть в списке presence-ов, то фигачим. room там должен быть, просто обязан.
|
// Если room есть в списке presence-ов, то фигачим. room там должен быть, просто обязан.
|
||||||
if present {
|
if present {
|
||||||
for _, name := range interfaceToStringSlice(namesInterface) {
|
for _, name := range interfaceToStringSlice(namesInterface) {
|
||||||
var v xmpp.Presence
|
var v xmpp.Presence
|
||||||
v.From = name
|
|
||||||
v.To = fmt.Sprintf("%s/%s", room, config.Jabber.Nick)
|
|
||||||
v.ID = "fake_id"
|
|
||||||
v.JID = v.From
|
|
||||||
v.Affiliation = "member"
|
|
||||||
v.Role = "participant"
|
|
||||||
v.Priority = ""
|
|
||||||
v.Show = ""
|
|
||||||
v.Status = ""
|
|
||||||
|
|
||||||
|
_ = json.Unmarshal([]byte(name), &v)
|
||||||
|
log.Infof("Fake presence forged for %s just for on-enter check", name)
|
||||||
// Оно там внутри всё само обработает, если вдруг возникнет wire error, то зарекконетится.
|
// Оно там внутри всё само обработает, если вдруг возникнет wire error, то зарекконетится.
|
||||||
_ = buny(v)
|
_ = buny(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: тоже самое и для nick-ов
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// probeServerLiveness проверяет живость соединения с сервером. Для многих серверов обязательная штука, без которой
|
// probeServerLiveness проверяет живость соединения с сервером. Для многих серверов обязательная штука, без которой
|
||||||
@@ -719,8 +710,6 @@ func probeServerLiveness() { //nolint:gocognit
|
|||||||
|
|
||||||
// probeMUCLiveness Пингует MUC-и, нужно для проверки, что клиент ещё находится в MUC-е.
|
// probeMUCLiveness Пингует MUC-и, нужно для проверки, что клиент ещё находится в MUC-е.
|
||||||
func probeMUCLiveness() { //nolint:gocognit
|
func probeMUCLiveness() { //nolint:gocognit
|
||||||
defer gTomb.Done()
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-gTomb.Dying():
|
case <-gTomb.Dying():
|
||||||
@@ -773,6 +762,7 @@ func probeMUCLiveness() { //nolint:gocognit
|
|||||||
log.Debugf("Sending MUC ping from %s to %s", talk.JID(), room)
|
log.Debugf("Sending MUC ping from %s to %s", talk.JID(), room)
|
||||||
|
|
||||||
if err := talk.PingS2S(talk.JID(), room); err != nil {
|
if err := talk.PingS2S(talk.JID(), room); err != nil {
|
||||||
|
err := fmt.Errorf("Unable to ping MUC %s: %v", room, err)
|
||||||
gTomb.Kill(err)
|
gTomb.Kill(err)
|
||||||
}
|
}
|
||||||
}(room)
|
}(room)
|
||||||
|
|||||||
2
main.go
2
main.go
@@ -128,7 +128,7 @@ func myLoop() {
|
|||||||
mucCapsList = NewCollection()
|
mucCapsList = NewCollection()
|
||||||
serverPingTimestampTx = 0
|
serverPingTimestampTx = 0
|
||||||
serverPingTimestampRx = 0
|
serverPingTimestampRx = 0
|
||||||
roomPresencesJid = NewCollection()
|
roomPresences = NewCollection()
|
||||||
|
|
||||||
// Установим коннект
|
// Установим коннект
|
||||||
establishConnection()
|
establishConnection()
|
||||||
|
|||||||
Reference in New Issue
Block a user