Handle correctly formatted AP attributedTo

pull/5870/head
Chocobozzz 2023-06-05 16:18:57 +02:00
parent cefe22cf7c
commit 7f7e9d4e90
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
7 changed files with 41 additions and 28 deletions

View File

@ -51,7 +51,8 @@ function setValidAttributedTo (obj: any) {
}
obj.attributedTo = obj.attributedTo.filter(a => {
return (a.type === 'Group' || a.type === 'Person') && isActivityPubUrlValid(a.id)
return isActivityPubUrlValid(a) ||
((a.type === 'Group' || a.type === 'Person') && isActivityPubUrlValid(a.id))
})
return true

View File

@ -3,8 +3,9 @@ import { logger } from '@server/helpers/logger'
import { JobQueue } from '@server/lib/job-queue'
import { ActorLoadByUrlType, loadActorByUrl } from '@server/lib/model-loaders'
import { MActor, MActorAccountChannelId, MActorAccountChannelIdActor, MActorAccountId, MActorFullActor } from '@server/types/models'
import { ActivityPubActor } from '@shared/models'
import { getAPId } from '../activity'
import { arrayify } from '@shared/core-utils'
import { ActivityPubActor, APObjectId } from '@shared/models'
import { fetchAPObject, getAPId } from '../activity'
import { checkUrlsSameHost } from '../url'
import { refreshActorIfNeeded } from './refresh'
import { APActorCreator, fetchRemoteActor } from './shared'
@ -40,7 +41,7 @@ async function getOrCreateAPActor (
const { actorObject } = await fetchRemoteActor(actorUrl)
if (actorObject === undefined) throw new Error('Cannot fetch remote actor ' + actorUrl)
// actorUrl is just an alias/rediraction, so process object id instead
// actorUrl is just an alias/redirection, so process object id instead
if (actorObject.id !== actorUrl) return getOrCreateAPActor(actorObject, 'all', recurseIfNeeded, updateCollections)
// Create the attributed to actor
@ -68,29 +69,48 @@ async function getOrCreateAPActor (
return actorRefreshed
}
function getOrCreateAPOwner (actorObject: ActivityPubActor, actorUrl: string) {
const accountAttributedTo = actorObject.attributedTo.find(a => a.type === 'Person')
if (!accountAttributedTo) throw new Error('Cannot find account attributed to video channel ' + actorUrl)
if (checkUrlsSameHost(accountAttributedTo.id, actorUrl) !== true) {
throw new Error(`Account attributed to ${accountAttributedTo.id} does not have the same host than actor url ${actorUrl}`)
async function getOrCreateAPOwner (actorObject: ActivityPubActor, actorUrl: string) {
const accountAttributedTo = await findOwner(actorUrl, actorObject.attributedTo, 'Person')
if (!accountAttributedTo) {
throw new Error(`Cannot find account attributed to video channel ${actorUrl}`)
}
try {
// Don't recurse another time
const recurseIfNeeded = false
return getOrCreateAPActor(accountAttributedTo.id, 'all', recurseIfNeeded)
return getOrCreateAPActor(accountAttributedTo, 'all', recurseIfNeeded)
} catch (err) {
logger.error('Cannot get or create account attributed to video channel ' + actorUrl)
throw new Error(err)
}
}
async function findOwner (rootUrl: string, attributedTo: APObjectId[] | APObjectId, type: 'Person' | 'Group') {
for (const actorToCheck of arrayify(attributedTo)) {
const actorObject = await fetchAPObject<ActivityPubActor>(getAPId(actorToCheck))
if (!actorObject) {
logger.warn('Unknown attributed to actor %s for owner %s', actorToCheck, rootUrl)
continue
}
if (checkUrlsSameHost(actorObject.id, rootUrl) !== true) {
logger.warn(`Account attributed to ${actorObject.id} does not have the same host than owner actor url ${rootUrl}`)
continue
}
if (actorObject.type === type) return actorObject
}
return undefined
}
// ---------------------------------------------------------------------------
export {
getOrCreateAPOwner,
getOrCreateAPActor
getOrCreateAPActor,
findOwner
}
// ---------------------------------------------------------------------------

View File

@ -77,7 +77,7 @@ async function setVideoChannel (playlistObject: PlaylistObject, playlistAttribut
throw new Error('Not attributed to for playlist object ' + getAPId(playlistObject))
}
const actor = await getOrCreateAPActor(playlistObject.attributedTo[0], 'all')
const actor = await getOrCreateAPActor(getAPId(playlistObject.attributedTo[0]), 'all')
if (!actor.VideoChannel) {
logger.warn('Playlist "attributedTo" %s is not a video channel.', playlistObject.id, { playlistObject, ...lTags(playlistObject.id) })

View File

@ -18,8 +18,7 @@ import {
MVideoThumbnail
} from '@server/types/models'
import { ActivityTagObject, ThumbnailType, VideoObject, VideoStreamingPlaylistType } from '@shared/models'
import { getOrCreateAPActor } from '../../actors'
import { checkUrlsSameHost } from '../../url'
import { findOwner, getOrCreateAPActor } from '../../actors'
import {
getCaptionAttributesFromObject,
getFileAttributesFromUrl,
@ -37,13 +36,9 @@ export abstract class APVideoAbstractBuilder {
protected abstract lTags: LoggerTagsFn
protected async getOrCreateVideoChannelFromVideoObject () {
const channel = this.videoObject.attributedTo.find(a => a.type === 'Group')
const channel = await findOwner(this.videoObject.id, this.videoObject.attributedTo, 'Group')
if (!channel) throw new Error('Cannot find associated video channel to video ' + this.videoObject.url)
if (checkUrlsSameHost(channel.id, this.videoObject.id) !== true) {
throw new Error(`Video channel url ${channel.id} does not have the same host than video object id ${this.videoObject.id}`)
}
return getOrCreateAPActor(channel.id, 'all')
}

View File

@ -114,10 +114,7 @@ export type ActivityUrlObject =
| ActivityVideoFileMetadataUrlObject
| ActivityTrackerUrlObject
export interface ActivityPubAttributedTo {
type: 'Group' | 'Person'
id: string
}
export type ActivityPubAttributedTo = { type: 'Group' | 'Person', id: string } | string
export interface ActivityTombstoneObject {
'@context'?: any

View File

@ -1,4 +1,4 @@
import { ActivityIconObject } from './common-objects'
import { ActivityIconObject, ActivityPubAttributedTo } from './common-objects'
export interface PlaylistObject {
id: string
@ -12,7 +12,7 @@ export interface PlaylistObject {
uuid: string
totalItems: number
attributedTo: string[]
attributedTo: ActivityPubAttributedTo[]
icon?: ActivityIconObject

View File

@ -1,4 +1,4 @@
import { ActivityTagObject } from './common-objects'
import { ActivityPubAttributedTo, ActivityTagObject } from './common-objects'
export interface VideoCommentObject {
type: 'Note'
@ -11,6 +11,6 @@ export interface VideoCommentObject {
published: string
updated: string
url: string
attributedTo: string
attributedTo: ActivityPubAttributedTo
tag: ActivityTagObject[]
}