feat(model): add IPBan entity for global IP blocking

Introduces the IPBan model to support global IP/CIDR ban rules enforced by the data plane. Includes fields for CIDR, status, expiration, and hit counts, and registers the model for auto-migration in the server startup.
This commit is contained in:
zenfun
2026-01-04 00:55:00 +08:00
parent f4d6f64068
commit ae2f4d7819
2 changed files with 40 additions and 2 deletions

38
internal/model/ip_ban.go Normal file
View File

@@ -0,0 +1,38 @@
package model
import (
"time"
"gorm.io/gorm"
)
// IPBan represents a global IP/CIDR ban rule.
// IP bans are enforced by the data plane (balancer) before token validation.
type IPBan struct {
gorm.Model
CIDR string `gorm:"size:64;uniqueIndex;not null" json:"cidr"` // Normalized CIDR (IPv4 /32, IPv6 /128)
Status string `gorm:"size:20;default:'active';index" json:"status"` // active, expired
Reason string `gorm:"size:512" json:"reason,omitempty"` // Optional ban reason
ExpiresAt *int64 `gorm:"index" json:"expires_at,omitempty"` // Unix timestamp, nil = permanent
HitCount int64 `gorm:"default:0" json:"hit_count"` // Number of blocked requests (synced from Redis)
CreatedBy string `gorm:"size:128" json:"created_by,omitempty"` // Creator identifier
}
// IPBanStatus constants
const (
IPBanStatusActive = "active"
IPBanStatusExpired = "expired"
)
// IsExpired returns true if the ban has expired.
func (b *IPBan) IsExpired() bool {
if b.ExpiresAt == nil {
return false // permanent ban
}
return time.Now().Unix() >= *b.ExpiresAt
}
// TableName returns the table name for IPBan.
func (IPBan) TableName() string {
return "ip_bans"
}