"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const chai_1 = require("chai");
const path_1 = require("path");
const shared_1 = require("../../shared");
const core_utils_1 = require("../../../../shared/core-utils");
const server_commands_1 = require("../../../../shared/server-commands");
function extractFilenameFromUrl(url) {
    const parts = (0, path_1.basename)(url).split(':');
    return parts[parts.length - 1];
}
describe('Object storage for video static file privacy', function () {
    if ((0, core_utils_1.areScalewayObjectStorageTestsDisabled)())
        return;
    let server;
    let userToken;
    function checkPrivateVODFiles(uuid) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const video = yield server.videos.getWithToken({ id: uuid });
            for (const file of video.files) {
                (0, shared_1.expectStartWith)(file.fileUrl, server.url + '/object-storage-proxy/webseed/private/');
                yield (0, server_commands_1.makeRawRequest)({ url: file.fileUrl, token: server.accessToken, expectedStatus: 200 });
            }
            for (const file of (0, core_utils_1.getAllFiles)(video)) {
                const internalFileUrl = yield server.sql.getInternalFileUrl(file.id);
                (0, shared_1.expectStartWith)(internalFileUrl, server_commands_1.ObjectStorageCommand.getScalewayBaseUrl());
                yield (0, server_commands_1.makeRawRequest)({ url: internalFileUrl, token: server.accessToken, expectedStatus: 403 });
            }
            const hls = (0, core_utils_1.getHLS)(video);
            if (hls) {
                for (const url of [hls.playlistUrl, hls.segmentsSha256Url]) {
                    (0, shared_1.expectStartWith)(url, server.url + '/object-storage-proxy/streaming-playlists/hls/private/');
                }
                yield (0, server_commands_1.makeRawRequest)({ url: hls.playlistUrl, token: server.accessToken, expectedStatus: 200 });
                yield (0, server_commands_1.makeRawRequest)({ url: hls.segmentsSha256Url, token: server.accessToken, expectedStatus: 200 });
                for (const file of hls.files) {
                    (0, shared_1.expectStartWith)(file.fileUrl, server.url + '/object-storage-proxy/streaming-playlists/hls/private/');
                    yield (0, server_commands_1.makeRawRequest)({ url: file.fileUrl, token: server.accessToken, expectedStatus: 200 });
                }
            }
        });
    }
    function checkPublicVODFiles(uuid) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const video = yield server.videos.getWithToken({ id: uuid });
            for (const file of (0, core_utils_1.getAllFiles)(video)) {
                (0, shared_1.expectStartWith)(file.fileUrl, server_commands_1.ObjectStorageCommand.getScalewayBaseUrl());
                yield (0, server_commands_1.makeRawRequest)({ url: file.fileUrl, expectedStatus: 200 });
            }
            const hls = (0, core_utils_1.getHLS)(video);
            if (hls) {
                (0, shared_1.expectStartWith)(hls.playlistUrl, server_commands_1.ObjectStorageCommand.getScalewayBaseUrl());
                (0, shared_1.expectStartWith)(hls.segmentsSha256Url, server_commands_1.ObjectStorageCommand.getScalewayBaseUrl());
                yield (0, server_commands_1.makeRawRequest)({ url: hls.playlistUrl, expectedStatus: 200 });
                yield (0, server_commands_1.makeRawRequest)({ url: hls.segmentsSha256Url, expectedStatus: 200 });
            }
        });
    }
    before(function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.timeout(120000);
            server = yield (0, server_commands_1.createSingleServer)(1, server_commands_1.ObjectStorageCommand.getDefaultScalewayConfig({ serverNumber: 1 }));
            yield (0, server_commands_1.setAccessTokensToServers)([server]);
            yield (0, server_commands_1.setDefaultVideoChannel)([server]);
            yield server.config.enableMinimumTranscoding();
            userToken = yield server.users.generateUserAndToken('user1');
        });
    });
    describe('VOD', function () {
        let privateVideoUUID;
        let publicVideoUUID;
        let userPrivateVideoUUID;
        function getSampleFileUrls(videoId) {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                const video = yield server.videos.getWithToken({ id: videoId });
                return {
                    webTorrentFile: video.files[0].fileUrl,
                    hlsFile: (0, core_utils_1.getHLS)(video).files[0].fileUrl
                };
            });
        }
        it('Should upload a private video and have appropriate object storage ACL', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(60000);
                {
                    const { uuid } = yield server.videos.quickUpload({ name: 'video', privacy: 3 });
                    privateVideoUUID = uuid;
                }
                {
                    const { uuid } = yield server.videos.quickUpload({ name: 'user video', token: userToken, privacy: 3 });
                    userPrivateVideoUUID = uuid;
                }
                yield (0, server_commands_1.waitJobs)([server]);
                yield checkPrivateVODFiles(privateVideoUUID);
            });
        });
        it('Should upload a public video and have appropriate object storage ACL', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(60000);
                const { uuid } = yield server.videos.quickUpload({ name: 'video', privacy: 2 });
                yield (0, server_commands_1.waitJobs)([server]);
                publicVideoUUID = uuid;
                yield checkPublicVODFiles(publicVideoUUID);
            });
        });
        it('Should not get files without appropriate OAuth token', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(60000);
                const { webTorrentFile, hlsFile } = yield getSampleFileUrls(privateVideoUUID);
                yield (0, server_commands_1.makeRawRequest)({ url: webTorrentFile, token: userToken, expectedStatus: 403 });
                yield (0, server_commands_1.makeRawRequest)({ url: webTorrentFile, token: server.accessToken, expectedStatus: 200 });
                yield (0, server_commands_1.makeRawRequest)({ url: hlsFile, token: userToken, expectedStatus: 403 });
                yield (0, server_commands_1.makeRawRequest)({ url: hlsFile, token: server.accessToken, expectedStatus: 200 });
            });
        });
        it('Should not get HLS file of another video', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(60000);
                const privateVideo = yield server.videos.getWithToken({ id: privateVideoUUID });
                const hlsFilename = (0, path_1.basename)((0, core_utils_1.getHLS)(privateVideo).files[0].fileUrl);
                const badUrl = server.url + '/object-storage-proxy/streaming-playlists/hls/private/' + userPrivateVideoUUID + '/' + hlsFilename;
                const goodUrl = server.url + '/object-storage-proxy/streaming-playlists/hls/private/' + privateVideoUUID + '/' + hlsFilename;
                yield (0, server_commands_1.makeRawRequest)({ url: badUrl, token: server.accessToken, expectedStatus: 404 });
                yield (0, server_commands_1.makeRawRequest)({ url: goodUrl, token: server.accessToken, expectedStatus: 200 });
            });
        });
        it('Should correctly check OAuth or video file token', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(60000);
                const badVideoFileToken = yield server.videoToken.getVideoFileToken({ token: userToken, videoId: userPrivateVideoUUID });
                const goodVideoFileToken = yield server.videoToken.getVideoFileToken({ videoId: privateVideoUUID });
                const { webTorrentFile, hlsFile } = yield getSampleFileUrls(privateVideoUUID);
                for (const url of [webTorrentFile, hlsFile]) {
                    yield (0, server_commands_1.makeRawRequest)({ url, expectedStatus: 403 });
                    yield (0, server_commands_1.makeRawRequest)({ url, token: userToken, expectedStatus: 403 });
                    yield (0, server_commands_1.makeRawRequest)({ url, token: server.accessToken, expectedStatus: 200 });
                    yield (0, server_commands_1.makeRawRequest)({ url, query: { videoFileToken: badVideoFileToken }, expectedStatus: 403 });
                    yield (0, server_commands_1.makeRawRequest)({ url, query: { videoFileToken: goodVideoFileToken }, expectedStatus: 200 });
                }
            });
        });
        it('Should reinject video file token', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(120000);
                const videoFileToken = yield server.videoToken.getVideoFileToken({ videoId: privateVideoUUID });
                yield (0, shared_1.checkVideoFileTokenReinjection)({
                    server,
                    videoUUID: privateVideoUUID,
                    videoFileToken,
                    resolutions: [240, 720],
                    isLive: false
                });
            });
        });
        it('Should update public video to private', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(60000);
                yield server.videos.update({ id: publicVideoUUID, attributes: { privacy: 4 } });
                yield checkPrivateVODFiles(publicVideoUUID);
            });
        });
        it('Should update private video to public', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(60000);
                yield server.videos.update({ id: publicVideoUUID, attributes: { privacy: 1 } });
                yield checkPublicVODFiles(publicVideoUUID);
            });
        });
    });
    describe('Live', function () {
        let normalLiveId;
        let normalLive;
        let permanentLiveId;
        let permanentLive;
        let unrelatedFileToken;
        function checkLiveFiles(live, liveId) {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                const ffmpegCommand = (0, server_commands_1.sendRTMPStream)({ rtmpBaseUrl: live.rtmpUrl, streamKey: live.streamKey });
                yield server.live.waitUntilPublished({ videoId: liveId });
                const video = yield server.videos.getWithToken({ id: liveId });
                const fileToken = yield server.videoToken.getVideoFileToken({ videoId: video.uuid });
                const hls = video.streamingPlaylists[0];
                for (const url of [hls.playlistUrl, hls.segmentsSha256Url]) {
                    (0, shared_1.expectStartWith)(url, server.url + '/object-storage-proxy/streaming-playlists/hls/private/');
                    yield (0, server_commands_1.makeRawRequest)({ url: hls.playlistUrl, token: server.accessToken, expectedStatus: 200 });
                    yield (0, server_commands_1.makeRawRequest)({ url: hls.segmentsSha256Url, token: server.accessToken, expectedStatus: 200 });
                    yield (0, server_commands_1.makeRawRequest)({ url, token: server.accessToken, expectedStatus: 200 });
                    yield (0, server_commands_1.makeRawRequest)({ url, query: { videoFileToken: fileToken }, expectedStatus: 200 });
                    yield (0, server_commands_1.makeRawRequest)({ url, token: userToken, expectedStatus: 403 });
                    yield (0, server_commands_1.makeRawRequest)({ url, expectedStatus: 403 });
                    yield (0, server_commands_1.makeRawRequest)({ url, query: { videoFileToken: unrelatedFileToken }, expectedStatus: 403 });
                }
                yield (0, server_commands_1.stopFfmpeg)(ffmpegCommand);
            });
        }
        function checkReplay(replay) {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                const fileToken = yield server.videoToken.getVideoFileToken({ videoId: replay.uuid });
                const hls = replay.streamingPlaylists[0];
                (0, chai_1.expect)(hls.files).to.not.have.lengthOf(0);
                for (const file of hls.files) {
                    yield (0, server_commands_1.makeRawRequest)({ url: file.fileUrl, token: server.accessToken, expectedStatus: 200 });
                    yield (0, server_commands_1.makeRawRequest)({ url: file.fileUrl, query: { videoFileToken: fileToken }, expectedStatus: 200 });
                    yield (0, server_commands_1.makeRawRequest)({ url: file.fileUrl, token: userToken, expectedStatus: 403 });
                    yield (0, server_commands_1.makeRawRequest)({ url: file.fileUrl, expectedStatus: 403 });
                    yield (0, server_commands_1.makeRawRequest)({
                        url: file.fileUrl,
                        query: { videoFileToken: unrelatedFileToken },
                        expectedStatus: 403
                    });
                }
                for (const url of [hls.playlistUrl, hls.segmentsSha256Url]) {
                    (0, shared_1.expectStartWith)(url, server.url + '/object-storage-proxy/streaming-playlists/hls/private/');
                    yield (0, server_commands_1.makeRawRequest)({ url, token: server.accessToken, expectedStatus: 200 });
                    yield (0, server_commands_1.makeRawRequest)({ url, query: { videoFileToken: fileToken }, expectedStatus: 200 });
                    yield (0, server_commands_1.makeRawRequest)({ url, token: userToken, expectedStatus: 403 });
                    yield (0, server_commands_1.makeRawRequest)({ url, expectedStatus: 403 });
                    yield (0, server_commands_1.makeRawRequest)({ url, query: { videoFileToken: unrelatedFileToken }, expectedStatus: 403 });
                }
            });
        }
        before(function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                yield server.config.enableMinimumTranscoding();
                const { uuid } = yield server.videos.quickUpload({ name: 'another video' });
                unrelatedFileToken = yield server.videoToken.getVideoFileToken({ videoId: uuid });
                yield server.config.enableLive({
                    allowReplay: true,
                    transcoding: true,
                    resolutions: 'min'
                });
                {
                    const { video, live } = yield server.live.quickCreate({ saveReplay: true, permanentLive: false, privacy: 3 });
                    normalLiveId = video.uuid;
                    normalLive = live;
                }
                {
                    const { video, live } = yield server.live.quickCreate({ saveReplay: true, permanentLive: true, privacy: 3 });
                    permanentLiveId = video.uuid;
                    permanentLive = live;
                }
            });
        });
        it('Should create a private normal live and have a private static path', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(240000);
                yield checkLiveFiles(normalLive, normalLiveId);
            });
        });
        it('Should create a private permanent live and have a private static path', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(240000);
                yield checkLiveFiles(permanentLive, permanentLiveId);
            });
        });
        it('Should reinject video file token in permanent live', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(240000);
                const ffmpegCommand = (0, server_commands_1.sendRTMPStream)({ rtmpBaseUrl: permanentLive.rtmpUrl, streamKey: permanentLive.streamKey });
                yield server.live.waitUntilPublished({ videoId: permanentLiveId });
                const video = yield server.videos.getWithToken({ id: permanentLiveId });
                const videoFileToken = yield server.videoToken.getVideoFileToken({ videoId: video.uuid });
                yield (0, shared_1.checkVideoFileTokenReinjection)({
                    server,
                    videoUUID: permanentLiveId,
                    videoFileToken,
                    resolutions: [720],
                    isLive: true
                });
                yield (0, server_commands_1.stopFfmpeg)(ffmpegCommand);
            });
        });
        it('Should have created a replay of the normal live with a private static path', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(240000);
                yield server.live.waitUntilReplacedByReplay({ videoId: normalLiveId });
                const replay = yield server.videos.getWithToken({ id: normalLiveId });
                yield checkReplay(replay);
            });
        });
        it('Should have created a replay of the permanent live with a private static path', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(240000);
                yield server.live.waitUntilWaiting({ videoId: permanentLiveId });
                yield (0, server_commands_1.waitJobs)([server]);
                const live = yield server.videos.getWithToken({ id: permanentLiveId });
                const replayFromList = yield (0, server_commands_1.findExternalSavedVideo)(server, live);
                const replay = yield server.videos.getWithToken({ id: replayFromList.id });
                yield checkReplay(replay);
            });
        });
    });
    describe('With private files proxy disabled and public ACL for private files', function () {
        let videoUUID;
        before(function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(240000);
                yield server.kill();
                const config = server_commands_1.ObjectStorageCommand.getDefaultScalewayConfig({
                    serverNumber: 1,
                    enablePrivateProxy: false,
                    privateACL: 'public-read'
                });
                yield server.run(config);
                const { uuid } = yield server.videos.quickUpload({ name: 'video', privacy: 3 });
                videoUUID = uuid;
                yield (0, server_commands_1.waitJobs)([server]);
            });
        });
        it('Should display object storage path for a private video and be able to access them', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(60000);
                yield checkPublicVODFiles(videoUUID);
            });
        });
        it('Should not be able to access object storage proxy', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                const privateVideo = yield server.videos.getWithToken({ id: videoUUID });
                const webtorrentFilename = extractFilenameFromUrl(privateVideo.files[0].fileUrl);
                const hlsFilename = extractFilenameFromUrl((0, core_utils_1.getHLS)(privateVideo).files[0].fileUrl);
                yield (0, server_commands_1.makeRawRequest)({
                    url: server.url + '/object-storage-proxy/webseed/private/' + webtorrentFilename,
                    token: server.accessToken,
                    expectedStatus: 400
                });
                yield (0, server_commands_1.makeRawRequest)({
                    url: server.url + '/object-storage-proxy/streaming-playlists/hls/private/' + videoUUID + '/' + hlsFilename,
                    token: server.accessToken,
                    expectedStatus: 400
                });
            });
        });
    });
    after(function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.timeout(240000);
            const { data } = yield server.videos.listAllForAdmin();
            for (const v of data) {
                yield server.videos.remove({ id: v.uuid });
            }
            for (const v of data) {
                yield server.servers.waitUntilLog('Removed files of video ' + v.url);
            }
            yield (0, server_commands_1.cleanupTests)([server]);
        });
    });
});
//# sourceMappingURL=video-static-file-privacy.js.map