From 8d4273463fb19d503b1aa0a32dc289f292ed614e Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 16 Nov 2018 15:02:48 +0100 Subject: Check follow constraints when getting a video --- server/middlewares/oauth.ts | 16 ++++++++ server/middlewares/validators/videos/videos.ts | 52 ++++++++++++++++++++------ 2 files changed, 57 insertions(+), 11 deletions(-) (limited to 'server/middlewares') 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 }) } +function authenticatePromiseIfNeeded (req: express.Request, res: express.Response) { + return new Promise(resolve => { + // Already authenticated? (or tried to) + if (res.locals.oauth && res.locals.oauth.token.User) return resolve() + + if (res.locals.authenticated === false) return res.sendStatus(401) + + authenticate(req, res, () => { + return resolve() + }) + }) +} + function optionalAuthenticate (req: express.Request, res: express.Response, next: express.NextFunction) { if (req.header('authorization')) return authenticate(req, res, next) + res.locals.authenticated = false + return next() } @@ -53,6 +68,7 @@ function token (req: express.Request, res: express.Response, next: express.NextF export { authenticate, + authenticatePromiseIfNeeded, optionalAuthenticate, token } diff --git a/server/middlewares/validators/videos/videos.ts b/server/middlewares/validators/videos/videos.ts index bf21bca8c..051a19e16 100644 --- a/server/middlewares/validators/videos/videos.ts +++ b/server/middlewares/validators/videos/videos.ts @@ -31,8 +31,8 @@ import { } from '../../../helpers/custom-validators/videos' import { getDurationFromVideoFile } from '../../../helpers/ffmpeg-utils' import { logger } from '../../../helpers/logger' -import { CONSTRAINTS_FIELDS } from '../../../initializers' -import { authenticate } from '../../oauth' +import { CONFIG, CONSTRAINTS_FIELDS } from '../../../initializers' +import { authenticatePromiseIfNeeded } from '../../oauth' import { areValidationErrors } from '../utils' import { cleanUpReqFiles } from '../../../helpers/express-utils' import { VideoModel } from '../../../models/video/video' @@ -43,6 +43,7 @@ import { VideoChangeOwnershipModel } from '../../../models/video/video-change-ow import { AccountModel } from '../../../models/account/account' import { VideoFetchType } from '../../../helpers/video' import { isNSFWQueryValid, isNumberArray, isStringArray } from '../../../helpers/custom-validators/search' +import { getServerActor } from '../../../helpers/utils' const videosAddValidator = getCommonVideoAttributes().concat([ body('videofile') @@ -127,6 +128,31 @@ const videosUpdateValidator = getCommonVideoAttributes().concat([ } ]) +async function checkVideoFollowConstraints (req: express.Request, res: express.Response, next: express.NextFunction) { + const video: VideoModel = res.locals.video + + // Anybody can watch local videos + if (video.isOwned() === true) return next() + + // Logged user + if (res.locals.oauth) { + // Users can search or watch remote videos + if (CONFIG.SEARCH.REMOTE_URI.USERS === true) return next() + } + + // Anybody can search or watch remote videos + if (CONFIG.SEARCH.REMOTE_URI.ANONYMOUS === true) return next() + + // Check our instance follows an actor that shared this video + const serverActor = await getServerActor() + if (await VideoModel.checkVideoHasInstanceFollow(video.id, serverActor.id) === true) return next() + + return res.status(403) + .json({ + error: 'Cannot get this video regarding follow constraints.' + }) +} + const videosCustomGetValidator = (fetchType: VideoFetchType) => { return [ param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), @@ -141,17 +167,20 @@ const videosCustomGetValidator = (fetchType: VideoFetchType) => { // Video private or blacklisted if (video.privacy === VideoPrivacy.PRIVATE || video.VideoBlacklist) { - return authenticate(req, res, () => { - const user: UserModel = res.locals.oauth.token.User + await authenticatePromiseIfNeeded(req, res) + + const user: UserModel = res.locals.oauth ? res.locals.oauth.token.User : null - // Only the owner or a user that have blacklist rights can see the video - if (video.VideoChannel.Account.userId !== user.id && !user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST)) { - return res.status(403) - .json({ error: 'Cannot get this private or blacklisted video.' }) - } + // Only the owner or a user that have blacklist rights can see the video + if ( + !user || + (video.VideoChannel.Account.userId !== user.id && !user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST)) + ) { + return res.status(403) + .json({ error: 'Cannot get this private or blacklisted video.' }) + } - return next() - }) + return next() } // Video is public, anyone can access it @@ -376,6 +405,7 @@ export { videosAddValidator, videosUpdateValidator, videosGetValidator, + checkVideoFollowConstraints, videosCustomGetValidator, videosRemoveValidator, -- cgit v1.2.3