Files
2026-09-19 23:25:20 +08:00

117 lines
3.4 KiB
Go

package api
import (
"database/sql"
"net/http"
"strconv"
"strings"
)
func (s *Server) alertRoutes(w http.ResponseWriter, r *http.Request, path string) {
if path == "alerts" && r.Method == "GET" {
scopes, ok := s.scopeIndex(w, r)
if !ok {
return
}
a, e := s.store.Alerts()
if e != nil {
fail(w, 500, "cannot read alerts")
return
}
filtered := a[:0]
for _, alert := range a {
if scopes == nil || scopes.MatchesResource(alert.ResourceID, requestScope(r)) {
filtered = append(filtered, alert)
}
}
respond(w, 200, filtered)
return
}
if path == "alerts/check" && r.Method == "POST" {
if e := s.alerts.Check(r.Context()); e != nil {
fail(w, 500, "alert check failed")
return
}
respond(w, 200, map[string]bool{"ok": true})
return
}
if path == "alerts/settings" && (r.Method == "GET" || r.Method == "PUT") {
c, e := s.store.AlertSettings()
if e != nil {
fail(w, 500, "cannot read alert settings")
return
}
if r.Method == "PUT" {
var body struct {
WebhookEnabled *bool `json:"webhookEnabled"`
WebhookURL string `json:"webhookURL"`
WebhookSecret string `json:"webhookSecret"`
ClearWebhook bool `json:"clearWebhook"`
AuthFailureThreshold *int `json:"authFailureThreshold"`
AuthFailureWindowSeconds *int `json:"authFailureWindowSeconds"`
CertificateReminderDays *int `json:"certificateReminderDays"`
HasWebhookURL bool `json:"hasWebhookURL"`
HasWebhookSecret bool `json:"hasWebhookSecret"`
}
if !decode(w, r, &body) {
return
}
if body.WebhookEnabled != nil {
c.WebhookEnabled = *body.WebhookEnabled
}
if body.WebhookURL != "" {
c.WebhookURL = body.WebhookURL
}
if body.WebhookSecret != "" {
c.WebhookSecret = body.WebhookSecret
}
if body.ClearWebhook {
c.WebhookURL = ""
c.WebhookSecret = ""
c.WebhookEnabled = false
}
if body.AuthFailureThreshold != nil {
c.AuthFailureThreshold = *body.AuthFailureThreshold
}
if body.AuthFailureWindowSeconds != nil {
c.AuthFailureWindowSeconds = *body.AuthFailureWindowSeconds
}
if body.CertificateReminderDays != nil {
c.CertificateReminderDays = *body.CertificateReminderDays
}
if e = c.Validate(); e != nil {
fail(w, 400, e.Error())
return
}
if e = s.store.SaveAlertSettings(c); e != nil {
fail(w, 500, "cannot save alert settings")
return
}
s.store.Event("", source(r), "alert_settings_updated", "")
}
respond(w, 200, map[string]any{"webhookEnabled": c.WebhookEnabled, "webhookURL": "", "webhookSecret": "", "hasWebhookURL": c.WebhookURL != "", "hasWebhookSecret": c.WebhookSecret != "", "authFailureThreshold": c.AuthFailureThreshold, "authFailureWindowSeconds": c.AuthFailureWindowSeconds, "certificateReminderDays": c.CertificateReminderDays})
return
}
parts := strings.Split(path, "/")
if len(parts) == 3 && parts[0] == "alerts" && parts[2] == "ack" && r.Method == "POST" {
id, e := strconv.ParseInt(parts[1], 10, 64)
if e != nil || id < 1 {
fail(w, 400, "invalid alert ID")
return
}
e = s.store.AcknowledgeAlert(id)
if e == sql.ErrNoRows {
fail(w, 404, "alert not found")
return
}
if e != nil {
fail(w, 500, "cannot acknowledge alert")
return
}
s.store.Event("", source(r), "alert_acknowledged", parts[1])
respond(w, 200, map[string]bool{"ok": true})
return
}
fail(w, 405, "method not allowed")
}