No One Can Stop Me Now
This commit is contained in:
143
services/setec-manager/internal/handlers/ssl.go
Normal file
143
services/setec-manager/internal/handlers/ssl.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"setec-manager/internal/acme"
|
||||
)
|
||||
|
||||
type certInfo struct {
|
||||
Domain string `json:"domain"`
|
||||
Issuer string `json:"issuer"`
|
||||
NotBefore time.Time `json:"not_before"`
|
||||
NotAfter time.Time `json:"not_after"`
|
||||
DaysLeft int `json:"days_left"`
|
||||
AutoRenew bool `json:"auto_renew"`
|
||||
}
|
||||
|
||||
func (h *Handler) SSLOverview(w http.ResponseWriter, r *http.Request) {
|
||||
certs := h.listCerts()
|
||||
h.render(w, "ssl.html", certs)
|
||||
}
|
||||
|
||||
func (h *Handler) SSLStatus(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, http.StatusOK, h.listCerts())
|
||||
}
|
||||
|
||||
func (h *Handler) SSLIssue(w http.ResponseWriter, r *http.Request) {
|
||||
domain := paramStr(r, "domain")
|
||||
if domain == "" {
|
||||
writeError(w, http.StatusBadRequest, "domain required")
|
||||
return
|
||||
}
|
||||
|
||||
client := acme.NewClient(
|
||||
h.Config.ACME.Email,
|
||||
h.Config.ACME.Staging,
|
||||
h.Config.Nginx.CertbotWebroot,
|
||||
h.Config.ACME.AccountDir,
|
||||
)
|
||||
|
||||
info, err := client.Issue(domain)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, fmt.Sprintf("certbot failed: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Update site SSL paths
|
||||
site, _ := h.DB.GetSiteByDomain(domain)
|
||||
if site != nil {
|
||||
site.SSLEnabled = true
|
||||
site.SSLCertPath = info.CertPath
|
||||
site.SSLKeyPath = info.KeyPath
|
||||
h.DB.UpdateSite(site)
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, map[string]string{"status": "issued", "cert": info.CertPath})
|
||||
}
|
||||
|
||||
func (h *Handler) SSLRenew(w http.ResponseWriter, r *http.Request) {
|
||||
domain := paramStr(r, "domain")
|
||||
|
||||
client := acme.NewClient(
|
||||
h.Config.ACME.Email,
|
||||
h.Config.ACME.Staging,
|
||||
h.Config.Nginx.CertbotWebroot,
|
||||
h.Config.ACME.AccountDir,
|
||||
)
|
||||
|
||||
if err := client.Renew(domain); err != nil {
|
||||
writeError(w, http.StatusInternalServerError, fmt.Sprintf("renewal failed: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, map[string]string{"status": "renewed"})
|
||||
}
|
||||
|
||||
func (h *Handler) listCerts() []certInfo {
|
||||
var certs []certInfo
|
||||
|
||||
// First, gather certs from DB-tracked sites
|
||||
sites, _ := h.DB.ListSites()
|
||||
for _, site := range sites {
|
||||
if !site.SSLEnabled || site.SSLCertPath == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
ci := certInfo{
|
||||
Domain: site.Domain,
|
||||
AutoRenew: site.SSLAuto,
|
||||
}
|
||||
|
||||
client := acme.NewClient(
|
||||
h.Config.ACME.Email,
|
||||
h.Config.ACME.Staging,
|
||||
h.Config.Nginx.CertbotWebroot,
|
||||
h.Config.ACME.AccountDir,
|
||||
)
|
||||
|
||||
info, err := client.GetCertInfo(site.Domain)
|
||||
if err == nil {
|
||||
ci.Issuer = info.Issuer
|
||||
ci.NotBefore = info.ExpiresAt.Add(-90 * 24 * time.Hour) // approximate
|
||||
ci.NotAfter = info.ExpiresAt
|
||||
ci.DaysLeft = info.DaysLeft
|
||||
}
|
||||
|
||||
certs = append(certs, ci)
|
||||
}
|
||||
|
||||
// Also check Let's Encrypt certs directory via ACME client
|
||||
client := acme.NewClient(
|
||||
h.Config.ACME.Email,
|
||||
h.Config.ACME.Staging,
|
||||
h.Config.Nginx.CertbotWebroot,
|
||||
h.Config.ACME.AccountDir,
|
||||
)
|
||||
|
||||
leCerts, _ := client.ListCerts()
|
||||
for _, le := range leCerts {
|
||||
// Skip if already found via site
|
||||
found := false
|
||||
for _, c := range certs {
|
||||
if c.Domain == le.Domain {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if found {
|
||||
continue
|
||||
}
|
||||
|
||||
certs = append(certs, certInfo{
|
||||
Domain: le.Domain,
|
||||
Issuer: le.Issuer,
|
||||
NotAfter: le.ExpiresAt,
|
||||
DaysLeft: le.DaysLeft,
|
||||
})
|
||||
}
|
||||
|
||||
return certs
|
||||
}
|
||||
Reference in New Issue
Block a user