aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-06-05 16:18:57 +0200
committerChocobozzz <me@florianbigard.com>2023-06-29 10:18:00 +0200
commit7f7e9d4e904fed9233f84089e3b2ea60ab8740f7 (patch)
tree7407ae25a483e3e8b43443a6bbdceb067b5db8e5 /server
parentcefe22cf7c5286af1eb0e7a19937e741e2c2f58a (diff)
downloadPeerTube-7f7e9d4e904fed9233f84089e3b2ea60ab8740f7.tar.gz
PeerTube-7f7e9d4e904fed9233f84089e3b2ea60ab8740f7.tar.zst
PeerTube-7f7e9d4e904fed9233f84089e3b2ea60ab8740f7.zip
Handle correctly formatted AP attributedTo
Diffstat (limited to 'server')
-rw-r--r--server/helpers/custom-validators/activitypub/misc.ts3
-rw-r--r--server/lib/activitypub/actors/get.ts42
-rw-r--r--server/lib/activitypub/playlists/create-update.ts2
-rw-r--r--server/lib/activitypub/videos/shared/abstract-builder.ts9
4 files changed, 36 insertions, 20 deletions
diff --git a/server/helpers/custom-validators/activitypub/misc.ts b/server/helpers/custom-validators/activitypub/misc.ts
index 279ad83dc..7df47cf15 100644
--- a/server/helpers/custom-validators/activitypub/misc.ts
+++ b/server/helpers/custom-validators/activitypub/misc.ts
@@ -51,7 +51,8 @@ function setValidAttributedTo (obj: any) {
51 } 51 }
52 52
53 obj.attributedTo = obj.attributedTo.filter(a => { 53 obj.attributedTo = obj.attributedTo.filter(a => {
54 return (a.type === 'Group' || a.type === 'Person') && isActivityPubUrlValid(a.id) 54 return isActivityPubUrlValid(a) ||
55 ((a.type === 'Group' || a.type === 'Person') && isActivityPubUrlValid(a.id))
55 }) 56 })
56 57
57 return true 58 return true
diff --git a/server/lib/activitypub/actors/get.ts b/server/lib/activitypub/actors/get.ts
index e73b7d707..b2be3f5fb 100644
--- a/server/lib/activitypub/actors/get.ts
+++ b/server/lib/activitypub/actors/get.ts
@@ -3,8 +3,9 @@ import { logger } from '@server/helpers/logger'
3import { JobQueue } from '@server/lib/job-queue' 3import { JobQueue } from '@server/lib/job-queue'
4import { ActorLoadByUrlType, loadActorByUrl } from '@server/lib/model-loaders' 4import { ActorLoadByUrlType, loadActorByUrl } from '@server/lib/model-loaders'
5import { MActor, MActorAccountChannelId, MActorAccountChannelIdActor, MActorAccountId, MActorFullActor } from '@server/types/models' 5import { MActor, MActorAccountChannelId, MActorAccountChannelIdActor, MActorAccountId, MActorFullActor } from '@server/types/models'
6import { ActivityPubActor } from '@shared/models' 6import { arrayify } from '@shared/core-utils'
7import { getAPId } from '../activity' 7import { ActivityPubActor, APObjectId } from '@shared/models'
8import { fetchAPObject, getAPId } from '../activity'
8import { checkUrlsSameHost } from '../url' 9import { checkUrlsSameHost } from '../url'
9import { refreshActorIfNeeded } from './refresh' 10import { refreshActorIfNeeded } from './refresh'
10import { APActorCreator, fetchRemoteActor } from './shared' 11import { APActorCreator, fetchRemoteActor } from './shared'
@@ -40,7 +41,7 @@ async function getOrCreateAPActor (
40 const { actorObject } = await fetchRemoteActor(actorUrl) 41 const { actorObject } = await fetchRemoteActor(actorUrl)
41 if (actorObject === undefined) throw new Error('Cannot fetch remote actor ' + actorUrl) 42 if (actorObject === undefined) throw new Error('Cannot fetch remote actor ' + actorUrl)
42 43
43 // actorUrl is just an alias/rediraction, so process object id instead 44 // actorUrl is just an alias/redirection, so process object id instead
44 if (actorObject.id !== actorUrl) return getOrCreateAPActor(actorObject, 'all', recurseIfNeeded, updateCollections) 45 if (actorObject.id !== actorUrl) return getOrCreateAPActor(actorObject, 'all', recurseIfNeeded, updateCollections)
45 46
46 // Create the attributed to actor 47 // Create the attributed to actor
@@ -68,29 +69,48 @@ async function getOrCreateAPActor (
68 return actorRefreshed 69 return actorRefreshed
69} 70}
70 71
71function getOrCreateAPOwner (actorObject: ActivityPubActor, actorUrl: string) { 72async function getOrCreateAPOwner (actorObject: ActivityPubActor, actorUrl: string) {
72 const accountAttributedTo = actorObject.attributedTo.find(a => a.type === 'Person') 73 const accountAttributedTo = await findOwner(actorUrl, actorObject.attributedTo, 'Person')
73 if (!accountAttributedTo) throw new Error('Cannot find account attributed to video channel ' + actorUrl) 74 if (!accountAttributedTo) {
74 75 throw new Error(`Cannot find account attributed to video channel ${actorUrl}`)
75 if (checkUrlsSameHost(accountAttributedTo.id, actorUrl) !== true) {
76 throw new Error(`Account attributed to ${accountAttributedTo.id} does not have the same host than actor url ${actorUrl}`)
77 } 76 }
78 77
79 try { 78 try {
80 // Don't recurse another time 79 // Don't recurse another time
81 const recurseIfNeeded = false 80 const recurseIfNeeded = false
82 return getOrCreateAPActor(accountAttributedTo.id, 'all', recurseIfNeeded) 81 return getOrCreateAPActor(accountAttributedTo, 'all', recurseIfNeeded)
83 } catch (err) { 82 } catch (err) {
84 logger.error('Cannot get or create account attributed to video channel ' + actorUrl) 83 logger.error('Cannot get or create account attributed to video channel ' + actorUrl)
85 throw new Error(err) 84 throw new Error(err)
86 } 85 }
87} 86}
88 87
88async function findOwner (rootUrl: string, attributedTo: APObjectId[] | APObjectId, type: 'Person' | 'Group') {
89 for (const actorToCheck of arrayify(attributedTo)) {
90 const actorObject = await fetchAPObject<ActivityPubActor>(getAPId(actorToCheck))
91
92 if (!actorObject) {
93 logger.warn('Unknown attributed to actor %s for owner %s', actorToCheck, rootUrl)
94 continue
95 }
96
97 if (checkUrlsSameHost(actorObject.id, rootUrl) !== true) {
98 logger.warn(`Account attributed to ${actorObject.id} does not have the same host than owner actor url ${rootUrl}`)
99 continue
100 }
101
102 if (actorObject.type === type) return actorObject
103 }
104
105 return undefined
106}
107
89// --------------------------------------------------------------------------- 108// ---------------------------------------------------------------------------
90 109
91export { 110export {
92 getOrCreateAPOwner, 111 getOrCreateAPOwner,
93 getOrCreateAPActor 112 getOrCreateAPActor,
113 findOwner
94} 114}
95 115
96// --------------------------------------------------------------------------- 116// ---------------------------------------------------------------------------
diff --git a/server/lib/activitypub/playlists/create-update.ts b/server/lib/activitypub/playlists/create-update.ts
index 9339e8ea4..920d3943a 100644
--- a/server/lib/activitypub/playlists/create-update.ts
+++ b/server/lib/activitypub/playlists/create-update.ts
@@ -77,7 +77,7 @@ async function setVideoChannel (playlistObject: PlaylistObject, playlistAttribut
77 throw new Error('Not attributed to for playlist object ' + getAPId(playlistObject)) 77 throw new Error('Not attributed to for playlist object ' + getAPId(playlistObject))
78 } 78 }
79 79
80 const actor = await getOrCreateAPActor(playlistObject.attributedTo[0], 'all') 80 const actor = await getOrCreateAPActor(getAPId(playlistObject.attributedTo[0]), 'all')
81 81
82 if (!actor.VideoChannel) { 82 if (!actor.VideoChannel) {
83 logger.warn('Playlist "attributedTo" %s is not a video channel.', playlistObject.id, { playlistObject, ...lTags(playlistObject.id) }) 83 logger.warn('Playlist "attributedTo" %s is not a video channel.', playlistObject.id, { playlistObject, ...lTags(playlistObject.id) })
diff --git a/server/lib/activitypub/videos/shared/abstract-builder.ts b/server/lib/activitypub/videos/shared/abstract-builder.ts
index 7c5c73139..8af67ecac 100644
--- a/server/lib/activitypub/videos/shared/abstract-builder.ts
+++ b/server/lib/activitypub/videos/shared/abstract-builder.ts
@@ -18,8 +18,7 @@ import {
18 MVideoThumbnail 18 MVideoThumbnail
19} from '@server/types/models' 19} from '@server/types/models'
20import { ActivityTagObject, ThumbnailType, VideoObject, VideoStreamingPlaylistType } from '@shared/models' 20import { ActivityTagObject, ThumbnailType, VideoObject, VideoStreamingPlaylistType } from '@shared/models'
21import { getOrCreateAPActor } from '../../actors' 21import { findOwner, getOrCreateAPActor } from '../../actors'
22import { checkUrlsSameHost } from '../../url'
23import { 22import {
24 getCaptionAttributesFromObject, 23 getCaptionAttributesFromObject,
25 getFileAttributesFromUrl, 24 getFileAttributesFromUrl,
@@ -37,13 +36,9 @@ export abstract class APVideoAbstractBuilder {
37 protected abstract lTags: LoggerTagsFn 36 protected abstract lTags: LoggerTagsFn
38 37
39 protected async getOrCreateVideoChannelFromVideoObject () { 38 protected async getOrCreateVideoChannelFromVideoObject () {
40 const channel = this.videoObject.attributedTo.find(a => a.type === 'Group') 39 const channel = await findOwner(this.videoObject.id, this.videoObject.attributedTo, 'Group')
41 if (!channel) throw new Error('Cannot find associated video channel to video ' + this.videoObject.url) 40 if (!channel) throw new Error('Cannot find associated video channel to video ' + this.videoObject.url)
42 41
43 if (checkUrlsSameHost(channel.id, this.videoObject.id) !== true) {
44 throw new Error(`Video channel url ${channel.id} does not have the same host than video object id ${this.videoObject.id}`)
45 }
46
47 return getOrCreateAPActor(channel.id, 'all') 42 return getOrCreateAPActor(channel.id, 'all')
48 } 43 }
49 44