2024-08-15 15:00:43 +00:00
|
|
|
package utils
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"grain/config"
|
|
|
|
cfg "grain/config/types"
|
|
|
|
"os"
|
|
|
|
"strings"
|
2024-08-15 20:20:22 +00:00
|
|
|
"sync"
|
|
|
|
"time"
|
2024-08-15 15:00:43 +00:00
|
|
|
|
|
|
|
"gopkg.in/yaml.v2"
|
|
|
|
)
|
|
|
|
|
2024-08-15 20:20:22 +00:00
|
|
|
// Structure to manage temporary bans with timestamps
|
|
|
|
type tempBanEntry struct {
|
|
|
|
count int // Number of temporary bans
|
|
|
|
unbanTime time.Time // Time when the pubkey should be unbanned
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
tempBannedPubkeys = make(map[string]*tempBanEntry)
|
|
|
|
mu sync.Mutex
|
|
|
|
)
|
|
|
|
|
|
|
|
func ClearTemporaryBans() {
|
|
|
|
mu.Lock()
|
|
|
|
defer mu.Unlock()
|
|
|
|
tempBannedPubkeys = make(map[string]*tempBanEntry)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-08-15 15:00:43 +00:00
|
|
|
// CheckBlacklist checks if a pubkey is in the blacklist based on event content
|
|
|
|
func CheckBlacklist(pubkey, eventContent string) (bool, string) {
|
|
|
|
cfg := config.GetConfig().Blacklist
|
|
|
|
|
|
|
|
if !cfg.Enabled {
|
|
|
|
return false, ""
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check for permanent blacklist by pubkey or npub
|
|
|
|
if isPubKeyPermanentlyBlacklisted(pubkey) {
|
|
|
|
return true, fmt.Sprintf("pubkey %s is permanently blacklisted", pubkey)
|
|
|
|
}
|
|
|
|
|
2024-08-15 20:20:22 +00:00
|
|
|
// Check for temporary ban
|
|
|
|
if isPubKeyTemporarilyBlacklisted(pubkey) {
|
|
|
|
return true, fmt.Sprintf("pubkey %s is temporarily blacklisted", pubkey)
|
|
|
|
}
|
|
|
|
|
2024-08-15 15:00:43 +00:00
|
|
|
// Check for permanent ban based on wordlist
|
|
|
|
for _, word := range cfg.PermanentBanWords {
|
|
|
|
if strings.Contains(eventContent, word) {
|
|
|
|
err := AddToPermanentBlacklist(pubkey)
|
|
|
|
if err != nil {
|
|
|
|
return true, fmt.Sprintf("pubkey %s is permanently banned and failed to save: %v", pubkey, err)
|
|
|
|
}
|
|
|
|
return true, fmt.Sprintf("pubkey %s is permanently banned for containing forbidden words", pubkey)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-15 20:20:22 +00:00
|
|
|
// Check for temporary ban based on wordlist
|
|
|
|
for _, word := range cfg.TempBanWords {
|
|
|
|
if strings.Contains(eventContent, word) {
|
|
|
|
err := AddToTemporaryBlacklist(pubkey)
|
|
|
|
if err != nil {
|
|
|
|
return true, fmt.Sprintf("pubkey %s is temporarily banned and failed to save: %v", pubkey, err)
|
|
|
|
}
|
|
|
|
return true, fmt.Sprintf("pubkey %s is temporarily banned for containing forbidden words", pubkey)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-15 15:00:43 +00:00
|
|
|
return false, ""
|
|
|
|
}
|
|
|
|
|
2024-08-15 20:20:22 +00:00
|
|
|
|
|
|
|
// Checks if a pubkey is temporarily blacklisted
|
|
|
|
func isPubKeyTemporarilyBlacklisted(pubkey string) bool {
|
|
|
|
mu.Lock()
|
|
|
|
defer mu.Unlock()
|
|
|
|
|
|
|
|
entry, exists := tempBannedPubkeys[pubkey]
|
|
|
|
if !exists {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the ban has expired, remove it from the temporary ban list
|
|
|
|
if time.Now().After(entry.unbanTime) {
|
|
|
|
delete(tempBannedPubkeys, pubkey)
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// Adds a pubkey to the temporary blacklist
|
|
|
|
func AddToTemporaryBlacklist(pubkey string) error {
|
|
|
|
mu.Lock()
|
|
|
|
defer mu.Unlock()
|
|
|
|
|
2024-08-15 15:00:43 +00:00
|
|
|
cfg := config.GetConfig().Blacklist
|
2024-08-15 20:20:22 +00:00
|
|
|
|
|
|
|
// Check if the pubkey is already temporarily banned
|
|
|
|
entry, exists := tempBannedPubkeys[pubkey]
|
|
|
|
if !exists {
|
|
|
|
entry = &tempBanEntry{
|
|
|
|
count: 1,
|
|
|
|
unbanTime: time.Now().Add(time.Duration(cfg.TempBanDuration) * time.Second),
|
|
|
|
}
|
|
|
|
tempBannedPubkeys[pubkey] = entry
|
|
|
|
}
|
|
|
|
|
|
|
|
// Increment the temporary ban count and set the unban time
|
|
|
|
entry.count++
|
|
|
|
entry.unbanTime = time.Now().Add(time.Duration(cfg.TempBanDuration) * time.Second)
|
|
|
|
|
|
|
|
// If the count exceeds max_temp_bans, move to permanent blacklist
|
|
|
|
if entry.count >= cfg.MaxTempBans {
|
|
|
|
delete(tempBannedPubkeys, pubkey)
|
|
|
|
return AddToPermanentBlacklist(pubkey)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Checks if a pubkey is permanently blacklisted (only using config.yml)
|
|
|
|
func isPubKeyPermanentlyBlacklisted(pubKey string) bool {
|
|
|
|
cfg := config.GetConfig().Blacklist // Get the latest configuration
|
|
|
|
|
2024-08-15 15:00:43 +00:00
|
|
|
if !cfg.Enabled {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check pubkeys
|
|
|
|
for _, blacklistedKey := range cfg.PermanentBlacklistPubkeys {
|
|
|
|
if pubKey == blacklistedKey {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check npubs
|
|
|
|
for _, npub := range cfg.PermanentBlacklistNpubs {
|
|
|
|
decodedPubKey, err := DecodeNpub(npub)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Error decoding npub:", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if pubKey == decodedPubKey {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func AddToPermanentBlacklist(pubkey string) error {
|
2024-08-15 20:20:22 +00:00
|
|
|
mu.Lock()
|
|
|
|
defer mu.Unlock()
|
|
|
|
|
2024-08-15 15:00:43 +00:00
|
|
|
cfg := config.GetConfig().Blacklist
|
|
|
|
|
|
|
|
// Check if already blacklisted
|
|
|
|
if isPubKeyPermanentlyBlacklisted(pubkey) {
|
|
|
|
return fmt.Errorf("pubkey %s is already in the permanent blacklist", pubkey)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add pubkey to the blacklist
|
|
|
|
cfg.PermanentBlacklistPubkeys = append(cfg.PermanentBlacklistPubkeys, pubkey)
|
|
|
|
|
|
|
|
// Persist changes to config.yml
|
|
|
|
return saveBlacklistConfig(cfg)
|
|
|
|
}
|
|
|
|
|
|
|
|
func saveBlacklistConfig(blacklistConfig cfg.BlacklistConfig) error {
|
2024-08-15 20:20:22 +00:00
|
|
|
configData := config.GetConfig()
|
|
|
|
configData.Blacklist = blacklistConfig
|
2024-08-15 15:00:43 +00:00
|
|
|
|
2024-08-15 20:20:22 +00:00
|
|
|
data, err := yaml.Marshal(configData)
|
2024-08-15 15:00:43 +00:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to marshal config: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = os.WriteFile("config.yml", data, 0644)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to write config to file: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2024-08-15 20:20:22 +00:00
|
|
|
|