]>
Commit | Line | Data |
---|---|---|
69818c93 | 1 | import 'express-validator' |
69818c93 | 2 | import * as express from 'express' |
0a6658fd C |
3 | import * as Promise from 'bluebird' |
4 | import * as validator from 'validator' | |
69818c93 | 5 | |
e02643f3 | 6 | import { database as db } from '../../initializers/database' |
65fcc311 C |
7 | import { checkErrors } from './utils' |
8 | import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers' | |
9 | import { logger, isVideoDurationValid } from '../../helpers' | |
0a6658fd | 10 | import { VideoInstance } from '../../models' |
34ca3b52 | 11 | |
69818c93 | 12 | function videosAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) { |
69f616ab C |
13 | // FIXME: Don't write an error message, it seems there is a bug with express-validator |
14 | // 'Should have a valid file' | |
15 | req.checkBody('videofile').isVideoFile(req.files) | |
be587647 | 16 | req.checkBody('name', 'Should have a valid name').isVideoNameValid() |
6e07c3de | 17 | req.checkBody('category', 'Should have a valid category').isVideoCategoryValid() |
6f0c39e2 | 18 | req.checkBody('licence', 'Should have a valid licence').isVideoLicenceValid() |
3092476e | 19 | req.checkBody('language', 'Should have a valid language').optional().isVideoLanguageValid() |
31b59b47 | 20 | req.checkBody('nsfw', 'Should have a valid NSFW attribute').isVideoNSFWValid() |
be587647 | 21 | req.checkBody('description', 'Should have a valid description').isVideoDescriptionValid() |
e54163c2 | 22 | req.checkBody('tags', 'Should have correct tags').optional().isVideoTagsValid() |
34ca3b52 | 23 | |
9f10b292 | 24 | logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) |
34ca3b52 | 25 | |
075f16ca | 26 | checkErrors(req, res, () => { |
b0f9f39e C |
27 | const videoFile: Express.Multer.File = req.files['videofile'][0] |
28 | const user = res.locals.oauth.token.User | |
67100f1f | 29 | |
b0f9f39e C |
30 | user.isAbleToUploadVideo(videoFile) |
31 | .then(isAble => { | |
32 | if (isAble === false) { | |
33 | res.status(403).send('The user video quota is exceeded with this video.') | |
34 | ||
35 | return undefined | |
36 | } | |
37 | ||
38 | return db.Video.getDurationFromFile(videoFile.path) | |
77a5501f C |
39 | .catch(err => { |
40 | logger.error('Invalid input file in videosAddValidator.', err) | |
41 | res.status(400).send('Invalid input file.') | |
42 | ||
43 | return undefined | |
44 | }) | |
b0f9f39e | 45 | }) |
6fcd19ba | 46 | .then(duration => { |
b0f9f39e | 47 | // Previous test failed, abort |
980246ea | 48 | if (duration === undefined) return undefined |
b0f9f39e | 49 | |
6fcd19ba C |
50 | if (!isVideoDurationValid('' + duration)) { |
51 | return res.status(400).send('Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).') | |
52 | } | |
67100f1f | 53 | |
6fcd19ba C |
54 | videoFile['duration'] = duration |
55 | next() | |
56 | }) | |
57 | .catch(err => { | |
5c98d3bf C |
58 | logger.error('Error in video add validator', err) |
59 | res.sendStatus(500) | |
77a5501f C |
60 | |
61 | return undefined | |
6fcd19ba | 62 | }) |
77a5501f | 63 | |
67100f1f | 64 | }) |
9f10b292 | 65 | } |
34ca3b52 | 66 | |
69818c93 | 67 | function videosUpdateValidator (req: express.Request, res: express.Response, next: express.NextFunction) { |
0a6658fd | 68 | req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() |
7b1f49de | 69 | req.checkBody('name', 'Should have a valid name').optional().isVideoNameValid() |
6e07c3de | 70 | req.checkBody('category', 'Should have a valid category').optional().isVideoCategoryValid() |
6f0c39e2 | 71 | req.checkBody('licence', 'Should have a valid licence').optional().isVideoLicenceValid() |
3092476e | 72 | req.checkBody('language', 'Should have a valid language').optional().isVideoLanguageValid() |
31b59b47 | 73 | req.checkBody('nsfw', 'Should have a valid NSFW attribute').optional().isVideoNSFWValid() |
7b1f49de C |
74 | req.checkBody('description', 'Should have a valid description').optional().isVideoDescriptionValid() |
75 | req.checkBody('tags', 'Should have correct tags').optional().isVideoTagsValid() | |
34ca3b52 | 76 | |
7b1f49de | 77 | logger.debug('Checking videosUpdate parameters', { parameters: req.body }) |
34ca3b52 | 78 | |
075f16ca C |
79 | checkErrors(req, res, () => { |
80 | checkVideoExists(req.params.id, res, () => { | |
63d00f5d C |
81 | // We need to make additional checks |
82 | if (res.locals.video.isOwned() === false) { | |
83 | return res.status(403).send('Cannot update video of another pod') | |
84 | } | |
45abb8b9 | 85 | |
63d00f5d C |
86 | if (res.locals.video.Author.userId !== res.locals.oauth.token.User.id) { |
87 | return res.status(403).send('Cannot update video of another user') | |
88 | } | |
45abb8b9 | 89 | |
63d00f5d C |
90 | next() |
91 | }) | |
7b1f49de C |
92 | }) |
93 | } | |
c173e565 | 94 | |
69818c93 | 95 | function videosGetValidator (req: express.Request, res: express.Response, next: express.NextFunction) { |
0a6658fd | 96 | req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() |
34ca3b52 | 97 | |
7b1f49de C |
98 | logger.debug('Checking videosGet parameters', { parameters: req.params }) |
99 | ||
075f16ca | 100 | checkErrors(req, res, () => { |
7b1f49de | 101 | checkVideoExists(req.params.id, res, next) |
9f10b292 C |
102 | }) |
103 | } | |
34ca3b52 | 104 | |
69818c93 | 105 | function videosRemoveValidator (req: express.Request, res: express.Response, next: express.NextFunction) { |
0a6658fd | 106 | req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() |
34ca3b52 | 107 | |
9f10b292 | 108 | logger.debug('Checking videosRemove parameters', { parameters: req.params }) |
34ca3b52 | 109 | |
075f16ca C |
110 | checkErrors(req, res, () => { |
111 | checkVideoExists(req.params.id, res, () => { | |
198b205c | 112 | // Check if the user who did the request is able to delete the video |
075f16ca | 113 | checkUserCanDeleteVideo(res.locals.oauth.token.User.id, res, () => { |
198b205c GS |
114 | next() |
115 | }) | |
34ca3b52 | 116 | }) |
9f10b292 C |
117 | }) |
118 | } | |
34ca3b52 | 119 | |
69818c93 | 120 | function videosSearchValidator (req: express.Request, res: express.Response, next: express.NextFunction) { |
65fcc311 | 121 | const searchableColumns = SEARCHABLE_COLUMNS.VIDEOS |
be587647 | 122 | req.checkParams('value', 'Should have a valid search').notEmpty() |
46246b5f | 123 | req.checkQuery('field', 'Should have correct searchable column').optional().isIn(searchableColumns) |
c45f7f84 | 124 | |
9f10b292 | 125 | logger.debug('Checking videosSearch parameters', { parameters: req.params }) |
c45f7f84 | 126 | |
9f10b292 C |
127 | checkErrors(req, res, next) |
128 | } | |
c45f7f84 | 129 | |
69818c93 | 130 | function videoAbuseReportValidator (req: express.Request, res: express.Response, next: express.NextFunction) { |
0a6658fd | 131 | req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() |
55fa55a9 C |
132 | req.checkBody('reason', 'Should have a valid reason').isVideoAbuseReasonValid() |
133 | ||
134 | logger.debug('Checking videoAbuseReport parameters', { parameters: req.body }) | |
135 | ||
075f16ca | 136 | checkErrors(req, res, () => { |
55fa55a9 C |
137 | checkVideoExists(req.params.id, res, next) |
138 | }) | |
139 | } | |
140 | ||
69818c93 | 141 | function videoRateValidator (req: express.Request, res: express.Response, next: express.NextFunction) { |
0a6658fd | 142 | req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() |
d38b8281 C |
143 | req.checkBody('rating', 'Should have a valid rate type').isVideoRatingTypeValid() |
144 | ||
145 | logger.debug('Checking videoRate parameters', { parameters: req.body }) | |
146 | ||
075f16ca | 147 | checkErrors(req, res, () => { |
d38b8281 C |
148 | checkVideoExists(req.params.id, res, next) |
149 | }) | |
150 | } | |
151 | ||
69818c93 | 152 | function videosBlacklistValidator (req: express.Request, res: express.Response, next: express.NextFunction) { |
0a6658fd | 153 | req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid() |
ab683a8e C |
154 | |
155 | logger.debug('Checking videosBlacklist parameters', { parameters: req.params }) | |
156 | ||
075f16ca C |
157 | checkErrors(req, res, () => { |
158 | checkVideoExists(req.params.id, res, () => { | |
ab683a8e C |
159 | checkVideoIsBlacklistable(req, res, next) |
160 | }) | |
161 | }) | |
162 | } | |
163 | ||
9f10b292 | 164 | // --------------------------------------------------------------------------- |
c45f7f84 | 165 | |
65fcc311 C |
166 | export { |
167 | videosAddValidator, | |
168 | videosUpdateValidator, | |
169 | videosGetValidator, | |
170 | videosRemoveValidator, | |
171 | videosSearchValidator, | |
172 | ||
173 | videoAbuseReportValidator, | |
174 | ||
175 | videoRateValidator, | |
176 | ||
177 | videosBlacklistValidator | |
178 | } | |
7b1f49de C |
179 | |
180 | // --------------------------------------------------------------------------- | |
181 | ||
69818c93 | 182 | function checkVideoExists (id: string, res: express.Response, callback: () => void) { |
0a6658fd C |
183 | let promise: Promise<VideoInstance> |
184 | if (validator.isInt(id)) { | |
185 | promise = db.Video.loadAndPopulateAuthorAndPodAndTags(+id) | |
186 | } else { // UUID | |
187 | promise = db.Video.loadByUUIDAndPopulateAuthorAndPodAndTags(id) | |
188 | } | |
189 | ||
190 | promise.then(video => { | |
7b1f49de C |
191 | if (!video) return res.status(404).send('Video not found') |
192 | ||
193 | res.locals.video = video | |
194 | callback() | |
195 | }) | |
6fcd19ba | 196 | .catch(err => { |
ad0997ad | 197 | logger.error('Error in video request validator.', err) |
6fcd19ba C |
198 | return res.sendStatus(500) |
199 | }) | |
7b1f49de | 200 | } |
198b205c | 201 | |
69818c93 | 202 | function checkUserCanDeleteVideo (userId: number, res: express.Response, callback: () => void) { |
198b205c | 203 | // Retrieve the user who did the request |
6fcd19ba C |
204 | db.User.loadById(userId) |
205 | .then(user => { | |
6d33593a C |
206 | if (res.locals.video.isOwned() === false) { |
207 | return res.status(403).send('Cannot remove video of another pod, blacklist it') | |
208 | } | |
209 | ||
6fcd19ba C |
210 | // Check if the user can delete the video |
211 | // The user can delete it if s/he is an admin | |
212 | // Or if s/he is the video's author | |
6d33593a C |
213 | if (user.isAdmin() === false && res.locals.video.Author.userId !== res.locals.oauth.token.User.id) { |
214 | return res.status(403).send('Cannot remove video of another user') | |
198b205c | 215 | } |
198b205c | 216 | |
6fcd19ba C |
217 | // If we reach this comment, we can delete the video |
218 | callback() | |
219 | }) | |
220 | .catch(err => { | |
ad0997ad | 221 | logger.error('Error in video request validator.', err) |
6fcd19ba C |
222 | return res.sendStatus(500) |
223 | }) | |
198b205c GS |
224 | } |
225 | ||
69818c93 | 226 | function checkVideoIsBlacklistable (req: express.Request, res: express.Response, callback: () => void) { |
198b205c | 227 | if (res.locals.video.isOwned() === true) { |
ab683a8e | 228 | return res.status(403).send('Cannot blacklist a local video') |
198b205c GS |
229 | } |
230 | ||
231 | callback() | |
232 | } |