From 9a27cdc27c900feaae5f6db4315c4ccdfc0c4493 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 17 Nov 2017 15:20:42 +0100 Subject: Optimize signature verification --- server/lib/activitypub/misc.ts | 16 ++++++++------ server/lib/activitypub/process-add.ts | 15 ++++++++----- server/lib/activitypub/process-update.ts | 1 - server/lib/activitypub/send-request.ts | 37 ++++++++++++++++++++++++-------- 4 files changed, 48 insertions(+), 21 deletions(-) (limited to 'server/lib') diff --git a/server/lib/activitypub/misc.ts b/server/lib/activitypub/misc.ts index c07d9f654..4c210eb10 100644 --- a/server/lib/activitypub/misc.ts +++ b/server/lib/activitypub/misc.ts @@ -2,11 +2,12 @@ import * as magnetUtil from 'magnet-uri' import { VideoTorrentObject } from '../../../shared' import { VideoChannelObject } from '../../../shared/models/activitypub/objects/video-channel-object' import { isVideoFileInfoHashValid } from '../../helpers/custom-validators/videos' -import { VIDEO_MIMETYPE_EXT } from '../../initializers/constants' +import { ACTIVITY_PUB, VIDEO_MIMETYPE_EXT } from '../../initializers/constants' import { AccountInstance } from '../../models/account/account-interface' import { VideoChannelInstance } from '../../models/video/video-channel-interface' import { VideoFileAttributes } from '../../models/video/video-file-interface' import { VideoAttributes, VideoInstance } from '../../models/video/video-interface' +import { VideoPrivacy } from '../../../shared/models/videos/video-privacy.enum' function videoChannelActivityObjectToDBAttributes (videoChannelObject: VideoChannelObject, account: AccountInstance) { return { @@ -23,8 +24,14 @@ function videoChannelActivityObjectToDBAttributes (videoChannelObject: VideoChan async function videoActivityObjectToDBAttributes ( videoChannel: VideoChannelInstance, - videoObject: VideoTorrentObject + videoObject: VideoTorrentObject, + to: string[] = [], + cc: string[] = [] ) { + let privacy = VideoPrivacy.PRIVATE + if (to.indexOf(ACTIVITY_PUB.PUBLIC) !== -1) privacy = VideoPrivacy.PUBLIC + else if (cc.indexOf(ACTIVITY_PUB.PUBLIC) !== -1) privacy = VideoPrivacy.UNLISTED + const duration = videoObject.duration.replace(/[^\d]+/, '') const videoData: VideoAttributes = { name: videoObject.name, @@ -43,11 +50,8 @@ async function videoActivityObjectToDBAttributes ( views: videoObject.views, likes: 0, dislikes: 0, - // likes: videoToCreateData.likes, - // dislikes: videoToCreateData.dislikes, remote: true, - privacy: 1 - // privacy: videoToCreateData.privacy + privacy } return videoData diff --git a/server/lib/activitypub/process-add.ts b/server/lib/activitypub/process-add.ts index 72c5b1932..c83d9e98e 100644 --- a/server/lib/activitypub/process-add.ts +++ b/server/lib/activitypub/process-add.ts @@ -17,7 +17,7 @@ async function processAddActivity (activity: ActivityAdd) { const videoChannelUrl = activity.target const videoChannel = await getOrCreateVideoChannel(account, videoChannelUrl) - return processAddVideo(account, videoChannel, activityObject as VideoTorrentObject) + return processAddVideo(account, activity, videoChannel, activityObject as VideoTorrentObject) } logger.warn('Unknown activity object type %s when creating activity.', activityType, { activity: activity.id }) @@ -32,16 +32,21 @@ export { // --------------------------------------------------------------------------- -function processAddVideo (account: AccountInstance, videoChannel: VideoChannelInstance, video: VideoTorrentObject) { +function processAddVideo (account: AccountInstance, activity: ActivityAdd, videoChannel: VideoChannelInstance, video: VideoTorrentObject) { const options = { - arguments: [ account, videoChannel, video ], + arguments: [ account, activity, videoChannel, video ], errorMessage: 'Cannot insert the remote video with many retries.' } return retryTransactionWrapper(addRemoteVideo, options) } -function addRemoteVideo (account: AccountInstance, videoChannel: VideoChannelInstance, videoToCreateData: VideoTorrentObject) { +function addRemoteVideo ( + account: AccountInstance, + activity: ActivityAdd, + videoChannel: VideoChannelInstance, + videoToCreateData: VideoTorrentObject +) { logger.debug('Adding remote video %s.', videoToCreateData.url) return db.sequelize.transaction(async t => { @@ -54,7 +59,7 @@ function addRemoteVideo (account: AccountInstance, videoChannel: VideoChannelIns const videoFromDatabase = await db.Video.loadByUUIDOrURL(videoToCreateData.uuid, videoToCreateData.id, t) if (videoFromDatabase) throw new Error('Video with this UUID/Url already exists.') - const videoData = await videoActivityObjectToDBAttributes(videoChannel, videoToCreateData) + const videoData = await videoActivityObjectToDBAttributes(videoChannel, videoToCreateData, activity.to, activity.cc) const video = db.Video.build(videoData) // Don't block on request diff --git a/server/lib/activitypub/process-update.ts b/server/lib/activitypub/process-update.ts index 4aefd1b9b..b732fce33 100644 --- a/server/lib/activitypub/process-update.ts +++ b/server/lib/activitypub/process-update.ts @@ -70,7 +70,6 @@ async function updateRemoteVideo (account: AccountInstance, videoAttributesToUpd videoInstance.set('views', videoData.views) // videoInstance.set('likes', videoData.likes) // videoInstance.set('dislikes', videoData.dislikes) - // videoInstance.set('privacy', videoData.privacy) await videoInstance.save(sequelizeOptions) diff --git a/server/lib/activitypub/send-request.ts b/server/lib/activitypub/send-request.ts index 8d013fa87..68a631a36 100644 --- a/server/lib/activitypub/send-request.ts +++ b/server/lib/activitypub/send-request.ts @@ -13,6 +13,8 @@ import { database as db } from '../../initializers' import { AccountInstance, VideoChannelInstance, VideoInstance } from '../../models' import { VideoAbuseInstance } from '../../models/video/video-abuse-interface' import { activitypubHttpJobScheduler } from '../jobs' +import { ACTIVITY_PUB } from '../../initializers/constants' +import { VideoPrivacy } from '../../../shared/models/videos/video-privacy.enum' async function sendCreateVideoChannel (videoChannel: VideoChannelInstance, t: Transaction) { const byAccount = videoChannel.Account @@ -50,7 +52,7 @@ async function sendAddVideo (video: VideoInstance, t: Transaction) { const byAccount = video.VideoChannel.Account const videoObject = video.toActivityPubObject() - const data = await addActivityData(video.url, byAccount, video.VideoChannel.url, videoObject) + const data = await addActivityData(video.url, byAccount, video, video.VideoChannel.url, videoObject) return broadcastToFollowers(data, byAccount, [ byAccount ], t) } @@ -96,7 +98,7 @@ async function sendVideoAnnounce (byAccount: AccountInstance, video: VideoInstan const url = getActivityPubUrl('video', video.uuid) + '#announce' const videoChannel = video.VideoChannel - const announcedActivity = await addActivityData(url, videoChannel.Account, videoChannel.url, video.toActivityPubObject()) + const announcedActivity = await addActivityData(url, videoChannel.Account, video, videoChannel.url, video.toActivityPubObject()) const data = await announceActivityData(url, byAccount, announcedActivity) return broadcastToFollowers(data, byAccount, [ byAccount ], t) @@ -167,19 +169,32 @@ async function unicastTo (data: any, byAccount: AccountInstance, toAccountUrl: s return activitypubHttpJobScheduler.createJob(t, 'activitypubHttpUnicastHandler', jobPayload) } -async function getPublicActivityTo (account: AccountInstance) { - const inboxUrls = await account.getFollowerSharedInboxUrls() +async function getAudience (accountSender: AccountInstance, isPublic = true) { + const followerInboxUrls = await accountSender.getFollowerSharedInboxUrls() - return inboxUrls.concat('https://www.w3.org/ns/activitystreams#Public') + // Thanks Mastodon: https://github.com/tootsuite/mastodon/blob/master/app/lib/activitypub/tag_manager.rb#L47 + let to = [] + let cc = [] + + if (isPublic) { + to = [ ACTIVITY_PUB.PUBLIC ] + cc = followerInboxUrls + } else { // Unlisted + to = followerInboxUrls + cc = [ ACTIVITY_PUB.PUBLIC ] + } + + return { to, cc } } async function createActivityData (url: string, byAccount: AccountInstance, object: any) { - const to = await getPublicActivityTo(byAccount) + const { to, cc } = await getAudience(byAccount) const activity: ActivityCreate = { type: 'Create', id: url, actor: byAccount.url, to, + cc, object } @@ -187,12 +202,13 @@ async function createActivityData (url: string, byAccount: AccountInstance, obje } async function updateActivityData (url: string, byAccount: AccountInstance, object: any) { - const to = await getPublicActivityTo(byAccount) + const { to, cc } = await getAudience(byAccount) const activity: ActivityUpdate = { type: 'Update', id: url, actor: byAccount.url, to, + cc, object } @@ -209,13 +225,16 @@ async function deleteActivityData (url: string, byAccount: AccountInstance) { return activity } -async function addActivityData (url: string, byAccount: AccountInstance, target: string, object: any) { - const to = await getPublicActivityTo(byAccount) +async function addActivityData (url: string, byAccount: AccountInstance, video: VideoInstance, target: string, object: any) { + const videoPublic = video.privacy === VideoPrivacy.PUBLIC + + const { to, cc } = await getAudience(byAccount, videoPublic) const activity: ActivityAdd = { type: 'Add', id: url, actor: byAccount.url, to, + cc, object, target } -- cgit v1.2.3