203 lines
6.1 KiB
Go
203 lines
6.1 KiB
Go
package drive
|
|
|
|
import (
|
|
"io"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
|
|
"github.com/ultisuite/ulti-backend/internal/api/apiresponse"
|
|
"github.com/ultisuite/ulti-backend/internal/api/apivalidate"
|
|
)
|
|
|
|
func (h *Handler) PublicRoutes() chi.Router {
|
|
r := chi.NewRouter()
|
|
r.Get("/shares/{token}", h.GetPublicShare)
|
|
r.Get("/shares/{token}/preview", h.PreviewPublicShare)
|
|
r.Get("/shares/{token}/download/*", h.DownloadPublicShare)
|
|
r.Put("/shares/{token}/files/*", h.UploadPublicShare)
|
|
r.Post("/shares/{token}/folders/*", h.CreatePublicShareFolder)
|
|
r.Delete("/shares/{token}/files/*", h.DeletePublicShareItem)
|
|
r.Post("/shares/{token}/rename", h.RenamePublicShareItem)
|
|
if h.publicOffice != nil {
|
|
h.publicOffice.RegisterPublicShareRoutes(r)
|
|
}
|
|
if h.publicRichText != nil {
|
|
h.publicRichText.RegisterPublicShareRoutes(r)
|
|
}
|
|
if h.publicUltidraw != nil {
|
|
h.publicUltidraw.RegisterPublicShareRoutes(r)
|
|
}
|
|
return r
|
|
}
|
|
|
|
func publicSharePassword(r *http.Request) string {
|
|
return strings.TrimSpace(r.URL.Query().Get("password"))
|
|
}
|
|
|
|
func (h *Handler) GetPublicShare(w http.ResponseWriter, r *http.Request) {
|
|
token := strings.TrimSpace(chi.URLParam(r, "token"))
|
|
if token == "" {
|
|
apivalidate.WriteValidationError(w, r, apivalidate.NewValidationError(
|
|
apivalidate.FieldDetail{Field: "token", Message: "required"},
|
|
))
|
|
return
|
|
}
|
|
path := strings.TrimSpace(r.URL.Query().Get("path"))
|
|
if path == "" {
|
|
path = "/"
|
|
}
|
|
|
|
view, err := h.svc.GetPublicShare(r.Context(), token, path, publicSharePassword(r))
|
|
if err != nil {
|
|
writeDriveError(w, r, err)
|
|
return
|
|
}
|
|
apiresponse.WriteJSON(w, http.StatusOK, view)
|
|
}
|
|
|
|
func (h *Handler) DownloadPublicShare(w http.ResponseWriter, r *http.Request) {
|
|
token := strings.TrimSpace(chi.URLParam(r, "token"))
|
|
if token == "" {
|
|
apivalidate.WriteValidationError(w, r, apivalidate.NewValidationError(
|
|
apivalidate.FieldDetail{Field: "token", Message: "required"},
|
|
))
|
|
return
|
|
}
|
|
filePath := strings.TrimSpace(chi.URLParam(r, "*"))
|
|
if filePath == "" {
|
|
filePath = "/"
|
|
}
|
|
|
|
body, contentType, err := h.svc.DownloadPublicShare(r.Context(), token, filePath, publicSharePassword(r))
|
|
if err != nil {
|
|
writeDriveError(w, r, err)
|
|
return
|
|
}
|
|
defer body.Close()
|
|
|
|
w.Header().Set("Content-Type", contentType)
|
|
_, _ = io.Copy(w, body)
|
|
}
|
|
|
|
func (h *Handler) PreviewPublicShare(w http.ResponseWriter, r *http.Request) {
|
|
token := strings.TrimSpace(chi.URLParam(r, "token"))
|
|
if token == "" {
|
|
apivalidate.WriteValidationError(w, r, apivalidate.NewValidationError(
|
|
apivalidate.FieldDetail{Field: "token", Message: "required"},
|
|
))
|
|
return
|
|
}
|
|
filePath := strings.TrimSpace(r.URL.Query().Get("path"))
|
|
if filePath == "" {
|
|
apivalidate.WriteValidationError(w, r, apivalidate.NewValidationError(
|
|
apivalidate.FieldDetail{Field: "path", Message: "required"},
|
|
))
|
|
return
|
|
}
|
|
width, _ := strconv.Atoi(r.URL.Query().Get("w"))
|
|
height, _ := strconv.Atoi(r.URL.Query().Get("h"))
|
|
|
|
body, contentType, err := h.svc.PreviewPublicShare(r.Context(), token, filePath, publicSharePassword(r), width, height)
|
|
if err != nil {
|
|
writeDriveError(w, r, err)
|
|
return
|
|
}
|
|
defer body.Close()
|
|
|
|
if contentType != "" {
|
|
w.Header().Set("Content-Type", contentType)
|
|
}
|
|
_, _ = io.Copy(w, body)
|
|
}
|
|
|
|
func (h *Handler) UploadPublicShare(w http.ResponseWriter, r *http.Request) {
|
|
token := strings.TrimSpace(chi.URLParam(r, "token"))
|
|
filePath := strings.TrimSpace(chi.URLParam(r, "*"))
|
|
if token == "" || filePath == "" {
|
|
apivalidate.WriteValidationError(w, r, apivalidate.NewValidationError(
|
|
apivalidate.FieldDetail{Field: "path", Message: "required"},
|
|
))
|
|
return
|
|
}
|
|
if !strings.HasPrefix(filePath, "/") {
|
|
filePath = "/" + filePath
|
|
}
|
|
if err := h.svc.UploadPublicShare(r.Context(), token, filePath, publicSharePassword(r), r.Body, r.Header.Get("Content-Type")); err != nil {
|
|
writeDriveError(w, r, err)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusCreated)
|
|
}
|
|
|
|
func (h *Handler) CreatePublicShareFolder(w http.ResponseWriter, r *http.Request) {
|
|
token := strings.TrimSpace(chi.URLParam(r, "token"))
|
|
folderPath := strings.TrimSpace(chi.URLParam(r, "*"))
|
|
if token == "" || folderPath == "" {
|
|
apivalidate.WriteValidationError(w, r, apivalidate.NewValidationError(
|
|
apivalidate.FieldDetail{Field: "path", Message: "required"},
|
|
))
|
|
return
|
|
}
|
|
if !strings.HasPrefix(folderPath, "/") {
|
|
folderPath = "/" + folderPath
|
|
}
|
|
if err := h.svc.CreatePublicShareFolder(r.Context(), token, folderPath, publicSharePassword(r)); err != nil {
|
|
writeDriveError(w, r, err)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusCreated)
|
|
}
|
|
|
|
func (h *Handler) DeletePublicShareItem(w http.ResponseWriter, r *http.Request) {
|
|
token := strings.TrimSpace(chi.URLParam(r, "token"))
|
|
filePath := strings.TrimSpace(chi.URLParam(r, "*"))
|
|
if token == "" || filePath == "" {
|
|
apivalidate.WriteValidationError(w, r, apivalidate.NewValidationError(
|
|
apivalidate.FieldDetail{Field: "path", Message: "required"},
|
|
))
|
|
return
|
|
}
|
|
if !strings.HasPrefix(filePath, "/") {
|
|
filePath = "/" + filePath
|
|
}
|
|
if err := h.svc.DeletePublicShareItem(r.Context(), token, filePath, publicSharePassword(r)); err != nil {
|
|
writeDriveError(w, r, err)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|
|
|
|
type publicRenameRequest struct {
|
|
Path string `json:"path"`
|
|
NewName string `json:"new_name"`
|
|
}
|
|
|
|
func (h *Handler) RenamePublicShareItem(w http.ResponseWriter, r *http.Request) {
|
|
token := strings.TrimSpace(chi.URLParam(r, "token"))
|
|
if token == "" {
|
|
apivalidate.WriteValidationError(w, r, apivalidate.NewValidationError(
|
|
apivalidate.FieldDetail{Field: "token", Message: "required"},
|
|
))
|
|
return
|
|
}
|
|
var req publicRenameRequest
|
|
if err := apivalidate.DecodeJSON(w, r, 32<<10, &req); err != nil {
|
|
return
|
|
}
|
|
if strings.TrimSpace(req.Path) == "" || strings.TrimSpace(req.NewName) == "" {
|
|
apivalidate.WriteValidationError(w, r, apivalidate.NewValidationError(
|
|
apivalidate.FieldDetail{Field: "path", Message: "required"},
|
|
apivalidate.FieldDetail{Field: "new_name", Message: "required"},
|
|
))
|
|
return
|
|
}
|
|
if err := h.svc.RenamePublicShareItem(r.Context(), token, req.Path, req.NewName, publicSharePassword(r)); err != nil {
|
|
writeDriveError(w, r, err)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|