Fix filling presence db, fix ban by useragent

This commit is contained in:
eleksir
2025-12-21 19:07:48 +03:00
parent 9ea444f365
commit de3db48d47
7 changed files with 273 additions and 103 deletions

View File

@@ -29,7 +29,7 @@
"user_agent": [ "user_agent": [
{ {
"software": "BadUserAgent", "name": "BadUserAgent",
"version": "0.666.0", "version": "0.666.0",
"os": "DeathStarOS" "os": "DeathStarOS"
} }

View File

@@ -204,6 +204,8 @@
# логгирует то, что пишется "в провод" # логгирует то, что пишется "в провод"
"lib": false, "lib": false,
# Дебаг периодических пингов. Мало полезная вещь, разве что для выявления сетевых аномалий. # Дебаг периодических пингов. Мало полезная вещь, разве что для выявления сетевых аномалий.
"ping": false "ping": false,
# Дебаг работы presence db.
"presence_db": false
} }
} }

View File

@@ -7,7 +7,9 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"github.com/davecgh/go-spew/spew"
"github.com/hjson/hjson-go" "github.com/hjson/hjson-go"
) )
@@ -123,13 +125,13 @@ func (j *Jabber) ReadBlacklist() error {
return err return err
} }
whitelistJSONPath := filepath.Dir(executablePath) + "/data/blacklist.json" blacklistJSONPath := filepath.Dir(executablePath) + "/data/blacklist.json"
locations := []string{ locations := []string{
"~/.bunyPresense-jabber-bot-blacklist.json", "~/.buny-jabber-bot-blacklist.json",
"~/bunyPresense-jabber-bot-blacklist.json", "~/buny-jabber-bot-blacklist.json",
"/etc/bunyPresense-jabber-bot-blacklist.json", "/etc/buny-jabber-bot-blacklist.json",
whitelistJSONPath, blacklistJSONPath,
} }
for _, location := range locations { for _, location := range locations {
@@ -188,7 +190,19 @@ func (j *Jabber) ReadBlacklist() error {
continue continue
} }
j.BlackList = sampleBlacklist for _, entry := range sampleBlacklist.Blacklist {
for str := range strings.SplitSeq(spew.Sdump(entry), "\n") {
log.Debug(str)
}
}
// Вообще говоря, нас уверяют, что простого "=" хватает, но на практике оказывается, что вложенные стуктуры
// могут и не скопироваться.
tmpjson, _ := json.Marshal(sampleBlacklist) //nolint: errchkjson // Да блять, сколько можно
// доёбываться, эти данные 100500 раз перекодировались, там ошибка возможна только если есть ошибка в
// encoding/json, но в этом случае мы в любом случае ничего поделать не можем, вот всяком случае в рантайме.
_ = json.Unmarshal(tmpjson, &j.BlackList)
blacklistLoaded = true blacklistLoaded = true
log.Infof("Using %s as blacklist file", location) log.Infof("Using %s as blacklist file", location)

View File

@@ -403,28 +403,42 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
if v.From != "" { if v.From != "" {
// На всякий случай: себя никогда не баним, явным образом. // На всякий случай: себя никогда не баним, явным образом.
if v.From == j.Talk.JID() { if v.From == j.Talk.JID() {
log.Debugf("Skipping useragent blacklist check for myself")
return err return err
} }
room := strings.SplitN(v.From, "/", 2)[0] room := strings.SplitN(v.From, "/", 2)[0]
var (
presenceJSONStrings []string
)
if presenceJSONInterface, present := j.RoomPresences.Get(room); present { if presenceJSONInterface, present := j.RoomPresences.Get(room); present {
presenceJSONStrings = InterfaceToStringSlice(presenceJSONInterface) presenceJSON, ok := presenceJSONInterface.([]byte)
if !ok {
log.Errorf("Looks like we have corrupted entry in presence db")
return nil
} }
log.Debugf("Looking up %s in presence db", v.From) var presences []xmpp.Presence
for _, presenceJSONString := range presenceJSONStrings { if err := json.Unmarshal(presenceJSON, &presences); err != nil {
var p xmpp.Presence log.Errorf("Looks like we have corrupted entry in presence db")
_ = json.Unmarshal([]byte(presenceJSONString), &p) return nil //nolint: nilerr // Это не критическая ошибка, её не надо возвращать.
}
if v.From == p.From { for _, p := range presences { //nolint: gocritic // Развели тут, блять, страну советов, напиши что надо сделать кодом, сука.
log.Infof("Found jid of %s in presence db: %s", v.From, p.JID) // Если находим, что у нас уже есть клиент с таким же From, то есть полным nick-ом (для groupchat)
// пропускаем его.
if p.From != v.From {
log.Debugf("Skip check for %s because it is not %s", p.From, v.From)
continue
}
if j.C.Debug.PresenceDB {
log.Debugf("Found jid of %s in presence db: %s", v.From, p.JID)
}
if p.Affiliation == "admin" || p.Affiliation == "owner" { if p.Affiliation == "admin" || p.Affiliation == "owner" {
log.Infof("Skipping useragent blacklist check for %s because his affiliation is %s", v.From, p.Affiliation) log.Infof("Skipping useragent blacklist check for %s because his affiliation is %s", v.From, p.Affiliation)
@@ -442,7 +456,7 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
log.Debug("Useragent is not owner or moderator, proceeding with check...") log.Debug("Useragent is not owner or moderator, proceeding with check...")
// Lookup in global blacklist. // Lookup in global blacklist.
log.Debug("Find our room in connected room list...") log.Debug("Searching our room in connected room list...")
for _, cRoom := range j.RoomsConnected { for _, cRoom := range j.RoomsConnected {
if cRoom == room { if cRoom == room {
@@ -452,12 +466,15 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
// Обработаем правила глобального чёрного списка. // Обработаем правила глобального чёрного списка.
if bEntry.RoomName == "" { if bEntry.RoomName == "" {
log.Debugf("Check in global blacklist") log.Debugf("Check in global blacklist")
log.Debugf("We have useragent struct with Name=%s, Version=%s, OS=%s", ver.Name, ver.Version, ver.Os)
for _, useragent := range bEntry.UserAgent { for _, useragent := range bEntry.UserAgent {
log.Debugf("We have useragent blacklist entry Name=%s, Version=%s, OS=%s", useragent.Name, useragent.Version, useragent.Os)
switch { switch {
case useragent.Name != "" && useragent.Version != "" && useragent.Os != "": case useragent.Name != "" && useragent.Version != "" && useragent.Os != "":
if ver.Name == useragent.Name && ver.Version == useragent.Version && ver.Os == useragent.Os { if ver.Name == useragent.Name && ver.Version == useragent.Version && ver.Os == useragent.Os {
log.Debug("Found all 3 components in black list, it is ban") log.Warnf("Hammer falls on %s (%s): Software Name, Version and OS match entry in blacklist", p.From, p.JID)
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type) id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
@@ -474,9 +491,9 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
return err return err
} }
case useragent.Name != "" && useragent.Version != "": case useragent.Name != "" && useragent.Version != "" && useragent.Os == "":
if ver.Name == useragent.Name && ver.Version == useragent.Version { if ver.Name == useragent.Name && ver.Version == useragent.Version {
log.Debug("Found sw name and version in blacklist, it is ban") log.Warnf("Hammer falls on %s (%s): Software Name and Version match entry in blacklist", p.From, p.JID)
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type) id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
@@ -493,9 +510,9 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
return err return err
} }
case useragent.Name != "": case useragent.Name != "" && useragent.Version == "" && useragent.Os == "":
if ver.Name == useragent.Name { if ver.Name == useragent.Name {
log.Debug("Found sw name in blacklist, it is ban") log.Warnf("Hammer falls on %s (%s): Software Name match entry in blacklist", p.From, p.JID)
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type) id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
@@ -512,9 +529,9 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
return err return err
} }
case useragent.Version != "": case useragent.Name == "" && useragent.Version != "" && useragent.Os == "":
if ver.Version == useragent.Version { if ver.Version == useragent.Version {
log.Debug("Found sw version in blacklist, it is ban") log.Warnf("Hammer falls on %s (%s): Software Version match entry in blacklist", p.From, p.JID)
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type) id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
@@ -532,16 +549,20 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
} }
} }
} }
log.Debug("No matches in global software versions blacklist")
} }
if bEntry.RoomName == room { if bEntry.RoomName == room {
log.Debug("Found blacklist entries for room") log.Debug("Found blacklist entries for room")
for _, useragent := range bEntry.UserAgent { for _, useragent := range bEntry.UserAgent {
log.Debugf("We have useragent blacklist entry Name=%s, Version=%s, OS=%s", useragent.Name, useragent.Version, useragent.Os)
switch { switch {
case useragent.Name != "" && useragent.Version != "" && useragent.Os != "": case useragent.Name != "" && useragent.Version != "" && useragent.Os != "":
if ver.Name == useragent.Name && ver.Version == useragent.Version && ver.Os == useragent.Os { if ver.Name == useragent.Name && ver.Version == useragent.Version && ver.Os == useragent.Os {
log.Debug("Found all 3 components in black list, it is ban") log.Warnf("Hammer falls on %s (%s): Software Name, Version and OS match entry in blacklist", p.From, p.JID)
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type) id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
@@ -558,9 +579,9 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
return err return err
} }
case useragent.Name != "" && useragent.Version != "": case useragent.Name != "" && useragent.Version != "" && useragent.Os == "":
if ver.Name == useragent.Name && ver.Version == useragent.Version { if ver.Name == useragent.Name && ver.Version == useragent.Version {
log.Debug("Found sw name and version in blacklist, it is ban") log.Warnf("Hammer falls on %s (%s): Software Name and Version match entry in blacklist", p.From, p.JID)
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type) id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
@@ -577,9 +598,9 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
return err return err
} }
case useragent.Name != "": case useragent.Name != "" && useragent.Version == "" && useragent.Os == "":
if ver.Name == useragent.Name { if ver.Name == useragent.Name {
log.Debug("Found sw name in blacklist, it is ban") log.Warnf("Hammer falls on %s (%s): Software Name match entry in blacklist", p.From, p.JID)
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type) id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
@@ -596,9 +617,9 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
return err return err
} }
case useragent.Version != "": case useragent.Name == "" && useragent.Version != "" && useragent.Os == "":
if ver.Version == useragent.Version { if ver.Version == useragent.Version {
log.Debug("Found sw version in blacklist, it is ban") log.Warnf("Hammer falls on %s (%s): Software Version match entry in blacklist", p.From, p.JID)
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type) id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
@@ -616,6 +637,8 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
} }
} }
} }
log.Debugf("No matches in software versions blacklist for %s", room)
} }
} }
} }

View File

@@ -632,8 +632,8 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
} }
} else { } else {
log.Infof( log.Infof(
"Presence notification, Type: %s, From: %s, To: %s Show: %s, Status: %s, Affiliation: %s, Role: %s, JID: %s", "Presence notification, Type: %s, From: %s, To: %s Show: %s, Status: %s, Affiliation: %s, Role: %s, JID: %s, Priority: %s",
v.Type, v.From, v.To, v.Show, v.Status, v.Affiliation, v.Role, v.JID, v.Type, v.From, v.To, v.Show, v.Status, v.Affiliation, v.Role, v.JID, v.Priority,
) )
if !strings.Contains(v.From, "/") { if !strings.Contains(v.From, "/") {
@@ -642,6 +642,12 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
return return
} }
if v.JID == "" {
log.Info("Useless presence notification without JID field, skipping")
return
}
room := strings.SplitN(v.From, "/", 2)[0] room := strings.SplitN(v.From, "/", 2)[0]
nick := strings.SplitN(v.From, "/", 2)[1] nick := strings.SplitN(v.From, "/", 2)[1]
@@ -651,8 +657,7 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
return return
} }
// Это наш собственный Presence. // На всякий случай добавим комнату, из которой пришло уведомление в список тех, в которые вхож бот.
if v.Show == "" && v.Status == "" {
if nick == j.GetBotNickFromRoomConfig(room) { if nick == j.GetBotNickFromRoomConfig(room) {
j.RoomsConnected = append(j.RoomsConnected, room) j.RoomsConnected = append(j.RoomsConnected, room)
// На всякий случай дедуплицируем список комнат, к которым мы заджойнились. // На всякий случай дедуплицируем список комнат, к которым мы заджойнились.
@@ -660,59 +665,159 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
j.RoomsConnected = slices.Compact(j.RoomsConnected) j.RoomsConnected = slices.Compact(j.RoomsConnected)
} }
}
switch v.Role { switch v.Role {
// Участник ушёл. // Участник ушёл.
case "none": case "none":
var (
newPresences = make([]xmpp.Presence, 0)
presenceJSON []byte
ok bool
presences []xmpp.Presence
)
// Обновлять базу имеет смысл только если есть хоть какая-то запись о комнате в ней.
if presenceJSONInterface, present := j.RoomPresences.Get(room); present { if presenceJSONInterface, present := j.RoomPresences.Get(room); present {
presenceJSONStrings := InterfaceToStringSlice(presenceJSONInterface) presenceJSON, ok = presenceJSONInterface.([]byte)
var newPresenceJSONStrings []string if !ok {
log.Errorf("Looks like we have corrupted entry in presence db")
for _, presenceJSONstring := range presenceJSONStrings { return
var p xmpp.Presence }
_ = json.Unmarshal([]byte(presenceJSONstring), &p) if err := json.Unmarshal(presenceJSON, &presences); err != nil {
log.Errorf("Looks like we have corrupted entry in presence db")
return
}
for _, p := range presences { //nolint: gocritic // Развели тут, блять, страну советов, напиши что надо сделать кодом, сука.
// Если находим, что у нас уже есть клиент с таким же From, то есть полным nick-ом (для groupchat)
// пропускаем его.
if p.From == v.From { if p.From == v.From {
if j.C.Debug.PresenceDB {
log.Debugf("Skipping presence for %s in room %s", v.JID, room)
}
continue continue
} }
newPresenceJSONStrings = append(newPresenceJSONStrings, presenceJSONstring) if j.C.Debug.PresenceDB {
log.Debugf("Appending presence for %s in room %s", v.JID, room)
} }
j.RoomPresences.Set(room, newPresenceJSONStrings) newPresences = append(newPresences, p)
} }
// Участник пришёл.
presenceJSON, _ = json.Marshal(newPresences) //nolint: errchkjson
if j.C.Debug.PresenceDB {
log.Debugf("Updating presence db for room %s", room)
}
j.RoomPresences.Set(room, presenceJSON)
// Больше нам, похоже с этим уведомлением нечего.
return
}
// Участник пришёл или изменил свой статус.
default: default:
var ( var (
presenceJSONStrings []string newPresences = make([]xmpp.Presence, 0)
newPresenceJSONStrings []string presenceJSON []byte
presenceJSONBytes []byte ok bool
presences []xmpp.Presence
skip bool
) )
if presenceJSONInterface, present := j.RoomPresences.Get(room); present { if presenceJSONInterface, present := j.RoomPresences.Get(room); present {
presenceJSONStrings = InterfaceToStringSlice(presenceJSONInterface) presenceJSON, ok = presenceJSONInterface.([]byte)
if !ok {
log.Errorf("Looks like we have corrupted entry in presence db")
return
} }
for _, presenceJSONString := range presenceJSONStrings { // Если мы нашли запись о комнате, то её надо обновить.
var p xmpp.Presence if err := json.Unmarshal(presenceJSON, &presences); err != nil {
log.Errorf("Looks like we have corrupted entry in presence db")
_ = json.Unmarshal([]byte(presenceJSONString), &p) return
}
for _, p := range presences { //nolint: gocritic // Развели тут, блять, страну советов, напиши что надо сделать кодом, сука.
// Если находим, что у нас уже есть клиент с таким же From, то есть полным nick-ом (для groupchat) // Если находим, что у нас уже есть клиент с таким же From, то есть полным nick-ом (для groupchat)
// просто замещаем его. // запоминаем его и добавим позднее.
if p.From == v.From { if p.From == v.From {
// Запоминаем участника только если его роль не поменялась на outcast. (То есть если это не
// бан.)
if v.Role == "outcast" {
if j.C.Debug.PresenceDB {
log.Debugf("Let's forget about %s because it is outcast/banned", p.JID)
}
skip = true
} else if j.C.Debug.PresenceDB {
log.Debugf("Skip adding %s to presences for %s, add as last one", p.JID, room)
}
continue continue
} }
newPresenceJSONStrings = append(newPresenceJSONStrings, presenceJSONString) if j.C.Debug.PresenceDB {
log.Debugf("Appending presence for %s in room %s", v.JID, room)
} }
presenceJSONBytes, _ = json.Marshal(v) //nolint:errchkjson newPresences = append(newPresences, p)
newPresenceJSONStrings = append(newPresenceJSONStrings, string(presenceJSONBytes)) }
j.RoomPresences.Set(room, newPresenceJSONStrings) }
if !skip {
if j.C.Debug.PresenceDB {
log.Debugf("Appending presence for %s in room %s", v.JID, room)
}
newPresences = append(newPresences, v)
} else if j.C.Debug.PresenceDB {
log.Debugf("Skip Appending outcast presence for %s in room %s", v.JID, room)
}
presenceJSON, _ = json.Marshal(newPresences) //nolint: errchkjson
if j.C.Debug.PresenceDB {
log.Debugf("Updating presence db for room %s", room)
}
j.RoomPresences.Set(room, presenceJSON)
}
if j.C.Debug.PresenceDB {
log.Debugf("List of presence entries in presence db of %s:", room)
if presenceJSONInterface, present := j.RoomPresences.Get(room); present {
var presences []xmpp.Presence
presenceJSON, ok := presenceJSONInterface.([]byte)
if !ok {
log.Debugf("Looks like we have corrupted entry in presence db")
return
}
// Если мы нашли запись о комнате, то её надо обновить.
if err := json.Unmarshal(presenceJSON, &presences); err != nil {
log.Debugf("Looks like we have corrupted entry in presence db")
return
}
for _, p := range presences { //nolint: gocritic // Развели тут, блять, страну советов, напиши что надо сделать кодом, сука.
log.Debugf("Found presence for %s from %s", p.JID, room)
}
}
} }
// Проверяем, а не злодей ли зашёл? Сделать это мы можем, только если мы находимся в комнате. // Проверяем, а не злодей ли зашёл? Сделать это мы можем, только если мы находимся в комнате.

