feat: support office document nodes
All checks were successful
CI / hygiene (push) Successful in 2s
Build and Deploy / build-and-deploy (push) Successful in 32s
CI / test (push) Successful in 20s

This commit is contained in:
Grendgi
2026-06-16 15:25:33 +03:00
parent 3de4e5dfe7
commit 3dc5044c99
6 changed files with 133 additions and 0 deletions

View File

@@ -73,6 +73,63 @@ func (h *NodeHandler) CreateFolder(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusCreated, node)
}
func (h *NodeHandler) ListOfficeLinks(w http.ResponseWriter, r *http.Request) {
userID := commonmw.GetUserID(r.Context())
links, err := h.repo.ListOfficeExternalURLs(r.Context(), userID, subordinates(r))
if err != nil {
writeInternalError(w, r, err, "failed to list office links")
return
}
writeJSON(w, http.StatusOK, links)
}
func (h *NodeHandler) CreateOfficeDocument(w http.ResponseWriter, r *http.Request) {
var req model.CreateOfficeDocumentRequest
if err := decodeJSON(r, &req); err != nil {
writeError(w, http.StatusBadRequest, "invalid json")
return
}
req.Title = strings.TrimSpace(req.Title)
req.OfficeID = strings.TrimSpace(req.OfficeID)
req.OfficeFormat = strings.Trim(strings.ToLower(req.OfficeFormat), ". ")
if req.Title == "" {
writeError(w, http.StatusBadRequest, "title is required")
return
}
if req.OfficeID == "" {
writeError(w, http.StatusBadRequest, "office_id is required")
return
}
if !allowedOfficeFormat(req.OfficeFormat) {
writeError(w, http.StatusBadRequest, "office_format is not allowed")
return
}
userID := commonmw.GetUserID(r.Context())
if !h.requireWritableParent(w, r, userID, req.ParentID) {
return
}
externalURL := "/office/" + req.OfficeID
originalFilename := req.Title + "." + req.OfficeFormat
mimeType := req.OfficeFormat
node, err := h.repo.CreateOfficeDocument(r.Context(), &model.Node{
ParentID: req.ParentID,
Title: req.Title,
OwnerUserID: userID,
OriginalFilename: &originalFilename,
MimeType: &mimeType,
Extension: &req.OfficeFormat,
SizeBytes: req.SizeBytes,
OfficeFormat: &req.OfficeFormat,
ExternalURL: &externalURL,
})
if err != nil {
writeInternalError(w, r, err, "failed to create office document")
return
}
h.repo.Audit(r.Context(), userID, "files.office_document_create", "files_node", node.ID, "{}")
writeJSON(w, http.StatusCreated, node)
}
func (h *NodeHandler) UploadFile(w http.ResponseWriter, r *http.Request) {
if !h.store.Configured() {
writeError(w, http.StatusServiceUnavailable, "storage not configured")
@@ -376,6 +433,15 @@ func emptyToNil(v string) *string {
return &v
}
func allowedOfficeFormat(format string) bool {
switch format {
case "doc", "docx", "odt", "xls", "xlsx", "xlsm", "ods", "ppt", "pptx", "odp":
return true
default:
return false
}
}
func subordinates(r *http.Request) []string {
ids := csvHeader(r, "X-User-Subordinates")
if len(ids) == 0 {