You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.7 KiB
Go
104 lines
2.7 KiB
Go
package http
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"github.com/gofiber/fiber/v3"
|
|
|
|
appadmin "knowfoolery/backend/services/admin-service/internal/application/admin"
|
|
"knowfoolery/backend/shared/infra/auth/rbac"
|
|
"knowfoolery/backend/shared/infra/auth/zitadel"
|
|
"knowfoolery/backend/shared/infra/observability/logging"
|
|
"knowfoolery/backend/shared/infra/observability/metrics"
|
|
"knowfoolery/backend/shared/infra/utils/httputil"
|
|
)
|
|
|
|
// Handler wires HTTP endpoints.
|
|
type Handler struct {
|
|
svc *appadmin.Service
|
|
logger *logging.Logger
|
|
metrics *metrics.Metrics
|
|
}
|
|
|
|
func NewHandler(svc *appadmin.Service, logger *logging.Logger, metrics *metrics.Metrics) *Handler {
|
|
return &Handler{svc: svc, logger: logger, metrics: metrics}
|
|
}
|
|
|
|
func (h *Handler) AdminAuth(c fiber.Ctx) error {
|
|
actorID := zitadel.GetUserID(c)
|
|
actorEmail := zitadel.GetUserEmail(c)
|
|
roles := zitadel.GetUserRoles(c)
|
|
mfa := zitadel.IsMFAVerified(c)
|
|
|
|
_ = h.svc.AppendAudit(c.Context(), actorID, actorEmail, "admin.auth", "admin", map[string]any{
|
|
"mfa": mfa,
|
|
"roles": roles,
|
|
})
|
|
|
|
return c.JSON(fiber.Map{
|
|
"ok": true,
|
|
"actor_id": actorID,
|
|
"actor_email": actorEmail,
|
|
"roles": roles,
|
|
"mfa": mfa,
|
|
})
|
|
}
|
|
|
|
func (h *Handler) Dashboard(c fiber.Ctx) error {
|
|
roles := zitadel.GetUserRoles(c)
|
|
if !rbac.UserHasPermission(roles, rbac.PermissionViewDashboard) {
|
|
return httputil.Forbidden(c, "dashboard permission required")
|
|
}
|
|
|
|
actorID := zitadel.GetUserID(c)
|
|
actorEmail := zitadel.GetUserEmail(c)
|
|
_ = h.svc.AppendAudit(c.Context(), actorID, actorEmail, "admin.dashboard.view", "dashboard", nil)
|
|
|
|
resp, err := h.svc.Dashboard(c.Context())
|
|
if err != nil {
|
|
h.logger.WithError(err).Error("dashboard failed")
|
|
return httputil.InternalError(c, "dashboard failed")
|
|
}
|
|
return c.JSON(resp)
|
|
}
|
|
|
|
func (h *Handler) AuditList(c fiber.Ctx) error {
|
|
roles := zitadel.GetUserRoles(c)
|
|
if !rbac.UserHasPermission(roles, rbac.PermissionViewAuditLog) {
|
|
return httputil.Forbidden(c, "audit permission required")
|
|
}
|
|
|
|
limit := parseIntQuery(c, "limit", 50)
|
|
offset := parseIntQuery(c, "offset", 0)
|
|
|
|
actorID := zitadel.GetUserID(c)
|
|
actorEmail := zitadel.GetUserEmail(c)
|
|
_ = h.svc.AppendAudit(c.Context(), actorID, actorEmail, "admin.audit.view", "audit", map[string]any{
|
|
"limit": limit,
|
|
"offset": offset,
|
|
})
|
|
|
|
entries, err := h.svc.ListAudit(c.Context(), limit, offset)
|
|
if err != nil {
|
|
h.logger.WithError(err).Error("audit list failed")
|
|
return httputil.InternalError(c, "audit list failed")
|
|
}
|
|
return c.JSON(fiber.Map{
|
|
"items": entries,
|
|
"limit": limit,
|
|
"offset": offset,
|
|
})
|
|
}
|
|
|
|
func parseIntQuery(c fiber.Ctx, key string, fallback int) int {
|
|
v := c.Query(key)
|
|
if v == "" {
|
|
return fallback
|
|
}
|
|
n, err := strconv.Atoi(v)
|
|
if err != nil {
|
|
return fallback
|
|
}
|
|
return n
|
|
}
|