View File

@@ -17,6 +17,7 @@ type (
Debug struct { Debug struct {
Lib bool `json:"lib,omitempty"` Lib bool `json:"lib,omitempty"`
Ping bool `json:"ping,omitempty"` Ping bool `json:"ping,omitempty"`
PresenceDB bool `json:"presence_db,omitempty"`
} `json:"debug"` } `json:"debug"`
Version string `json:"version,omitempty"` Version string `json:"version,omitempty"`
ExeName string `json:"exe_name,omitempty"` ExeName string `json:"exe_name,omitempty"`
@@ -69,7 +70,7 @@ type (
// MyWhiteList прототип структурки с белым списком jid-ов. // MyWhiteList прототип структурки с белым списком jid-ов.
MyWhiteList struct { MyWhiteList struct {
Whitelist []struct { Whitelist []struct {
RoomName string `json:"room_name,omitempty"` RoomName string `json:"room_name"`
Jid []string `json:"jid,omitempty"` Jid []string `json:"jid,omitempty"`
WipeBans bool `json:"wipe_bans,omitempty"` WipeBans bool `json:"wipe_bans,omitempty"`
} `json:"whitelist,omitempty"` } `json:"whitelist,omitempty"`
@@ -77,18 +78,24 @@ type (
// MyBlackList прототип структурки с чёрным списком jid-ов. // MyBlackList прототип структурки с чёрным списком jid-ов.
MyBlackList struct { MyBlackList struct {
Blacklist []struct { Blacklist []MyBlackListEntry `json:"blacklist"`
RoomName string `json:"room_name,omitempty"` }
JidRe []string `json:"jid_re,omitempty"`
NickRe []string `json:"nick_re,omitempty"` // MyBlackListEntry вложенная структура для MyBlackList.
PhraseRe []string `json:"phrase_re,omitempty"` MyBlackListEntry struct {
UserAgent []struct { RoomName string `json:"room_name"`
Name string `json:"name,omitempty"` JidRe []string `json:"jid_re"`
Version string `json:"version,omitempty"` NickRe []string `json:"nick_re"`
Os string `json:"os,omitempty"` PhraseRe []string `json:"phrase_re"`
} `json:"user_agent"` UserAgent []MyBlackListEntryUserAgent `json:"user_agent"`
ReasonEnable bool `json:"reason_enable,omitempty"` ReasonEnable bool `json:"reason_enable,omitempty"`
} `json:"blacklist"` }
// MyBlackListEntryUserAgent вложенная структура для MyBlackListEntry.
MyBlackListEntryUserAgent struct {
Name string `json:"name"`
Version string `json:"version"`
Os string `json:"os"`
} }
// Jabber основная структура-объект, содержащая стейты и проч. // Jabber основная структура-объект, содержащая стейты и проч.

View File

@@ -45,23 +45,30 @@ func InterfaceToStringSlice(iface any) []string {
// GetRealJIDfromNick достаёт из запомненных presence-ов по даденному nick-у real jid с resource-ом. Nick должен // GetRealJIDfromNick достаёт из запомненных presence-ов по даденному nick-у real jid с resource-ом. Nick должен
// содержать имя конфы, откуда участник. // содержать имя конфы, откуда участник.
func (j *Jabber) GetRealJIDfromNick(fullNick string) string { func (j *Jabber) GetRealJIDfromNick(fullNick string) string {
var p xmpp.Presence var (
presenceJSON []byte
ok bool
presences []xmpp.Presence
)
room := (strings.SplitN(fullNick, "/", 2))[0] room := (strings.SplitN(fullNick, "/", 2))[0]
// Достанем presence участника. if presenceJSONInterface, present := j.RoomPresences.Get(room); present {
presenceJSONInterface, present := j.RoomPresences.Get(room) presenceJSON, ok = presenceJSONInterface.([]byte)
if !ok {
log.Errorf("Looks like we have corrupted entry in presence db")
return ""
}
}
if err := json.Unmarshal(presenceJSON, &presences); err != nil {
log.Errorf("Looks like we have corrupted entry in presence db")
// Никого нет дома.
if !present {
return "" return ""
} }
presenceJSONStrings := InterfaceToStringSlice(presenceJSONInterface) for _, p := range presences { //nolint: gocritic // Развели тут, блять, страну советов, напиши что надо сделать кодом, сука.
for _, presepresenceJSONString := range presenceJSONStrings {
_ = json.Unmarshal([]byte(presepresenceJSONString), &p)
if p.From == fullNick { if p.From == fullNick {
return p.JID return p.JID
} }
@@ -191,17 +198,29 @@ func (j *Jabber) JoinMuc(room string) error {
j.GTomb.Go(func() error { return j.RotateStatus(room) }) j.GTomb.Go(func() error { return j.RotateStatus(room) })
// Время проверить участников на предмет злобности. // Время проверить участников на предмет злобности.
namesInterface, present := j.RoomPresences.Get(room) presenceJSONInterface, present := j.RoomPresences.Get(room)
// Если room есть в списке presence-ов, то фигачим. room там должен быть, просто обязан.
if present { if present {
for _, name := range InterfaceToStringSlice(namesInterface) { presenceJSON, ok := presenceJSONInterface.([]byte)
var v xmpp.Presence
_ = json.Unmarshal([]byte(name), &v) if !ok {
log.Infof("Fake presence forged for %s just for on-enter check", v.JID) log.Errorf("Looks like we have corrupted entry in presence db")
return nil
}
var presences []xmpp.Presence
if err := json.Unmarshal(presenceJSON, &presences); err != nil {
log.Errorf("Looks like we have corrupted entry in presence db")
return nil //nolint: nilerr // If presence db is corrupted it is a bad thing, but we log it anyway.
}
for _, p := range presences { //nolint: gocritic // Развели тут, блять, страну советов, напиши что надо сделать кодом, сука.
log.Infof("Fake presence forged for %s just for on-enter check", p.JID)
// Оно там внутри всё само обработает, если вдруг возникнет wire error, то зарекконетится. // Оно там внутри всё само обработает, если вдруг возникнет wire error, то зарекконетится.
_ = j.BunyPresense(v) _ = j.BunyPresense(p)
} }
} }