diff options
Diffstat (limited to 'server/middlewares/validators/videos.ts')
-rw-r--r-- | server/middlewares/validators/videos.ts | 294 |
1 files changed, 160 insertions, 134 deletions
diff --git a/server/middlewares/validators/videos.ts b/server/middlewares/validators/videos.ts index 213b4c46b..bc8b7e541 100644 --- a/server/middlewares/validators/videos.ts +++ b/server/middlewares/validators/videos.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import 'express-validator' | 1 | import { body, param, query } from 'express-validator/check' |
2 | import * as express from 'express' | 2 | import * as express from 'express' |
3 | import * as Promise from 'bluebird' | 3 | import * as Promise from 'bluebird' |
4 | import * as validator from 'validator' | 4 | import * as validator from 'validator' |
@@ -6,172 +6,198 @@ import * as validator from 'validator' | |||
6 | import { database as db } from '../../initializers/database' | 6 | import { database as db } from '../../initializers/database' |
7 | import { checkErrors } from './utils' | 7 | import { checkErrors } from './utils' |
8 | import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers' | 8 | import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers' |
9 | import { logger, isVideoDurationValid } from '../../helpers' | 9 | import { |
10 | logger, | ||
11 | isVideoDurationValid, | ||
12 | isVideoFile, | ||
13 | isVideoNameValid, | ||
14 | isVideoCategoryValid, | ||
15 | isVideoLicenceValid, | ||
16 | isVideoDescriptionValid, | ||
17 | isVideoLanguageValid, | ||
18 | isVideoTagsValid, | ||
19 | isVideoNSFWValid, | ||
20 | isVideoIdOrUUIDValid, | ||
21 | isVideoAbuseReasonValid, | ||
22 | isVideoRatingTypeValid | ||
23 | } from '../../helpers' | ||
10 | import { VideoInstance } from '../../models' | 24 | import { VideoInstance } from '../../models' |
11 | 25 | ||
12 | function videosAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) { | 26 | const videosAddValidator = [ |
13 | // FIXME: Don't write an error message, it seems there is a bug with express-validator | 27 | body('videofile').custom((value, { req }) => isVideoFile(req.files)).withMessage('Should have a valid file'), |
14 | // 'Should have a valid file' | 28 | body('name').custom(isVideoNameValid).withMessage('Should have a valid name'), |
15 | req.checkBody('videofile').isVideoFile(req.files) | 29 | body('category').custom(isVideoCategoryValid).withMessage('Should have a valid category'), |
16 | req.checkBody('name', 'Should have a valid name').isVideoNameValid() | 30 | body('licence').custom(isVideoLicenceValid).withMessage('Should have a valid licence'), |
17 | req.checkBody('category', 'Should have a valid category').isVideoCategoryValid() | 31 | body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'), |
18 | req.checkBody('licence', 'Should have a valid licence').isVideoLicenceValid() | 32 | body('nsfw').custom(isVideoNSFWValid).withMessage('Should have a valid NSFW attribute'), |
19 | req.checkBody('language', 'Should have a valid language').optional().isVideoLanguageValid() | 33 | body('description').custom(isVideoDescriptionValid).withMessage('Should have a valid description'), |
20 | req.checkBody('nsfw', 'Should have a valid NSFW attribute').isVideoNSFWValid() | 34 | body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'), |
21 | req.checkBody('description', 'Should have a valid description').isVideoDescriptionValid() | 35 | |
22 | req.checkBody('tags', 'Should have correct tags').optional().isVideoTagsValid() | 36 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
23 | 37 | logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) | |
24 | logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) | 38 | |
25 | 39 | checkErrors(req, res, () => { | |
26 | checkErrors(req, res, () => { | 40 | const videoFile: Express.Multer.File = req.files['videofile'][0] |
27 | const videoFile: Express.Multer.File = req.files['videofile'][0] | 41 | const user = res.locals.oauth.token.User |
28 | const user = res.locals.oauth.token.User | 42 | |
29 | 43 | user.isAbleToUploadVideo(videoFile) | |
30 | user.isAbleToUploadVideo(videoFile) | 44 | .then(isAble => { |
31 | .then(isAble => { | 45 | if (isAble === false) { |
32 | if (isAble === false) { | 46 | res.status(403) |
33 | res.status(403) | 47 | .json({ error: 'The user video quota is exceeded with this video.' }) |
34 | .json({ error: 'The user video quota is exceeded with this video.' }) | 48 | .end() |
35 | .end() | 49 | |
50 | return undefined | ||
51 | } | ||
52 | |||
53 | return db.Video.getDurationFromFile(videoFile.path) | ||
54 | .catch(err => { | ||
55 | logger.error('Invalid input file in videosAddValidator.', err) | ||
56 | res.status(400) | ||
57 | .json({ error: 'Invalid input file.' }) | ||
58 | .end() | ||
59 | |||
60 | return undefined | ||
61 | }) | ||
62 | }) | ||
63 | .then(duration => { | ||
64 | // Previous test failed, abort | ||
65 | if (duration === undefined) return | ||
66 | |||
67 | if (!isVideoDurationValid('' + duration)) { | ||
68 | return res.status(400) | ||
69 | .json({ | ||
70 | error: 'Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).' | ||
71 | }) | ||
72 | .end() | ||
73 | } | ||
74 | |||
75 | videoFile['duration'] = duration | ||
76 | next() | ||
77 | }) | ||
78 | .catch(err => { | ||
79 | logger.error('Error in video add validator', err) | ||
80 | res.sendStatus(500) | ||
36 | 81 | ||
37 | return undefined | 82 | return undefined |
83 | }) | ||
84 | }) | ||
85 | } | ||
86 | ] | ||
87 | |||
88 | const videosUpdateValidator = [ | ||
89 | param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), | ||
90 | body('name').optional().custom(isVideoNameValid).withMessage('Should have a valid name'), | ||
91 | body('category').optional().custom(isVideoCategoryValid).withMessage('Should have a valid category'), | ||
92 | body('licence').optional().custom(isVideoLicenceValid).withMessage('Should have a valid licence'), | ||
93 | body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'), | ||
94 | body('nsfw').optional().custom(isVideoNSFWValid).withMessage('Should have a valid NSFW attribute'), | ||
95 | body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'), | ||
96 | body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'), | ||
97 | |||
98 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
99 | logger.debug('Checking videosUpdate parameters', { parameters: req.body }) | ||
100 | |||
101 | checkErrors(req, res, () => { | ||
102 | checkVideoExists(req.params.id, res, () => { | ||
103 | // We need to make additional checks | ||
104 | if (res.locals.video.isOwned() === false) { | ||
105 | return res.status(403) | ||
106 | .json({ error: 'Cannot update video of another pod' }) | ||
107 | .end() | ||
38 | } | 108 | } |
39 | 109 | ||
40 | return db.Video.getDurationFromFile(videoFile.path) | 110 | if (res.locals.video.Author.userId !== res.locals.oauth.token.User.id) { |
41 | .catch(err => { | 111 | return res.status(403) |
42 | logger.error('Invalid input file in videosAddValidator.', err) | 112 | .json({ error: 'Cannot update video of another user' }) |
43 | res.status(400) | ||
44 | .json({ error: 'Invalid input file.' }) | ||
45 | .end() | ||
46 | |||
47 | return undefined | ||
48 | }) | ||
49 | }) | ||
50 | .then(duration => { | ||
51 | // Previous test failed, abort | ||
52 | if (duration === undefined) return | ||
53 | |||
54 | if (!isVideoDurationValid('' + duration)) { | ||
55 | return res.status(400) | ||
56 | .json({ | ||
57 | error: 'Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).' | ||
58 | }) | ||
59 | .end() | 113 | .end() |
60 | } | 114 | } |
61 | 115 | ||
62 | videoFile['duration'] = duration | ||
63 | next() | 116 | next() |
64 | }) | 117 | }) |
65 | .catch(err => { | ||
66 | logger.error('Error in video add validator', err) | ||
67 | res.sendStatus(500) | ||
68 | |||
69 | return undefined | ||
70 | }) | ||
71 | |||
72 | }) | ||
73 | } | ||
74 | |||
75 | function videosUpdateValidator (req: express.Request, res: express.Response, next: express.NextFunction) { | ||
76 | req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() | ||
77 | req.checkBody('name', 'Should have a valid name').optional().isVideoNameValid() | ||
78 | req.checkBody('category', 'Should have a valid category').optional().isVideoCategoryValid() | ||
79 | req.checkBody('licence', 'Should have a valid licence').optional().isVideoLicenceValid() | ||
80 | req.checkBody('language', 'Should have a valid language').optional().isVideoLanguageValid() | ||
81 | req.checkBody('nsfw', 'Should have a valid NSFW attribute').optional().isVideoNSFWValid() | ||
82 | req.checkBody('description', 'Should have a valid description').optional().isVideoDescriptionValid() | ||
83 | req.checkBody('tags', 'Should have correct tags').optional().isVideoTagsValid() | ||
84 | |||
85 | logger.debug('Checking videosUpdate parameters', { parameters: req.body }) | ||
86 | |||
87 | checkErrors(req, res, () => { | ||
88 | checkVideoExists(req.params.id, res, () => { | ||
89 | // We need to make additional checks | ||
90 | if (res.locals.video.isOwned() === false) { | ||
91 | return res.status(403) | ||
92 | .json({ error: 'Cannot update video of another pod' }) | ||
93 | .end() | ||
94 | } | ||
95 | |||
96 | if (res.locals.video.Author.userId !== res.locals.oauth.token.User.id) { | ||
97 | return res.status(403) | ||
98 | .json({ error: 'Cannot update video of another user' }) | ||
99 | .end() | ||
100 | } | ||
101 | |||
102 | next() | ||
103 | }) | 118 | }) |
104 | }) | 119 | } |
105 | } | 120 | ] |
106 | 121 | ||
107 | function videosGetValidator (req: express.Request, res: express.Response, next: express.NextFunction) { | 122 | const videosGetValidator = [ |
108 | req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() | 123 | param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), |
109 | 124 | ||
110 | logger.debug('Checking videosGet parameters', { parameters: req.params }) | 125 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
126 | logger.debug('Checking videosGet parameters', { parameters: req.params }) | ||
111 | 127 | ||
112 | checkErrors(req, res, () => { | 128 | checkErrors(req, res, () => { |
113 | checkVideoExists(req.params.id, res, next) | 129 | checkVideoExists(req.params.id, res, next) |
114 | }) | 130 | }) |
115 | } | 131 | } |
132 | ] | ||
116 | 133 | ||
117 | function videosRemoveValidator (req: express.Request, res: express.Response, next: express.NextFunction) { | 134 | const videosRemoveValidator = [ |
118 | req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() | 135 | param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), |
119 | 136 | ||
120 | logger.debug('Checking videosRemove parameters', { parameters: req.params }) | 137 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
138 | logger.debug('Checking videosRemove parameters', { parameters: req.params }) | ||
121 | 139 | ||
122 | checkErrors(req, res, () => { | 140 | checkErrors(req, res, () => { |
123 | checkVideoExists(req.params.id, res, () => { | 141 | checkVideoExists(req.params.id, res, () => { |
124 | // Check if the user who did the request is able to delete the video | 142 | // Check if the user who did the request is able to delete the video |
125 | checkUserCanDeleteVideo(res.locals.oauth.token.User.id, res, () => { | 143 | checkUserCanDeleteVideo(res.locals.oauth.token.User.id, res, () => { |
126 | next() | 144 | next() |
145 | }) | ||
127 | }) | 146 | }) |
128 | }) | 147 | }) |
129 | }) | 148 | } |
130 | } | 149 | ] |
131 | 150 | ||
132 | function videosSearchValidator (req: express.Request, res: express.Response, next: express.NextFunction) { | 151 | const videosSearchValidator = [ |
133 | const searchableColumns = SEARCHABLE_COLUMNS.VIDEOS | 152 | param('value').not().isEmpty().withMessage('Should have a valid search'), |
134 | req.checkParams('value', 'Should have a valid search').notEmpty() | 153 | query('field').optional().isIn(SEARCHABLE_COLUMNS.VIDEOS).withMessage('Should have correct searchable column'), |
135 | req.checkQuery('field', 'Should have correct searchable column').optional().isIn(searchableColumns) | ||
136 | 154 | ||
137 | logger.debug('Checking videosSearch parameters', { parameters: req.params }) | 155 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
156 | logger.debug('Checking videosSearch parameters', { parameters: req.params }) | ||
138 | 157 | ||
139 | checkErrors(req, res, next) | 158 | checkErrors(req, res, next) |
140 | } | 159 | } |
160 | ] | ||
141 | 161 | ||
142 | function videoAbuseReportValidator (req: express.Request, res: express.Response, next: express.NextFunction) { | 162 | const videoAbuseReportValidator = [ |
143 | req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() | 163 | param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), |
144 | req.checkBody('reason', 'Should have a valid reason').isVideoAbuseReasonValid() | 164 | body('reason').custom(isVideoAbuseReasonValid).withMessage('Should have a valid reason'), |
145 | 165 | ||
146 | logger.debug('Checking videoAbuseReport parameters', { parameters: req.body }) | 166 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
167 | logger.debug('Checking videoAbuseReport parameters', { parameters: req.body }) | ||
147 | 168 | ||
148 | checkErrors(req, res, () => { | 169 | checkErrors(req, res, () => { |
149 | checkVideoExists(req.params.id, res, next) | 170 | checkVideoExists(req.params.id, res, next) |
150 | }) | 171 | }) |
151 | } | 172 | } |
173 | ] | ||
152 | 174 | ||
153 | function videoRateValidator (req: express.Request, res: express.Response, next: express.NextFunction) { | 175 | const videoRateValidator = [ |
154 | req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() | 176 | param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), |
155 | req.checkBody('rating', 'Should have a valid rate type').isVideoRatingTypeValid() | 177 | body('rating').custom(isVideoRatingTypeValid).withMessage('Should have a valid rate type'), |
156 | 178 | ||
157 | logger.debug('Checking videoRate parameters', { parameters: req.body }) | 179 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
180 | logger.debug('Checking videoRate parameters', { parameters: req.body }) | ||
158 | 181 | ||
159 | checkErrors(req, res, () => { | 182 | checkErrors(req, res, () => { |
160 | checkVideoExists(req.params.id, res, next) | 183 | checkVideoExists(req.params.id, res, next) |
161 | }) | 184 | }) |
162 | } | 185 | } |
186 | ] | ||
163 | 187 | ||
164 | function videosBlacklistValidator (req: express.Request, res: express.Response, next: express.NextFunction) { | 188 | const videosBlacklistValidator = [ |
165 | req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() | 189 | param('id').custom(isVideoIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), |
166 | 190 | ||
167 | logger.debug('Checking videosBlacklist parameters', { parameters: req.params }) | 191 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
192 | logger.debug('Checking videosBlacklist parameters', { parameters: req.params }) | ||
168 | 193 | ||
169 | checkErrors(req, res, () => { | 194 | checkErrors(req, res, () => { |
170 | checkVideoExists(req.params.id, res, () => { | 195 | checkVideoExists(req.params.id, res, () => { |
171 | checkVideoIsBlacklistable(req, res, next) | 196 | checkVideoIsBlacklistable(req, res, next) |
197 | }) | ||
172 | }) | 198 | }) |
173 | }) | 199 | } |
174 | } | 200 | ] |
175 | 201 | ||
176 | // --------------------------------------------------------------------------- | 202 | // --------------------------------------------------------------------------- |
177 | 203 | ||