|
|
|
|
@@ -61,6 +61,9 @@ func (h *NodeHandler) CreateFolder(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
userID := commonmw.GetUserID(r.Context())
|
|
|
|
|
if !h.requireWritableParent(w, r, userID, req.ParentID) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
node, err := h.repo.CreateFolder(r.Context(), req.Title, req.ParentID, userID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeInternalError(w, r, err, "failed to create folder")
|
|
|
|
|
@@ -97,13 +100,16 @@ func (h *NodeHandler) UploadFile(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
title = strings.TrimSuffix(filename, filepath.Ext(filename))
|
|
|
|
|
}
|
|
|
|
|
userID := commonmw.GetUserID(r.Context())
|
|
|
|
|
parentID := emptyToNil(r.FormValue("parent_id"))
|
|
|
|
|
if !h.requireWritableParent(w, r, userID, parentID) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
key := storage.GenerateKey(userID, filename)
|
|
|
|
|
contentType := storage.GuessContentType(filename, header.Header.Get("Content-Type"))
|
|
|
|
|
if err := h.store.PutObject(r.Context(), key, file, header.Size, contentType); err != nil {
|
|
|
|
|
writeInternalError(w, r, err, "failed to upload file")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
parentID := emptyToNil(r.FormValue("parent_id"))
|
|
|
|
|
node, err := h.repo.CreateFile(r.Context(), &model.Node{
|
|
|
|
|
ParentID: parentID,
|
|
|
|
|
Title: title,
|
|
|
|
|
@@ -271,6 +277,30 @@ func (h *NodeHandler) requireNode(w http.ResponseWriter, r *http.Request) (*mode
|
|
|
|
|
return node, true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *NodeHandler) requireWritableParent(w http.ResponseWriter, r *http.Request, userID string, parentID *string) bool {
|
|
|
|
|
if parentID == nil || strings.TrimSpace(*parentID) == "" {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
parent, err := h.repo.GetForUser(r.Context(), *parentID, userID, subordinates(r))
|
|
|
|
|
if errors.Is(err, repository.ErrNotFound) {
|
|
|
|
|
writeError(w, http.StatusNotFound, "parent folder not found")
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeInternalError(w, r, err, "failed to check parent folder")
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if parent.NodeType != model.NodeTypeFolder {
|
|
|
|
|
writeError(w, http.StatusBadRequest, "parent_id must point to folder")
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if parent.EffectiveAccess != model.AccessEdit {
|
|
|
|
|
writeError(w, http.StatusForbidden, "edit access to parent folder required")
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *NodeHandler) publicNode(w http.ResponseWriter, r *http.Request) (*model.Node, bool) {
|
|
|
|
|
node, err := h.repo.GetByPublicToken(r.Context(), chi.URLParam(r, "token"))
|
|
|
|
|
if errors.Is(err, repository.ErrNotFound) {
|
|
|
|
|
|