base dashboard and login
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"crowdsec-dashy/internal/crowdsec"
|
||||
)
|
||||
|
||||
// HubHandler manages the hub page (collections, parsers, scenarios, postoverflows).
|
||||
type HubHandler struct {
|
||||
deps Deps
|
||||
}
|
||||
|
||||
func NewHubHandler(deps Deps) *HubHandler {
|
||||
return &HubHandler{deps: deps}
|
||||
}
|
||||
|
||||
// HubData is passed to the hub template.
|
||||
type HubData struct {
|
||||
PageData
|
||||
Tab string
|
||||
Items []crowdsec.HubItem // current tab's items
|
||||
}
|
||||
|
||||
// List renders the hub page for the active tab.
|
||||
func (h *HubHandler) List(w http.ResponseWriter, r *http.Request) {
|
||||
pd := NewPageData(r, "Hub", h.deps.CLIAvailable, h.deps.PollInterval)
|
||||
if f := readFlash(r); f.Message != "" {
|
||||
pd.Flash = f
|
||||
}
|
||||
|
||||
tab := sanitizeTab(r.URL.Query().Get("tab"))
|
||||
data := HubData{PageData: pd, Tab: tab}
|
||||
|
||||
if h.deps.CLIAvailable {
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var err error
|
||||
switch tab {
|
||||
case "collections":
|
||||
data.Items, err = h.deps.CLI.ListCollections(ctx)
|
||||
case "parsers":
|
||||
data.Items, err = h.deps.CLI.ListParsers(ctx)
|
||||
case "scenarios":
|
||||
data.Items, err = h.deps.CLI.ListScenarios(ctx)
|
||||
case "postoverflows":
|
||||
data.Items, err = h.deps.CLI.ListPostoverflows(ctx)
|
||||
}
|
||||
if err != nil {
|
||||
data.PageData.Flash = FlashMessage{Type: "error", Message: fmt.Sprintf("cscli error: %v", err)}
|
||||
}
|
||||
}
|
||||
|
||||
h.deps.Renderer.Render(w, "hub", data)
|
||||
}
|
||||
|
||||
// Install installs a hub item.
|
||||
func (h *HubHandler) Install(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, 4096)
|
||||
if err := r.ParseForm(); err != nil {
|
||||
flashRedirect(w, r, "/hub", "error", "invalid form data")
|
||||
return
|
||||
}
|
||||
if !checkCSRF(r) {
|
||||
http.Error(w, "forbidden", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
if !h.deps.CLIAvailable {
|
||||
flashRedirect(w, r, "/hub", "error", "cscli not available")
|
||||
return
|
||||
}
|
||||
|
||||
kind := r.FormValue("kind")
|
||||
name := r.FormValue("name")
|
||||
tab := sanitizeTab(r.FormValue("tab"))
|
||||
|
||||
if err := validateHubKind(kind); err != nil {
|
||||
flashRedirect(w, r, hubURL(tab), "error", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 120*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var err error
|
||||
switch kind {
|
||||
case "collections":
|
||||
err = h.deps.CLI.InstallCollection(ctx, name)
|
||||
case "parsers":
|
||||
err = h.deps.CLI.InstallParser(ctx, name)
|
||||
case "scenarios":
|
||||
err = h.deps.CLI.InstallScenario(ctx, name)
|
||||
default:
|
||||
flashRedirect(w, r, hubURL(tab), "error", "unsupported hub type")
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
flashRedirect(w, r, hubURL(tab), "error", fmt.Sprintf("install failed: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
flashRedirect(w, r, hubURL(tab), "success", fmt.Sprintf("Installed %s", name))
|
||||
}
|
||||
|
||||
// Remove uninstalls a hub item.
|
||||
func (h *HubHandler) Remove(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, 4096)
|
||||
if err := r.ParseForm(); err != nil {
|
||||
flashRedirect(w, r, "/hub", "error", "invalid form data")
|
||||
return
|
||||
}
|
||||
if !checkCSRF(r) {
|
||||
http.Error(w, "forbidden", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
if !h.deps.CLIAvailable {
|
||||
flashRedirect(w, r, "/hub", "error", "cscli not available")
|
||||
return
|
||||
}
|
||||
|
||||
kind := r.FormValue("kind")
|
||||
name := r.FormValue("name")
|
||||
tab := sanitizeTab(r.FormValue("tab"))
|
||||
|
||||
if err := validateHubKind(kind); err != nil {
|
||||
flashRedirect(w, r, hubURL(tab), "error", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 120*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var err error
|
||||
switch kind {
|
||||
case "collections":
|
||||
err = h.deps.CLI.RemoveCollection(ctx, name)
|
||||
case "parsers":
|
||||
err = h.deps.CLI.RemoveParser(ctx, name)
|
||||
case "scenarios":
|
||||
err = h.deps.CLI.RemoveScenario(ctx, name)
|
||||
default:
|
||||
flashRedirect(w, r, hubURL(tab), "error", "unsupported hub type")
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
flashRedirect(w, r, hubURL(tab), "error", fmt.Sprintf("remove failed: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
flashRedirect(w, r, hubURL(tab), "success", fmt.Sprintf("Removed %s", name))
|
||||
}
|
||||
|
||||
// Update runs cscli hub update + upgrade.
|
||||
func (h *HubHandler) Update(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, 1024)
|
||||
if err := r.ParseForm(); err != nil {
|
||||
flashRedirect(w, r, "/hub", "error", "invalid form data")
|
||||
return
|
||||
}
|
||||
if !checkCSRF(r) {
|
||||
http.Error(w, "forbidden", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
if !h.deps.CLIAvailable {
|
||||
flashRedirect(w, r, "/hub", "error", "cscli not available")
|
||||
return
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 180*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := h.deps.CLI.HubUpdate(ctx); err != nil {
|
||||
flashRedirect(w, r, "/hub", "error", fmt.Sprintf("hub update failed: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
flashRedirect(w, r, "/hub", "success", "Hub updated and upgraded successfully")
|
||||
}
|
||||
|
||||
func sanitizeTab(tab string) string {
|
||||
switch tab {
|
||||
case "collections", "parsers", "scenarios", "postoverflows":
|
||||
return tab
|
||||
}
|
||||
return "collections"
|
||||
}
|
||||
|
||||
func hubURL(tab string) string {
|
||||
return "/hub?tab=" + tab
|
||||
}
|
||||
|
||||
func validateHubKind(kind string) error {
|
||||
switch kind {
|
||||
case "collections", "parsers", "scenarios", "postoverflows":
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("invalid hub kind: %q", kind)
|
||||
}
|
||||
Reference in New Issue
Block a user