2 Federated following
Anthony Wang edited this page 2022-06-16 01:34:28 +08:00

Most of this is highly outdated. See https://github.com/go-gitea/gitea/pull/19981 for the latest updates

Inboxes/outboxes

https://github.com/go-gitea/gitea/issues/14186 has an in-depth overview of what needs to happen for this

let's start with something basic and worry about unit tests and moderation later

inboxes: POST request comes in add to database check which kind of request it is use callbacks or something to run the proper handing function if it's a follow request: use the user_model create follow function add an accept activity to the outbox

outboxes: (done, needs to be tested) function to add to outbox add to database Check the to field (C2S) for which actor to forward this to (technically there are to, bto, cc, bcc, and audience but that's too much for now) do a POST request with httpsigs using the activitypub.client stuff

Remote users

Use the existing users table.

https://github.com/go-gitea/gitea/issues/9045

I think we will also need to implement WebFinger because this is the de-facto standard for resolving a username like @ta180m@git.exozy.me into the actor IRI like https://git.exozy.me/api/v1/activitypub/user/ta180m

Also, for the federated following UI, I propose that if no user is logged into the current instance, there should be a popup box for the user to type in their own instance, and then the remote user should be rendered on their own instance.

Since user table already has two types column, one is LoginType which could be NoType, Plain, LDAP, SMTP, PAM, DLDAP, OAuth2,SSPI. Another column is UserType which could be Individual or Organization. We can have a new value for LoginType if reuse user table. Federate, but we need another table to store extra information. Maybe external_login_user table. And every external Gitea instance could be added as a record in login_source A login_source could also be disabled from Admin UI.

I think we'll go with the approach above since we basically have to store remote federated users somehow in the database.

Why federated following?

Instead of implementing things incrementally as what cjslep's issue suggests, I propose we first try to get the entire federated following flow working. This is because it is not too complex but requires us to think about a lot of important questions regarding federation. For instance, remote users will need to be handled in the database and the UI will have to be modified to support remote users. This entire task shouldn't be too difficult but it will help us learn important lessons about federation so it will be much easier after that to support federated issues, repos, and PRs.

How the federated following flow will work:

  • I browse another user's profile on a different Gitea instance
  • I click on the follow button (this currently doesn't show when you're not logged in so that will need to be fixed)
  • Since I'm not logged in on this particular Gitea instance, a popup box appears for me to type in my username and instance (like Mastodon)
  • Note: that step technically requires webfinger to be working for a @ta180m@git.exozy.me username to be resolved to the IRI for the actual actor
  • Here we have two options: We can either "cheat" and not implement rendering the remote instance on my instance or we can actually render the remote account on my instance. The second option is what Mastodon does but requires more work.
  • Now my instance sends a Follow activity to the other instance and the other instance replies with an Accept activity. This step is already implemented.
  • Lastly, the database should be updated on both instances to reflect this. This requires making changes to Gitea's internals.

Now for a detailed discussion about the two options for that step above:

This corresponds to the "Fetching ActivityStreams" section here: https://github.com/go-gitea/gitea/issues/14186

Basically, the second option is what we are probably going to do since it's also what Mastodon does. However, it's more complex and more work. Basically, let's say we have a repo on another instance. With this second option, we can actually render this remote repo on our currnet instance. Although repo federation is more complex than federated following and not something I want to delve into currently, it's helpful to consider hypothetically how this might work. (Yeah I should probably reread the ForgeFed spec before rambling about this)

Sorry, ignore the above. I'm reading the ForgeFed spec and it's pretty clear we will have to go with the second option and actually render remote users and repos. Well this is going to be a lot more UI work than I'm comfortable with... (I'm a backend person, OK?)

TODO

  • Code cleanup and error handling (needs a lot of work)
  • Webfinger
  • Remote user handling in the database
  • Add tables for the inbox/outbox
  • Create API endpoints for returing the follower/following OrderedCollections
  • Implement functions from fetching followers/following using GetUserFollowers/GetUserFollowing
  • Render remote user in UI
  • Popup box in UI for redirecting to your instance
  • Figure out why Mastodon doesn't want to render Gitea users