Fetch & store Actors of received Activities

This lays the groundwork for checking HTTP signatures.
This commit is contained in:
Jaidyn Ann 2024-12-18 14:08:09 -06:00
parent b05f9e765e
commit a37fc2bbfe

View File

@ -77,14 +77,52 @@ Returns the object associated with the given URI from our object-store."
(funcall func uri) (funcall func uri)
(error "No RETRIEVE function found in ACTIVITY-SERVIST:*CONFIG*.")))) (error "No RETRIEVE function found in ACTIVITY-SERVIST:*CONFIG*."))))
(defgeneric receive (obj) (defgeneric receive (obj)
(:documentation (:documentation
"Called when an OBJECT is sent to activity-servists HTTP inbox. "Called when an OBJECT is sent to activity-servists HTTP inbox.
This is done by other servers, and is how activities and objects get federated This is done by other servers, and is how activities and objects get federated
with ActivityPub. with ActivityPub.
To receive objects, you should overload this generic with (at the bare minimum) To receive objects, you should overload this generic with (at the bare minimum)
a method accepting JSON-LD:OBJECTs. Doing so is required not defining this a method accepting JSON-LD:OBJECTs. Doing so is required not defining this
method will cause an error when an object is sent to the inbox.")) method will cause an error when an object is sent to the inbox.
By default, there is a :BEFORE-method defined, which fetches received Activitys
Actors, and then calls RECEIVE on them in turn."))
;; We want to make sure that activitys actors are being retrieved and stored,
;; so that we can validate HTTP signatures (when that gets implemented).
(defmethod receive :before ((obj activity-vocabulary:activity))
(let* ((actor-uri (ignore-errors (activity-vocabulary:actor obj))))
(when actor-uri
(or (retrieve actor-uri)
(fetch-and-receive actor-uri)))))
;;; Fetching foreign objects
;;; ————————————————————————————————————————
;; “I will stab you in the eye, with a foreign object.”
;; — The Mountain Goats, “Foreign Object” (2015)
(defun fetch (obj-uri)
"Fetch & parse an ActivityPub object from a foreign server; returning the object"
(let ((json
(dexador:get obj-uri :headers '(("Accept" . "application/activity+json")))))
(json-ld:parse json)))
(defun fetch-and-receive (obj-uri)
"Fetch & pars an ActivityPub object from a foreign server; then try to pass it
along to our server.
If it RECEIVEs sans an error (de-facto rejecting the object), return the parsed object.
Otherwise, nil."
(let ((obj (fetch obj-uri)))
(when (and obj (ignore-errors (receive obj)))
obj)))