Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make federation of unlisted videos an instance-level server preference #2802

Merged
merged 5 commits into from
Jun 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions config/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ plugins:
check_latest_versions_interval: '12 hours' # How often you want to check new plugins/themes versions
url: 'https://packages.joinpeertube.org'

federation:
videos:
federate_unlisted: true

cache:
previews:
size: 500 # Max number of previews you want to cache
Expand Down
4 changes: 4 additions & 0 deletions config/production.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ plugins:
check_latest_versions_interval: '12 hours' # How often you want to check new plugins/themes versions
url: 'https://packages.joinpeertube.org'

federation:
videos:
federate_unlisted: true


###############################################################################
#
Expand Down
20 changes: 18 additions & 2 deletions server/helpers/video.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
import { Response } from 'express'
import { DEFAULT_AUDIO_RESOLUTION } from '@server/initializers/constants'
import { JobQueue } from '@server/lib/job-queue'
import { VideoTranscodingPayload } from '@shared/models'
import { VideoPrivacy, VideoTranscodingPayload } from '@shared/models'
import { CONFIG } from "@server/initializers/config"

type VideoFetchType = 'all' | 'only-video' | 'only-video-with-rights' | 'id' | 'none' | 'only-immutable-attributes'

Expand Down Expand Up @@ -96,12 +97,27 @@ function extractVideo (videoOrPlaylist: MVideo | MStreamingPlaylistVideo) {
: videoOrPlaylist
}

function isPrivacyForFederation (privacy: VideoPrivacy) {
const castedPrivacy = parseInt(privacy + '', 10)

return castedPrivacy === VideoPrivacy.PUBLIC ||
(CONFIG.FEDERATION.VIDEOS.FEDERATE_UNLISTED === true && castedPrivacy === VideoPrivacy.UNLISTED)
}

function getPrivaciesForFederation () {
return (CONFIG.FEDERATION.VIDEOS.FEDERATE_UNLISTED === true)
? [ { privacy: VideoPrivacy.PUBLIC }, { privacy: VideoPrivacy.UNLISTED } ]
: [ { privacy: VideoPrivacy.PUBLIC } ]
}

