Much work on error reporting architecture for validation
This commit is contained in:
parent
5593bb22d1
commit
25795cf364
|
@ -65,6 +65,10 @@ At present, only the duck-typing functions work. To play with them, use
|
||||||
(require '[dog-and-duck.quack.quack :as q])
|
(require '[dog-and-duck.quack.quack :as q])
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Full documentation is [here](https://simon-brooke.github.io/dog-and-duck/).
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
Prior to testing, you should clone [activitystreams-test-documents](https://github.com/w3c-social/activitystreams-test-documents) into the `resources` directory. You can then test with
|
Prior to testing, you should clone [activitystreams-test-documents](https://github.com/w3c-social/activitystreams-test-documents) into the `resources` directory. You can then test with
|
||||||
|
|
|
@ -1,112 +1,5 @@
|
||||||
# Using ActivityPub
|
# Using ActivityPub
|
||||||
|
|
||||||
```clojure
|
## Introduction
|
||||||
user=> (require '[clj-activitypub.core :as activitypub])
|
|
||||||
nil
|
I do not know what I am doing; I am learning, and playing. Nothing in this document should be treated as good advice; it simply relates to the current state of my knowledge.
|
||||||
user=> (require '[clj-activitypub.webfinger :as webfinger])
|
|
||||||
nil
|
|
||||||
user=> (require '[clojure.walk :refer [keywordize-keys]])
|
|
||||||
nil
|
|
||||||
user=> (require '[clojure.pprint :refer [pprint]])
|
|
||||||
nil
|
|
||||||
user=> (def base-domain "mastodon.scot")
|
|
||||||
#'user/base-domain
|
|
||||||
user=> (def account-handle "@simon_brooke@mastodon.scot")
|
|
||||||
#'user/account-handle
|
|
||||||
user=> (in-ns 'user)
|
|
||||||
#object[clojure.lang.Namespace 0x525575 "user"]
|
|
||||||
user=> (activitypub/parse-account account-handle )
|
|
||||||
{:domain "mastodon.scot", :username "simon_brooke"}
|
|
||||||
user=> (map *1 [:domain :username])
|
|
||||||
("mastodon.scot" "simon_brooke")
|
|
||||||
user=> (apply webfinger/fetch-user-id *1)
|
|
||||||
"https://mastodon.scot/users/simon_brooke"
|
|
||||||
user=> (activitypub/fetch-user *1)
|
|
||||||
{"followers" "https://mastodon.scot/users/simon_brooke/followers", "inbox" "https://mastodon.scot/users/simon_brooke/inbox", "url" "https://mastodon.scot/@simon_brooke", "@context" ["https://www.w3.org/ns/activitystreams" "https://w3id.org/security/v1" {"identityKey" {"@type" "@id", "@id" "toot:identityKey"}, "EncryptedMessage" "toot:EncryptedMessage", "Ed25519Key" "toot:Ed25519Key", "devices" {"@type" "@id", "@id" "toot:devices"}, "manuallyApprovesFollowers" "as:manuallyApprovesFollowers", "schema" "http://schema.org#", "PropertyValue" "schema:PropertyValue", "Curve25519Key" "toot:Curve25519Key", "claim" {"@type" "@id", "@id" "toot:claim"}, "value" "schema:value", "Hashtag" "as:Hashtag", "movedTo" {"@id" "as:movedTo", "@type" "@id"}, "discoverable" "toot:discoverable", "messageType" "toot:messageType", "messageFranking" "toot:messageFranking", "cipherText" "toot:cipherText", "toot" "http://joinmastodon.org/ns#", "alsoKnownAs" {"@id" "as:alsoKnownAs", "@type" "@id"}, "featured" {"@id" "toot:featured", "@type" "@id"}, "featuredTags" {"@id" "toot:featuredTags", "@type" "@id"}, "Ed25519Signature" "toot:Ed25519Signature", "focalPoint" {"@container" "@list", "@id" "toot:focalPoint"}, "fingerprintKey" {"@type" "@id", "@id" "toot:fingerprintKey"}, "Device" "toot:Device", "publicKeyBase64" "toot:publicKeyBase64", "deviceId" "toot:deviceId", "suspended" "toot:suspended"}], "devices" "https://mastodon.scot/users/simon_brooke/collections/devices", "manuallyApprovesFollowers" false, "image" {"type" "Image", "mediaType" "image/jpeg", "url" "https://media.mastodon.scot/mastodon-scot-public/accounts/headers/109/252/274/874/045/781/original/e1f1823c4361fa27.jpg"}, "endpoints" {"sharedInbox" "https://mastodon.scot/inbox"}, "id" "https://mastodon.scot/users/simon_brooke", "publicKey" {"id" "https://mastodon.scot/users/simon_brooke#main-key", "owner" "https://mastodon.scot/users/simon_brooke", "publicKeyPem" "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2/6GgLJgJlPhhqFm1tUQ\noSLnWxhDwq4HlZIHrBsVjkSvUAnHKqq42Q/hta+fkWB8rmTFpmjLXDj/Fi0uejvT\nBc+KrLwfX/yR8+G87afGCRS3CaumoLJ7zkBIlsFzIKMoIke1D3QuHX95yGGXs+hp\nmyxt/+CXRyZjK7u9NG7SMRUlpwvOlpD12Aei35Nb8NSr03JvY8/WVMIbWrecyI0b\nAlwj6axxHx7J15Yo+aEtKzZ2OFKXf+sh0QF9BEnYcmVKYlR6kiOglLFHKdCBUSYi\ni9Flv00TydqlGvR5fpShBqORiy0M/FVtNXlz2sNBEsGB2meipkjh+cRLzTbYo4KL\nJwIDAQAB\n-----END PUBLIC KEY-----\n"}, "summary" "<p>Anarcho-syndicalist, autistic, crofter, cyclist, depressive, entrepreneur, geek, Zapatista. Politics & environment, especially <a href=\"https://mastodon.scot/tags/LandReform\" class=\"mention hashtag\" rel=\"tag\">#<span>LandReform</span></a>. he/him.</p><p>Twitter: <span class=\"h-card\"><a href=\"https://mastodon.scot/@simon_brooke\" class=\"u-url mention\">@<span>simon_brooke</span></a></span><br />GitHub: simon-brooke<br />FetLife: Simon_Brooke</p><p>Credo: Life is harsh. What we can do - and what we should do - is strive to make it less harsh for the people around us.</p>", "attachment" [{"type" "PropertyValue", "name" "Home Page", "value" "<a href=\"https://www.journeyman.cc/~simon/\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://www.</span><span class=\"\">journeyman.cc/~simon/</span><span class=\"invisible\"></span></a>"}], "name" "Simon Brooke", "tag" [{"type" "Hashtag", "href" "https://mastodon.scot/tags/landreform", "name" "#landreform"}], "published" "2022-10-29T00:00:00Z", "preferredUsername" "simon_brooke", "discoverable" true, "alsoKnownAs" ["https://mastodon.social/users/simon_brooke"], "featured" "https://mastodon.scot/users/simon_brooke/collections/featured", "featuredTags" "https://mastodon.scot/users/simon_brooke/collections/tags", "type" "Person", "outbox" "https://mastodon.scot/users/simon_brooke/outbox", "following" "https://mastodon.scot/users/simon_brooke/following", "icon" {"type" "Image", "mediaType" "image/png", "url" "https://media.mastodon.scot/mastodon-scot-public/accounts/avatars/109/252/274/874/045/781/original/172e8f7530627e87.png"}}
|
|
||||||
user=> (def sb (keywordize-keys *1))
|
|
||||||
#'user/sb
|
|
||||||
user=> (:outbox sb)
|
|
||||||
"https://mastodon.scot/users/simon_brooke/outbox"
|
|
||||||
user=> (require '[clojure.data.json :as json])
|
|
||||||
nil
|
|
||||||
user=> (slurp (:outbox sb))
|
|
||||||
Execution error (IOException) at sun.net.www.protocol.http.HttpURLConnection/getInputStream0 (HttpURLConnection.java:1894).
|
|
||||||
Server returned HTTP response code: 403 for URL: https://mastodon.scot/users/simon_brooke/outbox
|
|
||||||
user=> (pprint sb)
|
|
||||||
{:inbox "https://mastodon.scot/users/simon_brooke/inbox",
|
|
||||||
:name "Simon Brooke",
|
|
||||||
:@context
|
|
||||||
["https://www.w3.org/ns/activitystreams"
|
|
||||||
"https://w3id.org/security/v1"
|
|
||||||
{:schema "http://schema.org#",
|
|
||||||
:messageType "toot:messageType",
|
|
||||||
:messageFranking "toot:messageFranking",
|
|
||||||
:identityKey {:@type "@id", :@id "toot:identityKey"},
|
|
||||||
:Hashtag "as:Hashtag",
|
|
||||||
:deviceId "toot:deviceId",
|
|
||||||
:publicKeyBase64 "toot:publicKeyBase64",
|
|
||||||
:value "schema:value",
|
|
||||||
:Ed25519Key "toot:Ed25519Key",
|
|
||||||
:featured {:@id "toot:featured", :@type "@id"},
|
|
||||||
:Curve25519Key "toot:Curve25519Key",
|
|
||||||
:discoverable "toot:discoverable",
|
|
||||||
:focalPoint {:@container "@list", :@id "toot:focalPoint"},
|
|
||||||
:suspended "toot:suspended",
|
|
||||||
:fingerprintKey {:@type "@id", :@id "toot:fingerprintKey"},
|
|
||||||
:Ed25519Signature "toot:Ed25519Signature",
|
|
||||||
:cipherText "toot:cipherText",
|
|
||||||
:EncryptedMessage "toot:EncryptedMessage",
|
|
||||||
:alsoKnownAs {:@id "as:alsoKnownAs", :@type "@id"},
|
|
||||||
:featuredTags {:@id "toot:featuredTags", :@type "@id"},
|
|
||||||
:devices {:@type "@id", :@id "toot:devices"},
|
|
||||||
:toot "http://joinmastodon.org/ns#",
|
|
||||||
:movedTo {:@id "as:movedTo", :@type "@id"},
|
|
||||||
:Device "toot:Device",
|
|
||||||
:PropertyValue "schema:PropertyValue",
|
|
||||||
:manuallyApprovesFollowers "as:manuallyApprovesFollowers",
|
|
||||||
:claim {:@type "@id", :@id "toot:claim"}}],
|
|
||||||
:featured
|
|
||||||
"https://mastodon.scot/users/simon_brooke/collections/featured",
|
|
||||||
:type "Person",
|
|
||||||
:discoverable true,
|
|
||||||
:icon
|
|
||||||
{:type "Image",
|
|
||||||
:mediaType "image/png",
|
|
||||||
:url
|
|
||||||
"https://media.mastodon.scot/mastodon-scot-public/accounts/avatars/109/252/274/874/045/781/original/172e8f7530627e87.png"},
|
|
||||||
:following "https://mastodon.scot/users/simon_brooke/following",
|
|
||||||
:summary
|
|
||||||
"<p>Anarcho-syndicalist, autistic, crofter, cyclist, depressive, entrepreneur, geek, Zapatista. Politics & environment, especially <a href=\"https://mastodon.scot/tags/LandReform\" class=\"mention hashtag\" rel=\"tag\">#<span>LandReform</span></a>. he/him.</p><p>Twitter: <span class=\"h-card\"><a href=\"https://mastodon.scot/@simon_brooke\" class=\"u-url mention\">@<span>simon_brooke</span></a></span><br />GitHub: simon-brooke<br />FetLife: Simon_Brooke</p><p>Credo: Life is harsh. What we can do - and what we should do - is strive to make it less harsh for the people around us.</p>",
|
|
||||||
:publicKey
|
|
||||||
{:id "https://mastodon.scot/users/simon_brooke#main-key",
|
|
||||||
:owner "https://mastodon.scot/users/simon_brooke",
|
|
||||||
:publicKeyPem
|
|
||||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2/6GgLJgJlPhhqFm1tUQ\noSLnWxhDwq4HlZIHrBsVjkSvUAnHKqq42Q/hta+fkWB8rmTFpmjLXDj/Fi0uejvT\nBc+KrLwfX/yR8+G87afGCRS3CaumoLJ7zkBIlsFzIKMoIke1D3QuHX95yGGXs+hp\nmyxt/+CXRyZjK7u9NG7SMRUlpwvOlpD12Aei35Nb8NSr03JvY8/WVMIbWrecyI0b\nAlwj6axxHx7J15Yo+aEtKzZ2OFKXf+sh0QF9BEnYcmVKYlR6kiOglLFHKdCBUSYi\ni9Flv00TydqlGvR5fpShBqORiy0M/FVtNXlz2sNBEsGB2meipkjh+cRLzTbYo4KL\nJwIDAQAB\n-----END PUBLIC KEY-----\n"},
|
|
||||||
:endpoints {:sharedInbox "https://mastodon.scot/inbox"},
|
|
||||||
:preferredUsername "simon_brooke",
|
|
||||||
:id "https://mastodon.scot/users/simon_brooke",
|
|
||||||
:alsoKnownAs ["https://mastodon.social/users/simon_brooke"],
|
|
||||||
:outbox "https://mastodon.scot/users/simon_brooke/outbox",
|
|
||||||
:url "https://mastodon.scot/@simon_brooke",
|
|
||||||
:featuredTags
|
|
||||||
"https://mastodon.scot/users/simon_brooke/collections/tags",
|
|
||||||
:devices
|
|
||||||
"https://mastodon.scot/users/simon_brooke/collections/devices",
|
|
||||||
:image
|
|
||||||
{:type "Image",
|
|
||||||
:mediaType "image/jpeg",
|
|
||||||
:url
|
|
||||||
"https://media.mastodon.scot/mastodon-scot-public/accounts/headers/109/252/274/874/045/781/original/e1f1823c4361fa27.jpg"},
|
|
||||||
:tag
|
|
||||||
[{:type "Hashtag",
|
|
||||||
:href "https://mastodon.scot/tags/landreform",
|
|
||||||
:name "#landreform"}],
|
|
||||||
:followers "https://mastodon.scot/users/simon_brooke/followers",
|
|
||||||
:published "2022-10-29T00:00:00Z",
|
|
||||||
:manuallyApprovesFollowers false,
|
|
||||||
:attachment
|
|
||||||
[{:type "PropertyValue",
|
|
||||||
:name "Home Page",
|
|
||||||
:value
|
|
||||||
"<a href=\"https://www.journeyman.cc/~simon/\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://www.</span><span class=\"\">journeyman.cc/~simon/</span><span class=\"invisible\"></span></a>"}]}
|
|
||||||
```
|
|
61
doc/Validation_Faults.md
Normal file
61
doc/Validation_Faults.md
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
# Validation Faults in ActivityPub documents
|
||||||
|
|
||||||
|
## Motivation
|
||||||
|
|
||||||
|
This document is intended to provide an extension vocabulary for [ActivityStreams](https://www.w3.org/TR/activitystreams-core/) documents, which provides vocabulary for categorising and describing faults in [ActivityPub](https://www.w3.org/TR/activitypub/) documents.
|
||||||
|
|
||||||
|
The motivation is to be able to serialise a validation report on an ActivityPub document as an ActivityStreams document.
|
||||||
|
|
||||||
|
## Intepretation
|
||||||
|
|
||||||
|
### Conformance
|
||||||
|
|
||||||
|
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
|
||||||
|
|
||||||
|
The key words MAY, MUST, MUST NOT, SHOULD, and SHOULD NOT are to be interpreted as described in [RFC2119].
|
||||||
|
|
||||||
|
### 'the spec'
|
||||||
|
|
||||||
|
Where the phrase 'the spec' is used in this document, it refers to a concatenation of the ActivityStreams specification and the ActivityPub specification.
|
||||||
|
|
||||||
|
## The `Fault` object type
|
||||||
|
|
||||||
|
The `Fault` object type is a novel object type introduced by this document to describe validation faults. Objects with the `Fault` object type MUST have at least the following fields (additional fields are not required but are optional):
|
||||||
|
|
||||||
|
1. `:@context` whose value shall be the URL of a document specifying this vocabulary;
|
||||||
|
2. `:type` whose value shall be `Fault`;
|
||||||
|
3. `:severity` whose value shall be one of `minor`, `should`, `must` or `critical`;
|
||||||
|
4. `:fault` whose value shall be a unique token representing the particular fault type;
|
||||||
|
5. `:narrative` whose value shall be a natural language description of the fault type.
|
||||||
|
|
||||||
|
### The Fields
|
||||||
|
|
||||||
|
#### Context
|
||||||
|
|
||||||
|
The value of the `@context` field of a fault report object shall be the URL of this
|
||||||
|
document, currently `https://simon-brooke.github.io/dog-and-duck/codox/Validation_Faults.html`.
|
||||||
|
|
||||||
|
#### Type
|
||||||
|
|
||||||
|
The value of the `type` field of a fault report object MUST be `Fault`.
|
||||||
|
|
||||||
|
#### Severity
|
||||||
|
|
||||||
|
Each fault report object MUST have a `severity` field whose value MUST be one of
|
||||||
|
|
||||||
|
1. `:minor` things which I consider to be faults, but which
|
||||||
|
don't actually breach the spec;
|
||||||
|
2. `:should` instances where the spec says something SHOULD
|
||||||
|
be done, which isn't;
|
||||||
|
3. `:must` instances where the spec says something MUST
|
||||||
|
be done, which isn't;
|
||||||
|
4. `:critical` instances where I believe the fault means that
|
||||||
|
the object cannot be meaningfully processed.
|
||||||
|
|
||||||
|
#### Fault
|
||||||
|
|
||||||
|
Unique codes shall be assigned to each fault type, and shall be documented in this section.
|
||||||
|
|
||||||
|
It is intended that there should ultimately be a well known site at which the fault codes can be resolved to natural language explanations in as many natural languages as possible of the nature of the particular fault.
|
||||||
|
|
||||||
|
|
|
@ -8,442 +8,451 @@
|
||||||
001 (ns clj-activitypub.core
|
001 (ns clj-activitypub.core
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
002 (:require [clj-activitypub.internal.crypto :as crypto]
|
002 "copied from [Jahfer's clj-activitypub library](https://github.com/jahfer/clj-activitypub).
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
003 [clj-activitypub.internal.thread-cache :as thread-cache]
|
003 If and when Jahfer issues a release of that library, this directory will be deleted and a
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
004 [clj-activitypub.internal.http-util :as http]
|
004 dependency on that library will be added to the project."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
005 [clj-http.client :as client]
|
005 (:require [clj-activitypub.internal.crypto :as crypto]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
006 [clojure.string :as str]))
|
006 [clj-activitypub.internal.thread-cache :as thread-cache]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
007 [clj-activitypub.internal.http-util :as http]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
008 [clj-http.client :as client]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
009 [clojure.string :as str]))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
007
|
010
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
008 (defn config
|
011 (defn config
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
009 "Creates hash of computed data relevant for most ActivityPub utilities."
|
012 "Creates hash of computed data relevant for most ActivityPub utilities."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
010 [{:keys [domain username username-route public-key private-key]
|
013 [{:keys [domain username username-route public-key private-key]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
011 :or {username-route "/users/"
|
014 :or {username-route "/users/"
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
012 public-key nil
|
015 public-key nil
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
013 private-key nil}}]
|
016 private-key nil}}]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 5 forms covered">
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
014 (let [base-url (str "https://" domain)]
|
017 (let [base-url (str "https://" domain)]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 8 forms covered">
|
<span class="not-covered" title="0 out of 8 forms covered">
|
||||||
015 {:domain domain
|
018 {:domain domain
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
016 :base-url base-url
|
019 :base-url base-url
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
017 :username username
|
020 :username username
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 5 forms covered">
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
018 :user-id (str base-url username-route username)
|
021 :user-id (str base-url username-route username)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
019 :public-key public-key
|
022 :public-key public-key
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
020 :private-key (when private-key
|
023 :private-key (when private-key
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
021 (crypto/private-key private-key))}))
|
024 (crypto/private-key private-key))}))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
022
|
025
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
023 (defn parse-account
|
026 (defn parse-account
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
024 "Given an ActivityPub handle (e.g. @jahfer@mastodon.social), produces
|
027 "Given an ActivityPub handle (e.g. @jahfer@mastodon.social), produces
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
025 a map containing {:domain ... :username ...}."
|
028 a map containing {:domain ... :username ...}."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
026 [handle]
|
029 [handle]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="9 out of 9 forms covered">
|
<span class="covered" title="9 out of 9 forms covered">
|
||||||
027 (let [[username domain] (filter #(not (str/blank? %))
|
030 (let [[username domain] (filter #(not (str/blank? %))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
028 (str/split handle #"@"))]
|
031 (str/split handle #"@"))]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
029 {:domain domain :username username}))
|
032 {:domain domain :username username}))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
030
|
033
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
031 (def ^:private user-cache (thread-cache/make))
|
034 (def ^:private user-cache (thread-cache/make))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
032 (defn fetch-user
|
035 (defn fetch-user
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
033 "Fetches the customer account details located at user-id from a remote
|
036 "Fetches the customer account details located at user-id from a remote
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
034 server. Will return cached results if they exist in memory."
|
037 server. Will return cached results if they exist in memory."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
035 [user-id]
|
038 [user-id]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
036 ((:get-v user-cache)
|
039 ((:get-v user-cache)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
037 user-id
|
040 user-id
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
038 #(:body
|
041 #(:body
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="11 out of 11 forms covered">
|
<span class="covered" title="11 out of 11 forms covered">
|
||||||
039 (client/get user-id {:as :json-string-keys
|
042 (client/get user-id {:as :json-string-keys
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
040 :throw-exceptions false
|
043 :throw-exceptions false
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
041 :ignore-unknown-host? true
|
044 :ignore-unknown-host? true
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
042 :headers {"Accept" "application/activity+json"}}))))
|
045 :headers {"Accept" "application/activity+json"}}))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
043
|
046
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
044 (defn actor
|
047 (defn actor
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
045 "Accepts a config, and returns a map in the form expected by the ActivityPub
|
048 "Accepts a config, and returns a map in the form expected by the ActivityPub
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
046 spec. See https://www.w3.org/TR/activitypub/#actor-objects for reference."
|
049 spec. See https://www.w3.org/TR/activitypub/#actor-objects for reference."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
047 [{:keys [user-id username public-key]}]
|
050 [{:keys [user-id username public-key]}]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 12 forms covered">
|
<span class="not-covered" title="0 out of 12 forms covered">
|
||||||
048 {"@context" ["https://www.w3.org/ns/activitystreams"
|
051 {"@context" ["https://www.w3.org/ns/activitystreams"
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
049 "https://w3id.org/security/v1"]
|
052 "https://w3id.org/security/v1"]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
050 :id user-id
|
053 :id user-id
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
051 :type "Person"
|
054 :type "Person"
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
052 :preferredUsername username
|
055 :preferredUsername username
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
053 :inbox (str user-id "/inbox")
|
056 :inbox (str user-id "/inbox")
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
054 :outbox (str user-id "/outbox")
|
057 :outbox (str user-id "/outbox")
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 8 forms covered">
|
<span class="not-covered" title="0 out of 8 forms covered">
|
||||||
055 :publicKey {:id (str user-id "#main-key")
|
058 :publicKey {:id (str user-id "#main-key")
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
056 :owner user-id
|
059 :owner user-id
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 6 forms covered">
|
<span class="not-covered" title="0 out of 6 forms covered">
|
||||||
057 :publicKeyPem (or public-key "")}})
|
060 :publicKeyPem (or public-key "")}})
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
058
|
061
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="6 out of 6 forms covered">
|
<span class="covered" title="6 out of 6 forms covered">
|
||||||
059 (def signature-headers ["(request-target)" "host" "date" "digest"])
|
062 (def signature-headers ["(request-target)" "host" "date" "digest"])
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
060
|
063
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
061 (defn- str-for-signature [headers]
|
064 (defn- str-for-signature [headers]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
062 (let [headers-xf (reduce-kv
|
065 (let [headers-xf (reduce-kv
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
063 (fn [m k v]
|
066 (fn [m k v]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 9 forms covered">
|
<span class="not-covered" title="0 out of 9 forms covered">
|
||||||
064 (assoc m (str/lower-case k) v)) {} headers)]
|
067 (assoc m (str/lower-case k) v)) {} headers)]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
065 (->> signature-headers
|
068 (->> signature-headers
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
066 (select-keys headers-xf)
|
069 (select-keys headers-xf)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 12 forms covered">
|
<span class="not-covered" title="0 out of 12 forms covered">
|
||||||
067 (reduce-kv (fn [coll k v] (conj coll (str k ": " v))) [])
|
070 (reduce-kv (fn [coll k v] (conj coll (str k ": " v))) [])
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
068 (interpose "\n")
|
071 (interpose "\n")
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
069 (apply str))))
|
072 (apply str))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
070
|
073
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
071 (defn gen-signature-header
|
074 (defn gen-signature-header
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
072 "Generates a HTTP Signature string based on the provided map of headers."
|
075 "Generates a HTTP Signature string based on the provided map of headers."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
073 [config headers]
|
076 [config headers]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
074 (let [{:keys [user-id private-key]} config
|
077 (let [{:keys [user-id private-key]} config
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
075 string-to-sign (str-for-signature headers)
|
078 string-to-sign (str-for-signature headers)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 6 forms covered">
|
<span class="not-covered" title="0 out of 6 forms covered">
|
||||||
076 signature (crypto/base64-encode (crypto/sign string-to-sign private-key))
|
079 signature (crypto/base64-encode (crypto/sign string-to-sign private-key))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 5 forms covered">
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
077 sig-header-keys {"keyId" user-id
|
080 sig-header-keys {"keyId" user-id
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
078 "headers" (str/join " " signature-headers)
|
081 "headers" (str/join " " signature-headers)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
079 "signature" signature}]
|
082 "signature" signature}]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
080 (->> sig-header-keys
|
083 (->> sig-header-keys
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
081 (reduce-kv (fn [m k v]
|
084 (reduce-kv (fn [m k v]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 11 forms covered">
|
<span class="not-covered" title="0 out of 11 forms covered">
|
||||||
082 (conj m (str k "=" "\"" v "\""))) [])
|
085 (conj m (str k "=" "\"" v "\""))) [])
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
083 (interpose ",")
|
086 (interpose ",")
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
084 (apply str))))
|
087 (apply str))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
085
|
088
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
086 (defn auth-headers
|
089 (defn auth-headers
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
087 "Given a config and request map of {:body ... :headers ...}, returns the
|
090 "Given a config and request map of {:body ... :headers ...}, returns the
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
088 original set of headers with Signature and Digest attributes appended."
|
091 original set of headers with Signature and Digest attributes appended."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
089 [config {:keys [body headers]}]
|
092 [config {:keys [body headers]}]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
090 (let [digest (http/digest body)
|
093 (let [digest (http/digest body)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
091 h (-> headers
|
094 h (-> headers
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
092 (assoc "Digest" digest)
|
095 (assoc "Digest" digest)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
093 (assoc "(request-target)" "post /inbox"))]
|
096 (assoc "(request-target)" "post /inbox"))]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 5 forms covered">
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
094 (assoc headers
|
097 (assoc headers
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
095 "Signature" (gen-signature-header config h)
|
098 "Signature" (gen-signature-header config h)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
096 "Digest" digest)))
|
099 "Digest" digest)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
097
|
100
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
098 (defmulti obj
|
101 (defmulti obj
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
099 "Produces a map representing an ActivityPub object which can be serialized
|
102 "Produces a map representing an ActivityPub object which can be serialized
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
100 directly to JSON in the form expected by the ActivityStreams 2.0 spec.
|
103 directly to JSON in the form expected by the ActivityStreams 2.0 spec.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
101 See https://www.w3.org/TR/activitystreams-vocabulary/ for reference."
|
104 See https://www.w3.org/TR/activitystreams-vocabulary/ for reference."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="partial" title="1 out of 4 forms covered">
|
<span class="partial" title="1 out of 4 forms covered">
|
||||||
102 (fn [_config object-data] (:type object-data)))
|
105 (fn [_config object-data] (:type object-data)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
103
|
106
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
104 (defmethod obj :note
|
107 (defmethod obj :note
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
105 [{:keys [user-id]}
|
108 [{:keys [user-id]}
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
106 {:keys [id published inReplyTo content to]
|
109 {:keys [id published inReplyTo content to]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
107 :or {published (http/date)
|
110 :or {published (http/date)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
108 inReplyTo ""
|
111 inReplyTo ""
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
109 to "https://www.w3.org/ns/activitystreams#Public"}}]
|
112 to "https://www.w3.org/ns/activitystreams#Public"}}]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 14 forms covered">
|
<span class="not-covered" title="0 out of 14 forms covered">
|
||||||
110 {"id" (str user-id "/notes/" id)
|
113 {"id" (str user-id "/notes/" id)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
111 "type" "Note"
|
114 "type" "Note"
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
112 "published" published
|
115 "published" published
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
113 "attributedTo" user-id
|
116 "attributedTo" user-id
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
114 "inReplyTo" inReplyTo
|
117 "inReplyTo" inReplyTo
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
115 "content" content
|
118 "content" content
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
116 "to" to})
|
119 "to" to})
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
117
|
120
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
118 (defmulti activity
|
121 (defmulti activity
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
119 "Produces a map representing an ActivityPub activity which can be serialized
|
122 "Produces a map representing an ActivityPub activity which can be serialized
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
120 directly to JSON in the form expected by the ActivityStreams 2.0 spec.
|
123 directly to JSON in the form expected by the ActivityStreams 2.0 spec.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
121 See https://www.w3.org/TR/activitystreams-vocabulary/ for reference."
|
124 See https://www.w3.org/TR/activitystreams-vocabulary/ for reference."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="partial" title="1 out of 2 forms covered">
|
<span class="partial" title="1 out of 2 forms covered">
|
||||||
122 (fn [_config activity-type _data] activity-type))
|
125 (fn [_config activity-type _data] activity-type))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
123
|
126
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
124 (defmethod activity :create [{:keys [user-id]} _ data]
|
127 (defmethod activity :create [{:keys [user-id]} _ data]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 9 forms covered">
|
<span class="not-covered" title="0 out of 9 forms covered">
|
||||||
125 {"@context" ["https://www.w3.org/ns/activitystreams"
|
128 {"@context" ["https://www.w3.org/ns/activitystreams"
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
126 "https://w3id.org/security/v1"]
|
129 "https://w3id.org/security/v1"]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
127 "type" "Create"
|
130 "type" "Create"
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
128 "actor" user-id
|
131 "actor" user-id
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
129 "object" data})
|
132 "object" data})
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
130
|
133
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
131 (defmethod activity :delete [{:keys [user-id]} _ data]
|
134 (defmethod activity :delete [{:keys [user-id]} _ data]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 9 forms covered">
|
<span class="not-covered" title="0 out of 9 forms covered">
|
||||||
132 {"@context" ["https://www.w3.org/ns/activitystreams"
|
135 {"@context" ["https://www.w3.org/ns/activitystreams"
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
133 "https://w3id.org/security/v1"]
|
136 "https://w3id.org/security/v1"]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
134 "type" "Delete"
|
137 "type" "Delete"
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
135 "actor" user-id
|
138 "actor" user-id
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
136 "object" data})
|
139 "object" data})
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
137
|
140
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
138 (defn with-config
|
141 (defn with-config
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
139 "Returns curried forms of the #activity and #obj multimethods in the form
|
142 "Returns curried forms of the #activity and #obj multimethods in the form
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
140 {:activity ... :obj ...}, with the initial parameter set to config."
|
143 {:activity ... :obj ...}, with the initial parameter set to config."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
141 [config]
|
144 [config]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 5 forms covered">
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
142 (let [f (juxt
|
145 (let [f (juxt
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
143 #(partial activity %)
|
146 #(partial activity %)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
144 #(partial obj %))
|
147 #(partial obj %))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
145 [activity-fn obj-fn] (f config)]
|
148 [activity-fn obj-fn] (f config)]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
146 {:activity activity-fn
|
149 {:activity activity-fn
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
147 :obj obj-fn}))
|
150 :obj obj-fn}))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -8,109 +8,118 @@
|
||||||
001 (ns clj-activitypub.internal.crypto
|
001 (ns clj-activitypub.internal.crypto
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
002 (:require [clojure.java.io :as io])
|
002 "copied from [Jahfer's clj-activitypub library](https://github.com/jahfer/clj-activitypub).
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
003 (:import (java.util Base64)
|
003 If and when Jahfer issues a release of that library, this directory will be deleted and a
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
004 (java.security MessageDigest SecureRandom Signature)))
|
004 dependency on that library will be added to the project."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
005
|
005 (:require [clojure.java.io :as io])
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
006 (java.security.Security/addProvider
|
006 (:import (java.util Base64)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
007 (org.bouncycastle.jce.provider.BouncyCastleProvider.))
|
007 (java.security MessageDigest SecureRandom Signature)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
008
|
008
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
009 (defn- keydata [reader]
|
009 (java.security.Security/addProvider
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
010 (org.bouncycastle.jce.provider.BouncyCastleProvider.))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
011
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
012 (defn- keydata [reader]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
010 (->> reader
|
013 (->> reader
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
011 (org.bouncycastle.openssl.PEMParser.)
|
014 (org.bouncycastle.openssl.PEMParser.)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
012 (.readObject)))
|
015 (.readObject)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
013
|
016
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
014 (defn- pem-string->key-pair [string]
|
017 (defn- pem-string->key-pair [string]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 6 forms covered">
|
<span class="not-covered" title="0 out of 6 forms covered">
|
||||||
015 (let [kd (keydata (io/reader (.getBytes string)))]
|
018 (let [kd (keydata (io/reader (.getBytes string)))]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
016 (.getKeyPair (org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.) kd)))
|
019 (.getKeyPair (org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.) kd)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
017
|
020
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
018 (defn private-key [private-pem-str]
|
021 (defn private-key [private-pem-str]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
019 (-> private-pem-str
|
022 (-> private-pem-str
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
020 (pem-string->key-pair)
|
023 (pem-string->key-pair)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
021 (.getPrivate)))
|
024 (.getPrivate)))
|
||||||
</span><br/>
|
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
|
||||||
022
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
|
||||||
023 (defn base64-encode [bytes]
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
|
||||||
024 (.encodeToString (Base64/getEncoder) bytes))
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
025
|
025
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
026 (defn sha256-base64 [data]
|
026 (defn base64-encode [bytes]
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 5 forms covered">
|
|
||||||
027 (let [digest (.digest (MessageDigest/getInstance "SHA-256") (.getBytes data))]
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
028 (base64-encode digest)))
|
027 (.encodeToString (Base64/getEncoder) bytes))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
029
|
028
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
030 (defn sign [data private-key]
|
029 (defn sha256-base64 [data]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
031 (let [bytes (.getBytes data)
|
030 (let [digest (.digest (MessageDigest/getInstance "SHA-256") (.getBytes data))]
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
|
||||||
032 signer (doto (Signature/getInstance "SHA256withRSA")
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
033 (.initSign private-key (SecureRandom.))
|
031 (base64-encode digest)))
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
|
||||||
034 (.update bytes))]
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
|
||||||
035 (.sign signer)))
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
036
|
032
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
033 (defn sign [data private-key]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
|
034 (let [bytes (.getBytes data)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
|
035 signer (doto (Signature/getInstance "SHA256withRSA")
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
036 (.initSign private-key (SecureRandom.))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
|
037 (.update bytes))]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
038 (.sign signer)))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
039
|
||||||
</span><br/>
|
</span><br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -8,76 +8,85 @@
|
||||||
001 (ns clj-activitypub.internal.http-util
|
001 (ns clj-activitypub.internal.http-util
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
002 (:require [clj-activitypub.internal.crypto :as crypto])
|
002 "copied from [Jahfer's clj-activitypub library](https://github.com/jahfer/clj-activitypub).
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
003 (:import (java.net URLEncoder)
|
003 If and when Jahfer issues a release of that library, this directory will be deleted and a
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
004 (java.time OffsetDateTime ZoneOffset)
|
004 dependency on that library will be added to the project."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
005 (java.time.format DateTimeFormatter)))
|
005 (:require [clj-activitypub.internal.crypto :as crypto])
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
006 (:import (java.net URLEncoder)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
007 (java.time OffsetDateTime ZoneOffset)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
008 (java.time.format DateTimeFormatter)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
006
|
009
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
007 (defn encode-url-params [params]
|
010 (defn encode-url-params [params]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
008 (->> params
|
011 (->> params
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
009 (reduce-kv
|
012 (reduce-kv
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
010 (fn [coll k v]
|
013 (fn [coll k v]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
011 (conj coll
|
014 (conj coll
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="11 out of 11 forms covered">
|
<span class="covered" title="11 out of 11 forms covered">
|
||||||
012 (str (URLEncoder/encode (name k)) "=" (URLEncoder/encode (str v)))))
|
015 (str (URLEncoder/encode (name k)) "=" (URLEncoder/encode (str v)))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
013 [])
|
016 [])
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
014 (interpose "&")
|
017 (interpose "&")
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
015 (apply str)))
|
018 (apply str)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
016
|
019
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
017 (defn date []
|
020 (defn date []
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
018 (-> (OffsetDateTime/now (ZoneOffset/UTC))
|
021 (-> (OffsetDateTime/now (ZoneOffset/UTC))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
019 (.format DateTimeFormatter/RFC_1123_DATE_TIME)))
|
022 (.format DateTimeFormatter/RFC_1123_DATE_TIME)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
020
|
023
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
021 (defn digest
|
024 (defn digest
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
022 "Accepts body from HTTP request and generates string
|
025 "Accepts body from HTTP request and generates string
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
023 for use in HTTP `Digest` request header."
|
026 for use in HTTP `Digest` request header."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
024 [body]
|
027 [body]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 6 forms covered">
|
<span class="not-covered" title="0 out of 6 forms covered">
|
||||||
025 (str "sha-256=" (crypto/sha256-base64 body)))
|
028 (str "sha-256=" (crypto/sha256-base64 body)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -5,136 +5,145 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
001 (ns clj-activitypub.internal.thread-cache)
|
001 (ns clj-activitypub.internal.thread-cache
|
||||||
</span><br/>
|
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
|
||||||
002
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
|
||||||
003 (defn- current-time
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
004 "Returns current time using UNIX epoch."
|
002 "copied from [Jahfer's clj-activitypub library](https://github.com/jahfer/clj-activitypub).
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
005 []
|
003 If and when Jahfer issues a release of that library, this directory will be deleted and a
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
006 (System/currentTimeMillis))
|
004 dependency on that library will be added to the project.")
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
007
|
005
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
008 (defn- update-read-at [store k v]
|
006 (defn- current-time
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
007 "Returns current time using UNIX epoch."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
008 []
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
009 (System/currentTimeMillis))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
010
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
011 (defn- update-read-at [store k v]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
009 (dosync
|
012 (dosync
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
010 (commute store assoc k
|
013 (commute store assoc k
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="7 out of 7 forms covered">
|
<span class="covered" title="7 out of 7 forms covered">
|
||||||
011 (merge v {:read-at (current-time)}))))
|
014 (merge v {:read-at (current-time)}))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
012
|
015
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
013 (defn make
|
016 (defn make
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
014 "Creates a thread-local cache."
|
017 "Creates a thread-local cache."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
015 ([] (make false))
|
018 ([] (make false))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
016 ([cache-if-nil]
|
019 ([cache-if-nil]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
017 (let [store (ref {})]
|
020 (let [store (ref {})]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
018 (letfn [(cache-kv ([k v]
|
021 (letfn [(cache-kv ([k v]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
019 (dosync
|
022 (dosync
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
020 (commute store assoc k
|
023 (commute store assoc k
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="6 out of 6 forms covered">
|
<span class="covered" title="6 out of 6 forms covered">
|
||||||
021 {:write-at (current-time)
|
024 {:write-at (current-time)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
022 :read-at (current-time)
|
025 :read-at (current-time)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
023 :value v})
|
026 :value v})
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
024 v)))
|
027 v)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
025 (get-v ([k]
|
028 (get-v ([k]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="11 out of 11 forms covered">
|
<span class="covered" title="11 out of 11 forms covered">
|
||||||
026 (when-let [data (get @store k)]
|
029 (when-let [data (get @store k)]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
027 (update-read-at store k data)
|
030 (update-read-at store k data)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
028 (:value data)))
|
031 (:value data)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
029 ([k compute-fn]
|
032 ([k compute-fn]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
030 (let [storage @store]
|
033 (let [storage @store]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
031 (if (contains? storage k)
|
034 (if (contains? storage k)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
032 (get-v k)
|
035 (get-v k)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
033 (let [v (compute-fn)]
|
036 (let [v (compute-fn)]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="partial" title="11 out of 12 forms covered">
|
<span class="partial" title="11 out of 12 forms covered">
|
||||||
034 (when (or (not (nil? v)) cache-if-nil)
|
037 (when (or (not (nil? v)) cache-if-nil)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
035 (cache-kv k v)
|
038 (cache-kv k v)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
036 (get-v k)))))))
|
039 (get-v k)))))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
037 (lru ([]
|
040 (lru ([]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
038 (mapv
|
041 (mapv
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 6 forms covered">
|
<span class="not-covered" title="0 out of 6 forms covered">
|
||||||
039 (fn [[k v]] [k (:value v)])
|
042 (fn [[k v]] [k (:value v)])
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 12 forms covered">
|
<span class="not-covered" title="0 out of 12 forms covered">
|
||||||
040 (sort-by #(-> % val :read-at) < @store))))]
|
043 (sort-by #(-> % val :read-at) < @store))))]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="6 out of 6 forms covered">
|
<span class="covered" title="6 out of 6 forms covered">
|
||||||
041 {:cache-kv cache-kv
|
044 {:cache-kv cache-kv
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
042 :get-v get-v
|
045 :get-v get-v
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
043 :cache-if-nil cache-if-nil
|
046 :cache-if-nil cache-if-nil
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
044 :lru lru}))))
|
047 :lru lru}))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -8,97 +8,106 @@
|
||||||
001 (ns clj-activitypub.webfinger
|
001 (ns clj-activitypub.webfinger
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
002 (:require [clj-http.client :as client]
|
002 "copied from [Jahfer's clj-activitypub library](https://github.com/jahfer/clj-activitypub).
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
003 [clj-activitypub.internal.http-util :as http]
|
003 If and when Jahfer issues a release of that library, this directory will be deleted and a
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
004 [clj-activitypub.internal.thread-cache :as thread-cache]))
|
004 dependency on that library will be added to the project."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
005 (:require [clj-http.client :as client]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
006 [clj-activitypub.internal.http-util :as http]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
007 [clj-activitypub.internal.thread-cache :as thread-cache]))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
005
|
008
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
006 (def remote-uri-path "/.well-known/webfinger")
|
009 (def remote-uri-path "/.well-known/webfinger")
|
||||||
</span><br/>
|
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
|
||||||
007
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
|
||||||
008 (defn- resource-str [domain username]
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="6 out of 6 forms covered">
|
|
||||||
009 (str "acct:" username "@" domain))
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
010
|
010
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
011 (defn resource-url
|
011 (defn- resource-str [domain username]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="covered" title="6 out of 6 forms covered">
|
||||||
012 "Builds a URL pointing to the user's account on the remote server."
|
012 (str "acct:" username "@" domain))
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
013 [domain username & [params]]
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
|
||||||
014 (let [resource (resource-str domain username)
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="8 out of 8 forms covered">
|
|
||||||
015 query-str (http/encode-url-params (merge params {:resource resource}))]
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="7 out of 7 forms covered">
|
|
||||||
016 (str "https://" domain remote-uri-path "?" query-str)))
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
017
|
013
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
018 (def ^:private user-id-cache
|
014 (defn resource-url
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
019 (thread-cache/make))
|
015 "Builds a URL pointing to the user's account on the remote server."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
016 [domain username & [params]]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
|
017 (let [resource (resource-str domain username)
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="8 out of 8 forms covered">
|
||||||
|
018 query-str (http/encode-url-params (merge params {:resource resource}))]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="7 out of 7 forms covered">
|
||||||
|
019 (str "https://" domain remote-uri-path "?" query-str)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
020
|
020
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
021 (defn fetch-user-id
|
021 (def ^:private user-id-cache
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
022 "Follows the webfinger request to a remote domain, retrieving the ID of the requested
|
022 (thread-cache/make))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
023 account. Typically returns a string in the form of a URL."
|
023
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
024 [domain username]
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
|
||||||
025 ((:get-v user-id-cache)
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
|
||||||
026 (str domain "@" username) ;; cache key
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
027 (fn []
|
024 (defn fetch-user-id
|
||||||
</span><br/>
|
|
||||||
<span class="partial" title="15 out of 16 forms covered">
|
|
||||||
028 (let [response (some-> (resource-url domain username {:rel "self"})
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="8 out of 8 forms covered">
|
|
||||||
029 (client/get {:as :json :throw-exceptions false :ignore-unknown-host? true}))]
|
|
||||||
</span><br/>
|
|
||||||
<span class="partial" title="27 out of 31 forms covered">
|
|
||||||
030 (some->> response :body :links
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="12 out of 12 forms covered">
|
|
||||||
031 (some #(when (= (:type %) "application/activity+json") %))
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
032 :href)))))
|
025 "Follows the webfinger request to a remote domain, retrieving the ID of the requested
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
026 account. Typically returns a string in the form of a URL."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
027 [domain username]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
|
028 ((:get-v user-id-cache)
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
|
029 (str domain "@" username) ;; cache key
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
030 (fn []
|
||||||
|
</span><br/>
|
||||||
|
<span class="partial" title="15 out of 16 forms covered">
|
||||||
|
031 (let [response (some-> (resource-url domain username {:rel "self"})
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="8 out of 8 forms covered">
|
||||||
|
032 (client/get {:as :json :throw-exceptions false :ignore-unknown-host? true}))]
|
||||||
|
</span><br/>
|
||||||
|
<span class="partial" title="27 out of 31 forms covered">
|
||||||
|
033 (some->> response :body :links
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="12 out of 12 forms covered">
|
||||||
|
034 (some #(when (= (:type %) "application/activity+json") %))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
035 :href)))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,54 +1,73 @@
|
||||||
{"coverage":
|
{"coverage":
|
||||||
{"dog_and_duck/quack/quack.clj":
|
{"dog_and_duck/quack/quack.clj":
|
||||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||||
null, null, null, null, null, null, null, null, null, null, 1, null,
|
|
||||||
null, null, null, null, null, null, null, null, null, null, null,
|
null, null, null, null, null, null, null, null, null, null, null,
|
||||||
17, null, 1, null, null, null, null, null, true, 5, null, null, 1,
|
null, null, null, null, null, null, null, null, null, null, null,
|
||||||
null, 1, null, null, null, null, 1, null, null, null, null, null, 1,
|
null, null, null, 1, null, null, null, null, null, null, null, null,
|
||||||
null, null, 4, null, 1, null, null, null, null, 1, null, null, null,
|
null, null, null, null, null, null, null, null, null, null, null,
|
||||||
null, 1, null, null, 4, null, 1, null, null, null, null, 1, null,
|
40, null, 0, null, 1, null, null, null, null, null, true, 4, null,
|
||||||
null, null, null, null, null, true, 10, 9, true, 2, null, null,
|
null, null, null, 1, null, null, null, null, 1, null, null, null,
|
||||||
null, true, 2, null, 1, null, null, true, 2, 2, 0, 0, 0, null, null,
|
null, null, true, null, null, 5, null, true, null, 1, null, null,
|
||||||
1, null, null, 0, 0, 0, 0, 0, 0, 0, null, null, null, 1, null, null,
|
null, null, 1, null, null, null, null, true, null, null, 5, null,
|
||||||
0, 0, 0, null, null, 1, null, null, null, null, null, 0, 0, 0, null,
|
null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||||
null, 1, null, null, null, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
null, null, null, null, true, 2, 2, 0, 0, 0, null, null, 1, null,
|
||||||
null, null, 0, 0, null, 1, null, null, 0, null, 1, null, null, 0,
|
null, null, null, null, null, null, 0, 0, 0, null, null, 1, null,
|
||||||
null, 1, null, null, 0, null, 1, null, null, 0, null, null],
|
null, 0, 0, 0, 0, 0, 0, 0, null, null, null, 1, null, null, 0, 0, 0,
|
||||||
|
null, null, 1, null, null, null, null, null, 0, 0, 0, null, null, 1,
|
||||||
|
null, null, null, null, null, true, true, true, true, 2, 1, null, 1,
|
||||||
|
1, true, true, 1, null, null, null, null, null, null, null, null, 0,
|
||||||
|
0, 0, 0, null, null, 1, null, null, 0, null, 1, null, null, 0, null,
|
||||||
|
1, null, null, 0, null, 1, null, null, 2, null, null],
|
||||||
|
"dog_and_duck/utils/process.clj":
|
||||||
|
[null, 1, null, null, 1, null, null, null, null, 1, 1, 1, null, true,
|
||||||
|
null, null, null, null, null, null, null, null, null, 1],
|
||||||
"clj_activitypub/internal/http_util.clj":
|
"clj_activitypub/internal/http_util.clj":
|
||||||
[null, 1, null, null, null, null, null, 1, 1, 1, 1, 2, 2, 1, 1, 1,
|
[null, 1, null, null, null, null, null, null, null, null, 1, 1, 1, 1,
|
||||||
null, 1, 0, 0, null, 1, null, null, null, 0],
|
2, 2, 1, 1, 1, null, 1, 0, 0, null, 1, null, null, null, 0],
|
||||||
"clj_activitypub/internal/thread_cache.clj":
|
"clj_activitypub/internal/thread_cache.clj":
|
||||||
[null, 1, null, 1, null, null, 8, null, 1, 4, 4, 4, null, 1, null, 2,
|
[null, 1, null, null, null, null, 1, null, null, 8, null, 1, 4, 4, 4,
|
||||||
null, 2, 2, 2, 2, 2, 2, 2, 2, null, 4, 4, 4, null, 4, 4, 2, 2, true,
|
null, 1, null, 2, null, 2, 2, 2, 2, 2, 2, 2, 2, null, 4, 4, 4, null,
|
||||||
2, 2, null, 0, 0, 0, 2, 2, 2, 2],
|
4, 4, 2, 2, true, 2, 2, null, 0, 0, 0, 2, 2, 2, 2],
|
||||||
"dog_and_duck/scratch/parser.clj":
|
"dog_and_duck/scratch/parser.clj":
|
||||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||||
null, null, null, null, null, null, null, null, null, null, null,
|
null, null, null, null, null, null, null, null, null, null, null,
|
||||||
null, 1, null, null, null, 7, 7, 7, 7, 7, true, 0, null, 1, null, 1,
|
null, 1, null, null, null, 10, 10, 10, 10, 10, true, 0, null, 1,
|
||||||
0, 0, 0, 0, 0, 0, 1],
|
null, 1, 0, 0, 0, 0, 0, 0, 1, null, 1],
|
||||||
"clj_activitypub/core.clj":
|
"clj_activitypub/core.clj":
|
||||||
[null, 1, null, null, null, null, null, null, 1, null, null, null,
|
[null, 1, null, null, null, null, null, null, null, null, null, 1,
|
||||||
null, null, 0, 0, 0, 0, 0, 0, 0, 0, null, 1, null, null, null, 6, 2,
|
null, null, null, null, null, 0, 0, 0, 0, 0, 0, 0, 0, null, 1, null,
|
||||||
2, null, 1, 1, null, null, null, 1, 1, 1, 1, null, null, 1, null, 1,
|
null, null, 6, 2, 2, null, 1, 1, null, null, null, 1, 1, 1, 1, null,
|
||||||
null, null, null, 0, null, 0, null, 0, 0, 0, 0, 0, 0, null, 1, null,
|
null, 1, null, 1, null, null, null, 0, null, 0, null, 0, 0, 0, 0, 0,
|
||||||
1, 0, 0, 0, 0, 0, 0, 0, 0, null, 1, null, null, 0, 0, 0, 0, 0, 0, 0,
|
0, null, 1, null, 1, 0, 0, 0, 0, 0, 0, 0, 0, null, 1, null, null, 0,
|
||||||
0, 0, 0, 0, null, 1, null, null, null, 0, 0, 0, 0, 0, 0, 0, null, 1,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null, 1, null, null, null, 0, 0, 0, 0,
|
||||||
null, null, null, true, null, 1, null, null, null, null, null, 0,
|
0, 0, 0, null, 1, null, null, null, true, null, 1, null, null, null,
|
||||||
null, 0, 0, 0, 0, 0, null, 1, null, null, null, true, null, 1, 0,
|
null, null, 0, null, 0, 0, 0, 0, 0, null, 1, null, null, null, true,
|
||||||
null, null, 0, 0, null, 1, 0, null, null, 0, 0, null, 1, null, null,
|
null, 1, 0, null, null, 0, 0, null, 1, 0, null, null, 0, 0, null, 1,
|
||||||
null, 0, 0, 0, 0, 0, 0],
|
null, null, null, 0, 0, 0, 0, 0, 0],
|
||||||
"clj_activitypub/internal/crypto.clj":
|
"clj_activitypub/internal/crypto.clj":
|
||||||
[null, 1, null, null, null, null, 1, 1, null, 1, 0, 0, null, null, 1,
|
[null, 1, null, null, null, null, null, null, null, 1, 1, null, 1, 0,
|
||||||
0, 0, null, 1, 0, 0, null, null, 1, 0, null, 1, 0, 0, null, 1, 0, 0,
|
0, null, null, 1, 0, 0, null, 1, 0, 0, null, null, 1, 0, null, 1, 0,
|
||||||
0, 0, 0, null],
|
0, null, 1, 0, 0, 0, 0, 0, null],
|
||||||
|
"dog_and_duck/quack/picky.clj":
|
||||||
|
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null, null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null, null, null, 1, null, null, null, null,
|
||||||
|
null, null, null, null, null, null, 1, null, 1, null, 1, 1, 1, 1, 1,
|
||||||
|
null, 1, null, null, null, 0, 0, 0, 0, 0, 0, 0, 0, null, 1, null,
|
||||||
|
null, null, null, 1, null, null, null, null, 1, null, null, null,
|
||||||
|
null, null, null, true, 10, 9, true, 2, null, null, null, true,
|
||||||
|
null, null, 3, null, null, null, 1, null, null, null, null, null,
|
||||||
|
null, 0, 0, 0, 0, null, 0, null, 0, null, 0, 0, 0, null, 1, null, 0,
|
||||||
|
0, 0, 0, 0, 0, null, null, null, null, null, 0, 0, null, null, null,
|
||||||
|
null, 0, 0, null, null, null, null, null, null, null],
|
||||||
"dog_and_duck/scratch/core.clj":[null, 1, null, 1, null, null, 0],
|
"dog_and_duck/scratch/core.clj":[null, 1, null, 1, null, null, 0],
|
||||||
"clj_activitypub/webfinger.clj":
|
"clj_activitypub/webfinger.clj":
|
||||||
[null, 1, null, null, null, null, 1, null, 1, 1, null, 1, null, null,
|
[null, 1, null, null, null, null, null, null, null, 1, null, 1, 1,
|
||||||
1, 1, 1, null, 1, 1, null, 1, null, null, null, 3, 3, 3, true, 1,
|
null, 1, null, null, 1, 1, 1, null, 1, 1, null, 1, null, null, null,
|
||||||
true, 2, null],
|
3, 3, 3, true, 1, true, 2, null],
|
||||||
"dog_and_duck/scratch/scratch.clj":
|
"dog_and_duck/scratch/scratch.clj":
|
||||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||||
null, null, null, null, null, null, null, null, null, null, null,
|
null, null, null, null, null, null, null, null, null, null, null,
|
||||||
null, null, null, null, null, 1, null, 1, 1, 1, null, null, null,
|
null, null, null, null, null, 1, null, 1, 1, 1, null, null, null,
|
||||||
null, 1, null, 1, 1, 1, 1, null, null, 1, null, null, 1, 1, null,
|
null, 1, null, 1, 1, 1, 1, null, null, 1, null, null, 1, 1, null,
|
||||||
null, null, null, 1, 1, 1, 1, 1, 1, null]}}
|
null, null, null, 1, 1, 1, 1, 1, 1, null, null]}}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?><report><stats><packages value="9"/><methods value="1223"/><srcfiles value="9"/><srclines value="284"/></stats><data><all name="total"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="52% (631/1223)"/><coverage type="line, %" value="54% (153/284)"/><package name="dog-and-duck.scratch.scratch"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="100% (75/75)"/><coverage type="line, %" value="100% (19/19)"/></package><package name="clj-activitypub.internal.thread-cache"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="83% (105/126)"/><coverage type="line, %" value="88% (30/34)"/></package><package name="clj-activitypub.internal.crypto"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="19% (9/48)"/><coverage type="line, %" value="39% (9/23)"/></package><package name="dog-and-duck.quack.quack"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="44% (199/448)"/><coverage type="line, %" value="46% (31/68)"/></package><package name="clj-activitypub.webfinger"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="96% (107/112)"/><coverage type="line, %" value="89% (16/18)"/></package><package name="clj-activitypub.internal.http-util"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="74% (29/39)"/><coverage type="line, %" value="80% (12/15)"/></package><package name="dog-and-duck.scratch.core"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="33% (2/6)"/><coverage type="line, %" value="67% (2/3)"/></package><package name="dog-and-duck.scratch.parser"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="50% (34/68)"/><coverage type="line, %" value="56% (10/18)"/></package><package name="clj-activitypub.core"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="24% (71/301)"/><coverage type="line, %" value="28% (24/86)"/></package></all></data></report>
|
<?xml version="1.0" encoding="UTF-8"?><report><stats><packages value="11"/><methods value="1530"/><srcfiles value="11"/><srclines value="340"/></stats><data><all name="total"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="53% (816/1530)"/><coverage type="line, %" value="52% (177/340)"/><package name="dog-and-duck.scratch.scratch"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="100% (75/75)"/><coverage type="line, %" value="100% (19/19)"/></package><package name="clj-activitypub.internal.thread-cache"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="83% (105/126)"/><coverage type="line, %" value="88% (30/34)"/></package><package name="clj-activitypub.internal.crypto"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="19% (9/48)"/><coverage type="line, %" value="39% (9/23)"/></package><package name="dog-and-duck.quack.quack"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="48% (237/490)"/><coverage type="line, %" value="43% (29/67)"/></package><package name="clj-activitypub.webfinger"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="96% (107/112)"/><coverage type="line, %" value="89% (16/18)"/></package><package name="dog-and-duck.quack.picky"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="50% (113/227)"/><coverage type="line, %" value="39% (19/49)"/></package><package name="clj-activitypub.internal.http-util"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="74% (29/39)"/><coverage type="line, %" value="80% (12/15)"/></package><package name="dog-and-duck.scratch.core"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="33% (2/6)"/><coverage type="line, %" value="67% (2/3)"/></package><package name="dog-and-duck.utils.process"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="86% (25/29)"/><coverage type="line, %" value="86% (6/7)"/></package><package name="dog-and-duck.scratch.parser"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="56% (43/77)"/><coverage type="line, %" value="58% (11/19)"/></package><package name="clj-activitypub.core"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="24% (71/301)"/><coverage type="line, %" value="28% (24/86)"/></package></all></data></report>
|
437
docs/cloverage/dog_and_duck/quack/picky.clj.html
Normal file
437
docs/cloverage/dog_and_duck/quack/picky.clj.html
Normal file
|
@ -0,0 +1,437 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<link rel="stylesheet" href="../../coverage.css"/> <title> dog_and_duck/quack/picky.clj </title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
001 (ns dog-and-duck.quack.picky "Fault-finder for ActivityPub documents.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
002
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
003 Generally, each `-faults` function will return:
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
004 1. `nil` if no faults were found;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
005 2. a sequence of fault objects if faults were found.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
006
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
007 Each fault object shall have the properties:
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
008 1. `:@context` whose value shall be the URL of a
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
009 document specifying this vocabulary;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
010 2. `:type` whose value shall be `Fault`;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
011 3. `:severity` whose value shall be one of
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
012 `minor`, `should`, `must` or `critical`;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
013 4. `:fault` whose value shall be a unique token
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
014 representing the particular fault type;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
015 5. `:narrative` whose value shall be a natural
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
016 language description of the fault type.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
017
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
018 Note that the reason for the `:fault` property is
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
019 to be able to have a well known place, linked to
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
020 from the @context URL, which allows narratives
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
021 for each fault type to be served in as many
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
022 natural languages as possible.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
023
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
024 The idea further is that it should ultimately be
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
025 possible to serialise a fault report as a
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
026 document which in its own right conforms to the
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
027 ActivityStreams spec."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
028 (:require [dog-and-duck.utils.process :refer [pid]]))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
029
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
030 (def ^:const severity
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
031 "Severity of faults found, as follows:
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
032
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
033 1. `:minor` things which I consider to be faults, but which
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
034 don't actually breach the spec;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
035 2. `:should` instances where the spec says something SHOULD
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
036 be done, which isn't;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
037 3. `:must` instances where the spec says something MUST
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
038 be done, which isn't;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
039 4. `:critical` instances where I believe the fault means that
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
040 the object cannot be meaningfully processed."
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
|
041 #{:minor :should :must :critical})
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
042
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
043 (def ^:const severity-filters
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
044 "Hack for implementing a severity hierarchy"
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="7 out of 7 forms covered">
|
||||||
|
045 {:all #{}
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
046 :minor #{:minor}
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
|
047 :should #{:minor :should}
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
|
048 :must #{:minor :should :must}
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
049 :critical severity})
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
050
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
051 (defn filter-severity
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
052 "Return a list of reports taken from these `reports` where the severity
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
053 of the report is greater than this `severity`."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
054 [reports severity]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 11 forms covered">
|
||||||
|
055 (assert
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 10 forms covered">
|
||||||
|
056 (and
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
057 (coll? reports)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
|
058 (every? map? reports)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
|
059 (every? :severity reports)))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
060 (remove
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 7 forms covered">
|
||||||
|
061 #((severity-filters severity) (:severity %))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
062 reports))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
063
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
064 (def ^:const activitystreams-context-uri
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
065 "The URI of the context of an ActivityStreams object is expected to be this
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
066 literal string."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
067 "https://www.w3.org/ns/activitystreams")
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
068
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
069 (def ^:const validation-fault-context-uri
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
070 "The URI of the context of a validation fault report object shall be this
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
071 literal string."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
072 "https://simon-brooke.github.io/dog-and-duck/codox/Validation_Faults.html")
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
073
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
074 (defn context?
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
075 "Returns `true` iff `x` quacks like an ActivityStreams context, else false.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
076
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
077 A context is either
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
078 1. the URI (actually an IRI) `activitystreams-context-uri`, or
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
079 2. a collection comprising that URI and a map."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
080 [x]
|
||||||
|
</span><br/>
|
||||||
|
<span class="partial" title="4 out of 6 forms covered">
|
||||||
|
081 (cond
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
|
082 (nil? x) false
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="11 out of 11 forms covered">
|
||||||
|
083 (string? x) (and (= x activitystreams-context-uri) true)
|
||||||
|
</span><br/>
|
||||||
|
<span class="partial" title="19 out of 20 forms covered">
|
||||||
|
084 (coll? x) (and (context? (first (remove map? x)))
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
|
085 (= (count x) 2)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
086 true)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
087 :else false))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
088
|
||||||
|
</span><br/>
|
||||||
|
<span class="partial" title="38 out of 40 forms covered">
|
||||||
|
089 (defmacro has-context?
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
090 "True if `x` is an ActivityStreams object with a valid context, else `false`."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
091 [x]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
092 `(context? ((keyword "@context") ~x)))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
093
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
094
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
095
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
096 (defn make-fault-object
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
097 "Return a fault object with these `severity`, `fault` and `narrative` values.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
098
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
099 An ActivityPub object MUST have a globally unique ID. Whether this is
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
100 meaningful depends on whether we persist fault report objects and serve
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
101 them, which at present I have no plans to do."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
102 [severity fault narrative]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 9 forms covered">
|
||||||
|
103 (assoc {}
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
|
104 (keyword "@context") validation-fault-context-uri
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
105 :id (str "https://"
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
|
106 (.. java.net.InetAddress getLocalHost getHostName)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
107 "/fault/"
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
108 pid
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
109 ":"
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
110 (inst-ms (java.util.Date.)))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
111 :type "Fault"
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
112 :severity severity
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
113 :fault fault
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
114 :narrative narrative))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
115
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
116 (defn object-faults
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
117 [x]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
|
118 (remove
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
119 empty?
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
|
120 (list
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
121 (when-not
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
122 (has-context? x)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
123 (make-fault-object
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
124 :should
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
125 :no-context
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
126 "Section 3 of the ActivityPub specification states
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
127 `Implementers SHOULD include the ActivityPub context in
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
128 their object definitions`.")
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 6 forms covered">
|
||||||
|
129 (when-not (:type x)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
130 (make-fault-object
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
131 :minor
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
132 :no-type
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
133 "The ActivityPub specification states that the `type` field is
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
134 optional, but it is hard to process objects with no known type."))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 7 forms covered">
|
||||||
|
135 (when-not (contains? x :id)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
136 (make-fault-object
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
137 :minor
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
138 :no-id-transient
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
139 "The ActivityPub specification allows objects without `id` fields
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
140 only if they are intentionally transient; even so it is preferred
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
141 that the object should have an explicit null id."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
142 ))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
143 ))))
|
||||||
|
</span><br/>
|
||||||
|
</body>
|
||||||
|
</html>
|
File diff suppressed because it is too large
Load diff
|
@ -139,5 +139,11 @@
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
045 (file-seq (file "resources/activitystreams-test-documents")))
|
045 (file-seq (file "resources/activitystreams-test-documents")))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
046
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="9 out of 9 forms covered">
|
||||||
|
047 (-> "resources/activitystreams-test-documents/simple0020.json" slurp clean first :actor)
|
||||||
|
</span><br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -137,7 +137,7 @@
|
||||||
044 ;;; examine what you got back!
|
044 ;;; examine what you got back!
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
045 (:outbox account)
|
045 (:inbox account)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
046
|
046
|
||||||
|
@ -184,5 +184,8 @@
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
060 )
|
060 )
|
||||||
</span><br/>
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
061
|
||||||
|
</span><br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
77
docs/cloverage/dog_and_duck/utils/process.clj.html
Normal file
77
docs/cloverage/dog_and_duck/utils/process.clj.html
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<link rel="stylesheet" href="../../coverage.css"/> <title> dog_and_duck/utils/process.clj </title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
001 (ns dog-and-duck.utils.process
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
002 (:require [clojure.string :refer [split]]))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
003
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
004 (def pid
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
005 "OK, this is hacky as fuck, but I hope it works. The problem is that the
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
006 way to get the process id has changed several times during the history
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
007 of Java development, and the code for one version of Java won't even compile
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
008 in a different version."
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="9 out of 9 forms covered">
|
||||||
|
009 (let [java-version (read-string (apply str (take 2
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
|
010 (split
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
011 (System/getProperty "java.version")
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
012 #"[_\.]"))))
|
||||||
|
</span><br/>
|
||||||
|
<span class="partial" title="4 out of 8 forms covered">
|
||||||
|
013 cmd (case java-version
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
014 18 "(let [[_ pid hostname]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
015 (re-find
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
016 #\"^(\\d+)@(.*)\"
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
017 (.getName
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
018 (java.lang.management.ManagementFactory/getRuntimeMXBean)))]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
019 pid)"
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
020 (19 110) "(.pid (java.lang.ProcessHandle/current))"
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
021 111 "(.getPid (java.lang.management.ManagementFactory/getRuntimeMXBean))"
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
022 ":default")]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
|
023 (eval (read-string cmd))))
|
||||||
|
</span><br/>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -29,7 +29,7 @@
|
||||||
style="width:69.76744186046511%;
|
style="width:69.76744186046511%;
|
||||||
float:left;"> 60 </div></td>
|
float:left;"> 60 </div></td>
|
||||||
<td class="with-number">30.23 %</td>
|
<td class="with-number">30.23 %</td>
|
||||||
<td class="with-number">147</td><td class="with-number">14</td><td class="with-number">86</td>
|
<td class="with-number">150</td><td class="with-number">14</td><td class="with-number">86</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="clj_activitypub/internal/crypto.clj.html">clj-activitypub.internal.crypto</a></td><td class="with-bar"><div class="covered"
|
<td><a href="clj_activitypub/internal/crypto.clj.html">clj-activitypub.internal.crypto</a></td><td class="with-bar"><div class="covered"
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
style="width:60.869565217391305%;
|
style="width:60.869565217391305%;
|
||||||
float:left;"> 14 </div></td>
|
float:left;"> 14 </div></td>
|
||||||
<td class="with-number">39.13 %</td>
|
<td class="with-number">39.13 %</td>
|
||||||
<td class="with-number">36</td><td class="with-number">8</td><td class="with-number">23</td>
|
<td class="with-number">39</td><td class="with-number">8</td><td class="with-number">23</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="clj_activitypub/internal/http_util.clj.html">clj-activitypub.internal.http-util</a></td><td class="with-bar"><div class="covered"
|
<td><a href="clj_activitypub/internal/http_util.clj.html">clj-activitypub.internal.http-util</a></td><td class="with-bar"><div class="covered"
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
style="width:20.0%;
|
style="width:20.0%;
|
||||||
float:left;"> 3 </div></td>
|
float:left;"> 3 </div></td>
|
||||||
<td class="with-number">80.00 %</td>
|
<td class="with-number">80.00 %</td>
|
||||||
<td class="with-number">25</td><td class="with-number">3</td><td class="with-number">15</td>
|
<td class="with-number">28</td><td class="with-number">3</td><td class="with-number">15</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="clj_activitypub/internal/thread_cache.clj.html">clj-activitypub.internal.thread-cache</a></td><td class="with-bar"><div class="covered"
|
<td><a href="clj_activitypub/internal/thread_cache.clj.html">clj-activitypub.internal.thread-cache</a></td><td class="with-bar"><div class="covered"
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
style="width:8.823529411764707%;
|
style="width:8.823529411764707%;
|
||||||
float:left;"> 3 </div></td>
|
float:left;"> 3 </div></td>
|
||||||
<td class="with-number">91.18 %</td>
|
<td class="with-number">91.18 %</td>
|
||||||
<td class="with-number">44</td><td class="with-number">3</td><td class="with-number">34</td>
|
<td class="with-number">47</td><td class="with-number">3</td><td class="with-number">34</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="clj_activitypub/webfinger.clj.html">clj-activitypub.webfinger</a></td><td class="with-bar"><div class="covered"
|
<td><a href="clj_activitypub/webfinger.clj.html">clj-activitypub.webfinger</a></td><td class="with-bar"><div class="covered"
|
||||||
|
@ -91,24 +91,41 @@
|
||||||
style="width:11.11111111111111%;
|
style="width:11.11111111111111%;
|
||||||
float:left;"> 2 </div></td>
|
float:left;"> 2 </div></td>
|
||||||
<td class="with-number">100.00 %</td>
|
<td class="with-number">100.00 %</td>
|
||||||
<td class="with-number">32</td><td class="with-number">5</td><td class="with-number">18</td>
|
<td class="with-number">35</td><td class="with-number">5</td><td class="with-number">18</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="dog_and_duck/quack/picky.clj.html">dog-and-duck.quack.picky</a></td><td class="with-bar"><div class="covered"
|
||||||
|
style="width:49.779735682819386%;
|
||||||
|
float:left;"> 113 </div><div class="not-covered"
|
||||||
|
style="width:50.220264317180614%;
|
||||||
|
float:left;"> 114 </div></td>
|
||||||
|
<td class="with-number">49.78 %</td>
|
||||||
|
<td class="with-bar"><div class="covered"
|
||||||
|
style="width:38.775510204081634%;
|
||||||
|
float:left;"> 19 </div><div class="partial"
|
||||||
|
style="width:6.122448979591836%;
|
||||||
|
float:left;"> 3 </div><div class="not-covered"
|
||||||
|
style="width:55.10204081632653%;
|
||||||
|
float:left;"> 27 </div></td>
|
||||||
|
<td class="with-number">44.90 %</td>
|
||||||
|
<td class="with-number">143</td><td class="with-number">11</td><td class="with-number">49</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="dog_and_duck/quack/quack.clj.html">dog-and-duck.quack.quack</a></td><td class="with-bar"><div class="covered"
|
<td><a href="dog_and_duck/quack/quack.clj.html">dog-and-duck.quack.quack</a></td><td class="with-bar"><div class="covered"
|
||||||
style="width:44.419642857142854%;
|
style="width:48.36734693877551%;
|
||||||
float:left;"> 199 </div><div class="not-covered"
|
float:left;"> 237 </div><div class="not-covered"
|
||||||
style="width:55.580357142857146%;
|
style="width:51.63265306122449%;
|
||||||
float:left;"> 249 </div></td>
|
float:left;"> 253 </div></td>
|
||||||
<td class="with-number">44.42 %</td>
|
<td class="with-number">48.37 %</td>
|
||||||
<td class="with-bar"><div class="covered"
|
<td class="with-bar"><div class="covered"
|
||||||
style="width:45.588235294117645%;
|
style="width:43.28358208955224%;
|
||||||
float:left;"> 31 </div><div class="partial"
|
float:left;"> 29 </div><div class="partial"
|
||||||
style="width:7.352941176470588%;
|
style="width:16.417910447761194%;
|
||||||
float:left;"> 5 </div><div class="not-covered"
|
float:left;"> 11 </div><div class="not-covered"
|
||||||
style="width:47.05882352941177%;
|
style="width:40.298507462686565%;
|
||||||
float:left;"> 32 </div></td>
|
float:left;"> 27 </div></td>
|
||||||
<td class="with-number">52.94 %</td>
|
<td class="with-number">59.70 %</td>
|
||||||
<td class="with-number">187</td><td class="with-number">26</td><td class="with-number">68</td>
|
<td class="with-number">227</td><td class="with-number">26</td><td class="with-number">67</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="dog_and_duck/scratch/core.clj.html">dog-and-duck.scratch.core</a></td><td class="with-bar"><div class="covered"
|
<td><a href="dog_and_duck/scratch/core.clj.html">dog-and-duck.scratch.core</a></td><td class="with-bar"><div class="covered"
|
||||||
|
@ -127,20 +144,20 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="dog_and_duck/scratch/parser.clj.html">dog-and-duck.scratch.parser</a></td><td class="with-bar"><div class="covered"
|
<td><a href="dog_and_duck/scratch/parser.clj.html">dog-and-duck.scratch.parser</a></td><td class="with-bar"><div class="covered"
|
||||||
style="width:50.0%;
|
style="width:55.84415584415584%;
|
||||||
float:left;"> 34 </div><div class="not-covered"
|
float:left;"> 43 </div><div class="not-covered"
|
||||||
style="width:50.0%;
|
style="width:44.15584415584416%;
|
||||||
float:left;"> 34 </div></td>
|
float:left;"> 34 </div></td>
|
||||||
<td class="with-number">50.00 %</td>
|
<td class="with-number">55.84 %</td>
|
||||||
<td class="with-bar"><div class="covered"
|
<td class="with-bar"><div class="covered"
|
||||||
style="width:55.55555555555556%;
|
style="width:57.89473684210526%;
|
||||||
float:left;"> 10 </div><div class="partial"
|
float:left;"> 11 </div><div class="partial"
|
||||||
style="width:5.555555555555555%;
|
style="width:5.2631578947368425%;
|
||||||
float:left;"> 1 </div><div class="not-covered"
|
float:left;"> 1 </div><div class="not-covered"
|
||||||
style="width:38.888888888888886%;
|
style="width:36.8421052631579%;
|
||||||
float:left;"> 7 </div></td>
|
float:left;"> 7 </div></td>
|
||||||
<td class="with-number">61.11 %</td>
|
<td class="with-number">63.16 %</td>
|
||||||
<td class="with-number">45</td><td class="with-number">7</td><td class="with-number">18</td>
|
<td class="with-number">47</td><td class="with-number">8</td><td class="with-number">19</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="dog_and_duck/scratch/scratch.clj.html">dog-and-duck.scratch.scratch</a></td><td class="with-bar"><div class="covered"
|
<td><a href="dog_and_duck/scratch/scratch.clj.html">dog-and-duck.scratch.scratch</a></td><td class="with-bar"><div class="covered"
|
||||||
|
@ -151,13 +168,28 @@
|
||||||
style="width:100.0%;
|
style="width:100.0%;
|
||||||
float:left;"> 19 </div></td>
|
float:left;"> 19 </div></td>
|
||||||
<td class="with-number">100.00 %</td>
|
<td class="with-number">100.00 %</td>
|
||||||
<td class="with-number">60</td><td class="with-number">9</td><td class="with-number">19</td>
|
<td class="with-number">61</td><td class="with-number">10</td><td class="with-number">19</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="dog_and_duck/utils/process.clj.html">dog-and-duck.utils.process</a></td><td class="with-bar"><div class="covered"
|
||||||
|
style="width:86.20689655172414%;
|
||||||
|
float:left;"> 25 </div><div class="not-covered"
|
||||||
|
style="width:13.793103448275861%;
|
||||||
|
float:left;"> 4 </div></td>
|
||||||
|
<td class="with-number">86.21 %</td>
|
||||||
|
<td class="with-bar"><div class="covered"
|
||||||
|
style="width:85.71428571428571%;
|
||||||
|
float:left;"> 6 </div><div class="partial"
|
||||||
|
style="width:14.285714285714286%;
|
||||||
|
float:left;"> 1 </div></td>
|
||||||
|
<td class="with-number">100.00 %</td>
|
||||||
|
<td class="with-number">23</td><td class="with-number">1</td><td class="with-number">7</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr><td>Totals:</td>
|
<tr><td>Totals:</td>
|
||||||
<td class="with-bar"></td>
|
<td class="with-bar"></td>
|
||||||
<td class="with-number">51.59 %</td>
|
<td class="with-number">53.33 %</td>
|
||||||
<td class="with-bar"></td>
|
<td class="with-bar"></td>
|
||||||
<td class="with-number">57.75 %</td>
|
<td class="with-number">58.24 %</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
|
|
File diff suppressed because one or more lines are too long
37
docs/codox/Validation_Faults.html
Normal file
37
docs/codox/Validation_Faults.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
15
docs/codox/dog-and-duck.quack.picky.html
Normal file
15
docs/codox/dog-and-duck.quack.picky.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
docs/codox/dog-and-duck.utils.process.html
Normal file
3
docs/codox/dog-and-duck.utils.process.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
docs/images/Dog_and_Duck_tavern.jpg
Normal file
BIN
docs/images/Dog_and_Duck_tavern.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
|
@ -1,14 +1,25 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
<head>
|
||||||
<title>The Old Dog and Duck: Documentation</title>
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
<link rel="stylesheet" type="text/css" href="codox/css/default.css" />
|
<title>The Old Dog and Duck: Documentation</title>
|
||||||
</head>
|
<link rel="stylesheet" type="text/css" href="codox/css/default.css" />
|
||||||
<body>
|
</head>
|
||||||
<h1>The Old Dog and Duck: Documentation</h1>
|
|
||||||
<ul>
|
<body>
|
||||||
<li><a href="codox/index.html">Primary documentaion</a></li>
|
<h1>The Old Dog and Duck: Documentation</h1>
|
||||||
<li><a href="cloverage/index.html">Test coverage</a></li>
|
<img src="images/Dog_and_Duck_tavern.jpg" alt="Victorian painting by Thomas H. Shepherd, based on a 1646 drawing">
|
||||||
</ul>
|
<p>'The Old Dog and Duck' is a fairly common pub name;
|
||||||
</body>
|
<a href="https://en.wikipedia.org/wiki/Dog_and_Duck,_St_George%27s_Fields">
|
||||||
</html>
|
the instance in the picture</a>
|
||||||
|
stood in St George's Fields, London from the seventeenth century
|
||||||
|
until 1812, when the site was cleared to make way for the new Bethlehem
|
||||||
|
Hospital.
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="codox/index.html">Primary documentation</a></li>
|
||||||
|
<li><a href="cloverage/index.html">Test coverage</a></li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -6,8 +6,7 @@
|
||||||
:doc/format :markdown}
|
:doc/format :markdown}
|
||||||
:output-path "docs/codox"
|
:output-path "docs/codox"
|
||||||
:source-uri "https://github.com/simon-brooke/dog-and-duck/blob/master/{filepath}#L{line}"}
|
:source-uri "https://github.com/simon-brooke/dog-and-duck/blob/master/{filepath}#L{line}"}
|
||||||
|
:description "A playground for hacking ActivityPub stuff."
|
||||||
:description "A Clojure library designed to implement the ActivityPub protocol."
|
|
||||||
:dependencies [[org.clojure/clojure "1.11.1"]
|
:dependencies [[org.clojure/clojure "1.11.1"]
|
||||||
[org.clojure/data.json "2.4.0"]
|
[org.clojure/data.json "2.4.0"]
|
||||||
[org.clojure/math.numeric-tower "0.0.5"]
|
[org.clojure/math.numeric-tower "0.0.5"]
|
||||||
|
|
14
resources/test_documents/announce.json
Normal file
14
resources/test_documents/announce.json
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"id": "https://mastodon.scot/users/simon_brooke/statuses/109545810804143431/activity",
|
||||||
|
"type": "Announce",
|
||||||
|
"actor": "https://mastodon.scot/users/simon_brooke",
|
||||||
|
"published": "2022-12-20T11:40:19Z",
|
||||||
|
"to": [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
],
|
||||||
|
"cc": [
|
||||||
|
"https://mastodon.social/users/borkdude",
|
||||||
|
"https://mastodon.scot/users/simon_brooke/followers"
|
||||||
|
],
|
||||||
|
"object": "https://mastodon.social/users/borkdude/statuses/109545794618575668"
|
||||||
|
}
|
63
resources/test_documents/create.json
Normal file
63
resources/test_documents/create.json
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
{
|
||||||
|
"id": "https://mastodon.scot/users/simon_brooke/statuses/109545806233872328/activity",
|
||||||
|
"type": "Create",
|
||||||
|
"actor": "https://mastodon.scot/users/simon_brooke",
|
||||||
|
"published": "2022-12-20T11:39:10Z",
|
||||||
|
"to": [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
],
|
||||||
|
"cc": [
|
||||||
|
"https://mastodon.scot/users/simon_brooke/followers"
|
||||||
|
],
|
||||||
|
"object": {
|
||||||
|
"inReplyTo": null,
|
||||||
|
"content": "<p>I'm still looking for a repository of <a href=\"https://mastodon.scot/tags/ActivityPub\" class=\"mention hashtag\" rel=\"tag\">#<span>ActivityPub</span></a> sample documents to run tests against. There's one of <a href=\"https://mastodon.scot/tags/ActivityStreams\" class=\"mention hashtag\" rel=\"tag\">#<span>ActivityStreams</span></a> documents here</p><p><a href=\"https://github.com/w3c-social/activitystreams-test-documents\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">github.com/w3c-social/activity</span><span class=\"invisible\">streams-test-documents</span></a></p><p>but they don't conform to the ActivityPub specification. Please, has anyone got pointers?</p><p>Captures of actual live interchanges between ActivityPub servers would be especially useful.</p><p><a href=\"https://mastodon.scot/tags/ActivityPubInClojure\" class=\"mention hashtag\" rel=\"tag\">#<span>ActivityPubInClojure</span></a></p>",
|
||||||
|
"sensitive": false,
|
||||||
|
"cc": [
|
||||||
|
"https://mastodon.scot/users/simon_brooke/followers"
|
||||||
|
],
|
||||||
|
"type": "Note",
|
||||||
|
"attributedTo": "https://mastodon.scot/users/simon_brooke",
|
||||||
|
"summary": null,
|
||||||
|
"replies": {
|
||||||
|
"id": "https://mastodon.scot/users/simon_brooke/statuses/109545806233872328/replies",
|
||||||
|
"type": "Collection",
|
||||||
|
"first": {
|
||||||
|
"type": "CollectionPage",
|
||||||
|
"next": "https://mastodon.scot/users/simon_brooke/statuses/109545806233872328/replies?only_other_accounts=true&page=true",
|
||||||
|
"partOf": "https://mastodon.scot/users/simon_brooke/statuses/109545806233872328/replies",
|
||||||
|
"items": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": "https://mastodon.scot/users/simon_brooke/statuses/109545806233872328",
|
||||||
|
"contentMap": {
|
||||||
|
"en": "<p>I'm still looking for a repository of <a href=\"https://mastodon.scot/tags/ActivityPub\" class=\"mention hashtag\" rel=\"tag\">#<span>ActivityPub</span></a> sample documents to run tests against. There's one of <a href=\"https://mastodon.scot/tags/ActivityStreams\" class=\"mention hashtag\" rel=\"tag\">#<span>ActivityStreams</span></a> documents here</p><p><a href=\"https://github.com/w3c-social/activitystreams-test-documents\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">github.com/w3c-social/activity</span><span class=\"invisible\">streams-test-documents</span></a></p><p>but they don't conform to the ActivityPub specification. Please, has anyone got pointers?</p><p>Captures of actual live interchanges between ActivityPub servers would be especially useful.</p><p><a href=\"https://mastodon.scot/tags/ActivityPubInClojure\" class=\"mention hashtag\" rel=\"tag\">#<span>ActivityPubInClojure</span></a></p>"
|
||||||
|
},
|
||||||
|
"conversation": "tag:mastodon.scot,2022-12-20:objectId=39176769:objectType=Conversation",
|
||||||
|
"url": "https://mastodon.scot/@simon_brooke/109545806233872328",
|
||||||
|
"inReplyToAtomUri": null,
|
||||||
|
"tag": [
|
||||||
|
{
|
||||||
|
"type": "Hashtag",
|
||||||
|
"href": "https://mastodon.scot/tags/activitypubinclojure",
|
||||||
|
"name": "#activitypubinclojure"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Hashtag",
|
||||||
|
"href": "https://mastodon.scot/tags/activitystreams",
|
||||||
|
"name": "#activitystreams"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Hashtag",
|
||||||
|
"href": "https://mastodon.scot/tags/activitypub",
|
||||||
|
"name": "#activitypub"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"atomUri": "https://mastodon.scot/users/simon_brooke/statuses/109545806233872328",
|
||||||
|
"published": "2022-12-20T11:39:10Z",
|
||||||
|
"attachment": [],
|
||||||
|
"to": [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
8
resources/test_documents/outbox.json
Normal file
8
resources/test_documents/outbox.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
"id": "https://mastodon.scot/users/simon_brooke/outbox",
|
||||||
|
"type": "OrderedCollection",
|
||||||
|
"totalItems": 2881,
|
||||||
|
"first": "https://mastodon.scot/users/simon_brooke/outbox?page=true",
|
||||||
|
"last": "https://mastodon.scot/users/simon_brooke/outbox?min_id=0\u0026page=true"
|
||||||
|
}
|
1
resources/test_documents/outbox_page.json
Normal file
1
resources/test_documents/outbox_page.json
Normal file
File diff suppressed because one or more lines are too long
143
src/dog_and_duck/quack/picky.clj
Normal file
143
src/dog_and_duck/quack/picky.clj
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
(ns dog-and-duck.quack.picky "Fault-finder for ActivityPub documents.
|
||||||
|
|
||||||
|
Generally, each `-faults` function will return:
|
||||||
|
1. `nil` if no faults were found;
|
||||||
|
2. a sequence of fault objects if faults were found.
|
||||||
|
|
||||||
|
Each fault object shall have the properties:
|
||||||
|
1. `:@context` whose value shall be the URL of a
|
||||||
|
document specifying this vocabulary;
|
||||||
|
2. `:type` whose value shall be `Fault`;
|
||||||
|
3. `:severity` whose value shall be one of
|
||||||
|
`minor`, `should`, `must` or `critical`;
|
||||||
|
4. `:fault` whose value shall be a unique token
|
||||||
|
representing the particular fault type;
|
||||||
|
5. `:narrative` whose value shall be a natural
|
||||||
|
language description of the fault type.
|
||||||
|
|
||||||
|
Note that the reason for the `:fault` property is
|
||||||
|
to be able to have a well known place, linked to
|
||||||
|
from the @context URL, which allows narratives
|
||||||
|
for each fault type to be served in as many
|
||||||
|
natural languages as possible.
|
||||||
|
|
||||||
|
The idea further is that it should ultimately be
|
||||||
|
possible to serialise a fault report as a
|
||||||
|
document which in its own right conforms to the
|
||||||
|
ActivityStreams spec."
|
||||||
|
(:require [dog-and-duck.utils.process :refer [pid]]))
|
||||||
|
|
||||||
|
(def ^:const severity
|
||||||
|
"Severity of faults found, as follows:
|
||||||
|
|
||||||
|
1. `:minor` things which I consider to be faults, but which
|
||||||
|
don't actually breach the spec;
|
||||||
|
2. `:should` instances where the spec says something SHOULD
|
||||||
|
be done, which isn't;
|
||||||
|
3. `:must` instances where the spec says something MUST
|
||||||
|
be done, which isn't;
|
||||||
|
4. `:critical` instances where I believe the fault means that
|
||||||
|
the object cannot be meaningfully processed."
|
||||||
|
#{:minor :should :must :critical})
|
||||||
|
|
||||||
|
(def ^:const severity-filters
|
||||||
|
"Hack for implementing a severity hierarchy"
|
||||||
|
{:all #{}
|
||||||
|
:minor #{:minor}
|
||||||
|
:should #{:minor :should}
|
||||||
|
:must #{:minor :should :must}
|
||||||
|
:critical severity})
|
||||||
|
|
||||||
|
(defn filter-severity
|
||||||
|
"Return a list of reports taken from these `reports` where the severity
|
||||||
|
of the report is greater than this `severity`."
|
||||||
|
[reports severity]
|
||||||
|
(assert
|
||||||
|
(and
|
||||||
|
(coll? reports)
|
||||||
|
(every? map? reports)
|
||||||
|
(every? :severity reports)))
|
||||||
|
(remove
|
||||||
|
#((severity-filters severity) (:severity %))
|
||||||
|
reports))
|
||||||
|
|
||||||
|
(def ^:const activitystreams-context-uri
|
||||||
|
"The URI of the context of an ActivityStreams object is expected to be this
|
||||||
|
literal string."
|
||||||
|
"https://www.w3.org/ns/activitystreams")
|
||||||
|
|
||||||
|
(def ^:const validation-fault-context-uri
|
||||||
|
"The URI of the context of a validation fault report object shall be this
|
||||||
|
literal string."
|
||||||
|
"https://simon-brooke.github.io/dog-and-duck/codox/Validation_Faults.html")
|
||||||
|
|
||||||
|
(defn context?
|
||||||
|
"Returns `true` iff `x` quacks like an ActivityStreams context, else false.
|
||||||
|
|
||||||
|
A context is either
|
||||||
|
1. the URI (actually an IRI) `activitystreams-context-uri`, or
|
||||||
|
2. a collection comprising that URI and a map."
|
||||||
|
[x]
|
||||||
|
(cond
|
||||||
|
(nil? x) false
|
||||||
|
(string? x) (and (= x activitystreams-context-uri) true)
|
||||||
|
(coll? x) (and (context? (first (remove map? x)))
|
||||||
|
(= (count x) 2)
|
||||||
|
true)
|
||||||
|
:else false))
|
||||||
|
|
||||||
|
(defmacro has-context?
|
||||||
|
"True if `x` is an ActivityStreams object with a valid context, else `false`."
|
||||||
|
[x]
|
||||||
|
`(context? ((keyword "@context") ~x)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(defn make-fault-object
|
||||||
|
"Return a fault object with these `severity`, `fault` and `narrative` values.
|
||||||
|
|
||||||
|
An ActivityPub object MUST have a globally unique ID. Whether this is
|
||||||
|
meaningful depends on whether we persist fault report objects and serve
|
||||||
|
them, which at present I have no plans to do."
|
||||||
|
[severity fault narrative]
|
||||||
|
(assoc {}
|
||||||
|
(keyword "@context") validation-fault-context-uri
|
||||||
|
:id (str "https://"
|
||||||
|
(.. java.net.InetAddress getLocalHost getHostName)
|
||||||
|
"/fault/"
|
||||||
|
pid
|
||||||
|
":"
|
||||||
|
(inst-ms (java.util.Date.)))
|
||||||
|
:type "Fault"
|
||||||
|
:severity severity
|
||||||
|
:fault fault
|
||||||
|
:narrative narrative))
|
||||||
|
|
||||||
|
(defn object-faults
|
||||||
|
[x]
|
||||||
|
(remove
|
||||||
|
empty?
|
||||||
|
(list
|
||||||
|
(when-not
|
||||||
|
(has-context? x)
|
||||||
|
(make-fault-object
|
||||||
|
:should
|
||||||
|
:no-context
|
||||||
|
"Section 3 of the ActivityPub specification states
|
||||||
|
`Implementers SHOULD include the ActivityPub context in
|
||||||
|
their object definitions`.")
|
||||||
|
(when-not (:type x)
|
||||||
|
(make-fault-object
|
||||||
|
:minor
|
||||||
|
:no-type
|
||||||
|
"The ActivityPub specification states that the `type` field is
|
||||||
|
optional, but it is hard to process objects with no known type."))
|
||||||
|
(when-not (contains? x :id)
|
||||||
|
(make-fault-object
|
||||||
|
:minor
|
||||||
|
:no-id-transient
|
||||||
|
"The ActivityPub specification allows objects without `id` fields
|
||||||
|
only if they are intentionally transient; even so it is preferred
|
||||||
|
that the object should have an explicit null id."
|
||||||
|
))
|
||||||
|
))))
|
|
@ -1,6 +1,21 @@
|
||||||
(ns dog-and-duck.quack.quack
|
(ns dog-and-duck.quack.quack
|
||||||
"Validator for ActivityPub objects: if it walks like a duck, and it quacks like a duck..."
|
"Validator for ActivityPub objects: if it walks like a duck, and it quacks
|
||||||
|
like a duck...
|
||||||
|
|
||||||
|
**NOTE THAT the ActivityPub spec
|
||||||
|
[says](https://www.w3.org/TR/activitypub/#obj)
|
||||||
|
|
||||||
|
> Servers SHOULD validate the content they receive to avoid content
|
||||||
|
> spoofing attacks
|
||||||
|
|
||||||
|
but in practice ActivityPub content collected in the wild bears only
|
||||||
|
a hazy relationship to the spec, so this is difficult. I suspect that
|
||||||
|
I may have to implement a `*strict*` dynamic variable, so that users can
|
||||||
|
toggle some checks off."
|
||||||
|
|
||||||
;;(:require [clojure.spec.alpha as s])
|
;;(:require [clojure.spec.alpha as s])
|
||||||
|
(:require [dog-and-duck.quack.picky :refer [filter-severity has-context?
|
||||||
|
object-faults]])
|
||||||
(:import [java.net URI URISyntaxException]))
|
(:import [java.net URI URISyntaxException]))
|
||||||
|
|
||||||
;;; Copyright (C) Simon Brooke, 2022
|
;;; Copyright (C) Simon Brooke, 2022
|
||||||
|
@ -30,9 +45,18 @@
|
||||||
But we are *just not having that*, because otherwise we're flying blind.
|
But we are *just not having that*, because otherwise we're flying blind.
|
||||||
We *shall* reject objects lacking at least `:type`. Missing `:id` keys are
|
We *shall* reject objects lacking at least `:type`. Missing `:id` keys are
|
||||||
tolerable because they represent transient objects, which we expect to
|
tolerable because they represent transient objects, which we expect to
|
||||||
handle."
|
handle.
|
||||||
[x]
|
|
||||||
|
**NOTE THAT** The ActivityPub spec [says](https://www.w3.org/TR/activitypub/#obj)
|
||||||
|
|
||||||
|
> Implementers SHOULD include the ActivityPub context in their object
|
||||||
|
> definitions
|
||||||
|
|
||||||
|
but in samples found in the wild they typically don't."
|
||||||
|
([x]
|
||||||
(and (map? x) (:type x) true))
|
(and (map? x) (:type x) true))
|
||||||
|
([x severity]
|
||||||
|
(empty? (filter-severity (object-faults x) severity))))
|
||||||
|
|
||||||
(defn persistent-object?
|
(defn persistent-object?
|
||||||
"`true` iff `x` is a persistent object.
|
"`true` iff `x` is a persistent object.
|
||||||
|
@ -44,7 +68,7 @@
|
||||||
(and (object? x) (uri? (URI. (:id x))))
|
(and (object? x) (uri? (URI. (:id x))))
|
||||||
(catch URISyntaxException _ false)))
|
(catch URISyntaxException _ false)))
|
||||||
|
|
||||||
(persistent-object? {:type "test" :id "https://mastodon.scot/@barfilfarm"})
|
;; (persistent-object? {:type "test" :id "https://mastodon.scot/@barfilfarm"})
|
||||||
|
|
||||||
(def ^:const actor-types
|
(def ^:const actor-types
|
||||||
"The set of types we will accept as actors.
|
"The set of types we will accept as actors.
|
||||||
|
@ -57,10 +81,12 @@
|
||||||
"Person"
|
"Person"
|
||||||
"Service"})
|
"Service"})
|
||||||
|
|
||||||
(defn actor-type?
|
(defmacro actor-type?
|
||||||
;; TODO: better as a macro
|
"Return `true` iff the `x` is a recognised actor type, else `false`."
|
||||||
[x]
|
[^String x]
|
||||||
(if (actor-types x) true false))
|
`(if (actor-types ~x) true false))
|
||||||
|
|
||||||
|
;; (actor-type? "Group")
|
||||||
|
|
||||||
(def ^:const verb-types
|
(def ^:const verb-types
|
||||||
"The set of types we will accept as verbs.
|
"The set of types we will accept as verbs.
|
||||||
|
@ -72,47 +98,14 @@
|
||||||
"Offer" "Question" "Reject" "Read" "Remove" "TentativeAccept"
|
"Offer" "Question" "Reject" "Read" "Remove" "TentativeAccept"
|
||||||
"TentativeReject" "Travel" "Undo" "Update" "View"})
|
"TentativeReject" "Travel" "Undo" "Update" "View"})
|
||||||
|
|
||||||
(defn verb-type?
|
(defmacro verb-type?
|
||||||
;; TODO: better as a macro
|
;; TODO: better as a macro
|
||||||
[x]
|
[^String x]
|
||||||
(if (verb-types x) true false))
|
`(if (verb-types ~x) true false))
|
||||||
|
|
||||||
(def ^:const activitystreams-context-uri
|
|
||||||
"The URI of the context of an ActivityStreams object is expected to be this
|
|
||||||
literal string."
|
|
||||||
"https://www.w3.org/ns/activitystreams")
|
|
||||||
|
|
||||||
(defn context?
|
|
||||||
"Returns `true` iff `x` quacks like an ActivityStreams context, else false.
|
|
||||||
|
|
||||||
A context is either
|
|
||||||
1. the URI (actually an IRI) `activitystreams-context-uri`, or
|
|
||||||
2. a collection comprising that URI and a map."
|
|
||||||
[x]
|
|
||||||
(cond
|
|
||||||
(nil? x) false
|
|
||||||
(string? x) (and (= x activitystreams-context-uri) true)
|
|
||||||
(coll? x) (and (context? (first (remove map? x)))
|
|
||||||
(= (count x) 2)
|
|
||||||
true)
|
|
||||||
:else false))
|
|
||||||
|
|
||||||
(defmacro has-context? [x]
|
|
||||||
`(context? ((keyword "@context") ~x)))
|
|
||||||
|
|
||||||
(defn actor?
|
(defn actor?
|
||||||
"Returns `true` if `x` quacks like an actor, else false."
|
"Returns `true` if `x` quacks like an actor, else false.
|
||||||
[x]
|
|
||||||
(and
|
|
||||||
(object? x)
|
|
||||||
(has-context? x)
|
|
||||||
(uri? (URI. (:inbox x)))
|
|
||||||
(uri? (URI. (:outbox x)))
|
|
||||||
(actor-type? (:type x))
|
|
||||||
true))
|
|
||||||
|
|
||||||
(defn activity?
|
|
||||||
"`true` iff `x` quacks like an activity, else false.
|
|
||||||
|
|
||||||
**NOTE THAT** [Section 4.1 of the spec]
|
**NOTE THAT** [Section 4.1 of the spec]
|
||||||
(https://www.w3.org/TR/activitypub/#actor-objects) says explicitly that
|
(https://www.w3.org/TR/activitypub/#actor-objects) says explicitly that
|
||||||
|
@ -126,11 +119,35 @@
|
||||||
|
|
||||||
However, none of the provided examples in the [activitystreams-test-documents repository]() does in fact have these properties"
|
However, none of the provided examples in the [activitystreams-test-documents repository]() does in fact have these properties"
|
||||||
[x]
|
[x]
|
||||||
|
(and
|
||||||
|
(object? x)
|
||||||
|
(has-context? x)
|
||||||
|
(uri? (URI. (:inbox x)))
|
||||||
|
(uri? (URI. (:outbox x)))
|
||||||
|
(actor-type? (:type x))
|
||||||
|
true))
|
||||||
|
|
||||||
|
(defn actor-or-uri?
|
||||||
|
"`true` if `x` is either a URI or an actor.
|
||||||
|
|
||||||
|
**TODO**: I need to decide about whether to reify referenced objects
|
||||||
|
before validation or after. After reification, every reference to an actor
|
||||||
|
*must be* to an actor object, but before, may only be to a URI pointing to
|
||||||
|
one."
|
||||||
|
[x]
|
||||||
|
(and
|
||||||
|
(cond (string? x) (uri? (URI. x))
|
||||||
|
:else (actor? x))
|
||||||
|
true))
|
||||||
|
|
||||||
|
(defn activity?
|
||||||
|
"`true` iff `x` quacks like an activity, else false."
|
||||||
|
[x]
|
||||||
(try
|
(try
|
||||||
(and (object? x)
|
(and (object? x)
|
||||||
(has-context? x)
|
(has-context? x)
|
||||||
(string? (:summary x))
|
(string? (:summary x))
|
||||||
(actor? (:actor x))
|
(actor-or-uri? (:actor x))
|
||||||
(verb-type? (:type x))
|
(verb-type? (:type x))
|
||||||
(or (object? (:object x)) (uri? (URI. (:object x))))
|
(or (object? (:object x)) (uri? (URI. (:object x))))
|
||||||
true)
|
true)
|
||||||
|
@ -156,35 +173,46 @@
|
||||||
true))
|
true))
|
||||||
|
|
||||||
(defn collection?
|
(defn collection?
|
||||||
"`true` iff `x` quacks like a collection of type `type`, else `false`.
|
"`true` iff `x` quacks like a collection of type `object-type`, else `false`.
|
||||||
|
|
||||||
With one argument, will recognise plain collections and ordered collections,
|
With one argument, will recognise plain collections and ordered collections,
|
||||||
but (currently) not collection pages."
|
but (currently) not collection pages."
|
||||||
([x type]
|
([x ^String object-type]
|
||||||
(let [items (or (:items x) (:orderedItems x))]
|
(let [items (or (:items x) (:orderedItems x))]
|
||||||
(and
|
(and
|
||||||
(cond
|
(cond
|
||||||
(:items x) (nil? (:orderedItems x))
|
(:items x) (nil? (:orderedItems x))
|
||||||
(:orderedItems x) (nil? (:items x))) ;; can't have both properties
|
(:orderedItems x) (nil? (:items x)) ;; can't have both properties
|
||||||
|
(integer? (:totalItems x)) true ;; can have neither, provided it has totalItems.
|
||||||
|
:else false)
|
||||||
(object? x)
|
(object? x)
|
||||||
(= (:type x) type)
|
(= (:type x) object-type)
|
||||||
(coll? items)
|
(if items
|
||||||
(every? object? items)
|
(and (coll? items)
|
||||||
(integer? (:totalItems x))
|
(every? object? items) ;; if there are items, they must form a
|
||||||
true)))
|
;; collection of objects.
|
||||||
|
true)
|
||||||
|
true) ;; but it's OK if there aren't.
|
||||||
|
true)
|
||||||
|
;; test for totalItems not done here, because collection pages don't
|
||||||
|
;; have it.
|
||||||
|
))
|
||||||
([x]
|
([x]
|
||||||
(or (collection? x "Collection")
|
(and
|
||||||
(collection? x "OrderedCollection"))))
|
(or (collection? x "Collection")
|
||||||
|
(collection? x "OrderedCollection"))
|
||||||
|
(integer? (:totalItems x))
|
||||||
|
true)))
|
||||||
|
|
||||||
(defn unordered-collection?
|
(defn unordered-collection?
|
||||||
"`true` iff `x` quacks like an unordered collection, else `false`."
|
"`true` iff `x` quacks like an unordered collection, else `false`."
|
||||||
[x]
|
[x]
|
||||||
(collection? x "Collection"))
|
(and (collection? x "Collection") (integer? (:totalItems x)) true))
|
||||||
|
|
||||||
(defn ordered-collection?
|
(defn ordered-collection?
|
||||||
"`true` iff `x` quacks like an ordered collection, else `false`."
|
"`true` iff `x` quacks like an ordered collection, else `false`."
|
||||||
[x]
|
[x]
|
||||||
(collection? x "OrderedCollection"))
|
(and (collection? x "OrderedCollection") (integer? (:totalItems x)) true))
|
||||||
|
|
||||||
(defn collection-page?
|
(defn collection-page?
|
||||||
"`true` iff `x` quacks like a page in a paged collection, else `false`."
|
"`true` iff `x` quacks like a page in a paged collection, else `false`."
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
(apply webfinger/fetch-user-id (map handle [:domain :username]))))))
|
(apply webfinger/fetch-user-id (map handle [:domain :username]))))))
|
||||||
|
|
||||||
;;; examine what you got back!
|
;;; examine what you got back!
|
||||||
(:outbox account)
|
(:inbox account)
|
||||||
|
|
||||||
|
|
||||||
(def rsa (pgp-gen/rsa-keypair-generator 2048))
|
(def rsa (pgp-gen/rsa-keypair-generator 2048))
|
||||||
|
|
23
src/dog_and_duck/utils/process.clj
Normal file
23
src/dog_and_duck/utils/process.clj
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
(ns dog-and-duck.utils.process
|
||||||
|
(:require [clojure.string :refer [split]]))
|
||||||
|
|
||||||
|
(def pid
|
||||||
|
"OK, this is hacky as fuck, but I hope it works. The problem is that the
|
||||||
|
way to get the process id has changed several times during the history
|
||||||
|
of Java development, and the code for one version of Java won't even compile
|
||||||
|
in a different version."
|
||||||
|
(let [java-version (read-string (apply str (take 2
|
||||||
|
(split
|
||||||
|
(System/getProperty "java.version")
|
||||||
|
#"[_\.]"))))
|
||||||
|
cmd (case java-version
|
||||||
|
18 "(let [[_ pid hostname]
|
||||||
|
(re-find
|
||||||
|
#\"^(\\d+)@(.*)\"
|
||||||
|
(.getName
|
||||||
|
(java.lang.management.ManagementFactory/getRuntimeMXBean)))]
|
||||||
|
pid)"
|
||||||
|
(19 110) "(.pid (java.lang.ProcessHandle/current))"
|
||||||
|
111 "(.getPid (java.lang.management.ManagementFactory/getRuntimeMXBean))"
|
||||||
|
":default")]
|
||||||
|
(eval (read-string cmd))))
|
|
@ -1,8 +1,10 @@
|
||||||
(ns dog-and-duck.quack.quack-test
|
(ns dog-and-duck.quack.quack-test
|
||||||
(:require [clojure.test :refer [deftest is testing]]
|
(:require [clojure.test :refer [deftest is testing]]
|
||||||
[dog-and-duck.quack.quack :refer [activitystreams-context-uri
|
[dog-and-duck.quack.picky :refer [activitystreams-context-uri
|
||||||
actor? actor-type? context?
|
context?]]
|
||||||
object? persistent-object?
|
[dog-and-duck.quack.quack :refer [actor? actor-type?
|
||||||
|
object? ordered-collection-page?
|
||||||
|
persistent-object?
|
||||||
verb-type?]]
|
verb-type?]]
|
||||||
[dog-and-duck.scratch.parser :refer [clean]]))
|
[dog-and-duck.scratch.parser :refer [clean]]))
|
||||||
|
|
||||||
|
@ -126,4 +128,14 @@
|
||||||
(let [expected true
|
(let [expected true
|
||||||
actual (actor? (-> "resources/activitystreams-test-documents/simple0020.json" slurp clean first :actor))]
|
actual (actor? (-> "resources/activitystreams-test-documents/simple0020.json" slurp clean first :actor))]
|
||||||
(is (= actual expected) "A Person is an actor"))
|
(is (= actual expected) "A Person is an actor"))
|
||||||
|
))
|
||||||
|
|
||||||
|
(deftest ordered-collection-page-test
|
||||||
|
(testing "identification of ordered collection pages."
|
||||||
|
(let [expected false
|
||||||
|
actual (ordered-collection-page? (-> "resources/activitystreams-test-documents/simple0020.json" slurp clean first))]
|
||||||
|
(is (= actual expected) "A Note is not an ordered collection page."))
|
||||||
|
(let [expected true
|
||||||
|
actual (ordered-collection-page? (-> "resources/test_documents/outbox_page.json" slurp clean first))]
|
||||||
|
(is (= actual expected) "A page from an outbox is an ordered collection page."))
|
||||||
))
|
))
|
Loading…
Reference in a new issue