Generation of rcv’d activities’ signed-strings
Also edits BODY-CONTENTS to replace the :RAW-BODY in a Clack HTTP request with the body string.
This commit is contained in:
parent
e5ef4db56b
commit
8898d4b3f7
|
@ -160,6 +160,33 @@ Returns the object if it was retrieved or fetched; nil otherwise."
|
||||||
(string-trim '(#\") value))))
|
(string-trim '(#\") value))))
|
||||||
(str:split #\, signature-header)))
|
(str:split #\, signature-header)))
|
||||||
|
|
||||||
|
(defun signed-string (env signature-alist)
|
||||||
|
"Generate the string that was signed for the signature-header of the Clack HTTP request ENV."
|
||||||
|
(let* ((headers (getf env :headers))
|
||||||
|
(header-names (signed-header-names signature-alist)))
|
||||||
|
(reduce
|
||||||
|
(lambda (a b) (format nil "~A~%~A" a b))
|
||||||
|
(mapcar
|
||||||
|
(lambda (header-name)
|
||||||
|
(str:string-case (string-downcase header-name)
|
||||||
|
;; (request-target) is a pseudo-header formatted like “post /inbox”.
|
||||||
|
("(request-target)"
|
||||||
|
(format nil "~A: ~A ~A"
|
||||||
|
header-name
|
||||||
|
(string-downcase (symbol-name (getf env :request-method)))
|
||||||
|
(getf env :path-info)))
|
||||||
|
;; Calculate digest ourselves; never can’t trust the enemy!
|
||||||
|
("digest"
|
||||||
|
(format nil "~A: SHA-256=~A" header-name (string-sha256sum (body-contents env))))
|
||||||
|
;; … we can trust them on everything else, tho.
|
||||||
|
(otherwise
|
||||||
|
(format nil "~A: ~A" header-name (gethash header-name headers)))))
|
||||||
|
header-names))))
|
||||||
|
|
||||||
|
(defun signed-header-names (signature-alist)
|
||||||
|
"Return a list of the names of headers used in a SIGNATURE-ALIST’s signed string."
|
||||||
|
(str:split #\space (cdr (assoc :headers signature-alist)) :omit-nulls 't))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; Fetching public keys
|
;;; Fetching public keys
|
||||||
|
@ -274,11 +301,12 @@ can be found). Uses the callback :RETRIEVE, defined in *CONFIG*."
|
||||||
(defun http-inbox (env path-items params)
|
(defun http-inbox (env path-items params)
|
||||||
"If one tries to send an activity to our inbox, pass it along to
|
"If one tries to send an activity to our inbox, pass it along to
|
||||||
the overloaded RECEIVE method."
|
the overloaded RECEIVE method."
|
||||||
(let* ((contents (body-contents (getf env :raw-body))))
|
(let* ((contents (body-contents env)))
|
||||||
(receive (json-ld:parse contents))
|
(receive (json-ld:parse contents))
|
||||||
'(200 (:content-type "text/plain") ("You win!"))))
|
'(200 (:content-type "text/plain") ("You win!"))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; Sending a note
|
;;; Sending a note
|
||||||
;;; ————————————————————————————————————————
|
;;; ————————————————————————————————————————
|
||||||
|
@ -383,6 +411,19 @@ the overloaded RECEIVE method."
|
||||||
|
|
||||||
;;; Utils.
|
;;; Utils.
|
||||||
;;; ————————————————————————————————————————
|
;;; ————————————————————————————————————————
|
||||||
|
(defun body-contents (env)
|
||||||
|
"Given a Clack HTTP request property-list ENV, return the request’s body
|
||||||
|
contents as a string. They are read from :RAW-BODY in this plist.
|
||||||
|
|
||||||
|
If the contents are a stream, the stream’s contents will be read into a
|
||||||
|
string and the stream’s object in ENV will be replaced with the string."
|
||||||
|
(let ((body (getf env :raw-body)))
|
||||||
|
(if (stringp body)
|
||||||
|
body
|
||||||
|
(setf (getf env :raw-body)
|
||||||
|
(babel:octets-to-string
|
||||||
|
(alexandria:read-stream-content-into-byte-vector body))))))
|
||||||
|
|
||||||
(defun assoc-by-path (alist path-items &optional (depth 0))
|
(defun assoc-by-path (alist path-items &optional (depth 0))
|
||||||
"Given an associative list and a path decomposed into a list of
|
"Given an associative list and a path decomposed into a list of
|
||||||
its components, return the item with the closest according
|
its components, return the item with the closest according
|
||||||
|
@ -427,9 +468,3 @@ or “/bear/apple/” or “/bear/”, but not “/bear” (not a directory)."
|
||||||
(loop for number across
|
(loop for number across
|
||||||
sequence
|
sequence
|
||||||
collect (format nil "~X" number))))
|
collect (format nil "~X" number))))
|
||||||
|
|
||||||
(defun body-contents (body)
|
|
||||||
"Given the :RAW-BODY of a Clack ENV, return its contents as a string."
|
|
||||||
(babel:octets-to-string
|
|
||||||
(alexandria:read-stream-content-into-byte-vector body)))
|
|
||||||
|
|
||||||
|
|
Ŝarĝante…
Reference in New Issue