183 lines
5.8 KiB
Go
183 lines
5.8 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// TestCreateRenewalQueueEntryRequest ist die Request-Struktur für das Erstellen eines Test-Queue-Eintrags
|
|
type TestCreateRenewalQueueEntryRequest struct {
|
|
CertificateID string `json:"certificateId"`
|
|
FQDNID string `json:"fqdnId"`
|
|
SpaceID string `json:"spaceId"`
|
|
MinutesFromNow int `json:"minutesFromNow"` // Negative Werte = in der Vergangenheit (sofort fällig)
|
|
}
|
|
|
|
// createTestRenewalQueueEntryHandler erstellt einen Test-Queue-Eintrag für die Renewal-Funktion
|
|
// Nur für Administratoren zugänglich
|
|
func createTestRenewalQueueEntryHandler(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
|
|
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
|
|
|
|
if r.Method == "OPTIONS" {
|
|
w.WriteHeader(http.StatusOK)
|
|
return
|
|
}
|
|
|
|
// Prüfe ob User Admin ist
|
|
userID, _ := getUserFromRequest(r)
|
|
if userID == "" {
|
|
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
isAdmin, err := isUserAdmin(userID)
|
|
if err != nil || !isAdmin {
|
|
http.Error(w, "Nur Administratoren können Test-Queue-Einträge erstellen", http.StatusForbidden)
|
|
return
|
|
}
|
|
|
|
// Parse Request Body
|
|
var req TestCreateRenewalQueueEntryRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
http.Error(w, "Ungültige Request-Daten", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Validiere Eingaben
|
|
if req.CertificateID == "" || req.FQDNID == "" || req.SpaceID == "" {
|
|
http.Error(w, "certificateId, fqdnId und spaceId sind erforderlich", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Prüfe ob Zertifikat existiert
|
|
var certExists bool
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
err = db.QueryRowContext(ctx, "SELECT EXISTS(SELECT 1 FROM certificates WHERE id = ?)", req.CertificateID).Scan(&certExists)
|
|
if err != nil {
|
|
http.Error(w, "Fehler beim Prüfen des Zertifikats", http.StatusInternalServerError)
|
|
log.Printf("Fehler beim Prüfen des Zertifikats: %v", err)
|
|
return
|
|
}
|
|
if !certExists {
|
|
http.Error(w, "Zertifikat nicht gefunden", http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
// Prüfe ob FQDN existiert
|
|
var fqdnExists bool
|
|
err = db.QueryRowContext(ctx, "SELECT EXISTS(SELECT 1 FROM fqdns WHERE id = ?)", req.FQDNID).Scan(&fqdnExists)
|
|
if err != nil {
|
|
http.Error(w, "Fehler beim Prüfen des FQDN", http.StatusInternalServerError)
|
|
log.Printf("Fehler beim Prüfen des FQDN: %v", err)
|
|
return
|
|
}
|
|
if !fqdnExists {
|
|
http.Error(w, "FQDN nicht gefunden", http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
// Berechne scheduled_at Zeitpunkt
|
|
now := time.Now().UTC()
|
|
scheduledAt := now.Add(time.Duration(req.MinutesFromNow) * time.Minute)
|
|
scheduledAtStr := scheduledAt.Format("2006-01-02 15:04:05")
|
|
|
|
// Generiere eindeutige Queue-ID
|
|
queueID := fmt.Sprintf("test-%s", uuid.New().String())
|
|
createdAt := now.Format("2006-01-02 15:04:05")
|
|
|
|
// Erstelle Queue-Eintrag
|
|
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
_, err = db.ExecContext(ctx, `
|
|
INSERT INTO renewal_queue (id, certificate_id, fqdn_id, space_id, scheduled_at, status, created_at)
|
|
VALUES (?, ?, ?, ?, ?, 'pending', ?)
|
|
`, queueID, req.CertificateID, req.FQDNID, req.SpaceID, scheduledAtStr, createdAt)
|
|
|
|
if err != nil {
|
|
http.Error(w, "Fehler beim Erstellen des Queue-Eintrags", http.StatusInternalServerError)
|
|
log.Printf("Fehler beim Erstellen des Queue-Eintrags: %v", err)
|
|
return
|
|
}
|
|
|
|
// Lade erstellten Eintrag
|
|
var entry struct {
|
|
ID string `json:"id"`
|
|
CertificateID string `json:"certificateId"`
|
|
FQDNID string `json:"fqdnId"`
|
|
SpaceID string `json:"spaceId"`
|
|
ScheduledAt string `json:"scheduledAt"`
|
|
Status string `json:"status"`
|
|
CreatedAt string `json:"createdAt"`
|
|
}
|
|
|
|
err = db.QueryRowContext(ctx, `
|
|
SELECT id, certificate_id, fqdn_id, space_id, scheduled_at, status, created_at
|
|
FROM renewal_queue
|
|
WHERE id = ?
|
|
`, queueID).Scan(&entry.ID, &entry.CertificateID, &entry.FQDNID, &entry.SpaceID, &entry.ScheduledAt, &entry.Status, &entry.CreatedAt)
|
|
|
|
if err != nil {
|
|
http.Error(w, "Fehler beim Abrufen des erstellten Eintrags", http.StatusInternalServerError)
|
|
log.Printf("Fehler beim Abrufen des erstellten Eintrags: %v", err)
|
|
return
|
|
}
|
|
|
|
w.WriteHeader(http.StatusCreated)
|
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
|
"success": true,
|
|
"entry": entry,
|
|
"message": fmt.Sprintf("Test-Queue-Eintrag erstellt (geplant: %s)", scheduledAtStr),
|
|
})
|
|
}
|
|
|
|
// triggerRenewalQueueHandler führt die Queue-Verarbeitung manuell aus
|
|
// Nur für Administratoren zugänglich
|
|
func triggerRenewalQueueHandler(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
|
|
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
|
|
|
|
if r.Method == "OPTIONS" {
|
|
w.WriteHeader(http.StatusOK)
|
|
return
|
|
}
|
|
|
|
// Prüfe ob User Admin ist
|
|
userID, _ := getUserFromRequest(r)
|
|
if userID == "" {
|
|
http.Error(w, "Nicht authentifiziert", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
isAdmin, err := isUserAdmin(userID)
|
|
if err != nil || !isAdmin {
|
|
http.Error(w, "Nur Administratoren können die Queue-Verarbeitung manuell auslösen", http.StatusForbidden)
|
|
return
|
|
}
|
|
|
|
// Führe Queue-Verarbeitung in einer Goroutine aus, um den Request nicht zu blockieren
|
|
go func() {
|
|
log.Println("Manuelle Queue-Verarbeitung gestartet (via Test-Endpoint)")
|
|
processRenewalQueue()
|
|
log.Println("Manuelle Queue-Verarbeitung abgeschlossen")
|
|
}()
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
|
"success": true,
|
|
"message": "Queue-Verarbeitung wurde gestartet (läuft im Hintergrund)",
|
|
})
|
|
}
|
|
|