diff options
author | Chocobozzz <me@florianbigard.com> | 2022-05-02 14:57:37 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2022-05-02 15:14:23 +0200 |
commit | b3d9dedcc36a333bae0bafe92eeede1a11796ce7 (patch) | |
tree | 9b3e03d7843aa902d4299fb2b4639debcdc3a33c | |
parent | 9a0b50ab31a9218082e3350fa2c231fea7919066 (diff) | |
download | PeerTube-b3d9dedcc36a333bae0bafe92eeede1a11796ce7.tar.gz PeerTube-b3d9dedcc36a333bae0bafe92eeede1a11796ce7.tar.zst PeerTube-b3d9dedcc36a333bae0bafe92eeede1a11796ce7.zip |
Allow oembed to fetch unlisted videos
-rw-r--r-- | server/middlewares/validators/oembed.ts | 36 | ||||
-rw-r--r-- | server/tests/api/check-params/services.ts | 67 |
2 files changed, 87 insertions, 16 deletions
diff --git a/server/middlewares/validators/oembed.ts b/server/middlewares/validators/oembed.ts index 32dd05271..fc1a294e0 100644 --- a/server/middlewares/validators/oembed.ts +++ b/server/middlewares/validators/oembed.ts | |||
@@ -6,7 +6,7 @@ import { VideoPlaylistModel } from '@server/models/video/video-playlist' | |||
6 | import { VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models' | 6 | import { VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models' |
7 | import { HttpStatusCode } from '../../../shared/models/http/http-error-codes' | 7 | import { HttpStatusCode } from '../../../shared/models/http/http-error-codes' |
8 | import { isTestInstance } from '../../helpers/core-utils' | 8 | import { isTestInstance } from '../../helpers/core-utils' |
9 | import { isIdOrUUIDValid, toCompleteUUID } from '../../helpers/custom-validators/misc' | 9 | import { isIdOrUUIDValid, isUUIDValid, toCompleteUUID } from '../../helpers/custom-validators/misc' |
10 | import { logger } from '../../helpers/logger' | 10 | import { logger } from '../../helpers/logger' |
11 | import { WEBSERVER } from '../../initializers/constants' | 11 | import { WEBSERVER } from '../../initializers/constants' |
12 | import { areValidationErrors } from './shared' | 12 | import { areValidationErrors } from './shared' |
@@ -107,15 +107,18 @@ const oembedValidator = [ | |||
107 | }) | 107 | }) |
108 | } | 108 | } |
109 | 109 | ||
110 | if (video.privacy !== VideoPrivacy.PUBLIC) { | 110 | if ( |
111 | return res.fail({ | 111 | video.privacy === VideoPrivacy.PUBLIC || |
112 | status: HttpStatusCode.FORBIDDEN_403, | 112 | (video.privacy === VideoPrivacy.UNLISTED && isUUIDValid(elementId) === true) |
113 | message: 'Video is not public' | 113 | ) { |
114 | }) | 114 | res.locals.videoAll = video |
115 | return next() | ||
115 | } | 116 | } |
116 | 117 | ||
117 | res.locals.videoAll = video | 118 | return res.fail({ |
118 | return next() | 119 | status: HttpStatusCode.FORBIDDEN_403, |
120 | message: 'Video is not publicly available' | ||
121 | }) | ||
119 | } | 122 | } |
120 | 123 | ||
121 | // Is playlist | 124 | // Is playlist |
@@ -128,15 +131,18 @@ const oembedValidator = [ | |||
128 | }) | 131 | }) |
129 | } | 132 | } |
130 | 133 | ||
131 | if (videoPlaylist.privacy !== VideoPlaylistPrivacy.PUBLIC) { | 134 | if ( |
132 | return res.fail({ | 135 | videoPlaylist.privacy === VideoPlaylistPrivacy.PUBLIC || |
133 | status: HttpStatusCode.FORBIDDEN_403, | 136 | (videoPlaylist.privacy === VideoPlaylistPrivacy.UNLISTED && isUUIDValid(elementId)) |
134 | message: 'Playlist is not public' | 137 | ) { |
135 | }) | 138 | res.locals.videoPlaylistSummary = videoPlaylist |
139 | return next() | ||
136 | } | 140 | } |
137 | 141 | ||
138 | res.locals.videoPlaylistSummary = videoPlaylist | 142 | return res.fail({ |
139 | return next() | 143 | status: HttpStatusCode.FORBIDDEN_403, |
144 | message: 'Playlist is not public' | ||
145 | }) | ||
140 | } | 146 | } |
141 | 147 | ||
142 | ] | 148 | ] |
diff --git a/server/tests/api/check-params/services.ts b/server/tests/api/check-params/services.ts index e63f09884..5d1713e03 100644 --- a/server/tests/api/check-params/services.ts +++ b/server/tests/api/check-params/services.ts | |||
@@ -1,6 +1,7 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | 2 | ||
3 | import 'mocha' | 3 | import 'mocha' |
4 | import { HttpStatusCode, VideoCreateResult, VideoPlaylistCreateResult, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models' | ||
4 | import { | 5 | import { |
5 | cleanupTests, | 6 | cleanupTests, |
6 | createSingleServer, | 7 | createSingleServer, |
@@ -9,12 +10,17 @@ import { | |||
9 | setAccessTokensToServers, | 10 | setAccessTokensToServers, |
10 | setDefaultVideoChannel | 11 | setDefaultVideoChannel |
11 | } from '@shared/server-commands' | 12 | } from '@shared/server-commands' |
12 | import { HttpStatusCode, VideoPlaylistPrivacy } from '@shared/models' | ||
13 | 13 | ||
14 | describe('Test services API validators', function () { | 14 | describe('Test services API validators', function () { |
15 | let server: PeerTubeServer | 15 | let server: PeerTubeServer |
16 | let playlistUUID: string | 16 | let playlistUUID: string |
17 | 17 | ||
18 | let privateVideo: VideoCreateResult | ||
19 | let unlistedVideo: VideoCreateResult | ||
20 | |||
21 | let privatePlaylist: VideoPlaylistCreateResult | ||
22 | let unlistedPlaylist: VideoPlaylistCreateResult | ||
23 | |||
18 | // --------------------------------------------------------------- | 24 | // --------------------------------------------------------------- |
19 | 25 | ||
20 | before(async function () { | 26 | before(async function () { |
@@ -26,6 +32,9 @@ describe('Test services API validators', function () { | |||
26 | 32 | ||
27 | server.store.videoCreated = await server.videos.upload({ attributes: { name: 'my super name' } }) | 33 | server.store.videoCreated = await server.videos.upload({ attributes: { name: 'my super name' } }) |
28 | 34 | ||
35 | privateVideo = await server.videos.quickUpload({ name: 'private', privacy: VideoPrivacy.PRIVATE }) | ||
36 | unlistedVideo = await server.videos.quickUpload({ name: 'unlisted', privacy: VideoPrivacy.UNLISTED }) | ||
37 | |||
29 | { | 38 | { |
30 | const created = await server.playlists.create({ | 39 | const created = await server.playlists.create({ |
31 | attributes: { | 40 | attributes: { |
@@ -36,6 +45,22 @@ describe('Test services API validators', function () { | |||
36 | }) | 45 | }) |
37 | 46 | ||
38 | playlistUUID = created.uuid | 47 | playlistUUID = created.uuid |
48 | |||
49 | privatePlaylist = await server.playlists.create({ | ||
50 | attributes: { | ||
51 | displayName: 'private', | ||
52 | privacy: VideoPlaylistPrivacy.PRIVATE, | ||
53 | videoChannelId: server.store.channel.id | ||
54 | } | ||
55 | }) | ||
56 | |||
57 | unlistedPlaylist = await server.playlists.create({ | ||
58 | attributes: { | ||
59 | displayName: 'unlisted', | ||
60 | privacy: VideoPlaylistPrivacy.UNLISTED, | ||
61 | videoChannelId: server.store.channel.id | ||
62 | } | ||
63 | }) | ||
39 | } | 64 | } |
40 | }) | 65 | }) |
41 | 66 | ||
@@ -91,6 +116,46 @@ describe('Test services API validators', function () { | |||
91 | await checkParamEmbed(server, embedUrl, HttpStatusCode.NOT_IMPLEMENTED_501, { format: 'xml' }) | 116 | await checkParamEmbed(server, embedUrl, HttpStatusCode.NOT_IMPLEMENTED_501, { format: 'xml' }) |
92 | }) | 117 | }) |
93 | 118 | ||
119 | it('Should fail with a private video', async function () { | ||
120 | const embedUrl = `http://localhost:${server.port}/videos/watch/${privateVideo.uuid}` | ||
121 | |||
122 | await checkParamEmbed(server, embedUrl, HttpStatusCode.FORBIDDEN_403) | ||
123 | }) | ||
124 | |||
125 | it('Should fail with an unlisted video with the int id', async function () { | ||
126 | const embedUrl = `http://localhost:${server.port}/videos/watch/${unlistedVideo.id}` | ||
127 | |||
128 | await checkParamEmbed(server, embedUrl, HttpStatusCode.FORBIDDEN_403) | ||
129 | }) | ||
130 | |||
131 | it('Should succeed with an unlisted video using the uuid id', async function () { | ||
132 | for (const uuid of [ unlistedVideo.uuid, unlistedVideo.shortUUID ]) { | ||
133 | const embedUrl = `http://localhost:${server.port}/videos/watch/${uuid}` | ||
134 | |||
135 | await checkParamEmbed(server, embedUrl, HttpStatusCode.OK_200) | ||
136 | } | ||
137 | }) | ||
138 | |||
139 | it('Should fail with a private playlist', async function () { | ||
140 | const embedUrl = `http://localhost:${server.port}/videos/watch/playlist/${privatePlaylist.uuid}` | ||
141 | |||
142 | await checkParamEmbed(server, embedUrl, HttpStatusCode.FORBIDDEN_403) | ||
143 | }) | ||
144 | |||
145 | it('Should fail with an unlisted playlist using the int id', async function () { | ||
146 | const embedUrl = `http://localhost:${server.port}/videos/watch/playlist/${unlistedPlaylist.id}` | ||
147 | |||
148 | await checkParamEmbed(server, embedUrl, HttpStatusCode.FORBIDDEN_403) | ||
149 | }) | ||
150 | |||
151 | it('Should succeed with an unlisted playlist using the uuid id', async function () { | ||
152 | for (const uuid of [ unlistedPlaylist.uuid, unlistedPlaylist.shortUUID ]) { | ||
153 | const embedUrl = `http://localhost:${server.port}/videos/watch/playlist/${uuid}` | ||
154 | |||
155 | await checkParamEmbed(server, embedUrl, HttpStatusCode.OK_200) | ||
156 | } | ||
157 | }) | ||
158 | |||
94 | it('Should succeed with the correct params with a video', async function () { | 159 | it('Should succeed with the correct params with a video', async function () { |
95 | const embedUrl = `http://localhost:${server.port}/videos/watch/${server.store.videoCreated.uuid}` | 160 | const embedUrl = `http://localhost:${server.port}/videos/watch/${server.store.videoCreated.uuid}` |
96 | const query = { | 161 | const query = { |