- Added a reset of the models.Setting struct before querying for settings in both the Manager and Cerberus components to avoid ID leakage from previous queries. - Introduced new functions in Cerberus for checking admin authentication and admin whitelist status. - Enhanced middleware logic to allow admin users to bypass ACL checks if their IP is whitelisted. - Added tests to verify the behavior of the middleware with respect to ACLs and admin whitelisting. - Created a new utility for checking if an IP is in a CIDR list. - Updated various services to use `Where` clause for fetching records by ID instead of directly passing the ID to `First`, ensuring consistency in query patterns. - Added comprehensive tests for settings queries to demonstrate and verify the fix for ID leakage issues.
97 lines
2.6 KiB
Go
97 lines
2.6 KiB
Go
package services
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
"github.com/Wikid82/charon/backend/internal/models"
|
|
)
|
|
|
|
// RemoteServerService encapsulates business logic for remote server management.
|
|
type RemoteServerService struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
// NewRemoteServerService creates a new remote server service.
|
|
func NewRemoteServerService(db *gorm.DB) *RemoteServerService {
|
|
return &RemoteServerService{db: db}
|
|
}
|
|
|
|
// ValidateUniqueServer ensures no duplicate name+host+port combinations.
|
|
func (s *RemoteServerService) ValidateUniqueServer(name, host string, port int, excludeID uint) error {
|
|
var count int64
|
|
query := s.db.Model(&models.RemoteServer{}).Where("name = ? OR (host = ? AND port = ?)", name, host, port)
|
|
|
|
if excludeID > 0 {
|
|
query = query.Where("id != ?", excludeID)
|
|
}
|
|
|
|
if err := query.Count(&count).Error; err != nil {
|
|
return fmt.Errorf("checking server uniqueness: %w", err)
|
|
}
|
|
|
|
if count > 0 {
|
|
return errors.New("server with same name or host:port already exists")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Create validates and creates a new remote server.
|
|
func (s *RemoteServerService) Create(server *models.RemoteServer) error {
|
|
if err := s.ValidateUniqueServer(server.Name, server.Host, server.Port, 0); err != nil {
|
|
return err
|
|
}
|
|
|
|
return s.db.Create(server).Error
|
|
}
|
|
|
|
// Update validates and updates an existing remote server.
|
|
func (s *RemoteServerService) Update(server *models.RemoteServer) error {
|
|
if err := s.ValidateUniqueServer(server.Name, server.Host, server.Port, server.ID); err != nil {
|
|
return err
|
|
}
|
|
|
|
return s.db.Save(server).Error
|
|
}
|
|
|
|
// Delete removes a remote server.
|
|
func (s *RemoteServerService) Delete(id uint) error {
|
|
return s.db.Delete(&models.RemoteServer{}, id).Error
|
|
}
|
|
|
|
// GetByID retrieves a remote server by ID.
|
|
func (s *RemoteServerService) GetByID(id uint) (*models.RemoteServer, error) {
|
|
var server models.RemoteServer
|
|
if err := s.db.Where("id = ?", id).First(&server).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &server, nil
|
|
}
|
|
|
|
// GetByUUID retrieves a remote server by UUID.
|
|
func (s *RemoteServerService) GetByUUID(uuidStr string) (*models.RemoteServer, error) {
|
|
var server models.RemoteServer
|
|
if err := s.db.Where("uuid = ?", uuidStr).First(&server).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &server, nil
|
|
}
|
|
|
|
// List retrieves all remote servers, optionally filtering by enabled status.
|
|
func (s *RemoteServerService) List(enabledOnly bool) ([]models.RemoteServer, error) {
|
|
var servers []models.RemoteServer
|
|
query := s.db
|
|
|
|
if enabledOnly {
|
|
query = query.Where("enabled = ?", true)
|
|
}
|
|
|
|
if err := query.Order("name ASC").Find(&servers).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return servers, nil
|
|
}
|