Improve activity pub actors implementation
authorChocobozzz <me@florianbigard.com>
Thu, 22 Mar 2018 17:40:33 +0000 (18:40 +0100)
committerChocobozzz <me@florianbigard.com>
Thu, 22 Mar 2018 17:40:56 +0000 (18:40 +0100)
server/helpers/activitypub.ts
server/helpers/custom-validators/activitypub/activity.ts
server/helpers/custom-validators/activitypub/misc.ts
server/lib/activitypub/actor.ts
server/lib/activitypub/process/process-accept.ts
server/lib/activitypub/process/process-reject.ts
server/lib/activitypub/process/process-undo.ts
server/lib/activitypub/process/process.ts
shared/models/activitypub/activity.ts

index d64a6dd78fd6bb849e92952415303ff591756a3a..1934fa0f024b600e491948bf428736315532ca84 100644 (file)
@@ -1,5 +1,5 @@
 import { ResultList } from '../../shared/models'
-import { Activity } from '../../shared/models/activitypub'
+import { Activity, ActivityPubActor } from '../../shared/models/activitypub'
 import { ACTIVITY_PUB } from '../initializers'
 import { ActorModel } from '../models/activitypub/actor'
 import { signObject } from './peertube-crypto'
@@ -98,9 +98,16 @@ function buildSignedActivity (byActor: ActorModel, data: Object) {
   return signObject(byActor, activity) as Promise<Activity>
 }
 
+function getActorUrl (activityActor: string | ActivityPubActor) {
+  if (typeof activityActor === 'string') return activityActor
+
+  return activityActor.id
+}
+
 // ---------------------------------------------------------------------------
 
 export {
+  getActorUrl,
   activityPubContextify,
   activityPubCollectionPagination,
   activityPubCollection,
index 632f1422317c19ccc6c0aecb758e0a29cb037755..7e4dccefbceca5d2ee4dc10af9ffd9175b65db3a 100644 (file)
@@ -26,7 +26,7 @@ function isRootActivityValid (activity: any) {
     ) ||
     (
       isActivityPubUrlValid(activity.id) &&
-      isActivityPubUrlValid(activity.actor)
+      (isActivityPubUrlValid(activity.actor) || isActivityPubUrlValid(activity.actor.id))
     )
 }
 
index 75d308e9d37972a1bdda5b6eaa223d4aad8728ad..2dac8e1ad77fa38add19a2ccade8a20da23242f5 100644 (file)
@@ -24,7 +24,7 @@ function isBaseActivityValid (activity: any, type: string) {
   return (activity['@context'] === undefined || Array.isArray(activity['@context'])) &&
     activity.type === type &&
     isActivityPubUrlValid(activity.id) &&
-    isActivityPubUrlValid(activity.actor) &&
+    (isActivityPubUrlValid(activity.actor) || isActivityPubUrlValid(activity.actor.id)) &&
     (
       activity.to === undefined ||
       (Array.isArray(activity.to) && activity.to.every(t => isActivityPubUrlValid(t)))
index b7114bbee400dade56d7071521cbb6bc7d9e0396..fa31e71c76aaf15ce1070b8f96290450dfd3cd2b 100644 (file)
@@ -5,6 +5,7 @@ import * as url from 'url'
 import * as uuidv4 from 'uuid/v4'
 import { ActivityPubActor, ActivityPubActorType } from '../../../shared/models/activitypub'
 import { ActivityPubAttributedTo } from '../../../shared/models/activitypub/objects'
+import { getActorUrl } from '../../helpers/activitypub'
 import { isActorObjectValid } from '../../helpers/custom-validators/activitypub/actor'
 import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
 import { retryTransactionWrapper, updateInstanceWithAnother } from '../../helpers/database-utils'
@@ -34,7 +35,9 @@ function setAsyncActorKeys (actor: ActorModel) {
     })
 }
 
