Allow oembed to fetch unlisted videos

pull/4977/head
Chocobozzz 2022-05-02 14:57:37 +02:00
parent 9a0b50ab31
commit b3d9dedcc3
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
2 changed files with 87 additions and 16 deletions

View File

@ -6,7 +6,7 @@ import { VideoPlaylistModel } from '@server/models/video/video-playlist'
import { VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models'
import { HttpStatusCode } from '../../../shared/models/http/http-error-codes'
import { isTestInstance } from '../../helpers/core-utils'
import { isIdOrUUIDValid, toCompleteUUID } from '../../helpers/custom-validators/misc'
import { isIdOrUUIDValid, isUUIDValid, toCompleteUUID } from '../../helpers/custom-validators/misc'
import { logger } from '../../helpers/logger'
import { WEBSERVER } from '../../initializers/constants'
import { areValidationErrors } from './shared'
@ -107,15 +107,18 @@ const oembedValidator = [
})
}
if (video.privacy !== VideoPrivacy.PUBLIC) {
return res.fail({
status: HttpStatusCode.FORBIDDEN_403,
message: 'Video is not public'
})
if (
video.privacy === VideoPrivacy.PUBLIC ||
(video.privacy === VideoPrivacy.UNLISTED && isUUIDValid(elementId) === true)
) {
res.locals.videoAll = video
return next()
}
res.locals.videoAll = video
return next()
return res.fail({
status: HttpStatusCode.FORBIDDEN_403,
message: 'Video is not publicly available'
})
}
// Is playlist
@ -128,15 +131,18 @@ const oembedValidator = [
})
}
if (videoPlaylist.privacy !== VideoPlaylistPrivacy.PUBLIC) {
return res.fail({
status: HttpStatusCode.FORBIDDEN_403,
message: 'Playlist is not public'
})
if (
videoPlaylist.privacy === VideoPlaylistPrivacy.PUBLIC ||
(videoPlaylist.privacy === VideoPlaylistPrivacy.UNLISTED && isUUIDValid(elementId))
) {
res.locals.videoPlaylistSummary = videoPlaylist
return next()
}
res.locals.videoPlaylistSummary = videoPlaylist
return next()
return res.fail({
status: HttpStatusCode.FORBIDDEN_403,
message: 'Playlist is not public'
})
}
]

View File

@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
import 'mocha'
import { HttpStatusCode, VideoCreateResult, VideoPlaylistCreateResult, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models'
import {
cleanupTests,
createSingleServer,
@ -9,12 +10,17 @@ import {
setAccessTokensToServers,
setDefaultVideoChannel
} from '@shared/server-commands'
import { HttpStatusCode, VideoPlaylistPrivacy } from '@shared/models'
describe('Test services API validators', function () {
let server: PeerTubeServer
let playlistUUID: string
let privateVideo: VideoCreateResult
let unlistedVideo: VideoCreateResult
let privatePlaylist: VideoPlaylistCreateResult
let unlistedPlaylist: VideoPlaylistCreateResult
// ---------------------------------------------------------------
before(async function () {
@ -26,6 +32,9 @@ describe('Test services API validators', function () {
server.store.videoCreated = await server.videos.upload({ attributes: { name: 'my super name' } })
privateVideo = await server.videos.quickUpload({ name: 'private', privacy: VideoPrivacy.PRIVATE })
unlistedVideo = await server.videos.quickUpload({ name: 'unlisted', privacy: VideoPrivacy.UNLISTED })
{
const created = await server.playlists.create({
attributes: {
@ -36,6 +45,22 @@ describe('Test services API validators', function () {
})
playlistUUID = created.uuid
privatePlaylist = await server.playlists.create({
attributes: {
displayName: 'private',
privacy: VideoPlaylistPrivacy.PRIVATE,
videoChannelId: server.store.channel.id
}
})
unlistedPlaylist = await server.playlists.create({
attributes: {
displayName: 'unlisted',
privacy: VideoPlaylistPrivacy.UNLISTED,
videoChannelId: server.store.channel.id
}
})
}
})
@ -91,6 +116,46 @@ describe('Test services API validators', function () {
await checkParamEmbed(server, embedUrl, HttpStatusCode.NOT_IMPLEMENTED_501, { format: 'xml' })
})
it('Should fail with a private video', async function () {
const embedUrl = `http://localhost:${server.port}/videos/watch/${privateVideo.uuid}`
await checkParamEmbed(server, embedUrl, HttpStatusCode.FORBIDDEN_403)
})
it('Should fail with an unlisted video with the int id', async function () {
const embedUrl = `http://localhost:${server.port}/videos/watch/${unlistedVideo.id}`
await checkParamEmbed(server, embedUrl, HttpStatusCode.FORBIDDEN_403)
})
it('Should succeed with an unlisted video using the uuid id', async function () {
for (const uuid of [ unlistedVideo.uuid, unlistedVideo.shortUUID ]) {
const embedUrl = `http://localhost:${server.port}/videos/watch/${uuid}`
await checkParamEmbed(server, embedUrl, HttpStatusCode.OK_200)
}
})
it('Should fail with a private playlist', async function () {
const embedUrl = `http://localhost:${server.port}/videos/watch/playlist/${privatePlaylist.uuid}`
await checkParamEmbed(server, embedUrl, HttpStatusCode.FORBIDDEN_403)
})
it('Should fail with an unlisted playlist using the int id', async function () {
const embedUrl = `http://localhost:${server.port}/videos/watch/playlist/${unlistedPlaylist.id}`
await checkParamEmbed(server, embedUrl, HttpStatusCode.FORBIDDEN_403)
})
it('Should succeed with an unlisted playlist using the uuid id', async function () {
for (const uuid of [ unlistedPlaylist.uuid, unlistedPlaylist.shortUUID ]) {
const embedUrl = `http://localhost:${server.port}/videos/watch/playlist/${uuid}`
await checkParamEmbed(server, embedUrl, HttpStatusCode.OK_200)
}
})
it('Should succeed with the correct params with a video', async function () {
const embedUrl = `http://localhost:${server.port}/videos/watch/${server.store.videoCreated.uuid}`
const query = {