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