Skip to content

Commit

Permalink
Fix delete comment federation
Browse files Browse the repository at this point in the history
  • Loading branch information
Chocobozzz committed Mar 27, 2018
1 parent 649f033 commit 73c0809
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 26 deletions.
15 changes: 11 additions & 4 deletions server/lib/activitypub/process/process-delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { VideoModel } from '../../../models/video/video'
import { VideoChannelModel } from '../../../models/video/video-channel'
import { VideoCommentModel } from '../../../models/video/video-comment'
import { getOrCreateActorAndServerAndModel } from '../actor'
import { forwardActivity } from '../send/misc'

async function processDeleteActivity (activity: ActivityDelete) {
const objectUrl = typeof activity.object === 'string' ? activity.object : activity.object.id
Expand All @@ -33,7 +34,7 @@ async function processDeleteActivity (activity: ActivityDelete) {
{
const videoCommentInstance = await VideoCommentModel.loadByUrlAndPopulateAccount(objectUrl)
if (videoCommentInstance) {
return processDeleteVideoComment(actor, videoCommentInstance)
return processDeleteVideoComment(actor, videoCommentInstance, activity)
}
}

Expand Down Expand Up @@ -116,21 +117,27 @@ async function deleteRemoteVideoChannel (videoChannelToRemove: VideoChannelModel
logger.info('Remote video channel with uuid %s removed.', videoChannelToRemove.Actor.uuid)
}

async function processDeleteVideoComment (actor: ActorModel, videoComment: VideoCommentModel) {
async function processDeleteVideoComment (byActor: ActorModel, videoComment: VideoCommentModel, activity: ActivityDelete) {
const options = {
arguments: [ actor, videoComment ],
arguments: [ byActor, videoComment, activity ],
errorMessage: 'Cannot remove the remote video comment with many retries.'
}

await retryTransactionWrapper(deleteRemoteVideoComment, options)
}

function deleteRemoteVideoComment (actor: ActorModel, videoComment: VideoCommentModel) {
function deleteRemoteVideoComment (byActor: ActorModel, videoComment: VideoCommentModel, activity: ActivityDelete) {
logger.debug('Removing remote video comment "%s".', videoComment.url)

return sequelizeTypescript.transaction(async t => {
await videoComment.destroy({ transaction: t })

if (videoComment.Video.isOwned()) {
// Don't resend the activity to the sender
const exceptions = [ byActor ]
await forwardActivity(activity, t, exceptions)
}

logger.info('Remote video comment %s removed.', videoComment.url)
})
}
6 changes: 3 additions & 3 deletions server/lib/activitypub/send/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ function getOriginVideoAudience (video: VideoModel, actorsInvolvedInVideo: Actor
}
}

function getOriginVideoCommentAudience (
function getVideoCommentAudience (
videoComment: VideoCommentModel,
threadParentComments: VideoCommentModel[],
actorsInvolvedInVideo: ActorModel[],
Expand Down Expand Up @@ -160,7 +160,7 @@ function buildAudience (followerInboxUrls: string[], isPublic = true) {
return { to, cc }
}

function audiencify (object: any, audience: ActivityAudience) {
function audiencify <T> (object: T, audience: ActivityAudience) {
return Object.assign(object, audience)
}

Expand Down Expand Up @@ -192,7 +192,7 @@ export {
getObjectFollowersAudience,
forwardActivity,
audiencify,
getOriginVideoCommentAudience,
getVideoCommentAudience,
computeUris,
broadcastToActors
}
8 changes: 4 additions & 4 deletions server/lib/activitypub/send/send-create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
getAudience,
getObjectFollowersAudience,
getOriginVideoAudience,
getOriginVideoCommentAudience,
getVideoCommentAudience,
unicastTo
} from './misc'

Expand Down Expand Up @@ -47,7 +47,7 @@ async function sendCreateVideoCommentToOrigin (comment: VideoCommentModel, t: Tr

const actorsInvolvedInComment = await getActorsInvolvedInVideo(comment.Video, t)
actorsInvolvedInComment.push(byActor)
const audience = getOriginVideoCommentAudience(comment, threadParentComments, actorsInvolvedInComment)
const audience = getVideoCommentAudience(comment, threadParentComments, actorsInvolvedInComment)

const data = await createActivityData(comment.url, byActor, commentObject, t, audience)

Expand All @@ -70,7 +70,7 @@ async function sendCreateVideoCommentToVideoFollowers (comment: VideoCommentMode
const actorsInvolvedInComment = await getActorsInvolvedInVideo(comment.Video, t)
actorsInvolvedInComment.push(byActor)

const audience = getOriginVideoCommentAudience(comment, threadParentComments, actorsInvolvedInComment)
const audience = getVideoCommentAudience(comment, threadParentComments, actorsInvolvedInComment, true)
const data = await createActivityData(comment.url, byActor, commentObject, t, audience)

// This was a reply, send it to the parent actors
Expand Down Expand Up @@ -144,7 +144,7 @@ async function createActivityData (
}

return audiencify({
type: 'Create',
type: 'Create' as 'Create',
id: url + '/activity',
actor: byActor.url,
object: audiencify(object, audience)
Expand Down
40 changes: 29 additions & 11 deletions server/lib/activitypub/send/send-delete.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Transaction } from 'sequelize'
import { ActivityDelete } from '../../../../shared/models/activitypub'
import { ActivityAudience, ActivityDelete } from '../../../../shared/models/activitypub'
import { ActorModel } from '../../../models/activitypub/actor'
import { VideoModel } from '../../../models/video/video'
import { VideoCommentModel } from '../../../models/video/video-comment'
import { VideoShareModel } from '../../../models/video/video-share'
import { getDeleteActivityPubUrl } from '../url'
import { broadcastToFollowers } from './misc'
import { audiencify, broadcastToActors, broadcastToFollowers, getActorsInvolvedInVideo, getVideoCommentAudience, unicastTo } from './misc'

async function sendDeleteVideo (video: VideoModel, t: Transaction) {
const url = getDeleteActivityPubUrl(video.url)
Expand All @@ -30,16 +30,30 @@ async function sendDeleteActor (byActor: ActorModel, t: Transaction) {
}

async function sendDeleteVideoComment (videoComment: VideoCommentModel, t: Transaction) {
const url = getDeleteActivityPubUrl(videoComment.url)
const isVideoOrigin = videoComment.Video.isOwned()

const url = getDeleteActivityPubUrl(videoComment.url)
const byActor = videoComment.Account.Actor
const data = deleteActivityData(url, videoComment.url, byActor)
const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, t)

const actorsInvolved = await VideoShareModel.loadActorsByShare(videoComment.Video.id, t)
actorsInvolved.push(videoComment.Video.VideoChannel.Account.Actor)
actorsInvolved.push(byActor)
const actorsInvolvedInComment = await getActorsInvolvedInVideo(videoComment.Video, t)
actorsInvolvedInComment.push(byActor)

return broadcastToFollowers(data, byActor, actorsInvolved, t)
const audience = getVideoCommentAudience(videoComment, threadParentComments, actorsInvolvedInComment, isVideoOrigin)
const data = deleteActivityData(url, videoComment.url, byActor, audience)

// This was a reply, send it to the parent actors
const actorsException = [ byActor ]
await broadcastToActors(data, byActor, threadParentComments.map(c => c.Account.Actor), actorsException)

// Broadcast to our followers
await broadcastToFollowers(data, byActor, [ byActor ], t)

// Send to actors involved in the comment
if (isVideoOrigin) return broadcastToFollowers(data, byActor, actorsInvolvedInComment, t, actorsException)

// Send to origin
return unicastTo(data, byActor, videoComment.Video.VideoChannel.Account.Actor.sharedInboxUrl)
}

// ---------------------------------------------------------------------------
Expand All @@ -52,11 +66,15 @@ export {

// ---------------------------------------------------------------------------

function deleteActivityData (url: string, object: string, byActor: ActorModel): ActivityDelete {
return {
type: 'Delete',
function deleteActivityData (url: string, object: string, byActor: ActorModel, audience?: ActivityAudience): ActivityDelete {
const activity = {
type: 'Delete' as 'Delete',
id: url,
actor: byActor.url,
object
}

if (audience) return audiencify(activity, audience)

return activity
}
2 changes: 1 addition & 1 deletion server/lib/activitypub/send/send-like.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ async function likeActivityData (
}

return audiencify({
type: 'Like',
type: 'Like' as 'Like',
id: url,
actor: byActor.url,
object: video.url
Expand Down
2 changes: 1 addition & 1 deletion server/lib/activitypub/send/send-undo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ async function undoActivityData (
}

return audiencify({
type: 'Undo',
type: 'Undo' as 'Undo',
id: url,
actor: byActor.url,
object
Expand Down
2 changes: 1 addition & 1 deletion server/lib/activitypub/send/send-update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ async function updateActivityData (
}

return audiencify({
type: 'Update',
type: 'Update' as 'Update',
id: url,
actor: byActor.url,
object: audiencify(object, audience)
Expand Down
31 changes: 30 additions & 1 deletion server/tests/api/videos/multiple-servers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,8 @@ describe('Test multiple servers', function () {
})

describe('Should comment these videos', function () {
let childOfFirstChild: VideoCommentThreadTree

it('Should add comment (threads and replies)', async function () {
this.timeout(25000)

Expand Down Expand Up @@ -821,7 +823,7 @@ describe('Test multiple servers', function () {
expect(firstChild.comment.account.host).equal('localhost:9002')
expect(firstChild.children).to.have.lengthOf(1)

const childOfFirstChild = firstChild.children[0]
childOfFirstChild = firstChild.children[0]
expect(childOfFirstChild.comment.text).to.equal('my super answer to answer of thread 1')
expect(childOfFirstChild.comment.account.name).equal('root')
expect(childOfFirstChild.comment.account.host).equal('localhost:9003')
Expand All @@ -835,6 +837,33 @@ describe('Test multiple servers', function () {
}
})

it('Should delete a reply', async function () {
this.timeout(10000)

await deleteVideoComment(servers[2].url, servers[2].accessToken, videoUUID, childOfFirstChild.comment.id)

await wait(5000)
})

it('Should not have this comment anymore', async function () {
for (const server of servers) {
const res1 = await getVideoCommentThreads(server.url, videoUUID, 0, 5)
const threadId = res1.body.data.find(c => c.text === 'my super first comment').id

const res2 = await getVideoThreadComments(server.url, videoUUID, threadId)

const tree: VideoCommentThreadTree = res2.body
expect(tree.comment.text).equal('my super first comment')

const firstChild = tree.children[0]
expect(firstChild.comment.text).to.equal('my super answer to thread 1')
expect(firstChild.children).to.have.lengthOf(0)

const secondChild = tree.children[1]
expect(secondChild.comment.text).to.equal('my second answer to thread 1')
}
})

it('Should delete the thread comments', async function () {
this.timeout(10000)

Expand Down

0 comments on commit 73c0809

Please sign in to comment.