optimization: send less data in case of "delete children" permission

Massimo Melina committed Sep 12, 2023 at 11:24 UTC 4e04a65f38f3cb0473d94f510320f89d44727454
1 file changed +35 -35
src/api.file_list.ts
+35 -35
@@ -20,6 +20,8 @@ import _ from 'lodash'
20 import { HTTP_FOOL, HTTP_METHOD_NOT_ALLOWED, HTTP_NOT_FOUND } from './const'
21 import Koa from 'koa'
22
23 +export interface DirEntry { n:string, s?:number, m?:Date, c?:Date, p?: string }
24 +
25 export const get_file_list: ApiHandler = async ({ uri, offset, limit, search, c }, ctx) => {
26 const node = await urlToNode(uri || '/', ctx)
27 const list = ctx.get('accept') === 'text/event-stream' ? new SendListReadable() : undefined
@@ -93,43 +95,41 @@ export const get_file_list: ApiHandler = async ({ uri, offset, limit, search, c
95 break
96 }
97 }
96 -}
97 -
98 -export interface DirEntry { n:string, s?:number, m?:Date, c?:Date, p?: string }
98
100 -async function nodeToDirEntry(ctx: Koa.Context, node: VfsNode): Promise<DirEntry | null> {
101 - let { source, default:def } = node
102 - const name = getNodeName(node)
103 - if (!source)
104 - return name ? { n: name + '/' } : null
105 - if (def)
106 - return { n: name }
107 - try {
108 - const st = await stat(source)
109 - const folder = st.isDirectory()
110 - const { ctime, mtime } = st
111 - const pl = node.can_list === WHO_NO_ONE ? 'l'
112 - : !hasPermission(node, 'can_list', ctx) ? 'L'
113 - : ''
114 - // no download here, but maybe inside?
115 - const pr = node.can_read === WHO_NO_ONE && !(folder && filesInsideCould()) ? 'r'
116 - : !hasPermission(node, 'can_read', ctx) ? 'R'
117 - : ''
118 - const pd = hasPermission(node, 'can_delete', ctx) ? 'd' : ''
119 - return {
120 - n: name + (folder ? '/' : ''),
121 - c: ctime,
122 - m: Math.abs(+mtime-+ctime) < 1000 ? undefined : mtime,
123 - s: folder ? undefined : st.size,
124 - p: (pr + pl + pd) || undefined
99 + async function nodeToDirEntry(ctx: Koa.Context, node: VfsNode): Promise<DirEntry | null> {
100 + let { source, default:def } = node
101 + const name = getNodeName(node)
102 + if (!source)
103 + return name ? { n: name + '/' } : null
104 + if (def)
105 + return { n: name }
106 + try {
107 + const st = await stat(source)
108 + const folder = st.isDirectory()
109 + const { ctime, mtime } = st
110 + const pl = node.can_list === WHO_NO_ONE ? 'l'
111 + : !hasPermission(node, 'can_list', ctx) ? 'L'
112 + : ''
113 + // no download here, but maybe inside?
114 + const pr = node.can_read === WHO_NO_ONE && !(folder && filesInsideCould()) ? 'r'
115 + : !hasPermission(node, 'can_read', ctx) ? 'R'
116 + : ''
117 + const pd = !can_delete && hasPermission(node, 'can_delete', ctx) ? 'd' : ''
118 + return {
119 + n: name + (folder ? '/' : ''),
120 + c: ctime,
121 + m: Math.abs(+mtime-+ctime) < 1000 ? undefined : mtime,
122 + s: folder ? undefined : st.size,
123 + p: (pr + pl + pd) || undefined
124 + }
125 + }
126 + catch {
127 + return null
128 }
126 - }
127 - catch {
128 - return null
129 - }
129
131 - function filesInsideCould(n: VfsNode=node): boolean | undefined {
132 - return masksCouldGivePermission(n.masks, 'can_read')
133 - || n.children?.some(c => c.can_read || filesInsideCould(c)) // we count on the boolean-compliant nature of the permission type here
130 + function filesInsideCould(n: VfsNode=node): boolean | undefined {
131 + return masksCouldGivePermission(n.masks, 'can_read')
132 + || n.children?.some(c => c.can_read || filesInsideCould(c)) // we count on the boolean-compliant nature of the permission type here
133 + }
134 }
135 }