Fix private video download

This commit is contained in:
Chocobozzz 2019-12-03 10:41:23 +01:00
parent 3f6b7aa1cf
commit eccf70f020
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
4 changed files with 24 additions and 16 deletions

View File

@ -2,7 +2,8 @@ import { Component, ElementRef, ViewChild } from '@angular/core'
import { VideoDetails } from '../../../shared/video/video-details.model' import { VideoDetails } from '../../../shared/video/video-details.model'
import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { I18n } from '@ngx-translate/i18n-polyfill' import { I18n } from '@ngx-translate/i18n-polyfill'
import { Notifier } from '@app/core' import { AuthService, Notifier } from '@app/core'
import { VideoPrivacy } from '@shared/models'
@Component({ @Component({
selector: 'my-video-download', selector: 'my-video-download',
@ -21,6 +22,7 @@ export class VideoDownloadComponent {
constructor ( constructor (
private notifier: Notifier, private notifier: Notifier,
private modalService: NgbModal, private modalService: NgbModal,
private auth: AuthService,
private i18n: I18n private i18n: I18n
) { } ) { }
@ -57,12 +59,16 @@ export class VideoDownloadComponent {
return return
} }
const suffix = this.video.privacy.id === VideoPrivacy.PRIVATE
? '?access_token=' + this.auth.getAccessToken()
: ''
switch (this.downloadType) { switch (this.downloadType) {
case 'direct': case 'direct':
return file.fileDownloadUrl return file.fileDownloadUrl + suffix
case 'torrent': case 'torrent':
return file.torrentDownloadUrl return file.torrentDownloadUrl + suffix
} }
} }

View File

@ -10,7 +10,7 @@ import {
WEBSERVER WEBSERVER
} from '../initializers/constants' } from '../initializers/constants'
import { cacheRoute } from '../middlewares/cache' import { cacheRoute } from '../middlewares/cache'
import { asyncMiddleware, videosGetValidator } from '../middlewares' import { asyncMiddleware, videosDownloadValidator } from '../middlewares'
import { VideoModel } from '../models/video/video' import { VideoModel } from '../models/video/video'
import { UserModel } from '../models/account/user' import { UserModel } from '../models/account/user'
import { VideoCommentModel } from '../models/video/video-comment' import { VideoCommentModel } from '../models/video/video-comment'
@ -39,12 +39,12 @@ staticRouter.use(
) )
staticRouter.use( staticRouter.use(
STATIC_DOWNLOAD_PATHS.TORRENTS + ':id-:resolution([0-9]+).torrent', STATIC_DOWNLOAD_PATHS.TORRENTS + ':id-:resolution([0-9]+).torrent',
asyncMiddleware(videosGetValidator), asyncMiddleware(videosDownloadValidator),
asyncMiddleware(downloadTorrent) asyncMiddleware(downloadTorrent)
) )
staticRouter.use( staticRouter.use(
STATIC_DOWNLOAD_PATHS.TORRENTS + ':id-:resolution([0-9]+)-hls.torrent', STATIC_DOWNLOAD_PATHS.TORRENTS + ':id-:resolution([0-9]+)-hls.torrent',
asyncMiddleware(videosGetValidator), asyncMiddleware(videosDownloadValidator),
asyncMiddleware(downloadHLSVideoFileTorrent) asyncMiddleware(downloadHLSVideoFileTorrent)
) )
@ -62,13 +62,13 @@ staticRouter.use(
staticRouter.use( staticRouter.use(
STATIC_DOWNLOAD_PATHS.VIDEOS + ':id-:resolution([0-9]+).:extension', STATIC_DOWNLOAD_PATHS.VIDEOS + ':id-:resolution([0-9]+).:extension',
asyncMiddleware(videosGetValidator), asyncMiddleware(videosDownloadValidator),
asyncMiddleware(downloadVideoFile) asyncMiddleware(downloadVideoFile)
) )
staticRouter.use( staticRouter.use(
STATIC_DOWNLOAD_PATHS.HLS_VIDEOS + ':id-:resolution([0-9]+)-fragmented.:extension', STATIC_DOWNLOAD_PATHS.HLS_VIDEOS + ':id-:resolution([0-9]+)-fragmented.:extension',
asyncMiddleware(videosGetValidator), asyncMiddleware(videosDownloadValidator),
asyncMiddleware(downloadHLSVideoFile) asyncMiddleware(downloadHLSVideoFile)
) )

View File

@ -12,8 +12,10 @@ const oAuthServer = new OAuthServer({
model: require('../lib/oauth-model') model: require('../lib/oauth-model')
}) })
function authenticate (req: express.Request, res: express.Response, next: express.NextFunction) { function authenticate (req: express.Request, res: express.Response, next: express.NextFunction, authenticateInQuery = false) {
oAuthServer.authenticate()(req, res, err => { const options = authenticateInQuery ? { allowBearerTokensInQueryString: true } : {}
oAuthServer.authenticate(options)(req, res, err => {
if (err) { if (err) {
logger.warn('Cannot authenticate.', { err }) logger.warn('Cannot authenticate.', { err })
@ -50,16 +52,14 @@ function authenticateSocket (socket: Socket, next: (err?: any) => void) {
}) })
} }
function authenticatePromiseIfNeeded (req: express.Request, res: express.Response) { function authenticatePromiseIfNeeded (req: express.Request, res: express.Response, authenticateInQuery = false) {
return new Promise(resolve => { return new Promise(resolve => {
// Already authenticated? (or tried to) // Already authenticated? (or tried to)
if (res.locals.oauth && res.locals.oauth.token.User) return resolve() if (res.locals.oauth && res.locals.oauth.token.User) return resolve()
if (res.locals.authenticated === false) return res.sendStatus(401) if (res.locals.authenticated === false) return res.sendStatus(401)
authenticate(req, res, () => { authenticate(req, res, () => resolve(), authenticateInQuery)
return resolve()
})
}) })
} }

View File

@ -147,7 +147,7 @@ async function checkVideoFollowConstraints (req: express.Request, res: express.R
}) })
} }
const videosCustomGetValidator = (fetchType: 'all' | 'only-video' | 'only-video-with-rights') => { const videosCustomGetValidator = (fetchType: 'all' | 'only-video' | 'only-video-with-rights', authenticateInQuery = false) => {
return [ return [
param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
@ -162,7 +162,7 @@ const videosCustomGetValidator = (fetchType: 'all' | 'only-video' | 'only-video-
// Video private or blacklisted // Video private or blacklisted
if (video.privacy === VideoPrivacy.PRIVATE || videoAll.VideoBlacklist) { if (video.privacy === VideoPrivacy.PRIVATE || videoAll.VideoBlacklist) {
await authenticatePromiseIfNeeded(req, res) await authenticatePromiseIfNeeded(req, res, authenticateInQuery)
const user = res.locals.oauth ? res.locals.oauth.token.User : null const user = res.locals.oauth ? res.locals.oauth.token.User : null
@ -193,6 +193,7 @@ const videosCustomGetValidator = (fetchType: 'all' | 'only-video' | 'only-video-
} }
const videosGetValidator = videosCustomGetValidator('all') const videosGetValidator = videosCustomGetValidator('all')
const videosDownloadValidator = videosCustomGetValidator('all', true)
const videosRemoveValidator = [ const videosRemoveValidator = [
param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
@ -407,6 +408,7 @@ export {
videosAddValidator, videosAddValidator,
videosUpdateValidator, videosUpdateValidator,
videosGetValidator, videosGetValidator,
videosDownloadValidator,
checkVideoFollowConstraints, checkVideoFollowConstraints,
videosCustomGetValidator, videosCustomGetValidator,
videosRemoveValidator, videosRemoveValidator,