diff options
author | buoyantair <buoyantair@protonmail.com> | 2018-11-18 21:55:52 +0530 |
---|---|---|
committer | buoyantair <buoyantair@protonmail.com> | 2018-11-18 21:55:52 +0530 |
commit | b9f234371bfaf0d9cfa81e02fcea92cac1f9ae13 (patch) | |
tree | dcdf451ac431ec7953bee58e814f642d1c370d1b /server/middlewares | |
parent | 92e07c3b5d9dbf2febedb1b5b87ec676eb6d1ac8 (diff) | |
parent | 9d0b856e930ee1c676d16a56408a3e4a18f8f978 (diff) | |
download | PeerTube-b9f234371bfaf0d9cfa81e02fcea92cac1f9ae13.tar.gz PeerTube-b9f234371bfaf0d9cfa81e02fcea92cac1f9ae13.tar.zst PeerTube-b9f234371bfaf0d9cfa81e02fcea92cac1f9ae13.zip |
Merge branch 'develop' of https://github.com/Chocobozzz/PeerTube into move-utils-to-shared
Diffstat (limited to 'server/middlewares')
-rw-r--r-- | server/middlewares/cache.ts | 7 | ||||
-rw-r--r-- | server/middlewares/oauth.ts | 16 | ||||
-rw-r--r-- | server/middlewares/validators/videos/videos.ts | 54 |
3 files changed, 66 insertions, 11 deletions
diff --git a/server/middlewares/cache.ts b/server/middlewares/cache.ts index 1e00fc731..8ffe75700 100644 --- a/server/middlewares/cache.ts +++ b/server/middlewares/cache.ts | |||
@@ -19,6 +19,7 @@ function cacheRoute (lifetimeArg: string | number) { | |||
19 | logger.debug('No cached results for route %s.', req.originalUrl) | 19 | logger.debug('No cached results for route %s.', req.originalUrl) |
20 | 20 | ||
21 | const sendSave = res.send.bind(res) | 21 | const sendSave = res.send.bind(res) |
22 | const redirectSave = res.redirect.bind(res) | ||
22 | 23 | ||
23 | res.send = (body) => { | 24 | res.send = (body) => { |
24 | if (res.statusCode >= 200 && res.statusCode < 400) { | 25 | if (res.statusCode >= 200 && res.statusCode < 400) { |
@@ -38,6 +39,12 @@ function cacheRoute (lifetimeArg: string | number) { | |||
38 | return sendSave(body) | 39 | return sendSave(body) |
39 | } | 40 | } |
40 | 41 | ||
42 | res.redirect = url => { | ||
43 | done() | ||
44 | |||
45 | return redirectSave(url) | ||
46 | } | ||
47 | |||
41 | return next() | 48 | return next() |
42 | } | 49 | } |
43 | 50 | ||
diff --git a/server/middlewares/oauth.ts b/server/middlewares/oauth.ts index 5233b66bd..8c1df2c3e 100644 --- a/server/middlewares/oauth.ts +++ b/server/middlewares/oauth.ts | |||
@@ -28,9 +28,24 @@ function authenticate (req: express.Request, res: express.Response, next: expres | |||
28 | }) | 28 | }) |
29 | } | 29 | } |
30 | 30 | ||
31 | function authenticatePromiseIfNeeded (req: express.Request, res: express.Response) { | ||
32 | return new Promise(resolve => { | ||
33 | // Already authenticated? (or tried to) | ||
34 | if (res.locals.oauth && res.locals.oauth.token.User) return resolve() | ||
35 | |||
36 | if (res.locals.authenticated === false) return res.sendStatus(401) | ||
37 | |||
38 | authenticate(req, res, () => { | ||
39 | return resolve() | ||
40 | }) | ||
41 | }) | ||
42 | } | ||
43 | |||
31 | function optionalAuthenticate (req: express.Request, res: express.Response, next: express.NextFunction) { | 44 | function optionalAuthenticate (req: express.Request, res: express.Response, next: express.NextFunction) { |
32 | if (req.header('authorization')) return authenticate(req, res, next) | 45 | if (req.header('authorization')) return authenticate(req, res, next) |
33 | 46 | ||
47 | res.locals.authenticated = false | ||
48 | |||
34 | return next() | 49 | return next() |
35 | } | 50 | } |
36 | 51 | ||
@@ -53,6 +68,7 @@ function token (req: express.Request, res: express.Response, next: express.NextF | |||
53 | 68 | ||
54 | export { | 69 | export { |
55 | authenticate, | 70 | authenticate, |
71 | authenticatePromiseIfNeeded, | ||
56 | optionalAuthenticate, | 72 | optionalAuthenticate, |
57 | token | 73 | token |
58 | } | 74 | } |
diff --git a/server/middlewares/validators/videos/videos.ts b/server/middlewares/validators/videos/videos.ts index 656d161d8..051a19e16 100644 --- a/server/middlewares/validators/videos/videos.ts +++ b/server/middlewares/validators/videos/videos.ts | |||
@@ -31,8 +31,8 @@ import { | |||
31 | } from '../../../helpers/custom-validators/videos' | 31 | } from '../../../helpers/custom-validators/videos' |
32 | import { getDurationFromVideoFile } from '../../../helpers/ffmpeg-utils' | 32 | import { getDurationFromVideoFile } from '../../../helpers/ffmpeg-utils' |
33 | import { logger } from '../../../helpers/logger' | 33 | import { logger } from '../../../helpers/logger' |
34 | import { CONSTRAINTS_FIELDS } from '../../../initializers' | 34 | import { CONFIG, CONSTRAINTS_FIELDS } from '../../../initializers' |
35 | import { authenticate } from '../../oauth' | 35 | import { authenticatePromiseIfNeeded } from '../../oauth' |
36 | import { areValidationErrors } from '../utils' | 36 | import { areValidationErrors } from '../utils' |
37 | import { cleanUpReqFiles } from '../../../helpers/express-utils' | 37 | import { cleanUpReqFiles } from '../../../helpers/express-utils' |
38 | import { VideoModel } from '../../../models/video/video' | 38 | import { VideoModel } from '../../../models/video/video' |
@@ -43,6 +43,7 @@ import { VideoChangeOwnershipModel } from '../../../models/video/video-change-ow | |||
43 | import { AccountModel } from '../../../models/account/account' | 43 | import { AccountModel } from '../../../models/account/account' |
44 | import { VideoFetchType } from '../../../helpers/video' | 44 | import { VideoFetchType } from '../../../helpers/video' |
45 | import { isNSFWQueryValid, isNumberArray, isStringArray } from '../../../helpers/custom-validators/search' | 45 | import { isNSFWQueryValid, isNumberArray, isStringArray } from '../../../helpers/custom-validators/search' |
46 | import { getServerActor } from '../../../helpers/utils' | ||
46 | 47 | ||
47 | const videosAddValidator = getCommonVideoAttributes().concat([ | 48 | const videosAddValidator = getCommonVideoAttributes().concat([ |
48 | body('videofile') | 49 | body('videofile') |
@@ -127,6 +128,31 @@ const videosUpdateValidator = getCommonVideoAttributes().concat([ | |||
127 | } | 128 | } |
128 | ]) | 129 | ]) |
129 | 130 | ||
131 | async function checkVideoFollowConstraints (req: express.Request, res: express.Response, next: express.NextFunction) { | ||
132 | const video: VideoModel = res.locals.video | ||
133 | |||
134 | // Anybody can watch local videos | ||
135 | if (video.isOwned() === true) return next() | ||
136 | |||
137 | // Logged user | ||
138 | if (res.locals.oauth) { | ||
139 | // Users can search or watch remote videos | ||
140 | if (CONFIG.SEARCH.REMOTE_URI.USERS === true) return next() | ||
141 | } | ||
142 | |||
143 | // Anybody can search or watch remote videos | ||
144 | if (CONFIG.SEARCH.REMOTE_URI.ANONYMOUS === true) return next() | ||
145 | |||
146 | // Check our instance follows an actor that shared this video | ||
147 | const serverActor = await getServerActor() | ||
148 | if (await VideoModel.checkVideoHasInstanceFollow(video.id, serverActor.id) === true) return next() | ||
149 | |||
150 | return res.status(403) | ||
151 | .json({ | ||
152 | error: 'Cannot get this video regarding follow constraints.' | ||
153 | }) | ||
154 | } | ||
155 | |||
130 | const videosCustomGetValidator = (fetchType: VideoFetchType) => { | 156 | const videosCustomGetValidator = (fetchType: VideoFetchType) => { |
131 | return [ | 157 | return [ |
132 | param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), | 158 | param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), |
@@ -141,17 +167,20 @@ const videosCustomGetValidator = (fetchType: VideoFetchType) => { | |||
141 | 167 | ||
142 | // Video private or blacklisted | 168 | // Video private or blacklisted |
143 | if (video.privacy === VideoPrivacy.PRIVATE || video.VideoBlacklist) { | 169 | if (video.privacy === VideoPrivacy.PRIVATE || video.VideoBlacklist) { |
144 | return authenticate(req, res, () => { | 170 | await authenticatePromiseIfNeeded(req, res) |
145 | const user: UserModel = res.locals.oauth.token.User | ||
146 | 171 | ||
147 | // Only the owner or a user that have blacklist rights can see the video | 172 | const user: UserModel = res.locals.oauth ? res.locals.oauth.token.User : null |
148 | if (video.VideoChannel.Account.userId !== user.id && !user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST)) { | ||
149 | return res.status(403) | ||
150 | .json({ error: 'Cannot get this private or blacklisted video.' }) | ||
151 | } | ||
152 | 173 | ||
153 | return next() | 174 | // Only the owner or a user that have blacklist rights can see the video |
154 | }) | 175 | if ( |
176 | !user || | ||
177 | (video.VideoChannel.Account.userId !== user.id && !user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST)) | ||
178 | ) { | ||
179 | return res.status(403) | ||
180 | .json({ error: 'Cannot get this private or blacklisted video.' }) | ||
181 | } | ||
182 | |||
183 | return next() | ||
155 | } | 184 | } |
156 | 185 | ||
157 | // Video is public, anyone can access it | 186 | // Video is public, anyone can access it |
@@ -376,6 +405,7 @@ export { | |||
376 | videosAddValidator, | 405 | videosAddValidator, |
377 | videosUpdateValidator, | 406 | videosUpdateValidator, |
378 | videosGetValidator, | 407 | videosGetValidator, |
408 | checkVideoFollowConstraints, | ||
379 | videosCustomGetValidator, | 409 | videosCustomGetValidator, |
380 | videosRemoveValidator, | 410 | videosRemoveValidator, |
381 | 411 | ||
@@ -393,6 +423,8 @@ export { | |||
393 | function areErrorsInScheduleUpdate (req: express.Request, res: express.Response) { | 423 | function areErrorsInScheduleUpdate (req: express.Request, res: express.Response) { |
394 | if (req.body.scheduleUpdate) { | 424 | if (req.body.scheduleUpdate) { |
395 | if (!req.body.scheduleUpdate.updateAt) { | 425 | if (!req.body.scheduleUpdate.updateAt) { |
426 | logger.warn('Invalid parameters: scheduleUpdate.updateAt is mandatory.') | ||
427 | |||
396 | res.status(400) | 428 | res.status(400) |
397 | .json({ error: 'Schedule update at is mandatory.' }) | 429 | .json({ error: 'Schedule update at is mandatory.' }) |
398 | 430 | ||