- Updated .env.example to include new configuration options for the UltiAI branding and API endpoints. - Enhanced Nginx configuration to support new API routes for the MCP and WebSocket connections. - Introduced sub-filters for branding adjustments in Nginx responses. - Added new JavaScript patch for API endpoint adjustments. - Implemented tests for new API functionalities and improved error handling in the AI gateway.
91 lines
2.9 KiB
Go
91 lines
2.9 KiB
Go
package admin
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"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/nextcloud"
|
|
)
|
|
|
|
func (h *Handler) registerDriveOrgMountRoutes(r chi.Router, read, write func(http.Handler) http.Handler) {
|
|
r.With(read).Get("/drive/org-mounts", h.ListDriveOrgMounts)
|
|
r.With(write).Post("/drive/org-mounts", h.CreateDriveOrgMount)
|
|
r.With(write).Delete("/drive/org-mounts/{mountID}", h.DeleteDriveOrgMount)
|
|
}
|
|
|
|
func (h *Handler) ListDriveOrgMounts(w http.ResponseWriter, r *http.Request) {
|
|
svc := h.driveService()
|
|
mounts, err := svc.ListOrgMountsAdmin(r.Context())
|
|
if err != nil {
|
|
h.logger.Error("list drive org mounts", "error", err)
|
|
apivalidate.WriteInternal(w, r)
|
|
return
|
|
}
|
|
apiresponse.WriteJSON(w, http.StatusOK, map[string]any{"mounts": mounts})
|
|
}
|
|
|
|
func (h *Handler) CreateDriveOrgMount(w http.ResponseWriter, r *http.Request) {
|
|
svc := h.driveService()
|
|
var req struct {
|
|
OrgSlug string `json:"org_slug"`
|
|
DisplayName string `json:"display_name"`
|
|
WebDAV nextcloud.WebDAVMountConfig `json:"webdav"`
|
|
}
|
|
if err := apivalidate.DecodeJSON(w, r, 32<<10, &req); err != nil {
|
|
return
|
|
}
|
|
if verr := validateOrgWebDAVMountRequest(req.OrgSlug, req.DisplayName, req.WebDAV); verr != nil {
|
|
apivalidate.WriteValidationError(w, r, verr)
|
|
return
|
|
}
|
|
mount, err := svc.CreateOrgWebDAVMount(r.Context(), req.OrgSlug, req.DisplayName, req.WebDAV)
|
|
if err != nil {
|
|
writeDriveAdminError(w, r, err)
|
|
return
|
|
}
|
|
apiresponse.WriteJSON(w, http.StatusCreated, mount)
|
|
}
|
|
|
|
func (h *Handler) DeleteDriveOrgMount(w http.ResponseWriter, r *http.Request) {
|
|
svc := h.driveService()
|
|
mountID := chi.URLParam(r, "mountID")
|
|
mount, err := svc.GetMountAdmin(r.Context(), mountID)
|
|
if err != nil {
|
|
writeDriveAdminError(w, r, err)
|
|
return
|
|
}
|
|
if mount.Scope != "org" {
|
|
apivalidate.WriteNotFound(w, r, "mount not found")
|
|
return
|
|
}
|
|
if err := svc.DeleteMount(r.Context(), mountID); err != nil {
|
|
writeDriveAdminError(w, r, err)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|
|
|
|
func validateOrgWebDAVMountRequest(orgSlug, displayName string, cfg nextcloud.WebDAVMountConfig) *apivalidate.ValidationError {
|
|
var details []apivalidate.FieldDetail
|
|
if strings.TrimSpace(orgSlug) == "" {
|
|
details = append(details, apivalidate.FieldDetail{Field: "org_slug", Message: "required"})
|
|
}
|
|
if strings.TrimSpace(displayName) == "" {
|
|
details = append(details, apivalidate.FieldDetail{Field: "display_name", Message: "required"})
|
|
}
|
|
if strings.TrimSpace(cfg.Host) == "" {
|
|
details = append(details, apivalidate.FieldDetail{Field: "webdav.host", Message: "required"})
|
|
}
|
|
if strings.TrimSpace(cfg.User) == "" {
|
|
details = append(details, apivalidate.FieldDetail{Field: "webdav.user", Message: "required"})
|
|
}
|
|
if len(details) > 0 {
|
|
return &apivalidate.ValidationError{Details: details}
|
|
}
|
|
return nil
|
|
}
|