-async function getOrCreateActorAndServerAndModel (actorUrl: string, recurseIfNeeded = true) {
+async function getOrCreateActorAndServerAndModel (activityActor: string | ActivityPubActor, recurseIfNeeded = true) {
+  const actorUrl = getActorUrl(activityActor)
+
   let actor = await ActorModel.loadByUrl(actorUrl)
 
   // We don't have this actor in our database, fetch it on remote
index 7db2f8ff03c33a32468852d8d3e731497725fb28..c55b57820e698fcc635d2f4e469e6de17c5ecd69 100644 (file)
@@ -1,4 +1,5 @@
 import { ActivityAccept } from '../../../../shared/models/activitypub'
+import { getActorUrl } from '../../../helpers/activitypub'
 import { ActorModel } from '../../../models/activitypub/actor'
 import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
 import { addFetchOutboxJob } from '../fetch'
@@ -6,7 +7,8 @@ import { addFetchOutboxJob } from '../fetch'
 async function processAcceptActivity (activity: ActivityAccept, inboxActor?: ActorModel) {
   if (inboxActor === undefined) throw new Error('Need to accept on explicit inbox.')
 
-  const targetActor = await ActorModel.loadByUrl(activity.actor)
+  const actorUrl = getActorUrl(activity.actor)
+  const targetActor = await ActorModel.loadByUrl(actorUrl)
 
   return processAccept(inboxActor, targetActor)
 }
index b2de28d79e8216447b3b2530073caefd9abe150d..f06b03772d08c6135d9d6dc90ce42b209a54eb2c 100644 (file)
@@ -1,4 +1,5 @@
 import { ActivityReject } from '../../../../shared/models/activitypub/activity'
+import { getActorUrl } from '../../../helpers/activitypub'
 import { sequelizeTypescript } from '../../../initializers'
 import { ActorModel } from '../../../models/activitypub/actor'
 import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
@@ -6,7 +7,8 @@ import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
 async function processRejectActivity (activity: ActivityReject, inboxActor?: ActorModel) {
   if (inboxActor === undefined) throw new Error('Need to reject on explicit inbox.')
 
-  const targetActor = await ActorModel.loadByUrl(activity.actor)
+  const actorUrl = getActorUrl(activity.actor)
+  const targetActor = await ActorModel.loadByUrl(actorUrl)
 
   return processReject(inboxActor, targetActor)
 }
index 5a770bb972948d6e94ec55adca670f0c6eac0020..565e7028983ef265db30f71da6a684424713718a 100644 (file)
@@ -1,5 +1,6 @@
 import { ActivityFollow, ActivityLike, ActivityUndo } from '../../../../shared/models/activitypub'
 import { DislikeObject } from '../../../../shared/models/activitypub/objects'
+import { getActorUrl } from '../../../helpers/activitypub'
 import { retryTransactionWrapper } from '../../../helpers/database-utils'
 import { logger } from '../../../helpers/logger'
 import { sequelizeTypescript } from '../../../initializers'
@@ -13,12 +14,14 @@ import { getOrCreateAccountAndVideoAndChannel } from '../videos'
 async function processUndoActivity (activity: ActivityUndo) {
   const activityToUndo = activity.object
 
+  const actorUrl = getActorUrl(activity.actor)
+
   if (activityToUndo.type === 'Like') {
-    return processUndoLike(activity.actor, activity)
+    return processUndoLike(actorUrl, activity)
   } else if (activityToUndo.type === 'Create' && activityToUndo.object.type === 'Dislike') {
-    return processUndoDislike(activity.actor, activity)
+    return processUndoDislike(actorUrl, activity)
   } else if (activityToUndo.type === 'Follow') {
-    return processUndoFollow(activity.actor, activityToUndo)
+    return processUndoFollow(actorUrl, activityToUndo)
   }
 
   logger.warn('Unknown activity object type %s -> %s when undo activity.', activityToUndo.type, { activity: activity.id })
index 094219489fe2d77b7dcba2ef4be04fc8b5ad4737..10d8ba1892dbe12708c9075d0569ee3d6847ea51 100644 (file)
@@ -1,4 +1,5 @@
 import { Activity, ActivityType } from '../../../../shared/models/activitypub'
+import { getActorUrl } from '../../../helpers/activitypub'
 import { logger } from '../../../helpers/logger'
 import { ActorModel } from '../../../models/activitypub/actor'
 import { processAcceptActivity } from './process-accept'
@@ -25,9 +26,11 @@ const processActivity: { [ P in ActivityType ]: (activity: Activity, inboxActor?
 
 async function processActivities (activities: Activity[], signatureActor?: ActorModel, inboxActor?: ActorModel) {
   for (const activity of activities) {
+    const actorUrl = getActorUrl(activity.actor)
+
     // When we fetch remote data, we don't have signature
-    if (signatureActor && activity.actor !== signatureActor.url) {
-      logger.warn('Signature mismatch between %s and %s.', activity.actor, signatureActor.url)
+    if (signatureActor && actorUrl !== signatureActor.url) {
+      logger.warn('Signature mismatch between %s and %s.', actorUrl, signatureActor.url)
       continue
     }
 
index a28260ffdf84b4923894598f06d3b31c21716968..f555f011842a526decec30b2e61596033f979993 100644 (file)
@@ -22,7 +22,7 @@ export interface BaseActivity {
   id: string
   to?: string[]
   cc?: string[]
-  actor: string
+  actor: string | ActivityPubActor
   type: ActivityType
   signature?: ActivityPubSignature
 }