Implement ban guarding. Some ip fixes

This commit is contained in:
Dominic Ferrando
2025-04-24 01:14:33 -04:00
parent 73d66560b6
commit 99f8c7f97d
6 changed files with 97 additions and 26 deletions
+40 -2
View File
@@ -4,6 +4,7 @@ import (
"database/sql"
"errors"
"io/fs"
"log"
"os"
"path"
"time"
@@ -349,9 +350,46 @@ func GetAdmin(db *sql.DB, username string) (Admin, error) {
return result, nil
}
func BanIp(db *sql.DB, ip string, reason string, expiration time.Time) error {
func BanIp(db *sql.DB, ipHash string, reason string, expiration time.Time) error {
log.Printf("IP: %s, reason: %s, expiration: %v", ipHash, reason, expiration)
// if the ban already exists for ip, only update if its greater than existing
_, err := db.Exec(`
INSERT INTO bans (ip_hash, reason, expiration)
VALUES (?, ?, ?)`, ip, reason, expiration)
VALUES (?, ?, ?)
ON CONFLICT(ip_hash) DO UPDATE SET
reason = excluded.reason,
expiration = excluded.expiration
WHERE excluded.expiration > bans.expiration
`, ipHash, reason, expiration)
return err
}
var ErrBanNotFound = errors.New("ban not found")
func GetBan(db *sql.DB, ip string) (Ban, error) {
row := db.QueryRow(`
SELECT ip_hash, reason, expiration
FROM bans
where ip_hash = ?`, ip)
var r Ban
err := row.Scan(&r.IpHash, &r.Reason, &r.Expiration)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return Ban{}, ErrBanNotFound
}
return Ban{}, err
}
if time.Now().After(r.Expiration) {
_, err := db.Exec(`
DELETE FROM bans
WHERE ip_hash = ?`, ip)
if err != nil {
return Ban{}, err
}
return Ban{}, ErrBanNotFound
}
return r, nil
}
+6
View File
@@ -34,3 +34,9 @@ type Admin struct {
Username string
Password string
}
type Ban struct {
IpHash string
Reason string
Expiration time.Time
}
+1 -1
View File
@@ -42,7 +42,7 @@ CREATE TABLE IF NOT EXISTS admins (
CREATE TABLE IF NOT EXISTS bans (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ip_hash TEXT NOT NULL,
ip_hash TEXT NOT NULL UNIQUE,
reason TEXT NOT NULL,
expiration DATETIME NOT NULL
);
+5 -5
View File
@@ -16,9 +16,9 @@ const POST_COOLDOWN = 15 * time.Second
const THREAD_COOLDOWN = 2 * time.Minute
func GetRemainingCooldown(ip string, m map[string]time.Time, duration time.Duration) time.Duration {
func GetRemainingCooldown(ipHash string, m map[string]time.Time, duration time.Duration) time.Duration {
CooldownMutex.RLock()
last, exists := m[ip]
last, exists := m[ipHash]
CooldownMutex.RUnlock()
if !exists {
return 0
@@ -26,12 +26,12 @@ func GetRemainingCooldown(ip string, m map[string]time.Time, duration time.Durat
return duration - time.Since(last)
}
func BeginCooldown(ip string, m map[string]time.Time, duration time.Duration) {
func BeginCooldown(ipHash string, m map[string]time.Time, duration time.Duration) {
CooldownMutex.Lock()
defer CooldownMutex.Unlock()
last, exists := m[ip]
last, exists := m[ipHash]
if !exists || time.Since(last) >= duration {
m[ip] = time.Now()
m[ipHash] = time.Now()
}
}