feat: Let's Encrypt SSL on site creation

This commit is contained in:
orohi
2026-06-17 05:57:01 +03:00
parent 9b7eb99d20
commit 00d6789897
18 changed files with 703 additions and 51 deletions
+88
View File
@@ -0,0 +1,88 @@
package sslsvc
import (
"context"
"log"
"time"
"github.com/panelhosting/panel/internal/config"
"github.com/panelhosting/panel/internal/repository"
"github.com/panelhosting/panel/internal/ssl"
)
type Service struct {
repo *repository.SSLRepository
issuer *ssl.Issuer
cfg *config.Config
}
func NewService(repo *repository.SSLRepository, issuer *ssl.Issuer, cfg *config.Config) *Service {
return &Service{repo: repo, issuer: issuer, cfg: cfg}
}
func (s *Service) IssueAsync(sslID, domainID int64, domain, webroot string) {
go func() {
ctx := context.Background()
if err := s.Issue(ctx, sslID, domainID, domain, webroot); err != nil {
log.Printf("ssl issue %s: %v", domain, err)
}
}()
}
func (s *Service) Issue(ctx context.Context, sslID, domainID int64, domain, webroot string) error {
if s.cfg.ACMEEmail == "" {
return s.repo.MarkError(ctx, sslID, "ACME_EMAIL not configured")
}
res, err := s.issuer.Obtain(ctx, domain, webroot)
if err != nil {
_ = s.repo.MarkError(ctx, sslID, err.Error())
return err
}
expiresAt, err := ssl.ParseCertExpiry(res.Certificate)
if err != nil {
expiresAt = time.Now().Add(90 * 24 * time.Hour)
}
issuerName := "Let's Encrypt"
if s.cfg.ACMEStaging {
issuerName = "Let's Encrypt (staging)"
}
return s.repo.MarkActive(ctx, sslID, issuerName, string(res.Certificate), string(res.PrivateKey), string(res.IssuerCertificate), time.Now(), expiresAt)
}
func (s *Service) IssueForSite(ctx context.Context, siteID int64) error {
domainID, err := s.repo.GetDomainIDBySite(ctx, siteID)
if err != nil {
return err
}
domain, webroot, err := s.repo.GetDomainInfo(ctx, domainID)
if err != nil {
return err
}
cert, err := s.repo.GetByDomainID(ctx, domainID)
if err != nil {
return err
}
var sslID int64
if cert == nil {
sslID, err = s.repo.CreatePending(ctx, domainID)
} else {
sslID = cert.ID
}
if err != nil {
return err
}
go func() {
if err := s.Issue(context.Background(), sslID, domainID, domain, webroot); err != nil {
log.Printf("ssl reissue %s: %v", domain, err)
}
}()
return nil
}