fix: shouldn't zip folder if it has no such permission, even if content has it
Massimo Melina committed
Dec 30, 2023 at 11:29 UTC
cb0d8528213a380c44c033dd5000a27299774e7b
4 files changed
+10
-3
src/api.get_file_list.ts
+2
-2
@@ -34,9 +34,9 @@ export const get_file_list: ApiHandler = async ({ uri, offset, limit, search, c,
34
const walker = walkNode(node, { ctx: admin ? undefined : ctx, onlyFolders, depth: search ? Infinity : 0 })
35
const onDirEntryHandlers = mapPlugins(plug => plug.onDirEntry)
36
const can_upload = admin || hasPermission(node, 'can_upload', ctx)
37
- const fakeChild = applyParentToChild({}, node) // we want to know if we want to delete children
37
+ const fakeChild = applyParentToChild({}, node) // can we delete children
38
const can_delete = admin || hasPermission(fakeChild, 'can_delete', ctx)
39
- const can_archive = admin || hasPermission(fakeChild, 'can_archive', ctx)
39
+ const can_archive = admin || hasPermission(node, 'can_archive', ctx)
40
const can_comment = can_upload && areCommentsEnabled()
41
const can_overwrite = can_upload && (can_delete || !dontOverwriteUploading.get())
42
const props = { can_archive, can_upload, can_delete, can_overwrite, accept: node.accept, can_comment }
src/zip.ts
+2
-1
@@ -1,6 +1,6 @@
1
// This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3
-import { getNodeName, hasPermission, nodeIsDirectory, nodeIsLink, urlToNode, VfsNode, walkNode } from './vfs'
3
+import { getNodeName, hasPermission, nodeIsDirectory, nodeIsLink, urlToNode, VfsNode, walkNode, statusCodeForMissingPerm } from './vfs'
4
import Koa from 'koa'
5
import { filterMapGenerator, isWindowsDrive, pattern2filter, wantArray } from './misc'
6
import { QuickZipStream } from './QuickZipStream'
@@ -13,6 +13,7 @@ import { HTTP_OK } from './const'
13
14
// expects 'node' to have had permissions checked by caller
15
export async function zipStreamFromFolder(node: VfsNode, ctx: Koa.Context) {
16
+ if (statusCodeForMissingPerm(node, 'can_archive', ctx)) return
17
ctx.status = HTTP_OK
18
ctx.mime = 'zip'
19
// ctx.query.list is undefined | string | string[]
tests/config.yaml
+3
@@ -104,8 +104,11 @@ vfs:
104
- name: cantSeeThisButChildren
105
can_see:
106
this: false
107
+ can_archive:
108
+ this: false
109
children:
110
- name: hi
111
+ source: tests
112
- name: cantSeeThisButChildrenMasks
113
can_see: false
114
masks:
tests/test.ts
+3
@@ -55,6 +55,7 @@ describe('basics', () => {
55
it('forbidden list.match **', req('/cantListPageAlt/page/gpl.png', 401))
56
57
it('cantListBut', reqList('/cantListBut/', 403))
58
+ it('cantListBut.zip', req('/cantListBut/?get=zip', 403))
59
it('cantListBut.parent', reqList('/', { permInList: { 'cantListBut/': 'l' } }))
60
it('cantListBut.child masked', reqList('/cantListBut/page', 200))
61
@@ -80,6 +81,8 @@ describe('basics', () => {
81
it('cantSeeThis.children', reqList('/cantSeeThis', { outList:['hi/'] }))
82
it('cantSeeThisButChildren', reqList('/', { outList:['cantSeeThisButChildren/'] }))
83
it('cantSeeThisButChildren.children', reqList('/cantSeeThisButChildren', { inList:['hi/'] }))
84
+ it('cantZipFolder', req('/cantSeeThisButChildren/?get=zip', 403))
85
+ it('cantZipFolder.butChildren', req('/cantSeeThisButChildren/hi/?get=zip', 200))
86
it('cantSeeThisButChildrenMasks', reqList('/', { outList:['cantSeeThisButChildrenMasks/'] }))
87
it('cantSeeThisButChildrenMasks.children', reqList('/cantSeeThisButChildrenMasks', { inList:['hi/'] }))
88