export {
VideoFetchType,
VideoFetchByUrlType,
fetchVideo,
getVideoWithAttributes,
fetchVideoByUrl,
addOptimizeOrMergeAudioJob,
extractVideo
extractVideo,
isPrivacyForFederation,
getPrivaciesForFederation
}
3 changes: 2 additions & 1 deletion server/initializers/checker-before-init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ function checkMissedConfig () {
'history.videos.max_age', 'views.videos.remote.max_age',
'rates_limit.login.window', 'rates_limit.login.max', 'rates_limit.ask_send_email.window', 'rates_limit.ask_send_email.max',
'theme.default',
'remote_redundancy.videos.accept_from'
'remote_redundancy.videos.accept_from',
'federation.videos.federate_unlisted'
]
const requiredAlternatives = [
[ // set
Expand Down
5 changes: 5 additions & 0 deletions server/initializers/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ const CONFIG = {
URL: config.get<string>('plugins.index.url')
}
},
FEDERATION: {
VIDEOS: {
FEDERATE_UNLISTED: config.get<boolean>('federation.videos.federate_unlisted')
}
},
ADMIN: {
get EMAIL () { return config.get<string>('admin.email') }
},
Expand Down
16 changes: 4 additions & 12 deletions server/models/video/video.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ import { ModelCache } from '@server/models/model-cache'
import { buildListQuery, BuildVideosQueryOptions, wrapForAPIResults } from './video-query-builder'
import { buildNSFWFilter } from '@server/helpers/express-utils'
import { getServerActor } from '@server/models/application/application'
import { getPrivaciesForFederation, isPrivacyForFederation } from "@server/helpers/video"

export enum ScopeNames {
AVAILABLE_FOR_LIST_IDS = 'AVAILABLE_FOR_LIST_IDS',
Expand Down Expand Up @@ -864,10 +865,7 @@ export class VideoModel extends Model<VideoModel> {
id: {
[Op.in]: Sequelize.literal('(' + rawQuery + ')')
},
[Op.or]: [
{ privacy: VideoPrivacy.PUBLIC },
{ privacy: VideoPrivacy.UNLISTED }
]
[Op.or]: getPrivaciesForFederation()
},
include: [
{
Expand Down Expand Up @@ -1582,12 +1580,6 @@ export class VideoModel extends Model<VideoModel> {
return videos
}

private static isPrivacyForFederation (privacy: VideoPrivacy) {
const castedPrivacy = parseInt(privacy + '', 10)

return castedPrivacy === VideoPrivacy.PUBLIC || castedPrivacy === VideoPrivacy.UNLISTED
}

static getCategoryLabel (id: number) {
return VIDEO_CATEGORIES[id] || 'Misc'
}
Expand Down Expand Up @@ -1813,11 +1805,11 @@ export class VideoModel extends Model<VideoModel> {
}

hasPrivacyForFederation () {
return VideoModel.isPrivacyForFederation(this.privacy)
return isPrivacyForFederation(this.privacy)
}

isNewVideo (newPrivacy: VideoPrivacy) {
return this.hasPrivacyForFederation() === false && VideoModel.isPrivacyForFederation(newPrivacy) === true
return this.hasPrivacyForFederation() === false && isPrivacyForFederation(newPrivacy) === true
}

setAsRefreshed () {
Expand Down
51 changes: 46 additions & 5 deletions server/tests/api/videos/video-privacy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'mocha'
import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enum'
import {
cleanupTests,
flushAndRunMultipleServers,
flushAndRunServer,
getVideosList,
getVideosListWithToken,
ServerInfo,
Expand All @@ -22,7 +22,7 @@ import { Video } from '@shared/models'
const expect = chai.expect

describe('Test video privacy', function () {
let servers: ServerInfo[] = []
const servers: ServerInfo[] = []
let anotherUserToken: string

let privateVideoId: number
Expand All @@ -32,14 +32,24 @@ describe('Test video privacy', function () {
let internalVideoUUID: string

let unlistedVideoUUID: string
let nonFederatedUnlistedVideoUUID: string

let now: number

const dontFederateUnlistedConfig = {
federation: {
videos: {
federate_unlisted: false
}
}
}

before(async function () {
this.timeout(50000)

// Run servers
servers = await flushAndRunMultipleServers(2)
servers.push(await flushAndRunServer(1, dontFederateUnlistedConfig))
servers.push(await flushAndRunServer(2))

// Get the access tokens
await setAccessTokensToServers(servers)
Expand Down Expand Up @@ -164,6 +174,37 @@ describe('Test video privacy', function () {
}
})

it('Should upload a non-federating unlisted video to server 1', async function () {
this.timeout(30000)

const attributes = {
name: 'unlisted video',
privacy: VideoPrivacy.UNLISTED
}
await uploadVideo(servers[0].url, servers[0].accessToken, attributes)

await waitJobs(servers)
})

it('Should list my new unlisted video', async function () {
const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 3)

expect(res.body.total).to.equal(3)
expect(res.body.data).to.have.lengthOf(3)

nonFederatedUnlistedVideoUUID = res.body.data[0].uuid
})

it('Should be able to get non-federated unlisted video from origin', async function () {
const res = await getVideo(servers[0].url, nonFederatedUnlistedVideoUUID)

expect(res.body.name).to.equal('unlisted video')
})

it('Should not be able to get non-federated unlisted video from federated server', async function () {
await getVideo(servers[1].url, nonFederatedUnlistedVideoUUID, 404)
})

it('Should update the private and internal videos to public on server 1', async function () {
this.timeout(10000)

Expand Down Expand Up @@ -230,8 +271,8 @@ describe('Test video privacy', function () {
const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 5)
const videos = res.body.data

expect(res.body.total).to.equal(2)
expect(videos).to.have.lengthOf(2)
expect(res.body.total).to.equal(3)
expect(videos).to.have.lengthOf(3)

const privateVideo = videos.find(v => v.name === 'private video becomes public')
const internalVideo = videos.find(v => v.name === 'internal video becomes public')
Expand Down