mirror of
https://github.com/EZ-Api/ez-api.git
synced 2026-01-13 17:47:51 +00:00
feat(server): integrate ip ban cron and refine updates
- Initialize and schedule IP ban maintenance tasks in server entry point - Perform initial IP ban sync to Redis on startup - Implement optional JSON unmarshalling to handle null `expires_at` in API - Add CIDR overlap validation when updating rule status to active
This commit is contained in:
@@ -15,10 +15,10 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidCIDR = errors.New("invalid CIDR format")
|
||||
ErrCIDROverlap = errors.New("CIDR overlaps with existing active rule")
|
||||
ErrIPBanNotFound = errors.New("IP ban not found")
|
||||
ErrDuplicateCIDR = errors.New("CIDR already exists")
|
||||
ErrInvalidCIDR = errors.New("invalid CIDR format")
|
||||
ErrCIDROverlap = errors.New("CIDR overlaps with existing active rule")
|
||||
ErrIPBanNotFound = errors.New("IP ban not found")
|
||||
ErrDuplicateCIDR = errors.New("CIDR already exists")
|
||||
)
|
||||
|
||||
// IPBanService handles global IP ban operations.
|
||||
@@ -93,9 +93,10 @@ type CreateIPBanRequest struct {
|
||||
|
||||
// UpdateIPBanRequest represents a request to update an IP ban.
|
||||
type UpdateIPBanRequest struct {
|
||||
Reason *string `json:"reason,omitempty"`
|
||||
ExpiresAt *int64 `json:"expires_at,omitempty"` // Use pointer to distinguish between "not set" and "set to null"
|
||||
Status *string `json:"status,omitempty"`
|
||||
Reason *string `json:"reason,omitempty"`
|
||||
ExpiresAt *int64 `json:"expires_at,omitempty"`
|
||||
ExpiresAtSet bool `json:"-"`
|
||||
Status *string `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// Create creates a new IP ban with validation.
|
||||
@@ -180,11 +181,25 @@ func (s *IPBanService) Update(ctx context.Context, id uint, req UpdateIPBanReque
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.Status != nil && *req.Status == model.IPBanStatusActive && ban.Status != model.IPBanStatusActive {
|
||||
var activeRules []model.IPBan
|
||||
if err := s.db.WithContext(ctx).
|
||||
Where("status = ? AND id <> ?", model.IPBanStatusActive, ban.ID).
|
||||
Find(&activeRules).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, rule := range activeRules {
|
||||
if CIDROverlaps(ban.CIDR, rule.CIDR) {
|
||||
return nil, fmt.Errorf("%w: overlaps with %s", ErrCIDROverlap, rule.CIDR)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updates := make(map[string]interface{})
|
||||
if req.Reason != nil {
|
||||
updates["reason"] = *req.Reason
|
||||
}
|
||||
if req.ExpiresAt != nil {
|
||||
if req.ExpiresAtSet {
|
||||
updates["expires_at"] = req.ExpiresAt
|
||||
}
|
||||
if req.Status != nil {
|
||||
|
||||
Reference in New Issue
Block a user