feat: auth, site creation with PHP version selection
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
package sitesvc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/panelhosting/panel/internal/models"
|
||||
"github.com/panelhosting/panel/internal/repository"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidSiteName = errors.New("site name must be 3-64 chars: lowercase letters, digits, hyphen")
|
||||
ErrInvalidDomain = errors.New("invalid domain")
|
||||
ErrInvalidPHPVersion = errors.New("unsupported php version")
|
||||
)
|
||||
|
||||
var (
|
||||
siteNameRegex = regexp.MustCompile(`^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$`)
|
||||
domainRegex = regexp.MustCompile(`^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$`)
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
sites *repository.SiteRepository
|
||||
servers *repository.ServerRepository
|
||||
phpVers *repository.PHPVersionRepository
|
||||
}
|
||||
|
||||
func NewService(sites *repository.SiteRepository, servers *repository.ServerRepository, php *repository.PHPVersionRepository) *Service {
|
||||
return &Service{sites: sites, servers: servers, phpVers: php}
|
||||
}
|
||||
|
||||
type CreateInput struct {
|
||||
Name string
|
||||
Domain string
|
||||
PHPVersion string
|
||||
ServerID int64
|
||||
OwnerID int64
|
||||
IsAdmin bool
|
||||
}
|
||||
|
||||
func (s *Service) List(ctx context.Context, user *models.User, isAdmin bool) ([]repository.SiteWithDomain, error) {
|
||||
return s.sites.ListForUser(ctx, user.ID, isAdmin)
|
||||
}
|
||||
|
||||
func (s *Service) ListPHPVersions(ctx context.Context) ([]string, error) {
|
||||
return s.phpVers.ListActive(ctx)
|
||||
}
|
||||
|
||||
func (s *Service) Create(ctx context.Context, in CreateInput) (*repository.SiteWithDomain, error) {
|
||||
name := strings.ToLower(strings.TrimSpace(in.Name))
|
||||
domain := strings.ToLower(strings.TrimSpace(in.Domain))
|
||||
phpVersion := strings.TrimSpace(in.PHPVersion)
|
||||
|
||||
if !siteNameRegex.MatchString(name) {
|
||||
return nil, ErrInvalidSiteName
|
||||
}
|
||||
if !domainRegex.MatchString(domain) {
|
||||
return nil, ErrInvalidDomain
|
||||
}
|
||||
if phpVersion == "" {
|
||||
return nil, ErrInvalidPHPVersion
|
||||
}
|
||||
|
||||
active, err := s.phpVers.IsActive(ctx, phpVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !active {
|
||||
return nil, ErrInvalidPHPVersion
|
||||
}
|
||||
|
||||
serverID := in.ServerID
|
||||
if serverID == 0 {
|
||||
srv, err := s.servers.GetFirst(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("no server available: %w", err)
|
||||
}
|
||||
serverID = srv.ID
|
||||
} else {
|
||||
if _, err := s.servers.GetByID(ctx, serverID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
documentRoot := fmt.Sprintf("/var/www/%s/public", name)
|
||||
return s.sites.Create(ctx, serverID, in.OwnerID, name, documentRoot, phpVersion, domain)
|
||||
}
|
||||
Reference in New Issue
Block a user