an upload with ?existing=overwrite will return an error if the file exists and you don't have permission
Massimo Melina committed
Aug 19, 2024 at 00:06 UTC
092c4afcb1033303f16c3883b81c7e401ce78054
1 file changed
+11
-4
src/upload.ts
+11
-4
@@ -1,4 +1,4 @@
1
-import { getNodeByName, hasPermission, statusCodeForMissingPerm, VfsNode } from './vfs'
1
+import { getNodeByName, statusCodeForMissingPerm, VfsNode } from './vfs'
2
import Koa from 'koa'
3
import { HTTP_CONFLICT, HTTP_FOOL, HTTP_PAYLOAD_TOO_LARGE, HTTP_RANGE_NOT_SATISFIABLE, HTTP_SERVER_ERROR,
4
HTTP_BAD_REQUEST } from './const'
@@ -15,7 +15,7 @@ import { getCurrentUsername } from './auth'
15
import { setCommentFor } from './comments'
16
import _ from 'lodash'
17
import events from './events'
18
-import { rename } from 'fs/promises'
18
+import { rename, rm } from 'fs/promises'
19
20
export const deleteUnfinishedUploadsAfter = defineConfig<undefined|number>('delete_unfinished_uploads_after', 86_400)
21
export const minAvailableMb = defineConfig('min_available_mb', 100)
@@ -86,6 +86,7 @@ export function uploadWriter(base: VfsNode, path: string, ctx: Koa.Context) {
86
if (ctx.query.existing === 'skip' && fs.existsSync(fullPath))
87
return fail(HTTP_CONFLICT, 'exists')
88
openFiles.add(fullPath)
89
+ let overwriteRequestedButForbidden = false
90
try {
91
// if upload creates a folder, then add meta to it too
92
if (fs.mkdirSync(dir, { recursive: true }))
@@ -146,6 +147,10 @@ export function uploadWriter(base: VfsNode, path: string, ctx: Koa.Context) {
147
}
148
let dest = fullPath
149
if (dontOverwriteUploading.get() && !await overwriteAnyway() && fs.existsSync(dest)) {
150
+ if (overwriteRequestedButForbidden) {
151
+ await rm(tempName)
152
+ return fail()
153
+ }
154
const ext = extname(dest)
155
const base = dest.slice(0, -ext.length || Infinity)
156
let i = 1
@@ -203,9 +208,11 @@ export function uploadWriter(base: VfsNode, path: string, ctx: Koa.Context) {
208
}
209
210
async function overwriteAnyway() {
206
- if (ctx.query.existing !== 'overwrite') return
211
+ if (ctx.query.existing !== 'overwrite') return false
212
const n = await getNodeByName(path, base)
208
- return n && hasPermission(n, 'can_delete', ctx)
213
+ if (n && !statusCodeForMissingPerm(n, 'can_delete', ctx)) return true
214
+ overwriteRequestedButForbidden = true
215
+ return false
216
}
217
218
function delayedDelete(path: string, secs: number, cb?: Callback) {