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