aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/middlewares
diff options
context:
space:
mode:
Diffstat (limited to 'server/middlewares')
-rw-r--r--server/middlewares/cache.ts7
-rw-r--r--server/middlewares/oauth.ts16
-rw-r--r--server/middlewares/validators/videos/videos.ts54
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
31function 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
31function optionalAuthenticate (req: express.Request, res: express.Response, next: express.NextFunction) { 44function 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
54export { 69export {
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'
32import { getDurationFromVideoFile } from '../../../helpers/ffmpeg-utils' 32import { getDurationFromVideoFile } from '../../../helpers/ffmpeg-utils'
33import { logger } from '../../../helpers/logger' 33import { logger } from '../../../helpers/logger'
34import { CONSTRAINTS_FIELDS } from '../../../initializers' 34import { CONFIG, CONSTRAINTS_FIELDS } from '../../../initializers'
35import { authenticate } from '../../oauth' 35import { authenticatePromiseIfNeeded } from '../../oauth'
36import { areValidationErrors } from '../utils' 36import { areValidationErrors } from '../utils'
37import { cleanUpReqFiles } from '../../../helpers/express-utils' 37import { cleanUpReqFiles } from '../../../helpers/express-utils'
38import { VideoModel } from '../../../models/video/video' 38import { VideoModel } from '../../../models/video/video'
@@ -43,6 +43,7 @@ import { VideoChangeOwnershipModel } from '../../../models/video/video-change-ow
43import { AccountModel } from '../../../models/account/account' 43import { AccountModel } from '../../../models/account/account'
44import { VideoFetchType } from '../../../helpers/video' 44import { VideoFetchType } from '../../../helpers/video'
45import { isNSFWQueryValid, isNumberArray, isStringArray } from '../../../helpers/custom-validators/search' 45import { isNSFWQueryValid, isNumberArray, isStringArray } from '../../../helpers/custom-validators/search'
46import { getServerActor } from '../../../helpers/utils'
46 47
47const videosAddValidator = getCommonVideoAttributes().concat([ 48const videosAddValidator = getCommonVideoAttributes().concat([
48 body('videofile') 49 body('videofile')
@@ -127,6 +128,31 @@ const videosUpdateValidator = getCommonVideoAttributes().concat([
127 } 128 }
128]) 129])
129 130
131async 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
130const videosCustomGetValidator = (fetchType: VideoFetchType) => { 156const 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 {
393function areErrorsInScheduleUpdate (req: express.Request, res: express.Response) { 423function 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