diff options
author | Chocobozzz <me@florianbigard.com> | 2018-07-31 15:09:34 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-07-31 15:09:34 +0200 |
commit | cf7a61b5a2b68fd966c4a355e37e84b048ed296b (patch) | |
tree | 4f4867344fe6856cb4f6b18856867c6e34171ea2 | |
parent | c487d3033cad9c5e0f85ae49ed3d2a7b6c2711d8 (diff) | |
download | PeerTube-cf7a61b5a2b68fd966c4a355e37e84b048ed296b.tar.gz PeerTube-cf7a61b5a2b68fd966c4a355e37e84b048ed296b.tar.zst PeerTube-cf7a61b5a2b68fd966c4a355e37e84b048ed296b.zip |
Cleanup req files on bad request
-rw-r--r-- | server/helpers/core-utils.ts | 2 | ||||
-rw-r--r-- | server/helpers/custom-validators/video-captions.ts | 2 | ||||
-rw-r--r-- | server/helpers/utils.ts | 28 | ||||
-rw-r--r-- | server/middlewares/validators/avatar.ts | 3 | ||||
-rw-r--r-- | server/middlewares/validators/video-captions.ts | 7 | ||||
-rw-r--r-- | server/middlewares/validators/video-channels.ts | 4 | ||||
-rw-r--r-- | server/middlewares/validators/videos.ts | 22 | ||||
-rw-r--r-- | server/tests/api/server/follows.ts | 2 | ||||
-rw-r--r-- | server/tests/api/server/handle-down.ts | 2 |
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 | '<': '<', | 58 | '<': '<', |
59 | '>': '>', | 59 | '>': '>', |
60 | '"': '"', | 60 | '"': '"', |
61 | "'": ''', | 61 | '\'': ''', |
62 | '/': '/', | 62 | '/': '/', |
63 | '`': '`', | 63 | '`': '`', |
64 | '=': '=' | 64 | '=': '=' |
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 @@ | |||
1 | import { CONSTRAINTS_FIELDS, VIDEO_CAPTIONS_MIMETYPE_EXT, VIDEO_LANGUAGES, VIDEO_MIMETYPE_EXT } from '../../initializers' | 1 | import { CONSTRAINTS_FIELDS, VIDEO_CAPTIONS_MIMETYPE_EXT, VIDEO_LANGUAGES } from '../../initializers' |
2 | import { exists, isFileValid } from './misc' | 2 | import { exists, isFileValid } from './misc' |
3 | import { Response } from 'express' | 3 | import { Response } from 'express' |
4 | import { VideoModel } from '../../models/video/video' | 4 | import { 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' | |||
6 | import { UserModel } from '../models/account/user' | 6 | import { UserModel } from '../models/account/user' |
7 | import { ActorModel } from '../models/activitypub/actor' | 7 | import { ActorModel } from '../models/activitypub/actor' |
8 | import { ApplicationModel } from '../models/application/application' | 8 | import { ApplicationModel } from '../models/application/application' |
9 | import { pseudoRandomBytesPromise } from './core-utils' | 9 | import { pseudoRandomBytesPromise, unlinkPromise } from './core-utils' |
10 | import { logger } from './logger' | 10 | import { logger } from './logger' |
11 | import { isArray } from './custom-validators/misc' | ||
11 | 12 | ||
12 | const isCidr = require('is-cidr') | 13 | const isCidr = require('is-cidr') |
13 | 14 | ||
15 | function 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 | |||
33 | function deleteFileAsync (path: string) { | ||
34 | unlinkPromise(path) | ||
35 | .catch(err => logger.error('Cannot delete the file %s asynchronously.', path, { err })) | ||
36 | } | ||
37 | |||
14 | async function generateRandomString (size: number) { | 38 | async 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 | ||
164 | export { | 188 | export { |
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' | |||
4 | import { areValidationErrors } from './utils' | 4 | import { areValidationErrors } from './utils' |
5 | import { CONSTRAINTS_FIELDS } from '../../initializers' | 5 | import { CONSTRAINTS_FIELDS } from '../../initializers' |
6 | import { logger } from '../../helpers/logger' | 6 | import { logger } from '../../helpers/logger' |
7 | import { cleanUpReqFiles } from '../../helpers/utils' | ||
7 | 8 | ||
8 | const updateAvatarValidator = [ | 9 | const 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' | |||
7 | import { UserRight } from '../../../shared' | 7 | import { UserRight } from '../../../shared' |
8 | import { logger } from '../../helpers/logger' | 8 | import { logger } from '../../helpers/logger' |
9 | import { isVideoCaptionExist, isVideoCaptionFile, isVideoCaptionLanguageValid } from '../../helpers/custom-validators/video-captions' | 9 | import { isVideoCaptionExist, isVideoCaptionFile, isVideoCaptionLanguageValid } from '../../helpers/custom-validators/video-captions' |
10 | import { cleanUpReqFiles } from '../../helpers/utils' | ||
10 | 11 | ||
11 | const addVideoCaptionValidator = [ | 12 | const 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 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { body, param } from 'express-validator/check' | 2 | import { body, param } from 'express-validator/check' |
3 | import { UserRight } from '../../../shared' | 3 | import { UserRight } from '../../../shared' |
4 | import { isAccountIdExist, isAccountNameWithHostExist } from '../../helpers/custom-validators/accounts' | 4 | import { isAccountNameWithHostExist } from '../../helpers/custom-validators/accounts' |
5 | import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' | 5 | import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' |
6 | import { | 6 | import { |
7 | isVideoChannelDescriptionValid, | 7 | isVideoChannelDescriptionValid, |
@@ -13,8 +13,6 @@ import { logger } from '../../helpers/logger' | |||
13 | import { UserModel } from '../../models/account/user' | 13 | import { UserModel } from '../../models/account/user' |
14 | import { VideoChannelModel } from '../../models/video/video-channel' | 14 | import { VideoChannelModel } from '../../models/video/video-channel' |
15 | import { areValidationErrors } from './utils' | 15 | import { areValidationErrors } from './utils' |
16 | import { isAvatarFile } from '../../helpers/custom-validators/users' | ||
17 | import { CONSTRAINTS_FIELDS } from '../../initializers' | ||
18 | 16 | ||
19 | const listVideoAccountChannelsValidator = [ | 17 | const 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' | |||
35 | import { VideoShareModel } from '../../models/video/video-share' | 35 | import { VideoShareModel } from '../../models/video/video-share' |
36 | import { authenticate } from '../oauth' | 36 | import { authenticate } from '../oauth' |
37 | import { areValidationErrors } from './utils' | 37 | import { areValidationErrors } from './utils' |
38 | import { cleanUpReqFiles } from '../../helpers/utils' | ||
38 | 39 | ||
39 | const videosAddValidator = getCommonVideoAttributes().concat([ | 40 | const 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]) |