aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-07-31 15:09:34 +0200
committerChocobozzz <me@florianbigard.com>2018-07-31 15:09:34 +0200
commitcf7a61b5a2b68fd966c4a355e37e84b048ed296b (patch)
tree4f4867344fe6856cb4f6b18856867c6e34171ea2
parentc487d3033cad9c5e0f85ae49ed3d2a7b6c2711d8 (diff)
downloadPeerTube-cf7a61b5a2b68fd966c4a355e37e84b048ed296b.tar.gz
PeerTube-cf7a61b5a2b68fd966c4a355e37e84b048ed296b.tar.zst
PeerTube-cf7a61b5a2b68fd966c4a355e37e84b048ed296b.zip
Cleanup req files on bad request
-rw-r--r--server/helpers/core-utils.ts2
-rw-r--r--server/helpers/custom-validators/video-captions.ts2
-rw-r--r--server/helpers/utils.ts28
-rw-r--r--server/middlewares/validators/avatar.ts3
-rw-r--r--server/middlewares/validators/video-captions.ts7
-rw-r--r--server/middlewares/validators/video-channels.ts4
-rw-r--r--server/middlewares/validators/videos.ts22
-rw-r--r--server/tests/api/server/follows.ts2
-rw-r--r--server/tests/api/server/handle-down.ts2
9 files changed, 50 insertions, 22 deletions
diff --git a/server/helpers/core-utils.ts b/server/helpers/core-utils.ts
index 2951aef1e..884206aad 100644
--- a/server/helpers/core-utils.ts
+++ b/server/helpers/core-utils.ts
@@ -58,7 +58,7 @@ function escapeHTML (stringParam) {
58 '<': '&lt;', 58 '<': '&lt;',
59 '>': '&gt;', 59 '>': '&gt;',
60 '"': '&quot;', 60 '"': '&quot;',
61 "'": '&#39;', 61 '\'': '&#39;',
62 '/': '&#x2F;', 62 '/': '&#x2F;',
63 '`': '&#x60;', 63 '`': '&#x60;',
64 '=': '&#x3D;' 64 '=': '&#x3D;'
diff --git a/server/helpers/custom-validators/video-captions.ts b/server/helpers/custom-validators/video-captions.ts
index 6a9c6d75c..6b1729f36 100644
--- a/server/helpers/custom-validators/video-captions.ts
+++ b/server/helpers/custom-validators/video-captions.ts
@@ -1,4 +1,4 @@
1import { CONSTRAINTS_FIELDS, VIDEO_CAPTIONS_MIMETYPE_EXT, VIDEO_LANGUAGES, VIDEO_MIMETYPE_EXT } from '../../initializers' 1import { CONSTRAINTS_FIELDS, VIDEO_CAPTIONS_MIMETYPE_EXT, VIDEO_LANGUAGES } from '../../initializers'
2import { exists, isFileValid } from './misc' 2import { exists, isFileValid } from './misc'
3import { Response } from 'express' 3import { Response } from 'express'
4import { VideoModel } from '../../models/video/video' 4import { VideoModel } from '../../models/video/video'
diff --git a/server/helpers/utils.ts b/server/helpers/utils.ts
index cfb427570..7abcec5d7 100644
--- a/server/helpers/utils.ts
+++ b/server/helpers/utils.ts
@@ -6,11 +6,35 @@ import { CONFIG } from '../initializers'
6import { UserModel } from '../models/account/user' 6import { UserModel } from '../models/account/user'
7import { ActorModel } from '../models/activitypub/actor' 7import { ActorModel } from '../models/activitypub/actor'
8import { ApplicationModel } from '../models/application/application' 8import { ApplicationModel } from '../models/application/application'
9import { pseudoRandomBytesPromise } from './core-utils' 9import { pseudoRandomBytesPromise, unlinkPromise } from './core-utils'
10import { logger } from './logger' 10import { logger } from './logger'
11import { isArray } from './custom-validators/misc'
11 12
12const isCidr = require('is-cidr') 13const isCidr = require('is-cidr')
13 14
15function cleanUpReqFiles (req: { files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[] }) {
16 const files = req.files
17
18 if (!files) return
19
20 if (isArray(files)) {
21 (files as Express.Multer.File[]).forEach(f => deleteFileAsync(f.path))
22 return
23 }
24
25 for (const key of Object.keys(files)) {
26 const file = files[key]
27
28 if (isArray(file)) file.forEach(f => deleteFileAsync(f.path))
29 else deleteFileAsync(file.path)
30 }
31}
32
33function deleteFileAsync (path: string) {
34 unlinkPromise(path)
35 .catch(err => logger.error('Cannot delete the file %s asynchronously.', path, { err }))
36}
37
14async function generateRandomString (size: number) { 38async function generateRandomString (size: number) {
15 const raw = await pseudoRandomBytesPromise(size) 39 const raw = await pseudoRandomBytesPromise(size)
16 40
@@ -162,6 +186,8 @@ type SortType = { sortModel: any, sortValue: string }
162// --------------------------------------------------------------------------- 186// ---------------------------------------------------------------------------
163 187
164export { 188export {
189 cleanUpReqFiles,
190 deleteFileAsync,
165 generateRandomString, 191 generateRandomString,
166 getFormattedObjects, 192 getFormattedObjects,
167 isSignupAllowed, 193 isSignupAllowed,
diff --git a/server/middlewares/validators/avatar.ts b/server/middlewares/validators/avatar.ts
index f346ea92f..5860735c6 100644
--- a/server/middlewares/validators/avatar.ts
+++ b/server/middlewares/validators/avatar.ts
@@ -4,6 +4,7 @@ import { isAvatarFile } from '../../helpers/custom-validators/users'
4import { areValidationErrors } from './utils' 4import { areValidationErrors } from './utils'
5import { CONSTRAINTS_FIELDS } from '../../initializers' 5import { CONSTRAINTS_FIELDS } from '../../initializers'
6import { logger } from '../../helpers/logger' 6import { logger } from '../../helpers/logger'
7import { cleanUpReqFiles } from '../../helpers/utils'
7 8
8const updateAvatarValidator = [ 9const updateAvatarValidator = [
9 body('avatarfile').custom((value, { req }) => isAvatarFile(req.files)).withMessage( 10 body('avatarfile').custom((value, { req }) => isAvatarFile(req.files)).withMessage(
@@ -14,7 +15,7 @@ const updateAvatarValidator = [
14 (req: express.Request, res: express.Response, next: express.NextFunction) => { 15 (req: express.Request, res: express.Response, next: express.NextFunction) => {
15 logger.debug('Checking updateAvatarValidator parameters', { files: req.files }) 16 logger.debug('Checking updateAvatarValidator parameters', { files: req.files })
16 17
17 if (areValidationErrors(req, res)) return 18 if (areValidationErrors(req, res)) return cleanUpReqFiles(req)
18 19
19 return next() 20 return next()
20 } 21 }
diff --git a/server/middlewares/validators/video-captions.ts b/server/middlewares/validators/video-captions.ts
index b6d92d380..18d537bc4 100644
--- a/server/middlewares/validators/video-captions.ts
+++ b/server/middlewares/validators/video-captions.ts
@@ -7,6 +7,7 @@ import { CONSTRAINTS_FIELDS } from '../../initializers'
7import { UserRight } from '../../../shared' 7import { UserRight } from '../../../shared'
8import { logger } from '../../helpers/logger' 8import { logger } from '../../helpers/logger'
9import { isVideoCaptionExist, isVideoCaptionFile, isVideoCaptionLanguageValid } from '../../helpers/custom-validators/video-captions' 9import { isVideoCaptionExist, isVideoCaptionFile, isVideoCaptionLanguageValid } from '../../helpers/custom-validators/video-captions'
10import { cleanUpReqFiles } from '../../helpers/utils'
10 11
11const addVideoCaptionValidator = [ 12const addVideoCaptionValidator = [
12 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'), 13 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'),
@@ -20,12 +21,12 @@ const addVideoCaptionValidator = [
20 async (req: express.Request, res: express.Response, next: express.NextFunction) => { 21 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
21 logger.debug('Checking addVideoCaption parameters', { parameters: req.body }) 22 logger.debug('Checking addVideoCaption parameters', { parameters: req.body })
22 23
23 if (areValidationErrors(req, res)) return 24 if (areValidationErrors(req, res)) return cleanUpReqFiles(req)
24 if (!await isVideoExist(req.params.videoId, res)) return 25 if (!await isVideoExist(req.params.videoId, res)) return cleanUpReqFiles(req)
25 26
26 // Check if the user who did the request is able to update the video 27 // Check if the user who did the request is able to update the video
27 const user = res.locals.oauth.token.User 28 const user = res.locals.oauth.token.User
28 if (!checkUserCanManageVideo(user, res.locals.video, UserRight.UPDATE_ANY_VIDEO, res)) return 29 if (!checkUserCanManageVideo(user, res.locals.video, UserRight.UPDATE_ANY_VIDEO, res)) return cleanUpReqFiles(req)
29 30
30 return next() 31 return next()
31 } 32 }
diff --git a/server/middlewares/validators/video-channels.ts b/server/middlewares/validators/video-channels.ts
index 7f65f7290..143ce9582 100644
--- a/server/middlewares/validators/video-channels.ts
+++ b/server/middlewares/validators/video-channels.ts
@@ -1,7 +1,7 @@
1import * as express from 'express' 1import * as express from 'express'
2import { body, param } from 'express-validator/check' 2import { body, param } from 'express-validator/check'
3import { UserRight } from '../../../shared' 3import { UserRight } from '../../../shared'
4import { isAccountIdExist, isAccountNameWithHostExist } from '../../helpers/custom-validators/accounts' 4import { isAccountNameWithHostExist } from '../../helpers/custom-validators/accounts'
5import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' 5import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
6import { 6import {
7 isVideoChannelDescriptionValid, 7 isVideoChannelDescriptionValid,
@@ -13,8 +13,6 @@ import { logger } from '../../helpers/logger'
13import { UserModel } from '../../models/account/user' 13import { UserModel } from '../../models/account/user'
14import { VideoChannelModel } from '../../models/video/video-channel' 14import { VideoChannelModel } from '../../models/video/video-channel'
15import { areValidationErrors } from './utils' 15import { areValidationErrors } from './utils'
16import { isAvatarFile } from '../../helpers/custom-validators/users'
17import { CONSTRAINTS_FIELDS } from '../../initializers'
18 16
19const listVideoAccountChannelsValidator = [ 17const listVideoAccountChannelsValidator = [
20 param('accountName').exists().withMessage('Should have a valid account name'), 18 param('accountName').exists().withMessage('Should have a valid account name'),
diff --git a/server/middlewares/validators/videos.ts b/server/middlewares/validators/videos.ts
index d9af2aa0a..9357c1e39 100644
--- a/server/middlewares/validators/videos.ts
+++ b/server/middlewares/validators/videos.ts
@@ -35,6 +35,7 @@ import { CONSTRAINTS_FIELDS } from '../../initializers'
35import { VideoShareModel } from '../../models/video/video-share' 35import { VideoShareModel } from '../../models/video/video-share'
36import { authenticate } from '../oauth' 36import { authenticate } from '../oauth'
37import { areValidationErrors } from './utils' 37import { areValidationErrors } from './utils'
38import { cleanUpReqFiles } from '../../helpers/utils'
38 39
39const videosAddValidator = getCommonVideoAttributes().concat([ 40const videosAddValidator = getCommonVideoAttributes().concat([
40 body('videofile') 41 body('videofile')
@@ -50,13 +51,13 @@ const videosAddValidator = getCommonVideoAttributes().concat([
50 async (req: express.Request, res: express.Response, next: express.NextFunction) => { 51 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
51 logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) 52 logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files })
52 53
53 if (areValidationErrors(req, res)) return 54 if (areValidationErrors(req, res)) return cleanUpReqFiles(req)
54 if (areErrorsInScheduleUpdate(req, res)) return 55 if (areErrorsInScheduleUpdate(req, res)) return cleanUpReqFiles(req)
55 56
56 const videoFile: Express.Multer.File = req.files['videofile'][0] 57 const videoFile: Express.Multer.File = req.files['videofile'][0]
57 const user = res.locals.oauth.token.User 58 const user = res.locals.oauth.token.User
58 59
59 if (!await isVideoChannelOfAccountExist(req.body.channelId, user, res)) return 60 if (!await isVideoChannelOfAccountExist(req.body.channelId, user, res)) return cleanUpReqFiles(req)
60 61
61 const isAble = await user.isAbleToUploadVideo(videoFile) 62 const isAble = await user.isAbleToUploadVideo(videoFile)
62 if (isAble === false) { 63 if (isAble === false) {
@@ -64,7 +65,7 @@ const videosAddValidator = getCommonVideoAttributes().concat([
64 .json({ error: 'The user video quota is exceeded with this video.' }) 65 .json({ error: 'The user video quota is exceeded with this video.' })
65 .end() 66 .end()
66 67
67 return 68 return cleanUpReqFiles(req)
68 } 69 }
69 70
70 let duration: number 71 let duration: number
@@ -77,7 +78,7 @@ const videosAddValidator = getCommonVideoAttributes().concat([
77 .json({ error: 'Invalid input file.' }) 78 .json({ error: 'Invalid input file.' })
78 .end() 79 .end()
79 80
80 return 81 return cleanUpReqFiles(req)
81 } 82 }
82 83
83 videoFile['duration'] = duration 84 videoFile['duration'] = duration
@@ -99,23 +100,24 @@ const videosUpdateValidator = getCommonVideoAttributes().concat([
99 async (req: express.Request, res: express.Response, next: express.NextFunction) => { 100 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
100 logger.debug('Checking videosUpdate parameters', { parameters: req.body }) 101 logger.debug('Checking videosUpdate parameters', { parameters: req.body })
101 102
102 if (areValidationErrors(req, res)) return 103 if (areValidationErrors(req, res)) return cleanUpReqFiles(req)
103 if (areErrorsInScheduleUpdate(req, res)) return 104 if (areErrorsInScheduleUpdate(req, res)) return cleanUpReqFiles(req)
104 if (!await isVideoExist(req.params.id, res)) return 105 if (!await isVideoExist(req.params.id, res)) return cleanUpReqFiles(req)
105 106
106 const video = res.locals.video 107 const video = res.locals.video
107 108
108 // Check if the user who did the request is able to update the video 109 // Check if the user who did the request is able to update the video
109 const user = res.locals.oauth.token.User 110 const user = res.locals.oauth.token.User
110 if (!checkUserCanManageVideo(user, res.locals.video, UserRight.UPDATE_ANY_VIDEO, res)) return 111 if (!checkUserCanManageVideo(user, res.locals.video, UserRight.UPDATE_ANY_VIDEO, res)) return cleanUpReqFiles(req)
111 112
112 if (video.privacy !== VideoPrivacy.PRIVATE && req.body.privacy === VideoPrivacy.PRIVATE) { 113 if (video.privacy !== VideoPrivacy.PRIVATE && req.body.privacy === VideoPrivacy.PRIVATE) {
114 cleanUpReqFiles(req)
113 return res.status(409) 115 return res.status(409)
114 .json({ error: 'Cannot set "private" a video that was not private.' }) 116 .json({ error: 'Cannot set "private" a video that was not private.' })
115 .end() 117 .end()
116 } 118 }
117 119
118 if (req.body.channelId && !await isVideoChannelOfAccountExist(req.body.channelId, user, res)) return 120 if (req.body.channelId && !await isVideoChannelOfAccountExist(req.body.channelId, user, res)) return cleanUpReqFiles(req)
119 121
120 return next() 122 return next()
121 } 123 }
diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts
index a19b47509..25c87b4dc 100644
--- a/server/tests/api/server/follows.ts
+++ b/server/tests/api/server/follows.ts
@@ -178,7 +178,7 @@ describe('Test follows', function () {
178 }) 178 })
179 179
180 it('Should upload a video on server 2 and 3 and propagate only the video of server 2', async function () { 180 it('Should upload a video on server 2 and 3 and propagate only the video of server 2', async function () {
181 this.timeout(10000) 181 this.timeout(35000)
182 182
183 await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'server2' }) 183 await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'server2' })
184 await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3' }) 184 await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3' })
diff --git a/server/tests/api/server/handle-down.ts b/server/tests/api/server/handle-down.ts
index fb9722630..18a0d9ce3 100644
--- a/server/tests/api/server/handle-down.ts
+++ b/server/tests/api/server/handle-down.ts
@@ -176,7 +176,7 @@ describe('Test handle downs', function () {
176 }) 176 })
177 177
178 it('Should re-follow server 1', async function () { 178 it('Should re-follow server 1', async function () {
179 this.timeout(15000) 179 this.timeout(35000)
180 180
181 await reRunServer(servers[1]) 181 await reRunServer(servers[1])
182 await reRunServer(servers[2]) 182 await reRunServer(servers[2])