From 1e7eb25f6cb6893db8f99ff40ef0509aa2a16614 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 15 Jan 2019 14:52:33 +0100 Subject: [PATCH] Correctly send Flag/Dislike/View activities --- server/controllers/activitypub/client.ts | 15 ++--- server/controllers/api/videos/abuse.ts | 2 +- server/controllers/api/videos/index.ts | 4 +- server/lib/activitypub/send/send-create.ts | 69 --------------------- server/lib/activitypub/send/send-dislike.ts | 41 ++++++++++++ server/lib/activitypub/send/send-flag.ts | 39 ++++++++++++ server/lib/activitypub/send/send-undo.ts | 12 ++-- server/lib/activitypub/send/send-view.ts | 40 ++++++++++++ server/lib/activitypub/video-rates.ts | 5 +- 9 files changed, 138 insertions(+), 89 deletions(-) create mode 100644 server/lib/activitypub/send/send-dislike.ts create mode 100644 server/lib/activitypub/send/send-flag.ts create mode 100644 server/lib/activitypub/send/send-view.ts diff --git a/server/controllers/activitypub/client.ts b/server/controllers/activitypub/client.ts index 1a4e28dc8..7e87f6f3b 100644 --- a/server/controllers/activitypub/client.ts +++ b/server/controllers/activitypub/client.ts @@ -3,22 +3,18 @@ import * as express from 'express' import { VideoPrivacy, VideoRateType } from '../../../shared/models/videos' import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub' import { CONFIG, ROUTE_CACHE_LIFETIME } from '../../initializers' -import { buildAnnounceWithVideoAudience, buildDislikeActivity, buildLikeActivity } from '../../lib/activitypub/send' +import { buildAnnounceWithVideoAudience, buildLikeActivity } from '../../lib/activitypub/send' import { audiencify, getAudience } from '../../lib/activitypub/audience' import { buildCreateActivity } from '../../lib/activitypub/send/send-create' import { asyncMiddleware, - videosShareValidator, executeIfActivityPub, localAccountValidator, localVideoChannelValidator, - videosCustomGetValidator + videosCustomGetValidator, + videosShareValidator } from '../../middlewares' -import { - getAccountVideoRateValidator, - videoCommentGetValidator, - videosGetValidator -} from '../../middlewares/validators' +import { getAccountVideoRateValidator, videoCommentGetValidator, videosGetValidator } from '../../middlewares/validators' import { AccountModel } from '../../models/account/account' import { ActorModel } from '../../models/activitypub/actor' import { ActorFollowModel } from '../../models/activitypub/actor-follow' @@ -40,6 +36,7 @@ import { VideoCaptionModel } from '../../models/video/video-caption' import { videoRedundancyGetValidator } from '../../middlewares/validators/redundancy' import { getServerActor } from '../../helpers/utils' import { VideoRedundancyModel } from '../../models/redundancy/video-redundancy' +import { buildDislikeActivity } from '../../lib/activitypub/send/send-dislike' const activityPubClientRouter = express.Router() @@ -156,7 +153,7 @@ function getAccountVideoRate (rateType: VideoRateType) { const url = getRateUrl(rateType, byActor, accountVideoRate.Video) const APObject = rateType === 'like' ? buildLikeActivity(url, byActor, accountVideoRate.Video) - : buildCreateActivity(url, byActor, buildDislikeActivity(url, byActor, accountVideoRate.Video)) + : buildDislikeActivity(url, byActor, accountVideoRate.Video) return activityPubResponse(activityPubContextify(APObject), res) } diff --git a/server/controllers/api/videos/abuse.ts b/server/controllers/api/videos/abuse.ts index fe0a95cd5..32f9c4793 100644 --- a/server/controllers/api/videos/abuse.ts +++ b/server/controllers/api/videos/abuse.ts @@ -3,7 +3,6 @@ import { UserRight, VideoAbuseCreate, VideoAbuseState } from '../../../../shared import { logger } from '../../../helpers/logger' import { getFormattedObjects } from '../../../helpers/utils' import { sequelizeTypescript } from '../../../initializers' -import { sendVideoAbuse } from '../../../lib/activitypub/send' import { asyncMiddleware, asyncRetryTransactionMiddleware, @@ -23,6 +22,7 @@ import { VideoAbuseModel } from '../../../models/video/video-abuse' import { auditLoggerFactory, VideoAbuseAuditView } from '../../../helpers/audit-logger' import { UserModel } from '../../../models/account/user' import { Notifier } from '../../../lib/notifier' +import { sendVideoAbuse } from '../../../lib/activitypub/send/send-flag' const auditLogger = auditLoggerFactory('abuse') const abuseVideoRouter = express.Router() diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index 2b2dfa7ca..8414ca42c 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts @@ -23,7 +23,6 @@ import { fetchRemoteVideoDescription, getVideoActivityPubUrl } from '../../../lib/activitypub' -import { sendCreateView } from '../../../lib/activitypub/send' import { JobQueue } from '../../../lib/job-queue' import { Redis } from '../../../lib/redis' import { @@ -59,6 +58,7 @@ import { resetSequelizeInstance } from '../../../helpers/database-utils' import { move } from 'fs-extra' import { watchingRouter } from './watching' import { Notifier } from '../../../lib/notifier' +import { sendView } from '../../../lib/activitypub/send/send-view' const auditLogger = auditLoggerFactory('videos') const videosRouter = express.Router() @@ -422,7 +422,7 @@ async function viewVideo (req: express.Request, res: express.Response) { ]) const serverActor = await getServerActor() - await sendCreateView(serverActor, videoInstance, undefined) + await sendView(serverActor, videoInstance, undefined) return res.status(204).end() } diff --git a/server/lib/activitypub/send/send-create.ts b/server/lib/activitypub/send/send-create.ts index e3fca0a17..73e667ad4 100644 --- a/server/lib/activitypub/send/send-create.ts +++ b/server/lib/activitypub/send/send-create.ts @@ -3,9 +3,7 @@ import { ActivityAudience, ActivityCreate } from '../../../../shared/models/acti import { VideoPrivacy } from '../../../../shared/models/videos' import { ActorModel } from '../../../models/activitypub/actor' import { VideoModel } from '../../../models/video/video' -import { VideoAbuseModel } from '../../../models/video/video-abuse' import { VideoCommentModel } from '../../../models/video/video-comment' -import { getVideoAbuseActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoViewActivityPubUrl } from '../url' import { broadcastToActors, broadcastToFollowers, sendVideoRelatedActivity, unicastTo } from './utils' import { audiencify, getActorsInvolvedInVideo, getAudience, getAudienceFromFollowersOf, getVideoCommentAudience } from '../audience' import { logger } from '../../../helpers/logger' @@ -25,20 +23,6 @@ async function sendCreateVideo (video: VideoModel, t: Transaction) { return broadcastToFollowers(createActivity, byActor, [ byActor ], t) } -async function sendVideoAbuse (byActor: ActorModel, videoAbuse: VideoAbuseModel, video: VideoModel) { - if (!video.VideoChannel.Account.Actor.serverId) return // Local - - const url = getVideoAbuseActivityPubUrl(videoAbuse) - - logger.info('Creating job to send video abuse %s.', url) - - // Custom audience, we only send the abuse to the origin instance - const audience = { to: [ video.VideoChannel.Account.Actor.url ], cc: [] } - const createActivity = buildCreateActivity(url, byActor, videoAbuse.toActivityPubObject(), audience) - - return unicastTo(createActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl) -} - async function sendCreateCacheFile (byActor: ActorModel, fileRedundancy: VideoRedundancyModel) { logger.info('Creating job to send file cache of %s.', fileRedundancy.url) @@ -91,37 +75,6 @@ async function sendCreateVideoComment (comment: VideoCommentModel, t: Transactio return unicastTo(createActivity, byActor, comment.Video.VideoChannel.Account.Actor.sharedInboxUrl) } -async function sendCreateView (byActor: ActorModel, video: VideoModel, t: Transaction) { - logger.info('Creating job to send view of %s.', video.url) - - const url = getVideoViewActivityPubUrl(byActor, video) - const viewActivity = buildViewActivity(url, byActor, video) - - return sendVideoRelatedCreateActivity({ - // Use the server actor to send the view - byActor, - video, - url, - object: viewActivity, - transaction: t - }) -} - -async function sendCreateDislike (byActor: ActorModel, video: VideoModel, t: Transaction) { - logger.info('Creating job to dislike %s.', video.url) - - const url = getVideoDislikeActivityPubUrl(byActor, video) - const dislikeActivity = buildDislikeActivity(url, byActor, video) - - return sendVideoRelatedCreateActivity({ - byActor, - video, - url, - object: dislikeActivity, - transaction: t - }) -} - function buildCreateActivity (url: string, byActor: ActorModel, object: any, audience?: ActivityAudience): ActivityCreate { if (!audience) audience = getAudience(byActor) @@ -136,33 +89,11 @@ function buildCreateActivity (url: string, byActor: ActorModel, object: any, aud ) } -function buildDislikeActivity (url: string, byActor: ActorModel, video: VideoModel) { - return { - id: url, - type: 'Dislike', - actor: byActor.url, - object: video.url - } -} - -function buildViewActivity (url: string, byActor: ActorModel, video: VideoModel) { - return { - id: url, - type: 'View', - actor: byActor.url, - object: video.url - } -} - // --------------------------------------------------------------------------- export { sendCreateVideo, - sendVideoAbuse, buildCreateActivity, - sendCreateView, - sendCreateDislike, - buildDislikeActivity, sendCreateVideoComment, sendCreateCacheFile } diff --git a/server/lib/activitypub/send/send-dislike.ts b/server/lib/activitypub/send/send-dislike.ts new file mode 100644 index 000000000..a88436f2c --- /dev/null +++ b/server/lib/activitypub/send/send-dislike.ts @@ -0,0 +1,41 @@ +import { Transaction } from 'sequelize' +import { ActorModel } from '../../../models/activitypub/actor' +import { VideoModel } from '../../../models/video/video' +import { getVideoDislikeActivityPubUrl } from '../url' +import { logger } from '../../../helpers/logger' +import { ActivityAudience, ActivityDislike } from '../../../../shared/models/activitypub' +import { sendVideoRelatedActivity } from './utils' +import { audiencify, getAudience } from '../audience' + +async function sendDislike (byActor: ActorModel, video: VideoModel, t: Transaction) { + logger.info('Creating job to dislike %s.', video.url) + + const activityBuilder = (audience: ActivityAudience) => { + const url = getVideoDislikeActivityPubUrl(byActor, video) + + return buildDislikeActivity(url, byActor, video, audience) + } + + return sendVideoRelatedActivity(activityBuilder, { byActor, video, transaction: t }) +} + +function buildDislikeActivity (url: string, byActor: ActorModel, video: VideoModel, audience?: ActivityAudience): ActivityDislike { + if (!audience) audience = getAudience(byActor) + + return audiencify( + { + id: url, + type: 'Dislike' as 'Dislike', + actor: byActor.url, + object: video.url + }, + audience + ) +} + +// --------------------------------------------------------------------------- + +export { + sendDislike, + buildDislikeActivity +} diff --git a/server/lib/activitypub/send/send-flag.ts b/server/lib/activitypub/send/send-flag.ts new file mode 100644 index 000000000..96a7311b9 --- /dev/null +++ b/server/lib/activitypub/send/send-flag.ts @@ -0,0 +1,39 @@ +import { ActorModel } from '../../../models/activitypub/actor' +import { VideoModel } from '../../../models/video/video' +import { VideoAbuseModel } from '../../../models/video/video-abuse' +import { getVideoAbuseActivityPubUrl } from '../url' +import { unicastTo } from './utils' +import { logger } from '../../../helpers/logger' +import { ActivityAudience, ActivityFlag } from '../../../../shared/models/activitypub' +import { audiencify, getAudience } from '../audience' + +async function sendVideoAbuse (byActor: ActorModel, videoAbuse: VideoAbuseModel, video: VideoModel) { + if (!video.VideoChannel.Account.Actor.serverId) return // Local user + + const url = getVideoAbuseActivityPubUrl(videoAbuse) + + logger.info('Creating job to send video abuse %s.', url) + + // Custom audience, we only send the abuse to the origin instance + const audience = { to: [ video.VideoChannel.Account.Actor.url ], cc: [] } + const flagActivity = buildFlagActivity(url, byActor, videoAbuse, audience) + + return unicastTo(flagActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl) +} + +function buildFlagActivity (url: string, byActor: ActorModel, videoAbuse: VideoAbuseModel, audience: ActivityAudience): ActivityFlag { + if (!audience) audience = getAudience(byActor) + + const activity = Object.assign( + { id: url, actor: byActor.url }, + videoAbuse.toActivityPubObject() + ) + + return audiencify(activity, audience) +} + +// --------------------------------------------------------------------------- + +export { + sendVideoAbuse +} diff --git a/server/lib/activitypub/send/send-undo.ts b/server/lib/activitypub/send/send-undo.ts index bf1b6e117..eb18a6cb6 100644 --- a/server/lib/activitypub/send/send-undo.ts +++ b/server/lib/activitypub/send/send-undo.ts @@ -2,7 +2,7 @@ import { Transaction } from 'sequelize' import { ActivityAnnounce, ActivityAudience, - ActivityCreate, + ActivityCreate, ActivityDislike, ActivityFollow, ActivityLike, ActivityUndo @@ -13,13 +13,14 @@ import { VideoModel } from '../../../models/video/video' import { getActorFollowActivityPubUrl, getUndoActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from '../url' import { broadcastToFollowers, sendVideoRelatedActivity, unicastTo } from './utils' import { audiencify, getAudience } from '../audience' -import { buildCreateActivity, buildDislikeActivity } from './send-create' +import { buildCreateActivity } from './send-create' import { buildFollowActivity } from './send-follow' import { buildLikeActivity } from './send-like' import { VideoShareModel } from '../../../models/video/video-share' import { buildAnnounceWithVideoAudience } from './send-announce' import { logger } from '../../../helpers/logger' import { VideoRedundancyModel } from '../../../models/redundancy/video-redundancy' +import { buildDislikeActivity } from './send-dislike' async function sendUndoFollow (actorFollow: ActorFollowModel, t: Transaction) { const me = actorFollow.ActorFollower @@ -65,9 +66,8 @@ async function sendUndoDislike (byActor: ActorModel, video: VideoModel, t: Trans const dislikeUrl = getVideoDislikeActivityPubUrl(byActor, video) const dislikeActivity = buildDislikeActivity(dislikeUrl, byActor, video) - const createDislikeActivity = buildCreateActivity(dislikeUrl, byActor, dislikeActivity) - return sendUndoVideoRelatedActivity({ byActor, video, url: dislikeUrl, activity: createDislikeActivity, transaction: t }) + return sendUndoVideoRelatedActivity({ byActor, video, url: dislikeUrl, activity: dislikeActivity, transaction: t }) } async function sendUndoCacheFile (byActor: ActorModel, redundancyModel: VideoRedundancyModel, t: Transaction) { @@ -94,7 +94,7 @@ export { function undoActivityData ( url: string, byActor: ActorModel, - object: ActivityFollow | ActivityLike | ActivityCreate | ActivityAnnounce, + object: ActivityFollow | ActivityLike | ActivityDislike | ActivityCreate | ActivityAnnounce, audience?: ActivityAudience ): ActivityUndo { if (!audience) audience = getAudience(byActor) @@ -114,7 +114,7 @@ async function sendUndoVideoRelatedActivity (options: { byActor: ActorModel, video: VideoModel, url: string, - activity: ActivityFollow | ActivityLike | ActivityCreate | ActivityAnnounce, + activity: ActivityFollow | ActivityLike | ActivityDislike | ActivityCreate | ActivityAnnounce, transaction: Transaction }) { const activityBuilder = (audience: ActivityAudience) => { diff --git a/server/lib/activitypub/send/send-view.ts b/server/lib/activitypub/send/send-view.ts new file mode 100644 index 000000000..8ad126be0 --- /dev/null +++ b/server/lib/activitypub/send/send-view.ts @@ -0,0 +1,40 @@ +import { Transaction } from 'sequelize' +import { ActivityAudience, ActivityView } from '../../../../shared/models/activitypub' +import { ActorModel } from '../../../models/activitypub/actor' +import { VideoModel } from '../../../models/video/video' +import { getVideoLikeActivityPubUrl } from '../url' +import { sendVideoRelatedActivity } from './utils' +import { audiencify, getAudience } from '../audience' +import { logger } from '../../../helpers/logger' + +async function sendView (byActor: ActorModel, video: VideoModel, t: Transaction) { + logger.info('Creating job to send view of %s.', video.url) + + const activityBuilder = (audience: ActivityAudience) => { + const url = getVideoLikeActivityPubUrl(byActor, video) + + return buildViewActivity(url, byActor, video, audience) + } + + return sendVideoRelatedActivity(activityBuilder, { byActor, video, transaction: t }) +} + +function buildViewActivity (url: string, byActor: ActorModel, video: VideoModel, audience?: ActivityAudience): ActivityView { + if (!audience) audience = getAudience(byActor) + + return audiencify( + { + id: url, + type: 'View' as 'View', + actor: byActor.url, + object: video.url + }, + audience + ) +} + +// --------------------------------------------------------------------------- + +export { + sendView +} diff --git a/server/lib/activitypub/video-rates.ts b/server/lib/activitypub/video-rates.ts index 45a2b22ea..7aac79118 100644 --- a/server/lib/activitypub/video-rates.ts +++ b/server/lib/activitypub/video-rates.ts @@ -1,7 +1,7 @@ import { Transaction } from 'sequelize' import { AccountModel } from '../../models/account/account' import { VideoModel } from '../../models/video/video' -import { sendCreateDislike, sendLike, sendUndoDislike, sendUndoLike } from './send' +import { sendLike, sendUndoDislike, sendUndoLike } from './send' import { VideoRateType } from '../../../shared/models/videos' import * as Bluebird from 'bluebird' import { getOrCreateActorAndServerAndModel } from './actor' @@ -12,6 +12,7 @@ import { doRequest } from '../../helpers/requests' import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub' import { ActorModel } from '../../models/activitypub/actor' import { getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from './url' +import { sendDislike } from './send/send-dislike' async function createRates (ratesUrl: string[], video: VideoModel, rate: VideoRateType) { let rateCounts = 0 @@ -82,7 +83,7 @@ async function sendVideoRateChange (account: AccountModel, // Like if (likes > 0) await sendLike(actor, video, t) // Dislike - if (dislikes > 0) await sendCreateDislike(actor, video, t) + if (dislikes > 0) await sendDislike(actor, video, t) } function getRateUrl (rateType: VideoRateType, actor: ActorModel, video: VideoModel) {