diff options
Diffstat (limited to 'server/tests')
-rw-r--r-- | server/tests/api/object-storage/video-static-file-privacy.ts | 36 | ||||
-rw-r--r-- | server/tests/api/videos/video-static-file-privacy.ts | 61 | ||||
-rw-r--r-- | server/tests/shared/checks.ts | 7 | ||||
-rw-r--r-- | server/tests/shared/index.ts | 2 | ||||
-rw-r--r-- | server/tests/shared/streaming-playlists.ts | 50 | ||||
-rw-r--r-- | server/tests/shared/video-playlists.ts (renamed from server/tests/shared/playlists.ts) | 0 |
6 files changed, 151 insertions, 5 deletions
diff --git a/server/tests/api/object-storage/video-static-file-privacy.ts b/server/tests/api/object-storage/video-static-file-privacy.ts index 62edd10ba..71ad35a43 100644 --- a/server/tests/api/object-storage/video-static-file-privacy.ts +++ b/server/tests/api/object-storage/video-static-file-privacy.ts | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { basename } from 'path' | 4 | import { basename } from 'path' |
5 | import { expectStartWith } from '@server/tests/shared' | 5 | import { checkVideoFileTokenReinjection, expectStartWith } from '@server/tests/shared' |
6 | import { areScalewayObjectStorageTestsDisabled, getAllFiles, getHLS } from '@shared/core-utils' | 6 | import { areScalewayObjectStorageTestsDisabled, getAllFiles, getHLS } from '@shared/core-utils' |
7 | import { HttpStatusCode, LiveVideo, VideoDetails, VideoPrivacy } from '@shared/models' | 7 | import { HttpStatusCode, LiveVideo, VideoDetails, VideoPrivacy } from '@shared/models' |
8 | import { | 8 | import { |
@@ -191,6 +191,20 @@ describe('Object storage for video static file privacy', function () { | |||
191 | } | 191 | } |
192 | }) | 192 | }) |
193 | 193 | ||
194 | it('Should reinject video file token', async function () { | ||
195 | this.timeout(120000) | ||
196 | |||
197 | const videoFileToken = await server.videoToken.getVideoFileToken({ videoId: privateVideoUUID }) | ||
198 | |||
199 | await checkVideoFileTokenReinjection({ | ||
200 | server, | ||
201 | videoUUID: privateVideoUUID, | ||
202 | videoFileToken, | ||
203 | resolutions: [ 240, 720 ], | ||
204 | isLive: false | ||
205 | }) | ||
206 | }) | ||
207 | |||
194 | it('Should update public video to private', async function () { | 208 | it('Should update public video to private', async function () { |
195 | this.timeout(60000) | 209 | this.timeout(60000) |
196 | 210 | ||
@@ -315,6 +329,26 @@ describe('Object storage for video static file privacy', function () { | |||
315 | await checkLiveFiles(permanentLive, permanentLiveId) | 329 | await checkLiveFiles(permanentLive, permanentLiveId) |
316 | }) | 330 | }) |
317 | 331 | ||
332 | it('Should reinject video file token in permanent live', async function () { | ||
333 | this.timeout(240000) | ||
334 | |||
335 | const ffmpegCommand = sendRTMPStream({ rtmpBaseUrl: permanentLive.rtmpUrl, streamKey: permanentLive.streamKey }) | ||
336 | await server.live.waitUntilPublished({ videoId: permanentLiveId }) | ||
337 | |||
338 | const video = await server.videos.getWithToken({ id: permanentLiveId }) | ||
339 | const videoFileToken = await server.videoToken.getVideoFileToken({ videoId: video.uuid }) | ||
340 | |||
341 | await checkVideoFileTokenReinjection({ | ||
342 | server, | ||
343 | videoUUID: permanentLiveId, | ||
344 | videoFileToken, | ||
345 | resolutions: [ 720 ], | ||
346 | isLive: true | ||
347 | }) | ||
348 | |||
349 | await stopFfmpeg(ffmpegCommand) | ||
350 | }) | ||
351 | |||
318 | it('Should have created a replay of the normal live with a private static path', async function () { | 352 | it('Should have created a replay of the normal live with a private static path', async function () { |
319 | this.timeout(240000) | 353 | this.timeout(240000) |
320 | 354 | ||
diff --git a/server/tests/api/videos/video-static-file-privacy.ts b/server/tests/api/videos/video-static-file-privacy.ts index eaaed5aad..ef0774b41 100644 --- a/server/tests/api/videos/video-static-file-privacy.ts +++ b/server/tests/api/videos/video-static-file-privacy.ts | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { decode } from 'magnet-uri' | 4 | import { decode } from 'magnet-uri' |
5 | import { expectStartWith } from '@server/tests/shared' | 5 | import { checkVideoFileTokenReinjection, expectStartWith } from '@server/tests/shared' |
6 | import { getAllFiles, wait } from '@shared/core-utils' | 6 | import { getAllFiles, wait } from '@shared/core-utils' |
7 | import { HttpStatusCode, LiveVideo, VideoDetails, VideoPrivacy } from '@shared/models' | 7 | import { HttpStatusCode, LiveVideo, VideoDetails, VideoPrivacy } from '@shared/models' |
8 | import { | 8 | import { |
@@ -248,6 +248,35 @@ describe('Test video static file privacy', function () { | |||
248 | await checkVideoFiles({ id: uuid, expectedStatus: HttpStatusCode.OK_200, token: server.accessToken, videoFileToken }) | 248 | await checkVideoFiles({ id: uuid, expectedStatus: HttpStatusCode.OK_200, token: server.accessToken, videoFileToken }) |
249 | }) | 249 | }) |
250 | 250 | ||
251 | it('Should reinject video file token', async function () { | ||
252 | this.timeout(120000) | ||
253 | |||
254 | const { uuid } = await server.videos.quickUpload({ name: 'video', privacy: VideoPrivacy.PRIVATE }) | ||
255 | |||
256 | const videoFileToken = await server.videoToken.getVideoFileToken({ videoId: uuid }) | ||
257 | await waitJobs([ server ]) | ||
258 | |||
259 | const video = await server.videos.getWithToken({ id: uuid }) | ||
260 | const hls = video.streamingPlaylists[0] | ||
261 | |||
262 | { | ||
263 | const query = { videoFileToken } | ||
264 | const { text } = await makeRawRequest({ url: hls.playlistUrl, query, expectedStatus: HttpStatusCode.OK_200 }) | ||
265 | |||
266 | expect(text).to.not.include(videoFileToken) | ||
267 | } | ||
268 | |||
269 | { | ||
270 | await checkVideoFileTokenReinjection({ | ||
271 | server, | ||
272 | videoUUID: uuid, | ||
273 | videoFileToken, | ||
274 | resolutions: [ 240, 720 ], | ||
275 | isLive: false | ||
276 | }) | ||
277 | } | ||
278 | }) | ||
279 | |||
251 | it('Should be able to access a private video of another user with an admin OAuth token or file token', async function () { | 280 | it('Should be able to access a private video of another user with an admin OAuth token or file token', async function () { |
252 | this.timeout(120000) | 281 | this.timeout(120000) |
253 | 282 | ||
@@ -360,6 +389,36 @@ describe('Test video static file privacy', function () { | |||
360 | await checkLiveFiles(permanentLive, permanentLiveId) | 389 | await checkLiveFiles(permanentLive, permanentLiveId) |
361 | }) | 390 | }) |
362 | 391 | ||
392 | it('Should reinject video file token on permanent live', async function () { | ||
393 | this.timeout(240000) | ||
394 | |||
395 | const ffmpegCommand = sendRTMPStream({ rtmpBaseUrl: permanentLive.rtmpUrl, streamKey: permanentLive.streamKey }) | ||
396 | await server.live.waitUntilPublished({ videoId: permanentLiveId }) | ||
397 | |||
398 | const video = await server.videos.getWithToken({ id: permanentLiveId }) | ||
399 | const videoFileToken = await server.videoToken.getVideoFileToken({ videoId: video.uuid }) | ||
400 | const hls = video.streamingPlaylists[0] | ||
401 | |||
402 | { | ||
403 | const query = { videoFileToken } | ||
404 | const { text } = await makeRawRequest({ url: hls.playlistUrl, query, expectedStatus: HttpStatusCode.OK_200 }) | ||
405 | |||
406 | expect(text).to.not.include(videoFileToken) | ||
407 | } | ||
408 | |||
409 | { | ||
410 | await checkVideoFileTokenReinjection({ | ||
411 | server, | ||
412 | videoUUID: permanentLiveId, | ||
413 | videoFileToken, | ||
414 | resolutions: [ 720 ], | ||
415 | isLive: true | ||
416 | }) | ||
417 | } | ||
418 | |||
419 | await stopFfmpeg(ffmpegCommand) | ||
420 | }) | ||
421 | |||
363 | it('Should have created a replay of the normal live with a private static path', async function () { | 422 | it('Should have created a replay of the normal live with a private static path', async function () { |
364 | this.timeout(240000) | 423 | this.timeout(240000) |
365 | 424 | ||
diff --git a/server/tests/shared/checks.ts b/server/tests/shared/checks.ts index 55ebc6c3e..523d37420 100644 --- a/server/tests/shared/checks.ts +++ b/server/tests/shared/checks.ts | |||
@@ -23,6 +23,12 @@ function expectNotStartWith (str: string, start: string) { | |||
23 | expect(str.startsWith(start), `${str} does not start with ${start}`).to.be.false | 23 | expect(str.startsWith(start), `${str} does not start with ${start}`).to.be.false |
24 | } | 24 | } |
25 | 25 | ||
26 | function expectEndWith (str: string, end: string) { | ||
27 | expect(str.endsWith(end), `${str} does not end with ${end}`).to.be.true | ||
28 | } | ||
29 | |||
30 | // --------------------------------------------------------------------------- | ||
31 | |||
26 | async function expectLogDoesNotContain (server: PeerTubeServer, str: string) { | 32 | async function expectLogDoesNotContain (server: PeerTubeServer, str: string) { |
27 | const content = await server.servers.getLogContent() | 33 | const content = await server.servers.getLogContent() |
28 | 34 | ||
@@ -103,6 +109,7 @@ export { | |||
103 | testFileExistsOrNot, | 109 | testFileExistsOrNot, |
104 | expectStartWith, | 110 | expectStartWith, |
105 | expectNotStartWith, | 111 | expectNotStartWith, |
112 | expectEndWith, | ||
106 | checkBadStartPagination, | 113 | checkBadStartPagination, |
107 | checkBadCountPagination, | 114 | checkBadCountPagination, |
108 | checkBadSortPagination, | 115 | checkBadSortPagination, |
diff --git a/server/tests/shared/index.ts b/server/tests/shared/index.ts index 9f7ade53d..963ef8fe6 100644 --- a/server/tests/shared/index.ts +++ b/server/tests/shared/index.ts | |||
@@ -6,7 +6,7 @@ export * from './directories' | |||
6 | export * from './generate' | 6 | export * from './generate' |
7 | export * from './live' | 7 | export * from './live' |
8 | export * from './notifications' | 8 | export * from './notifications' |
9 | export * from './playlists' | 9 | export * from './video-playlists' |
10 | export * from './plugins' | 10 | export * from './plugins' |
11 | export * from './requests' | 11 | export * from './requests' |
12 | export * from './streaming-playlists' | 12 | export * from './streaming-playlists' |
diff --git a/server/tests/shared/streaming-playlists.ts b/server/tests/shared/streaming-playlists.ts index 824c3dcef..5c62af812 100644 --- a/server/tests/shared/streaming-playlists.ts +++ b/server/tests/shared/streaming-playlists.ts | |||
@@ -1,7 +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 { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { basename } from 'path' | 4 | import { basename, dirname, join } from 'path' |
5 | import { removeFragmentedMP4Ext, uuidRegex } from '@shared/core-utils' | 5 | import { removeFragmentedMP4Ext, uuidRegex } from '@shared/core-utils' |
6 | import { sha256 } from '@shared/extra-utils' | 6 | import { sha256 } from '@shared/extra-utils' |
7 | import { HttpStatusCode, VideoStreamingPlaylist, VideoStreamingPlaylistType } from '@shared/models' | 7 | import { HttpStatusCode, VideoStreamingPlaylist, VideoStreamingPlaylistType } from '@shared/models' |
@@ -188,9 +188,55 @@ async function completeCheckHlsPlaylist (options: { | |||
188 | } | 188 | } |
189 | } | 189 | } |
190 | 190 | ||
191 | async function checkVideoFileTokenReinjection (options: { | ||
192 | server: PeerTubeServer | ||
193 | videoUUID: string | ||
194 | videoFileToken: string | ||
195 | resolutions: number[] | ||
196 | isLive: boolean | ||
197 | }) { | ||
198 | const { server, resolutions, videoFileToken, videoUUID, isLive } = options | ||
199 | |||
200 | const video = await server.videos.getWithToken({ id: videoUUID }) | ||
201 | const hls = video.streamingPlaylists[0] | ||
202 | |||
203 | const query = { videoFileToken, reinjectVideoFileToken: 'true' } | ||
204 | const { text } = await makeRawRequest({ url: hls.playlistUrl, query, expectedStatus: HttpStatusCode.OK_200 }) | ||
205 | |||
206 | for (let i = 0; i < resolutions.length; i++) { | ||
207 | const resolution = resolutions[i] | ||
208 | |||
209 | const suffix = isLive | ||
210 | ? i | ||
211 | : `-${resolution}` | ||
212 | |||
213 | expect(text).to.contain(`${suffix}.m3u8?videoFileToken=${videoFileToken}`) | ||
214 | } | ||
215 | |||
216 | const resolutionPlaylists = extractResolutionPlaylistUrls(hls.playlistUrl, text) | ||
217 | expect(resolutionPlaylists).to.have.lengthOf(resolutions.length) | ||
218 | |||
219 | for (const url of resolutionPlaylists) { | ||
220 | const { text } = await makeRawRequest({ url, query, expectedStatus: HttpStatusCode.OK_200 }) | ||
221 | |||
222 | const extension = isLive | ||
223 | ? '.ts' | ||
224 | : '.mp4' | ||
225 | |||
226 | expect(text).to.contain(`${extension}?videoFileToken=${videoFileToken}`) | ||
227 | } | ||
228 | } | ||
229 | |||
230 | function extractResolutionPlaylistUrls (masterPath: string, masterContent: string) { | ||
231 | return masterContent.match(/^([^.]+\.m3u8.*)/mg) | ||
232 | .map(filename => join(dirname(masterPath), filename)) | ||
233 | } | ||
234 | |||
191 | export { | 235 | export { |
192 | checkSegmentHash, | 236 | checkSegmentHash, |
193 | checkLiveSegmentHash, | 237 | checkLiveSegmentHash, |
194 | checkResolutionsInMasterPlaylist, | 238 | checkResolutionsInMasterPlaylist, |
195 | completeCheckHlsPlaylist | 239 | completeCheckHlsPlaylist, |
240 | extractResolutionPlaylistUrls, | ||
241 | checkVideoFileTokenReinjection | ||
196 | } | 242 | } |
diff --git a/server/tests/shared/playlists.ts b/server/tests/shared/video-playlists.ts index 8db303fd8..8db303fd8 100644 --- a/server/tests/shared/playlists.ts +++ b/server/tests/shared/video-playlists.ts | |||