- 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.
130 lines
3.9 KiB
Go
130 lines
3.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/api/drive"
|
|
"github.com/ultisuite/ulti-backend/internal/api/middleware"
|
|
)
|
|
|
|
func (h *Handler) registerDriveAdminRoutes(r chi.Router, read, write func(http.Handler) http.Handler) {
|
|
r.With(read).Get("/drive/org-folders", h.ListDriveOrgFolders)
|
|
r.With(write).Post("/drive/org-folders", h.CreateDriveOrgFolder)
|
|
r.With(write).Put("/drive/org-folders/{folderID}", h.UpdateDriveOrgFolder)
|
|
r.With(write).Delete("/drive/org-folders/{folderID}", h.DeleteDriveOrgFolder)
|
|
r.With(write).Post("/drive/org-folders/sync", h.SyncDriveOrgFolders)
|
|
h.registerDriveOrgMountRoutes(r, read, write)
|
|
}
|
|
|
|
func (h *Handler) driveService() *drive.Service {
|
|
return drive.NewService(h.svc.nc, nil, h.svc.db)
|
|
}
|
|
|
|
func (h *Handler) ListDriveOrgFolders(w http.ResponseWriter, r *http.Request) {
|
|
svc := h.driveService()
|
|
folders, err := svc.ListOrgFoldersAdmin(r.Context())
|
|
if err != nil {
|
|
h.logger.Error("list drive org folders", "error", err)
|
|
apivalidate.WriteInternal(w, r)
|
|
return
|
|
}
|
|
apiresponse.WriteJSON(w, http.StatusOK, map[string]any{"folders": folders})
|
|
}
|
|
|
|
func (h *Handler) CreateDriveOrgFolder(w http.ResponseWriter, r *http.Request) {
|
|
claims := middleware.ClaimsFromContext(r.Context())
|
|
svc := h.driveService()
|
|
var req struct {
|
|
OrgSlug string `json:"org_slug"`
|
|
MountPoint string `json:"mount_point"`
|
|
QuotaBytes *int64 `json:"quota_bytes"`
|
|
}
|
|
if err := apivalidate.DecodeJSON(w, r, 32<<10, &req); err != nil {
|
|
return
|
|
}
|
|
createdBy := ""
|
|
if claims != nil {
|
|
createdBy = claims.Email
|
|
}
|
|
folder, err := svc.CreateOrgFolder(r.Context(), drive.CreateOrgFolderParams{
|
|
OrgSlug: req.OrgSlug,
|
|
MountPoint: req.MountPoint,
|
|
QuotaBytes: req.QuotaBytes,
|
|
CreatedBy: createdBy,
|
|
})
|
|
if err != nil {
|
|
writeDriveAdminError(w, r, err)
|
|
return
|
|
}
|
|
apiresponse.WriteJSON(w, http.StatusCreated, folder)
|
|
}
|
|
|
|
func (h *Handler) UpdateDriveOrgFolder(w http.ResponseWriter, r *http.Request) {
|
|
svc := h.driveService()
|
|
var req struct {
|
|
MountPoint string `json:"mount_point"`
|
|
QuotaBytes *int64 `json:"quota_bytes"`
|
|
}
|
|
if err := apivalidate.DecodeJSON(w, r, 32<<10, &req); err != nil {
|
|
return
|
|
}
|
|
folder, err := svc.UpdateOrgFolder(r.Context(), chi.URLParam(r, "folderID"), req.MountPoint, req.QuotaBytes)
|
|
if err != nil {
|
|
writeDriveAdminError(w, r, err)
|
|
return
|
|
}
|
|
apiresponse.WriteJSON(w, http.StatusOK, folder)
|
|
}
|
|
|
|
func (h *Handler) DeleteDriveOrgFolder(w http.ResponseWriter, r *http.Request) {
|
|
svc := h.driveService()
|
|
if err := svc.DeleteOrgFolder(r.Context(), chi.URLParam(r, "folderID")); err != nil {
|
|
writeDriveAdminError(w, r, err)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|
|
|
|
func (h *Handler) SyncDriveOrgFolders(w http.ResponseWriter, r *http.Request) {
|
|
claims := middleware.ClaimsFromContext(r.Context())
|
|
svc := h.driveService()
|
|
var req struct {
|
|
OrgSlugs []string `json:"org_slugs"`
|
|
}
|
|
if err := apivalidate.DecodeJSON(w, r, 32<<10, &req); err != nil {
|
|
return
|
|
}
|
|
createdBy := ""
|
|
if claims != nil {
|
|
createdBy = claims.Email
|
|
}
|
|
folders, err := svc.SyncOrgFolders(r.Context(), req.OrgSlugs, createdBy)
|
|
if err != nil {
|
|
writeDriveAdminError(w, r, err)
|
|
return
|
|
}
|
|
apiresponse.WriteJSON(w, http.StatusOK, map[string]any{"folders": folders})
|
|
}
|
|
|
|
func writeDriveAdminError(w http.ResponseWriter, r *http.Request, err error) {
|
|
switch {
|
|
case err == drive.ErrNotFound:
|
|
apivalidate.WriteNotFound(w, r, "not found")
|
|
case err == drive.ErrConflict:
|
|
apiresponse.WriteError(w, r, http.StatusConflict, "drive.conflict", "resource conflict", nil)
|
|
case err == drive.ErrInvalid:
|
|
apiresponse.WriteError(w, r, http.StatusBadRequest, apiresponse.CodeInvalidRequest, "invalid request body", nil)
|
|
default:
|
|
if strings.Contains(err.Error(), "not found") {
|
|
apivalidate.WriteNotFound(w, r, "not found")
|
|
return
|
|
}
|
|
apivalidate.WriteInternal(w, r)
|
|
}
|
|
}
|