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

* Add preference for federating unlisted videos

* Connect unlisted video federation with new preference

* Apply pull request feedback

* Fix lint issues

* Remove preference for federating unlisted videos from web admin interface
pull/2828/head
Levi Bard 2020-06-03 09:42:07 +02:00 committed by GitHub
parent 78646451c9
commit 3092e9bbb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 83 additions and 20 deletions

View File

@ -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

View File

@ -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
###############################################################################
#

View File

@ -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'
@ -96,6 +97,19 @@ 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,
@ -103,5 +117,7 @@ export {
getVideoWithAttributes,
fetchVideoByUrl,
addOptimizeOrMergeAudioJob,
extractVideo
extractVideo,
isPrivacyForFederation,
getPrivaciesForFederation
}

View File

@ -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

View File

@ -155,6 +155,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') }
},

View File

@ -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',
@ -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: [
{
@ -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'
}
@ -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 () {

View File

@ -5,7 +5,7 @@ import 'mocha'
import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enum'
import {
cleanupTests,
flushAndRunMultipleServers,
flushAndRunServer,
getVideosList,
getVideosListWithToken,
ServerInfo,
@ -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
@ -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)
@ -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)
@ -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')