bridgy-fed icon indicating copy to clipboard operation
bridgy-fed copied to clipboard

support peertube

Open swentel opened this issue 7 years ago • 19 comments

https://github.com/Chocobozzz/PeerTube https://docs.joinpeertube.org/lang/en/devdocs/federation.html

apparently it can communicate with mastodon, so sounds hopeful :)

swentel avatar Nov 02 '18 09:11 swentel

Tried adding a comment, no luck, bummer - it crashes out heavily :)

see https://fed.brid.gy/log?start_time=1544538485&key=https%3A%2F%2Frealize.be%2Freply%2Fcontent%2F1686+https%3A%2F%2Fvideo.jacky.wtf%2Fvideos%2Fwatch%2Fadebaeae-c0c5-4519-8305-2ce5e296e05e

swentel avatar Dec 11 '18 14:12 swentel

thanks for testing! i've fixed that bug. we now get a 400 from peertube on the AP request. body below.

they're not looking in HTTP headers for our signature, or they're looking in the wrong place, or somehow else they expect a different flavor of HTTP Signature than we currently have working with Mastodon.

background:

  • https://w3c.github.io/activitypub/#authorization-lds
  • https://tools.ietf.org/html/draft-cavage-http-signatures-07
  • https://github.com/tootsuite/mastodon/issues/4906#issuecomment-328844846
{
  "errors": {
    "signature.type": {
      "location": "body",
      "param": "signature.type",
      "msg": "Should have a valid signature type"
    },
    "signature.created": {
      "location": "body",
      "param": "signature.created",
      "msg": "Should have a valid signature created date"
    },
    "signature.creator": {
      "location": "body",
      "param": "signature.creator",
      "msg": "Should have a valid signature creator"
    },
    "signature.signatureValue": {
      "location": "body",
      "param": "signature.signatureValue",
      "msg": "Should have a valid signature value"
    }
  }
}

snarfed avatar Dec 11 '18 19:12 snarfed

Yes, when sending the signature in the body, I can get past validation, but then I'm greeted with a 500 response :) We'll have to ping jacky to see if he sees anything in the logs which might be useful.

swentel avatar Dec 11 '18 20:12 swentel

This looks like the bit here:

[36m2018-12-11T19:47:48.359438136Z app[web.1]:[0m [video.jacky.wtf:443] 2018-12-11 19:47:48.358 [33mwarn[39m: Incorrect request parameters {
[36m2018-12-11T19:47:48.359548304Z app[web.1]:[0m   "meta": {
[36m2018-12-11T19:47:48.359557906Z app[web.1]:[0m     "path": "/accounts/root/inbox",
[36m2018-12-11T19:47:48.359562297Z app[web.1]:[0m     "err": {
[36m2018-12-11T19:47:48.359566218Z app[web.1]:[0m       "signature.type": {
[36m2018-12-11T19:47:48.359570308Z app[web.1]:[0m         "location": "body",
[36m2018-12-11T19:47:48.359574431Z app[web.1]:[0m         "param": "signature.type",
[36m2018-12-11T19:47:48.359578780Z app[web.1]:[0m         "value": "keyId=\"https://fed.brid.gy/realize.be#main-key\",algorithm=\"rsa-sha256\",headers=\"date\",signature=\"FSBsV9l04dAT6fooQXTXuVQvdaoGkDqLP2aDPnVtrpp0rEEm70ZhJizrvUGzkyE5EXTQCJC30XDd46J7Sw/644hPmtdLjCb4Yh6ARyud4Xg1w8A4jMF5PIIZNuVmGD1jljMchvMxksxgJ6bIJI6+l8v2Rnw92XYLn96OIwrisUQ=\"",
[36m2018-12-11T19:47:48.359585585Z app[web.1]:[0m         "msg": "Should have a valid signature type"
[36m2018-12-11T19:47:48.359589945Z app[web.1]:[0m       },
[36m2018-12-11T19:47:48.359593645Z app[web.1]:[0m       "signature.created": {
[36m2018-12-11T19:47:48.359597611Z app[web.1]:[0m         "location": "body",
[36m2018-12-11T19:47:48.359623217Z app[web.1]:[0m         "param": "signature.created",
[36m2018-12-11T19:47:48.359628686Z app[web.1]:[0m         "msg": "Should have a valid signature created date"
[36m2018-12-11T19:47:48.359632770Z app[web.1]:[0m       },
[36m2018-12-11T19:47:48.359636519Z app[web.1]:[0m       "signature.creator": {
[36m2018-12-11T19:47:48.359640371Z app[web.1]:[0m         "location": "body",
[36m2018-12-11T19:47:48.359644559Z app[web.1]:[0m         "param": "signature.creator",
[36m2018-12-11T19:47:48.359648687Z app[web.1]:[0m         "msg": "Should have a valid signature creator"
[36m2018-12-11T19:47:48.359653289Z app[web.1]:[0m       },
[36m2018-12-11T19:47:48.359657017Z app[web.1]:[0m       "signature.signatureValue": {
[36m2018-12-11T19:47:48.359661257Z app[web.1]:[0m         "location": "body",
[36m2018-12-11T19:47:48.359665308Z app[web.1]:[0m         "param": "signature.signatureValue",
[36m2018-12-11T19:47:48.359669412Z app[web.1]:[0m         "msg": "Should have a valid signature value"
[36m2018-12-11T19:47:48.359673343Z app[web.1]:[0m       }
[36m2018-12-11T19:47:48.359677508Z app[web.1]:[0m     }
[36m2018-12-11T19:47:48.359709514Z app[web.1]:[0m   },
[36m2018-12-11T19:47:48.359714186Z app[web.1]:[0m   "err": {
[36m2018-12-11T19:47:48.359717647Z app[web.1]:[0m     "signature.type": {
[36m2018-12-11T19:47:48.359721000Z app[web.1]:[0m       "location": "body",
[36m2018-12-11T19:47:48.359724661Z app[web.1]:[0m       "param": "signature.type",
[36m2018-12-11T19:47:48.359728332Z app[web.1]:[0m       "value": "keyId=\"https://fed.brid.gy/realize.be#main-key\",algorithm=\"rsa-sha256\",headers=\"date\",signature=\"FSBsV9l04dAT6fooQXTXuVQvdaoGkDqLP2aDPnVtrpp0rEEm70ZhJizrvUGzkyE5EXTQCJC30XDd46J7Sw/644hPmtdLjCb4Yh6ARyud4Xg1w8A4jMF5PIIZNuVmGD1jljMchvMxksxgJ6bIJI6+l8v2Rnw92XYLn96OIwrisUQ=\"",
[36m2018-12-11T19:47:48.359733350Z app[web.1]:[0m       "msg": "Should have a valid signature type"
[36m2018-12-11T19:47:48.359736895Z app[web.1]:[0m     },
[36m2018-12-11T19:47:48.359740212Z app[web.1]:[0m     "signature.created": {
[36m2018-12-11T19:47:48.359743584Z app[web.1]:[0m       "location": "body",
[36m2018-12-11T19:47:48.359747427Z app[web.1]:[0m       "param": "signature.created",
[36m2018-12-11T19:47:48.359751382Z app[web.1]:[0m       "msg": "Should have a valid signature created date"
[36m2018-12-11T19:47:48.359754918Z app[web.1]:[0m     },
[36m2018-12-11T19:47:48.359758222Z app[web.1]:[0m     "signature.creator": {
[36m2018-12-11T19:47:48.359761574Z app[web.1]:[0m       "location": "body",
[36m2018-12-11T19:47:48.359765174Z app[web.1]:[0m       "param": "signature.creator",
[36m2018-12-11T19:47:48.359787209Z app[web.1]:[0m       "msg": "Should have a valid signature creator"
[36m2018-12-11T19:47:48.359791613Z app[web.1]:[0m     },
[36m2018-12-11T19:47:48.359794951Z app[web.1]:[0m     "signature.signatureValue": {
[36m2018-12-11T19:47:48.359798314Z app[web.1]:[0m       "location": "body",
[36m2018-12-11T19:47:48.359801826Z app[web.1]:[0m       "param": "signature.signatureValue",
[36m2018-12-11T19:47:48.359805337Z app[web.1]:[0m       "msg": "Should have a valid signature value"
[36m2018-12-11T19:47:48.359808962Z app[web.1]:[0m     }
[36m2018-12-11T19:47:48.359812116Z app[web.1]:[0m   }
[36m2018-12-11T19:47:48.359815369Z app[web.1]:[0m }
[36m2018-12-11T19:48:45.636942544Z app[web.1]:[0m [video.jacky.wtf:443] 2018-12-11 19:48:45.636 [33mwarn[39m: Incorrect request parameters {
[36m2018-12-11T19:48:45.636972589Z app[web.1]:[0m   "meta": {
[36m2018-12-11T19:48:45.636977974Z app[web.1]:[0m     "path": "/accounts/root/inbox",
[36m2018-12-11T19:48:45.636982258Z app[web.1]:[0m     "err": {
[36m2018-12-11T19:48:45.637009324Z app[web.1]:[0m       "signature.type": {
[36m2018-12-11T19:48:45.637014519Z app[web.1]:[0m         "location": "body",
[36m2018-12-11T19:48:45.637020284Z app[web.1]:[0m         "param": "signature.type",
[36m2018-12-11T19:48:45.637026453Z app[web.1]:[0m         "msg": "Should have a valid signature type"
[36m2018-12-11T19:48:45.637032863Z app[web.1]:[0m       },
[36m2018-12-11T19:48:45.637037198Z app[web.1]:[0m       "signature.created": {
[36m2018-12-11T19:48:45.637041306Z app[web.1]:[0m         "location": "body",
[36m2018-12-11T19:48:45.637045318Z app[web.1]:[0m         "param": "signature.created",
[36m2018-12-11T19:48:45.637049453Z app[web.1]:[0m         "msg": "Should have a valid signature created date"
[36m2018-12-11T19:48:45.637065061Z app[web.1]:[0m       },
[36m2018-12-11T19:48:45.637089190Z app[web.1]:[0m       "signature.creator": {
[36m2018-12-11T19:48:45.637095308Z app[web.1]:[0m         "location": "body",
[36m2018-12-11T19:48:45.637098962Z app[web.1]:[0m         "param": "signature.creator",
[36m2018-12-11T19:48:45.637102454Z app[web.1]:[0m         "msg": "Should have a valid signature creator"
[36m2018-12-11T19:48:45.637105951Z app[web.1]:[0m       },
[36m2018-12-11T19:48:45.637109142Z app[web.1]:[0m       "signature.signatureValue": {
[36m2018-12-11T19:48:45.637112590Z app[web.1]:[0m         "location": "body",
[36m2018-12-11T19:48:45.637116097Z app[web.1]:[0m         "param": "signature.signatureValue",
[36m2018-12-11T19:48:45.637119627Z app[web.1]:[0m         "msg": "Should have a valid signature value"
[36m2018-12-11T19:48:45.637123067Z app[web.1]:[0m       }
[36m2018-12-11T19:48:45.637126337Z app[web.1]:[0m     }
[36m2018-12-11T19:48:45.637129461Z app[web.1]:[0m   },
[36m2018-12-11T19:48:45.637132666Z app[web.1]:[0m   "err": {
[36m2018-12-11T19:48:45.637135989Z app[web.1]:[0m     "signature.type": {
[36m2018-12-11T19:48:45.637139414Z app[web.1]:[0m       "location": "body",
[36m2018-12-11T19:48:45.637142815Z app[web.1]:[0m       "param": "signature.type",
[36m2018-12-11T19:48:45.637146325Z app[web.1]:[0m       "msg": "Should have a valid signature type"
[36m2018-12-11T19:48:45.637149740Z app[web.1]:[0m     },
[36m2018-12-11T19:48:45.637171031Z app[web.1]:[0m     "signature.created": {
[36m2018-12-11T19:48:45.637175417Z app[web.1]:[0m       "location": "body",
[36m2018-12-11T19:48:45.637178946Z app[web.1]:[0m       "param": "signature.created",
[36m2018-12-11T19:48:45.637182358Z app[web.1]:[0m       "msg": "Should have a valid signature created date"
[36m2018-12-11T19:48:45.637185950Z app[web.1]:[0m     },
[36m2018-12-11T19:48:45.637189066Z app[web.1]:[0m     "signature.creator": {
[36m2018-12-11T19:48:45.637192352Z app[web.1]:[0m       "location": "body",
[36m2018-12-11T19:48:45.637196206Z app[web.1]:[0m       "param": "signature.creator",
[36m2018-12-11T19:48:45.637199858Z app[web.1]:[0m       "msg": "Should have a valid signature creator"
[36m2018-12-11T19:48:45.637203285Z app[web.1]:[0m     },
[36m2018-12-11T19:48:45.637206581Z app[web.1]:[0m     "signature.signatureValue": {
[36m2018-12-11T19:48:45.637209909Z app[web.1]:[0m       "location": "body",
[36m2018-12-11T19:48:45.637213437Z app[web.1]:[0m       "param": "signature.signatureValue",
[36m2018-12-11T19:48:45.637216966Z app[web.1]:[0m       "msg": "Should have a valid signature value"
[36m2018-12-11T19:48:45.637220510Z app[web.1]:[0m     }
[36m2018-12-11T19:48:45.637223710Z app[web.1]:[0m   }
[36m2018-12-11T19:48:45.637226899Z app[web.1]:[0m }

jalcine avatar Dec 11 '18 22:12 jalcine

@swentel errors look basically the same. i suspect they may not support rsa-sha256? any idea which algorithms they do support? or do you think i'm misinterpreting?

snarfed avatar Dec 11 '18 22:12 snarfed

Lemme ask on IRC; it'd be weird if the algo wasn't supported

jalcine avatar Dec 11 '18 22:12 jalcine

IRC might take a while but PeerTube uses libsodium via a binding which (IIRC) supports SHA256

jalcine avatar Dec 11 '18 22:12 jalcine

Yeah so the upper library jsonld-signatures isn't up to date (it's a pinned version). That might have something to do with it.

jalcine avatar Dec 11 '18 23:12 jalcine

Hi, I'm the developer of peertube.

Could you copy the body of your request so I can investigate? If you use HTTP signature (that peertube supports), you don't need to add the signature field in the body.

Chocobozzz avatar Dec 12 '18 07:12 Chocobozzz

@Chocobozzz Hey, thanks for jumping in here! (note, I'll be on #peertube when I'm online, feel free to ping me there)

Interestingly enough, I'm getting 403 now with or without 'signature' in the header or when I omit signature params from the body. So this is what I'm sending:

Headers

Array
(
    [Content-Type] => application/activity+json
    [date] => 2018-12-12T08:09:40+0000
    [signature] => keyId="https://fed.brid.gy/realize.be#main-key",algorithm="rsa-sha256",headers="date",signature="REDACTED"
)

Object

stdClass Object
(
    [@context] => Array
        (
            [0] => https://www.w3.org/ns/activitystreams
            [1] => https://w3id.org/security/v1
        )

    [type] => Create
    [actor] => https://fed.brid.gy/r/http://realize.be
    [to] => Array
        (
            [0] => https://www.w3.org/ns/activitystreams#Public
            [1] => https://video.jacky.wtf/accounts/root
        )

    [object] => stdClass Object
        (
            [id] => https://fed.brid.gy/r/https://realize.be/reply/content/1686
            [type] => Note
            [published] => 2018-12-12T08:09:40Z
            [content] => Great to see a my app mentioned in a presentation :)
            [inReplyTo] => https://video.jacky.wtf/videos/watch/adebaeae-c0c5-4519-8305-2ce5e296e05e
            [to] => Array
                (
                    [0] => https://www.w3.org/ns/activitystreams#Public
                    [1] => https://video.jacky.wtf/accounts/root
                )

        )

    [signature.signatureValue] => REDACTED
    [signature.creator] => https://fed.brid.gy/realize.be#main-key
    [signature.created] => 2018-12-12T08:09:40+0000
    [signature.type] => RsaSignature2017
)

If I do not send the signature params, I'm getting the 403 error response now, so it looks like it might be the signature now ?

 [error]  Client error: `POST https://video.jacky.wtf/accounts/root/inbox` resulted in a `403 Forbidden` response:
Forbidden

This is what I got yesterday when for instance signature.type was missing in the body (and no signature in the header)

[error]  Client error: `POST https://video.jacky.wtf/accounts/root/inbox` resulted in a `400 Bad Request` response:
{"errors":{"signature.type":{"location":"body","param":"signature.type","msg":"Should have a valid signature type"},"sig (truncated...)

swentel avatar Dec 12 '18 08:12 swentel

We did some quick debugging on IRC to peertube2.cpy.re, and it looked like the actor object wasn't valid which I was sending. The validation can be seen at https://github.com/Chocobozzz/PeerTube/blob/develop/server/helpers/custom-validators/activitypub/actor.ts#L44

So I experimented a bit with the actor object and sending this now (some urls don't exist, but it seems the validators simply check whether the URL is valid, don't actually do a request), but still 403.

    [actor] => stdClass Object
        (
            [id] => https://fed.brid.gy/realize.be
            [type] => Person
            [following] => https://fed.brid.gy/realize.be/following
            [followers] => https://fed.brid.gy/realize.be/followers
            [inbox] => https://fed.brid.gy/realize.be/inbox
            [outbox] => https://fed.brid.gy/realize.be/outbox
            [preferredUsername] => realize.be
            [url] => https://fed.brid.gy/r/http://realize.be
            [publicKey] => stdClass Object
                (
                    [id] => https://fed.brid.gy/realize.be
                    [owner] => https://fed.brid.gy/realize.be
                    [publicKeyPem] => REDACTED
                )

            [endpoints] => stdClass Object
                (
                    [sharedInbox] => https://fed.brid.gy/shared-inbox
                )

        )

swentel avatar Dec 12 '18 10:12 swentel

@swentel The object behind https://fed.brid.gy/realize.be should be in this format too

Chocobozzz avatar Dec 13 '18 08:12 Chocobozzz

@Chocobozzz hmm which object/property do you mean exactly ?

swentel avatar Dec 13 '18 12:12 swentel

This object:

-> % ap_curl https://fed.brid.gy/realize.be
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   891  100   891    0     0    786      0  0:00:01  0:00:01 --:--:--   787
{
  "preferredUsername": "realize.be",
  "name": "swentel",
  "url": "https://fed.brid.gy/r/http://realize.be",
  "image": [
    {
      "url": "https://realize.be/vue/images/swentel-200.png",
      "type": "Image",
      "name": "swentel"
    }
  ],
  "publicKey": {
    "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCYiVcwkf2ba8ftHhgL8cwBjaQ\nLYfLB5TdjTYkJ6YAWIrFYBdZbXEYRqLouX8VyNqvkIGSLtogR+GQDzIPdsOlo/pr\nGiDK5fF34DbD2iycfRwCPuM6VhwZcG4hZhRXVGvreR0ru4T3M+4mjmRWhto9BCLk\nhVBC79trHtcOLo+UgwIDAQAB\n-----END PUBLIC KEY-----"
  },
  "inbox": "https://fed.brid.gy/realize.be/inbox",
  "@context": "https://www.w3.org/ns/activitystreams",
  "type": "Person",
  "id": "https://fed.brid.gy/realize.be",
  "icon": [
    {
      "url": "https://realize.be/vue/images/swentel-200.png",
      "type": "Image",
      "name": "swentel"
    }
  ]
}

It is missing outbox, followers, following etc

Chocobozzz avatar Dec 13 '18 12:12 Chocobozzz

Oh ok, makes sense. I can't control the output of that one sadly enough, that's something that @snarfed will have to add then.

swentel avatar Dec 13 '18 12:12 swentel

@Chocobozzz thanks for looking at this!

fwiw, AP technically says that outbox is required (MUST), but followers and following are only recommended (SHOULD), not strictly required: https://w3c.github.io/activitypub/#actor-objects

outbox isn't straightforward for bridgy fed, since it doesn't support AP client-to-server, and it would need to do a nontrivial amount of extra work to find and fetch all of a user's posts, since it's not the canonical store...but it definitely is doable. followers and following are too.

...having said that, though, do you actually need or use those properties to accept an incoming federated post? or does your AP library just validate overly strictly and require them? if you don't use them, any chance you could relax your AP code or library a bit?

thanks again for looking!

snarfed avatar Dec 13 '18 19:12 snarfed

i added the outbox, followers, and following fields recently. i haven't actually implemented them yet - all three fields point to nonexistent endpoint URLs - but this may get us a bit farther in interop testing? @swentel feel free to try!

example from https://fed.brid.gy/realize.be :

{
  "@context": "https://www.w3.org/ns/activitystreams", 
  "type": "Person", 
  "id": "https://fed.brid.gy/realize.be", 
  "inbox": "https://fed.brid.gy/realize.be/inbox", 
  "outbox": "https://fed.brid.gy/realize.be/outbox", 
  "followers": "https://fed.brid.gy/realize.be/followers", 
  "following": "https://fed.brid.gy/realize.be/following", 
  "..."
}

snarfed avatar Jan 14 '19 19:01 snarfed

@snarfed tried it, but is now a 403 at the inbox, will have to check with @Chocobozzz to see what else we're missing.

swentel avatar Jan 15 '19 08:01 swentel

Don't hesitate to come on #peertube (freenode) so we can test the federation. If you have a 403 it means peertube rejected the signature.

Chocobozzz avatar Jan 15 '19 09:01 Chocobozzz

I tried federating this like to this video on video.antopie.org (running PeerTube v5.0.1) just now, and got this HTTP 403 error:

{
  "type": "about:blank",
  "title": "Forbidden",
  "detail": "(request-target) was not a signed header",
  "status": 403,
  "error": "(request-target) was not a signed header"
}

Bridgy Fed log here. Here's the full AS2 object we sent:

{
  "published": "2023-01-17T13:57:26-08:00",
  "content": "likes <a class=\"u-like u-like-of\" href=\"https://video.antopie.org/w/2SwQSiFef99ewJXSnZpyqW\">Imagine \u2013 Playing For Change \u2013 Song Around The World (John Lennon) \u2013 AntTube</a>",
  "url": "https://fed.brid.gy/r/https://snarfed.org/2023-01-17_imagine-playing-for-change-song-around-the-world-john-lennon-anttube",
  "actor": {
    "url": "https://fed.brid.gy/r/https://snarfed.org/",
    "image": {
      "url": "https://secure.gravatar.com/avatar/947b5f3f323da0ef785b6f02d9c265d6?s=96&d=blank&r=g",
      "type": "Image"
    },
    "type": "Person",
    "name": "Ryan Barrett",
    "icon": {
      "url": "https://secure.gravatar.com/avatar/947b5f3f323da0ef785b6f02d9c265d6?s=96&d=blank&r=g",
      "type": "Image"
    },
    "id": "https://fed.brid.gy/snarfed.org",
    "preferredUsername": "[snarfed.org](http://snarfed.org/)"
  },
  "@context": "https://www.w3.org/ns/activitystreams",
  "type": "Like",
  "object": "https://video.antopie.org/videos/watch/0f2755a5-1c4f-4c55-bef4-4fce00a8766e",
  "id": "https://fed.brid.gy/r/https://snarfed.org/2023-01-17_imagine-playing-for-change-song-around-the-world-john-lennon-anttube",
  "cc": [
    "https://video.antopie.org/accounts/observatoire_des_armements",
    "https://video.antopie.org/video-channels/desarmement",
    "https://www.w3.org/ns/activitystreams#Public",
    "https://video.antopie.org/accounts/observatoire_des_armements/followers"
  ],
  "to": [
    "https://www.w3.org/ns/activitystreams#Public"
  ]
}

snarfed avatar Jan 17 '23 22:01 snarfed

Looks like the error here is that the Request-Target HTTP header wasn't included in the HTTP Signature? I'm not even familiar with that header. Hmm. Related: https://github.com/Chocobozzz/PeerTube/issues/4963

snarfed avatar Jan 17 '23 22:01 snarfed

Evidently it's a special HTTP Signatures thing? And the spec does require it to be included. OK then.

If the header field name is (request-target) then generate the header field value by concatenating the lowercased :method, an ASCII space, and the :path pseudo-headers (as specified in HTTP/2, Section 8.1.2.3 [7]). Note: For the avoidance of doubt, lowercasing only applies to the :method pseudo-header and not to the :path pseudo-header.

snarfed avatar Jan 17 '23 22:01 snarfed

Added (request-target) and the like federated successfully!

snarfed avatar Jan 18 '23 03:01 snarfed

Closing, we now have at least some basic federation with Peertube working.

snarfed avatar Jan 18 '23 03:01 snarfed