fix: validate parent folder access
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user