feat(sidecar): enforce per-user BasePath on all filesystem mutations
Folder create/rename/delete/move, photo move, heap convert, and file rename now reject paths outside the caller's BasePath (403). Sources resolved via PhotoPrism UIDs are re-checked in movePhotoFiles. The USER_BASEPATHS reconciler also sets upload_path so client-app uploads land inside the user's subtree. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,6 +56,9 @@ func handlePhotosMove(cfg *Config, pp *ppClient) gin.HandlerFunc {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid targetFolder"})
|
||||
return
|
||||
}
|
||||
if !requireUserScope(c, cfg, targetAbs, false) {
|
||||
return
|
||||
}
|
||||
|
||||
// Resolve each photo's FULL file list via the single-photo endpoint
|
||||
// rather than the /photos search (see resolvePhotosFull) — the search
|
||||
@@ -67,7 +70,7 @@ func handlePhotosMove(cfg *Config, pp *ppClient) gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
moved, copied, errs, err := movePhotoFiles(cfg, pp, token, photos, targetAbs, subfolder, mode)
|
||||
moved, copied, errs, err := movePhotoFiles(cfg, pp, token, photos, targetAbs, subfolder, mode, userScopeRoot(c, cfg))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
@@ -148,6 +151,9 @@ func handleFolderMove(cfg *Config, pp *ppClient) gin.HandlerFunc {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid path"})
|
||||
return
|
||||
}
|
||||
if !requireUserScope(c, cfg, oldAbs, true) {
|
||||
return
|
||||
}
|
||||
st, err := os.Stat(oldAbs)
|
||||
if err != nil || !st.IsDir() {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "not a directory"})
|
||||
@@ -158,6 +164,9 @@ func handleFolderMove(cfg *Config, pp *ppClient) gin.HandlerFunc {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid targetParent"})
|
||||
return
|
||||
}
|
||||
if !requireUserScope(c, cfg, targetParentAbs, false) {
|
||||
return
|
||||
}
|
||||
// Can't move a folder into itself or one of its own descendants.
|
||||
if sameOrUnder(targetParentAbs, oldAbs) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "cannot move a folder into itself"})
|
||||
|
||||
Reference in New Issue
Block a user