103 lines
3.0 KiB
Go
103 lines
3.0 KiB
Go
package calendar
|
|
|
|
import (
|
|
"log/slog"
|
|
"net/http"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
|
|
"github.com/ultisuite/ulti-backend/internal/api/apiresponse"
|
|
"github.com/ultisuite/ulti-backend/internal/api/apivalidate"
|
|
"github.com/ultisuite/ulti-backend/internal/api/middleware"
|
|
"github.com/ultisuite/ulti-backend/internal/api/query"
|
|
"github.com/ultisuite/ulti-backend/internal/nextcloud"
|
|
"github.com/ultisuite/ulti-backend/internal/permission"
|
|
)
|
|
|
|
type Handler struct {
|
|
svc *Service
|
|
logger *slog.Logger
|
|
}
|
|
|
|
func NewHandler(nc *nextcloud.Client) *Handler {
|
|
return &Handler{
|
|
svc: NewService(nc),
|
|
logger: slog.Default().With("component", "calendar-api"),
|
|
}
|
|
}
|
|
|
|
func (h *Handler) Routes() chi.Router {
|
|
r := chi.NewRouter()
|
|
read := middleware.RequirePermission(permission.ResourceCalendar, permission.LevelRead)
|
|
write := middleware.RequirePermission(permission.ResourceCalendar, permission.LevelWrite)
|
|
|
|
r.With(read).Get("/", h.ListCalendars)
|
|
r.With(read).Get("/{calID}/events", h.ListEvents)
|
|
r.With(write).Post("/{calID}/events", h.CreateEvent)
|
|
r.With(write).Delete("/events/*", h.DeleteEvent)
|
|
return r
|
|
}
|
|
|
|
func (h *Handler) ListCalendars(w http.ResponseWriter, r *http.Request) {
|
|
claims := middleware.ClaimsFromContext(r.Context())
|
|
cals, err := h.svc.ListCalendars(r.Context(), claims.Sub)
|
|
if err != nil {
|
|
h.logger.Error("list calendars", "error", err)
|
|
apivalidate.WriteInternal(w, r)
|
|
return
|
|
}
|
|
apiresponse.WriteJSON(w, http.StatusOK, map[string]any{"calendars": cals})
|
|
}
|
|
|
|
func (h *Handler) ListEvents(w http.ResponseWriter, r *http.Request) {
|
|
claims := middleware.ClaimsFromContext(r.Context())
|
|
params, err := query.ParseListRequest(r)
|
|
if err != nil {
|
|
apivalidate.WriteQueryError(w, r, err)
|
|
return
|
|
}
|
|
|
|
result, err := h.svc.ListEvents(r.Context(), claims.Sub, chi.URLParam(r, "calID"), params)
|
|
if err != nil {
|
|
h.logger.Error("list events", "error", err)
|
|
apivalidate.WriteInternal(w, r)
|
|
return
|
|
}
|
|
apiresponse.WriteJSON(w, http.StatusOK, result)
|
|
}
|
|
|
|
func (h *Handler) CreateEvent(w http.ResponseWriter, r *http.Request) {
|
|
claims := middleware.ClaimsFromContext(r.Context())
|
|
|
|
var event nextcloud.Event
|
|
if err := apivalidate.DecodeJSON(w, r, maxRequestBody, &event); err != nil {
|
|
return
|
|
}
|
|
if verr := validateCreateEvent(&event); verr != nil {
|
|
apivalidate.WriteValidationError(w, r, verr)
|
|
return
|
|
}
|
|
|
|
if err := h.svc.CreateEvent(r.Context(), claims.Sub, chi.URLParam(r, "calID"), &event); err != nil {
|
|
h.logger.Error("create event", "error", err)
|
|
apivalidate.WriteInternal(w, r)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusCreated)
|
|
}
|
|
|
|
func (h *Handler) DeleteEvent(w http.ResponseWriter, r *http.Request) {
|
|
claims := middleware.ClaimsFromContext(r.Context())
|
|
eventPath := chi.URLParam(r, "*")
|
|
if verr := validateDeletePath(eventPath); verr != nil {
|
|
apivalidate.WriteValidationError(w, r, verr)
|
|
return
|
|
}
|
|
if err := h.svc.DeleteEvent(r.Context(), claims.Sub, eventPath); err != nil {
|
|
h.logger.Error("delete event", "error", err)
|
|
apivalidate.WriteInternal(w, r)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|