aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/middlewares/validators
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2022-01-06 13:27:29 +0100
committerChocobozzz <me@florianbigard.com>2022-01-06 13:27:29 +0100
commit795212f7acc690c88c86d0fab8772f6564d59cb8 (patch)
tree3a0203fc1957fd8cf8876774051137a0b04236fc /server/middlewares/validators
parent7b54a81cccf6b4c12269e9d6897d608b1a99537a (diff)
downloadPeerTube-795212f7acc690c88c86d0fab8772f6564d59cb8.tar.gz
PeerTube-795212f7acc690c88c86d0fab8772f6564d59cb8.tar.zst
PeerTube-795212f7acc690c88c86d0fab8772f6564d59cb8.zip
Prevent caption listing of private videos
Diffstat (limited to 'server/middlewares/validators')
-rw-r--r--server/middlewares/validators/shared/videos.ts33
-rw-r--r--server/middlewares/validators/videos/video-captions.ts22
-rw-r--r--server/middlewares/validators/videos/videos.ts19
3 files changed, 55 insertions, 19 deletions
diff --git a/server/middlewares/validators/shared/videos.ts b/server/middlewares/validators/shared/videos.ts
index 71b81654f..fc978b63a 100644
--- a/server/middlewares/validators/shared/videos.ts
+++ b/server/middlewares/validators/shared/videos.ts
@@ -1,16 +1,20 @@
1import { Response } from 'express' 1import { Request, Response } from 'express'
2import { loadVideo, VideoLoadType } from '@server/lib/model-loaders' 2import { loadVideo, VideoLoadType } from '@server/lib/model-loaders'
3import { authenticatePromiseIfNeeded } from '@server/middlewares/auth'
4import { VideoModel } from '@server/models/video/video'
3import { VideoChannelModel } from '@server/models/video/video-channel' 5import { VideoChannelModel } from '@server/models/video/video-channel'
4import { VideoFileModel } from '@server/models/video/video-file' 6import { VideoFileModel } from '@server/models/video/video-file'
5import { 7import {
6 MUser, 8 MUser,
7 MUserAccountId, 9 MUserAccountId,
10 MVideo,
8 MVideoAccountLight, 11 MVideoAccountLight,
9 MVideoFormattableDetails, 12 MVideoFormattableDetails,
10 MVideoFullLight, 13 MVideoFullLight,
11 MVideoId, 14 MVideoId,
12 MVideoImmutable, 15 MVideoImmutable,
13 MVideoThumbnail 16 MVideoThumbnail,
17 MVideoWithRights
14} from '@server/types/models' 18} from '@server/types/models'
15import { HttpStatusCode, UserRight } from '@shared/models' 19import { HttpStatusCode, UserRight } from '@shared/models'
16 20
@@ -89,6 +93,27 @@ async function doesVideoChannelOfAccountExist (channelId: number, user: MUserAcc
89 return true 93 return true
90} 94}
91 95
96async function checkCanSeeVideoIfPrivate (req: Request, res: Response, video: MVideo, authenticateInQuery = false) {
97 if (!video.requiresAuth()) return true
98
99 const videoWithRights = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.id)
100
101 return checkCanSeePrivateVideo(req, res, videoWithRights, authenticateInQuery)
102}
103
104async function checkCanSeePrivateVideo (req: Request, res: Response, video: MVideoWithRights, authenticateInQuery = false) {
105 await authenticatePromiseIfNeeded(req, res, authenticateInQuery)
106
107 const user = res.locals.oauth ? res.locals.oauth.token.User : null
108
109 // Only the owner or a user that have blocklist rights can see the video
110 if (!user || !user.canGetVideo(video)) {
111 return false
112 }
113
114 return true
115}
116
92function checkUserCanManageVideo (user: MUser, video: MVideoAccountLight, right: UserRight, res: Response, onlyOwned = true) { 117function checkUserCanManageVideo (user: MUser, video: MVideoAccountLight, right: UserRight, res: Response, onlyOwned = true) {
93 // Retrieve the user who did the request 118 // Retrieve the user who did the request
94 if (onlyOwned && video.isOwned() === false) { 119 if (onlyOwned && video.isOwned() === false) {
@@ -120,5 +145,7 @@ export {
120 doesVideoChannelOfAccountExist, 145 doesVideoChannelOfAccountExist,
121 doesVideoExist, 146 doesVideoExist,
122 doesVideoFileOfVideoExist, 147 doesVideoFileOfVideoExist,
123 checkUserCanManageVideo 148 checkUserCanManageVideo,
149 checkCanSeeVideoIfPrivate,
150 checkCanSeePrivateVideo
124} 151}
diff --git a/server/middlewares/validators/videos/video-captions.ts b/server/middlewares/validators/videos/video-captions.ts
index 38321ccf9..4fc4c8ec5 100644
--- a/server/middlewares/validators/videos/video-captions.ts
+++ b/server/middlewares/validators/videos/video-captions.ts
@@ -1,11 +1,18 @@
1import express from 'express' 1import express from 'express'
2import { body, param } from 'express-validator' 2import { body, param } from 'express-validator'
3import { UserRight } from '../../../../shared' 3import { HttpStatusCode, UserRight } from '../../../../shared'
4import { isVideoCaptionFile, isVideoCaptionLanguageValid } from '../../../helpers/custom-validators/video-captions' 4import { isVideoCaptionFile, isVideoCaptionLanguageValid } from '../../../helpers/custom-validators/video-captions'
5import { cleanUpReqFiles } from '../../../helpers/express-utils' 5import { cleanUpReqFiles } from '../../../helpers/express-utils'
6import { logger } from '../../../helpers/logger' 6import { logger } from '../../../helpers/logger'
7import { CONSTRAINTS_FIELDS, MIMETYPES } from '../../../initializers/constants' 7import { CONSTRAINTS_FIELDS, MIMETYPES } from '../../../initializers/constants'
8import { areValidationErrors, checkUserCanManageVideo, doesVideoCaptionExist, doesVideoExist, isValidVideoIdParam } from '../shared' 8import {
9 areValidationErrors,
10 checkCanSeeVideoIfPrivate,
11 checkUserCanManageVideo,
12 doesVideoCaptionExist,
13 doesVideoExist,
14 isValidVideoIdParam
15} from '../shared'
9 16
10const addVideoCaptionValidator = [ 17const addVideoCaptionValidator = [
11 isValidVideoIdParam('videoId'), 18 isValidVideoIdParam('videoId'),
@@ -64,7 +71,16 @@ const listVideoCaptionsValidator = [
64 logger.debug('Checking listVideoCaptions parameters', { parameters: req.params }) 71 logger.debug('Checking listVideoCaptions parameters', { parameters: req.params })
65 72
66 if (areValidationErrors(req, res)) return 73 if (areValidationErrors(req, res)) return
67 if (!await doesVideoExist(req.params.videoId, res, 'id')) return 74 if (!await doesVideoExist(req.params.videoId, res, 'only-video')) return
75
76 const video = res.locals.onlyVideo
77
78 if (!await checkCanSeeVideoIfPrivate(req, res, video)) {
79 return res.fail({
80 status: HttpStatusCode.FORBIDDEN_403,
81 message: 'Cannot list captions of private/internal/blocklisted video'
82 })
83 }
68 84
69 return next() 85 return next()
70 } 86 }
diff --git a/server/middlewares/validators/videos/videos.ts b/server/middlewares/validators/videos/videos.ts
index 3ebdbc33d..782f495e8 100644
--- a/server/middlewares/validators/videos/videos.ts
+++ b/server/middlewares/validators/videos/videos.ts
@@ -51,9 +51,9 @@ import { CONSTRAINTS_FIELDS, OVERVIEWS } from '../../../initializers/constants'
51import { isLocalVideoAccepted } from '../../../lib/moderation' 51import { isLocalVideoAccepted } from '../../../lib/moderation'
52import { Hooks } from '../../../lib/plugins/hooks' 52import { Hooks } from '../../../lib/plugins/hooks'
53import { VideoModel } from '../../../models/video/video' 53import { VideoModel } from '../../../models/video/video'
54import { authenticatePromiseIfNeeded } from '../../auth'
55import { 54import {
56 areValidationErrors, 55 areValidationErrors,
56 checkCanSeePrivateVideo,
57 checkUserCanManageVideo, 57 checkUserCanManageVideo,
58 doesVideoChannelOfAccountExist, 58 doesVideoChannelOfAccountExist,
59 doesVideoExist, 59 doesVideoExist,
@@ -317,19 +317,12 @@ const videosCustomGetValidator = (
317 317
318 // Video private or blacklisted 318 // Video private or blacklisted
319 if (video.requiresAuth()) { 319 if (video.requiresAuth()) {
320 await authenticatePromiseIfNeeded(req, res, authenticateInQuery) 320 if (await checkCanSeePrivateVideo(req, res, video, authenticateInQuery)) return next()
321 321
322 const user = res.locals.oauth ? res.locals.oauth.token.User : null 322 return res.fail({
323 323 status: HttpStatusCode.FORBIDDEN_403,
324 // Only the owner or a user that have blocklist rights can see the video 324 message: 'Cannot get this private/internal or blocklisted video'
325 if (!user || !user.canGetVideo(video)) { 325 })
326 return res.fail({
327 status: HttpStatusCode.FORBIDDEN_403,
328 message: 'Cannot get this private/internal or blocklisted video'
329 })
330 }
331
332 return next()
333 } 326 }
334 327
335 // Video is public, anyone can access it 328 // Video is public, anyone can access it