feat: add simple audit ui

This commit is contained in:
Christoph Haas
2025-03-29 16:42:31 +01:00
parent a49cfa6343
commit 6cbccf6d43
23 changed files with 2098 additions and 1557 deletions

View File

@@ -0,0 +1,69 @@
package handlers
import (
"context"
"net/http"
"github.com/go-pkgz/routegroup"
"github.com/h44z/wg-portal/internal/app/api/core/respond"
"github.com/h44z/wg-portal/internal/app/api/v0/model"
"github.com/h44z/wg-portal/internal/config"
"github.com/h44z/wg-portal/internal/domain"
)
type AuditService interface {
// GetAll returns all audit entries ordered by timestamp. Newest first.
GetAll(ctx context.Context) ([]domain.AuditEntry, error)
}
type AuditEndpoint struct {
cfg *config.Config
authenticator Authenticator
auditService AuditService
}
func NewAuditEndpoint(
cfg *config.Config,
authenticator Authenticator,
auditService AuditService,
) AuditEndpoint {
return AuditEndpoint{
cfg: cfg,
authenticator: authenticator,
auditService: auditService,
}
}
func (e AuditEndpoint) GetName() string {
return "AuditEndpoint"
}
func (e AuditEndpoint) RegisterRoutes(g *routegroup.Bundle) {
apiGroup := g.Mount("/audit")
apiGroup.Use(e.authenticator.LoggedIn(ScopeAdmin))
apiGroup.HandleFunc("GET /entries", e.handleEntriesGet())
}
// handleExternalLoginProvidersGet returns a gorm Handler function.
//
// @ID audit_handleEntriesGet
// @Tags Audit
// @Summary Get all available audit entries. Ordered by timestamp.
// @Produce json
// @Success 200 {object} []model.AuditEntry
// @Router /audit/entries [get]
func (e AuditEndpoint) handleEntriesGet() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
providers, err := e.auditService.GetAll(r.Context())
if err != nil {
respond.JSON(w, http.StatusInternalServerError, model.Error{
Code: http.StatusInternalServerError, Message: err.Error(),
})
return
}
respond.JSON(w, http.StatusOK, model.NewAuditEntries(providers))
}
}

View File

@@ -0,0 +1,36 @@
package model
import (
"github.com/h44z/wg-portal/internal/domain"
)
type AuditEntry struct {
Id uint64 `json:"Id"`
Timestamp string `json:"Timestamp"`
ContextUser string `json:"ContextUser"`
Severity string `json:"Severity"`
Origin string `json:"Origin"` // origin: for example user auth, stats, ...
Message string `message:"Message"`
}
// NewAuditEntry creates a REST API AuditEntry from a domain AuditEntry.
func NewAuditEntry(src domain.AuditEntry) AuditEntry {
return AuditEntry{
Id: src.UniqueId,
Timestamp: src.CreatedAt.Format("2006-01-02 15:04:05"),
ContextUser: src.ContextUser,
Severity: string(src.Severity),
Origin: src.Origin,
Message: src.Message,
}
}
// NewAuditEntries creates a slice of REST API AuditEntry from a slice of domain AuditEntry.
func NewAuditEntries(src []domain.AuditEntry) []AuditEntry {
dst := make([]AuditEntry, 0, len(src))
for _, entry := range src {
dst = append(dst, NewAuditEntry(entry))
}
return dst
}