Initial commit
This commit is contained in:
@@ -1,163 +1,160 @@
|
||||
package moon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func RunAndBan() {
|
||||
for {
|
||||
// If user have both events, he is not spammer. So wipe him from unchecked events list, just for sure.
|
||||
for _, chatid := range ChatList {
|
||||
Log.Infof("RunAndBan by chatid: %d", chatid)
|
||||
var (
|
||||
ListAppearedMembers, ListNewMembers []string
|
||||
empty string
|
||||
)
|
||||
|
||||
var ListAppearedMembers, ListNewMembers []int64
|
||||
AppearedMembers.Range(
|
||||
func(k, _ any) bool {
|
||||
ListAppearedMembers = append(ListAppearedMembers, k.(string))
|
||||
|
||||
AppearedMembers[chatid].Range(
|
||||
func(k, _ any) bool {
|
||||
ListAppearedMembers = append(ListAppearedMembers, k.(int64))
|
||||
return true
|
||||
},
|
||||
)
|
||||
|
||||
return true
|
||||
},
|
||||
)
|
||||
NewMembers.Range(
|
||||
func(k, _ any) bool {
|
||||
ListNewMembers = append(ListNewMembers, k.(string))
|
||||
|
||||
NewMembers[chatid].Range(
|
||||
func(k, _ any) bool {
|
||||
ListNewMembers = append(ListNewMembers, k.(int64))
|
||||
return true
|
||||
},
|
||||
)
|
||||
|
||||
return true
|
||||
},
|
||||
)
|
||||
|
||||
for _, AppearedMember := range ListAppearedMembers {
|
||||
for _, NewMember := range ListNewMembers {
|
||||
if AppearedMember == NewMember {
|
||||
// TODO: Store also additional attributes in temporary database.
|
||||
Log.Infof(
|
||||
"Skip banning user %s %s (username = %s, id = %d) in %s %s (%d), because it has both events newMember and updateMember",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
NewMember,
|
||||
"",
|
||||
"",
|
||||
chatid,
|
||||
)
|
||||
|
||||
Log.Infof(
|
||||
"Deleting user %s %s (username = %s, id = %d) in %s %s (%d), from AppearedMember DB",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
NewMember,
|
||||
"",
|
||||
"",
|
||||
chatid,
|
||||
)
|
||||
|
||||
AppearedMembers[chatid].Delete(AppearedMember)
|
||||
|
||||
Log.Infof(
|
||||
"Deleting user %s %s (username = %s, id = %d) in %s %s (%d), from NewMember DB",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
NewMember,
|
||||
"",
|
||||
"",
|
||||
chatid,
|
||||
)
|
||||
|
||||
NewMembers[chatid].Delete(NewMember)
|
||||
}
|
||||
for _, AppearedMember := range ListAppearedMembers {
|
||||
for _, NewMember := range ListNewMembers {
|
||||
if AppearedMember == NewMember {
|
||||
AppearedMembers.Delete(AppearedMember)
|
||||
NewMembers.Delete(NewMember)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentTime := time.Now().Unix()
|
||||
|
||||
// We would like to process only events that definitely older than 10 seconds!
|
||||
for _, chatid := range ChatList {
|
||||
var (
|
||||
ListAppearedMembers, ListNewMembers []int64
|
||||
)
|
||||
ListAppearedMembers = ListAppearedMembers[:0]
|
||||
ListNewMembers = ListNewMembers[:0]
|
||||
ListAppearedMembers = slices.Clip(ListAppearedMembers)
|
||||
ListNewMembers = slices.Clip(ListNewMembers)
|
||||
|
||||
AppearedMembers[chatid].Range(
|
||||
func(k, v interface{}) bool {
|
||||
ListAppearedMembers = append(ListAppearedMembers, k.(int64))
|
||||
AppearedMembers.Range(
|
||||
func(k, _ any) bool {
|
||||
ListAppearedMembers = append(ListAppearedMembers, k.(string))
|
||||
|
||||
return true
|
||||
},
|
||||
)
|
||||
return true
|
||||
},
|
||||
)
|
||||
|
||||
NewMembers[chatid].Range(
|
||||
func(k, v interface{}) bool {
|
||||
ListNewMembers = append(ListNewMembers, k.(int64))
|
||||
NewMembers.Range(
|
||||
func(k, _ any) bool {
|
||||
ListNewMembers = append(ListNewMembers, k.(string))
|
||||
|
||||
return true
|
||||
},
|
||||
)
|
||||
return true
|
||||
},
|
||||
)
|
||||
|
||||
for _, AppearedMember := range ListAppearedMembers {
|
||||
eventTimestamp, found := AppearedMembers[chatid].Get(AppearedMember)
|
||||
for _, AppearedMember := range ListAppearedMembers {
|
||||
eventTimestamp, found := AppearedMembers.Get(AppearedMember)
|
||||
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
eventTimeDelta := currentTime - eventTimestamp.(int64)
|
||||
|
||||
// Looks like it is spammer!
|
||||
if eventTimeDelta > 10 {
|
||||
// TODO: Store also additional attributes in temporary database.
|
||||
Log.Infof(
|
||||
"Ban user %s %s (username = %s, id = %d) in chat %s %s (%d) that have no newChatMember message since chatMemberUpdated for more than 10 seconds",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
AppearedMember,
|
||||
"",
|
||||
"",
|
||||
chatid,
|
||||
)
|
||||
|
||||
squash(
|
||||
chatid,
|
||||
"",
|
||||
"",
|
||||
AppearedMember,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
)
|
||||
|
||||
AppearedMembers[chatid].Delete(AppearedMember)
|
||||
}
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, NewMember := range ListNewMembers {
|
||||
eventTimestamp, found := NewMembers[chatid].Get(NewMember)
|
||||
eventTimeDelta := currentTime - eventTimestamp.(int64)
|
||||
|
||||
// Spammer?
|
||||
if eventTimeDelta > 10 {
|
||||
item := strings.Split(AppearedMember, "+")
|
||||
chatid, err := strconv.ParseInt(item[0], 10, 64)
|
||||
|
||||
if err != nil {
|
||||
Log.Errorf("Got broken key in AppearedMembers cache: %s", AppearedMember)
|
||||
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
eventTimeDelta := currentTime - eventTimestamp.(int64)
|
||||
userid, err := strconv.ParseInt(item[1], 10, 64)
|
||||
|
||||
// Totally new members should not have chatMemberUpdated events.
|
||||
if eventTimeDelta > 15 {
|
||||
// TODO: Store also additional attributes in temporary database.
|
||||
Log.Debugf("Clean newChatMember event record older than 10 seconds for user user %s %s (username = %s, id = %d) in chat %s %s (%d)",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
NewMember,
|
||||
"",
|
||||
"",
|
||||
chatid,
|
||||
)
|
||||
if err != nil {
|
||||
Log.Errorf("Got broken key in AppearedMembers cache: %s", AppearedMember)
|
||||
|
||||
NewMembers[chatid].Delete(NewMember)
|
||||
continue
|
||||
}
|
||||
|
||||
Log.Infof(
|
||||
"Ban user %s %s (username = %s, id = %d) in chat %s %s (%d) that have no newChatMember message since chatMemberUpdated for more than 10 seconds",
|
||||
empty,
|
||||
empty,
|
||||
empty,
|
||||
userid,
|
||||
empty,
|
||||
empty,
|
||||
chatid,
|
||||
)
|
||||
|
||||
squash(
|
||||
chatid,
|
||||
empty,
|
||||
empty,
|
||||
userid,
|
||||
empty,
|
||||
empty,
|
||||
empty,
|
||||
)
|
||||
|
||||
AppearedMembers.Delete(AppearedMember)
|
||||
}
|
||||
}
|
||||
|
||||
for _, NewMember := range ListNewMembers {
|
||||
eventTimestamp, found := NewMembers.Get(NewMember)
|
||||
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
eventTimeDelta := currentTime - eventTimestamp.(int64)
|
||||
|
||||
// Spammer?
|
||||
if eventTimeDelta > 10 {
|
||||
item := strings.Split(NewMember, "+")
|
||||
chatid, err := strconv.ParseInt(item[0], 10, 64)
|
||||
|
||||
if err != nil {
|
||||
Log.Errorf("Got broken key in AppearedMembers cache: %s", NewMember)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
userid, err := strconv.ParseInt(item[1], 10, 64)
|
||||
|
||||
if err != nil {
|
||||
Log.Errorf("Got broken key in AppearedMembers cache: %s", NewMember)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
Log.Debugf("Clean newChatMember event record older than 10 seconds for user user %s %s (username = %s, id = %d) in chat %s %s (%d)",
|
||||
empty,
|
||||
empty,
|
||||
empty,
|
||||
userid,
|
||||
empty,
|
||||
empty,
|
||||
chatid,
|
||||
)
|
||||
|
||||
NewMembers.Delete(NewMember)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,4 +162,142 @@ func RunAndBan() {
|
||||
}
|
||||
}
|
||||
|
||||
func PeriodicCASCheck() {
|
||||
for {
|
||||
var (
|
||||
ListPendingMembers []string
|
||||
empty string
|
||||
)
|
||||
|
||||
PendingCASMembers.Range(
|
||||
func(k, _ any) bool {
|
||||
ListPendingMembers = append(ListPendingMembers, k.(string))
|
||||
|
||||
return true
|
||||
},
|
||||
)
|
||||
|
||||
currentTime := time.Now().Unix()
|
||||
|
||||
for _, PendingMember := range ListPendingMembers {
|
||||
eventTimestamp, found := PendingCASMembers.Get(PendingMember)
|
||||
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
eventTimeDelta := currentTime - eventTimestamp.(int64)
|
||||
|
||||
// It's time to check for second time this id if it was banned in CAS.
|
||||
if eventTimeDelta > 300 {
|
||||
item := strings.Split(PendingMember, "+")
|
||||
chatid, err := strconv.ParseInt(item[0], 10, 64)
|
||||
|
||||
if err != nil {
|
||||
Log.Errorf("Got broken key in PendingMembers cache: %s", PendingMember)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
userid, err := strconv.ParseInt(item[1], 10, 64)
|
||||
|
||||
if err != nil {
|
||||
Log.Errorf("Got broken key in PendingMembers cache: %s", PendingMember)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
value := Cfg.GetValue(
|
||||
"BannedMembers",
|
||||
fmt.Sprintf("%d", chatid),
|
||||
fmt.Sprintf("%d", userid),
|
||||
)
|
||||
|
||||
if value != "" {
|
||||
Log.Debugf("User %s %s (username = %s, id = %d) in %s %s (%d) is already banned, skip cas check.",
|
||||
empty,
|
||||
empty,
|
||||
empty,
|
||||
userid,
|
||||
empty,
|
||||
empty,
|
||||
chatid,
|
||||
)
|
||||
|
||||
Log.Debugf(
|
||||
"Remove user %s %s (username = %s, id = %d) in %s %s (%d) from PendingCASMembers",
|
||||
empty,
|
||||
empty,
|
||||
empty,
|
||||
userid,
|
||||
empty,
|
||||
empty,
|
||||
chatid,
|
||||
)
|
||||
|
||||
key := fmt.Sprintf("%d+%d", chatid, userid)
|
||||
PendingCASMembers.Delete(key)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
Log.Debugf("Checking user %s %s (username = %s, id = %d) in %s %s (%d) for second time in CAS",
|
||||
empty,
|
||||
empty,
|
||||
empty,
|
||||
userid,
|
||||
empty,
|
||||
empty,
|
||||
chatid,
|
||||
)
|
||||
|
||||
banned, err := CasCheckID(userid)
|
||||
|
||||
if err != nil {
|
||||
Log.Error(err)
|
||||
}
|
||||
|
||||
if banned {
|
||||
Log.Infof(
|
||||
"Ban user %s %s (username = %s, id = %d) in %s %s (%d) by CAS blacklist",
|
||||
empty,
|
||||
empty,
|
||||
empty,
|
||||
userid,
|
||||
empty,
|
||||
empty,
|
||||
chatid,
|
||||
)
|
||||
|
||||
squash(
|
||||
userid,
|
||||
empty,
|
||||
empty,
|
||||
userid,
|
||||
empty,
|
||||
empty,
|
||||
empty,
|
||||
)
|
||||
}
|
||||
|
||||
Log.Debugf(
|
||||
"Remove user %s %s (username = %s, id = %d) in %s %s (%d) from PendingCASMembers",
|
||||
empty,
|
||||
empty,
|
||||
empty,
|
||||
userid,
|
||||
empty,
|
||||
empty,
|
||||
chatid,
|
||||
)
|
||||
|
||||
PendingCASMembers.Delete(PendingMember)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
time.Sleep(10 * time.Minute)
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||
|
||||
Reference in New Issue
Block a user