X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Flib%2Factivitypub%2Fvideo-comments.ts;h=e87301fe7d0b25250d67579de96ca5680828bd82;hb=b718fd22374d64534bcfe69932cf562894abed6a;hp=17c86a38144aaa371d17228b091e974fe9c30cf3;hpb=2ccaeeb341ffe8c2609039bf4c6d8835b4650316;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/lib/activitypub/video-comments.ts b/server/lib/activitypub/video-comments.ts index 17c86a381..e87301fe7 100644 --- a/server/lib/activitypub/video-comments.ts +++ b/server/lib/activitypub/video-comments.ts @@ -1,13 +1,15 @@ import { VideoCommentObject } from '../../../shared/models/activitypub/objects/video-comment-object' -import { isVideoCommentObjectValid } from '../../helpers/custom-validators/activitypub/video-comments' +import { sanitizeAndCheckVideoCommentObject } from '../../helpers/custom-validators/activitypub/video-comments' import { logger } from '../../helpers/logger' import { doRequest } from '../../helpers/requests' -import { ACTIVITY_PUB } from '../../initializers' +import { ACTIVITY_PUB, CRAWL_REQUEST_CONCURRENCY } from '../../initializers' import { ActorModel } from '../../models/activitypub/actor' import { VideoModel } from '../../models/video/video' import { VideoCommentModel } from '../../models/video/video-comment' import { getOrCreateActorAndServerAndModel } from './actor' -import { getOrCreateAccountAndVideoAndChannel } from './videos' +import { getOrCreateVideoAndAccountAndChannel } from './videos' +import * as Bluebird from 'bluebird' +import { checkUrlsSameHost } from '../../helpers/activitypub' async function videoCommentActivityObjectToDBAttributes (video: VideoModel, actor: ActorModel, comment: VideoCommentObject) { let originCommentId: number = null @@ -15,7 +17,7 @@ async function videoCommentActivityObjectToDBAttributes (video: VideoModel, acto // If this is not a reply to the video (thread), create or get the parent comment if (video.url !== comment.inReplyTo) { - const [ parent ] = await addVideoComment(video, comment.inReplyTo) + const { comment: parent } = await addVideoComment(video, comment.inReplyTo) if (!parent) { logger.warn('Cannot fetch or get parent comment %s of comment %s.', comment.inReplyTo, comment.id) return undefined @@ -26,7 +28,7 @@ async function videoCommentActivityObjectToDBAttributes (video: VideoModel, acto } return { - url: comment.url, + url: comment.id, text: comment.content, videoId: video.id, accountId: actor.Account.id, @@ -37,10 +39,10 @@ async function videoCommentActivityObjectToDBAttributes (video: VideoModel, acto } } -async function addVideoComments (instance: VideoModel, commentUrls: string[]) { - for (const commentUrl of commentUrls) { - await addVideoComment(instance, commentUrl) - } +async function addVideoComments (commentUrls: string[], instance: VideoModel) { + return Bluebird.map(commentUrls, commentUrl => { + return addVideoComment(instance, commentUrl) + }, { concurrency: CRAWL_REQUEST_CONCURRENCY }) } async function addVideoComment (videoInstance: VideoModel, commentUrl: string) { @@ -52,24 +54,36 @@ async function addVideoComment (videoInstance: VideoModel, commentUrl: string) { activityPub: true }) - if (isVideoCommentObjectValid(body) === false) { + if (sanitizeAndCheckVideoCommentObject(body) === false) { logger.debug('Remote video comment JSON is not valid.', { body }) - return undefined + return { created: false } } const actorUrl = body.attributedTo - if (!actorUrl) return [] + if (!actorUrl) return { created: false } + + if (checkUrlsSameHost(commentUrl, actorUrl) !== true) { + throw new Error(`Actor url ${actorUrl} has not the same host than the comment url ${commentUrl}`) + } + + if (checkUrlsSameHost(body.id, commentUrl) !== true) { + throw new Error(`Comment url ${commentUrl} host is different from the AP object id ${body.id}`) + } - const actor = await getOrCreateActorAndServerAndModel(actorUrl) + const actor = await getOrCreateActorAndServerAndModel(actorUrl, 'all') const entry = await videoCommentActivityObjectToDBAttributes(videoInstance, actor, body) - if (!entry) return [] + if (!entry) return { created: false } - return VideoCommentModel.findOrCreate({ + const [ comment, created ] = await VideoCommentModel.findOrCreate({ where: { url: body.id }, defaults: entry }) + comment.Account = actor.Account + comment.Video = videoInstance + + return { comment, created } } async function resolveThread (url: string, comments: VideoCommentModel[] = []) { @@ -81,7 +95,6 @@ async function resolveThread (url: string, comments: VideoCommentModel[] = []) { // Speed up things and resolve directly the thread if (commentFromDatabase.InReplyToVideoComment) { const data = await VideoCommentModel.listThreadParentComments(commentFromDatabase, undefined, 'DESC') - console.log(data) parentComments = parentComments.concat(data) } @@ -91,7 +104,8 @@ async function resolveThread (url: string, comments: VideoCommentModel[] = []) { try { // Maybe it's a reply to a video? - const { video } = await getOrCreateAccountAndVideoAndChannel(url) + // If yes, it's done: we resolved all the thread + const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: url }) if (comments.length !== 0) { const firstReply = comments[ comments.length - 1 ] @@ -112,7 +126,7 @@ async function resolveThread (url: string, comments: VideoCommentModel[] = []) { return { video, parents: comments } } catch (err) { - logger.debug('Cannot get or create account and video and channel for reply %s, fetch comment', url, err) + logger.debug('Cannot get or create account and video and channel for reply %s, fetch comment', url, { err }) if (comments.length > ACTIVITY_PUB.MAX_RECURSION_COMMENTS) { throw new Error('Recursion limit reached when resolving a thread') @@ -124,16 +138,24 @@ async function resolveThread (url: string, comments: VideoCommentModel[] = []) { activityPub: true }) - if (isVideoCommentObjectValid(body) === false) { + if (sanitizeAndCheckVideoCommentObject(body) === false) { throw new Error('Remote video comment JSON is not valid :' + JSON.stringify(body)) } const actorUrl = body.attributedTo if (!actorUrl) throw new Error('Miss attributed to in comment') + if (checkUrlsSameHost(url, actorUrl) !== true) { + throw new Error(`Actor url ${actorUrl} has not the same host than the comment url ${url}`) + } + + if (checkUrlsSameHost(body.id, url) !== true) { + throw new Error(`Comment url ${url} host is different from the AP object id ${body.id}`) + } + const actor = await getOrCreateActorAndServerAndModel(actorUrl) const comment = new VideoCommentModel({ - url: body.url, + url: body.id, text: body.content, videoId: null, accountId: actor.Account.id,