Sending the user as the actor in our activities
Related to #236 and #254 . Currently our activities are being sent with a generic "BACKLINKS SERVICE" actor. This means that from the receiver's point of view, the Parisian user didn't join the Nanteais server, but the Parisian server did
For many reasons and most pressingly for key exchange, we want to specify the actor as the user, not the server. For example it means that I can check that the incoming user has the permission to do that on my server, rather than having to put superuser-level trust into every server in the federation
Why it's hard
The backlink is discovered during a post_save listener, where we check if the object being updated has links to external resources. The post-save is a safe way to know in Django that an object has been updated:
- by a request to a view
- in the admin panel
- in a shell script
- in a unit test
- anywhere in else in code, e.g. within another
post_save
listener
Possible solutions
Saving the creator on djangoldp.models.Model
By saving the creator to the Model (in the viewset/serializer), we could access it during automated backlink detection (which has access to the instance triggering the backlink). The issue with this would be along the lines of extensibility for application developers - e.g. when saving an object in a custom View
Getting the user into the post_save event handler
- Firing a custom event signal in
LDPViewSet
should be fairly straightforward for this because theuser
is simple, it's therequest.user
. Overriding the changes in the admin panel might be straightforward (I haven't researched). However it's insufficient for the bulk of the saves (those which are triggered in code) - something extremely common for DjangoLDP packages to do - Overriding
Model.save
to raise an exception if theuser
is not passed into it. A safe solution but awful - essentially moves the problem onto the application developer
Changing the way that the backlink is sent
... ?
Using ActivityPub client-to-server
To be accurate, we use ActivityStreams in our backlinks but we're not using ActivityPub. Very briefly, we use Activities for our backlinks, which we then use in a server-to-server federation (like ActivityPub), but we don't use the client-to-server protocol at all (we send linked data to pre-configured endpoints client-side (#377 ))
The ActivityPub spec describes the user sending an object/Activity to their outbox (client-to-server). In the outbox the server would have access to the user who sent the activity. Evidently this is a considerable shift, and since ActivityPub is based on Linked Data to implement decentralised social networking applications, the scope of DjangoLDP is probably wider. Needs discussion
Sometimes sending the backlink from the server itself
Sending the user as the "server user" when we don't know. Easier but means that the receiver has to trust totally the "server user" which is a big security problem
This is more or less the original suggestion on #236, and it might not resolve the server-to-server key exchange issues which we were discussing this morning
ping @balessan @decentral1se