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