Rework the activitystreams implementation and vocabularies

Julien LepillerFri May 01 04:02:41+0200 2020

1dce4de

Rework the activitystreams implementation and vocabularies

Makefile.am

44
godir=$(libdir)/guile/$(GUILE_EFFECTIVE_VERSION)/site-ccache
55
66
SOURCES= \
7-
  activitystreams/activitystreams.scm \
7+
  activitypub/vocabulary.scm \
88
  activitystreams/ontology.scm \
9+
  activitystreams/predicates.scm \
10+
  activitystreams/vocabulary.scm \
911
  http-signature/asn1.scm \
10-
  http-signature/ontology.scm \
12+
  http-signature/vocabulary.scm \
1113
  webfinger/webfinger.scm
1214
1315
info_TEXINFOS= doc/guile-fediverse.texi

activitypub/vocabulary.scm unknown status 1

1+
;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu>
2+
;;;; 
3+
;;;; This library is free software; you can redistribute it and/or
4+
;;;; modify it under the terms of the GNU Lesser General Public
5+
;;;; License as published by the Free Software Foundation; either
6+
;;;; version 3 of the License, or (at your option) any later version.
7+
;;;; 
8+
;;;; This library is distributed in the hope that it will be useful,
9+
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11+
;;;; Lesser General Public License for more details.
12+
;;;; 
13+
;;;; You should have received a copy of the GNU Lesser General Public
14+
;;;; License along with this library; if not, write to the Free Software
15+
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16+
;;;; 
17+
;;;;
18+
;;;;
19+
;;;; Note that most of this file is a direct translation of the activitystreams
20+
;;;; vocabulary specification (esp. comments in type and property) which
21+
;;;; is under these terms:
22+
;;;;
23+
;;;;    Copyright ?? 2017 Activity Streams Working Group, IBM & W3C?? (MIT,
24+
;;;;    ERCIM, Keio, Beihang). W3C liability, trademark and permissive
25+
;;;;    document license rules apply.
26+
;;;;
27+
;;;; You should have received a copy of the Permissive Document License along
28+
;;;; with this library; if not, that document license is accessible online at:
29+
;;;; https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
30+
;;;;
31+
;;;; The origin document used to develop this can be found at:
32+
;;;; https://www.w3.org/TR/activitystreams-vocabulary
33+
34+
(define-module (activitypub vocabulary)
35+
  #:use-module ((activitystreams vocabulary) #:prefix as:)
36+
  #:use-module (activitystreams ontology)
37+
  #:use-module (activitystreams predicates)
38+
  #:use-module (ice-9 match)
39+
  #:use-module (jsonld json)
40+
  #:use-module (web uri)
41+
  #:export (activitypub-ontology))
42+
43+
(define-public source
44+
  (build-as-property
45+
    "source" as:Object json-object?
46+
    #:comment
47+
    "The source property is intended to convey some sort of source from which
48+
the content markup was derived, as a form of provenance, or to support future
49+
editing by clients.  In general, clients do the conversion from source to
50+
content, not the other way around."))
51+
52+
(define-public content
53+
  (build-as-property
54+
    "content" source string-or-lang-string?))
55+
56+
(define-public mediaType
57+
  (build-as-property
58+
    "mediaType" source mime-type?))
59+
60+
(define-public inbox
61+
  (build-as-property
62+
    "inbox" as:Object as:OrderedCollection
63+
    #:comment "The inbox stream contains all activities received by the actor.
64+
The server should filter content according to the requester's permission.  In
65+
general, the owner of an inbox is likely to be able to access all of their
66+
inbox contents.  Depending on access control, some other content may be
67+
public, whereas other content may require authentication for non-owner users,
68+
if they can access the inbox at all."))
69+
70+
(define-public outbox
71+
  (build-as-property
72+
    "outbox" as:Object as:OrderedCollection
73+
    #:comment
74+
    "The outbox stream contains activities the user has published, subject to
75+
the ability of the requestor to retrieve the activity (that is, the contents of
76+
the outbox are filtered by the permissions of the person reading it).  If a
77+
user submits a request without Authorization the server should respond with all
78+
of the Public posts.  This could potentially be all relevant objects published
79+
by the user, though the number of available items is left to the discretion of
80+
those implementing and deploying the server."))
81+
82+
(define-public following
83+
  (build-as-property
84+
    "following" as:Object as:Collection
85+
    #:comment
86+
    "This is a list of everybody that the actor has followed, added as a side
87+
effect.  The following collection MUST be either an OrderedCollection or a
88+
Collection and MAY be filtered on privileges of an authenticated user or as
89+
appropriate when no authentication is given."))
90+
91+
(define-public followers
92+
  (build-as-property
93+
    "followers" as:Object as:Collection
94+
    #:comment
95+
    "This is a list of everyone who has sent a Follow activity for the actor,
96+
added as a side effect.  This is where one would find a list of all the actors
97+
that are following the actor.  The followers collection MUST be either an
98+
OrderedCollection or a Collection and MAY be filtered on privileges of an
99+
authenticated user or as appropriate when no authentication is given."))
100+
101+
(define-public liked
102+
  (build-as-property
103+
    "liked" as:Object as:Collection
104+
    #:comment
105+
    "This is a list of every object from all of the actor's Like activities,
106+
added as a side effect.  The liked collection MUST be either an OrderedCollection
107+
or a Collection and MAY be filtered on privileges of an authenticated user or
108+
as appropriate when no authentication is given."))
109+
110+
(define-public streams
111+
  (build-as-property
112+
    "streams" as:Object as:Collection
113+
    #:comment
114+
    "A list of supplementary Collections which may be of interest."))
115+
116+
(define-public preferredUsername
117+
  (build-as-property
118+
    "preferredUsername" as:Object string?
119+
    #:comment
120+
    "A short username which may be used to refer to the actor, with no
121+
uniqueness guarantees."))
122+
123+
(define-public endpoints
124+
  (build-as-property
125+
    "endpoints" as:Object json-object?
126+
    #:comment
127+
    "A json object which maps additional (typically server/domain-wide)
128+
endpoints which may be useful either for this actor or someone referencing this
129+
actor.  This mapping may be nested inside the actor document as the value or
130+
may be a link to a JSON-LD document with these properties."))
131+
132+
(define-public proxyUrl
133+
  (build-as-property
134+
    "proxyUrl" endpoints uri?
135+
    #:comment
136+
    "Endpoint URI so this actor's clients may access remote ActivityStreams
137+
objects which require authentication to access.  To use this endpoint, the
138+
client posts an x-www-form-urlencoded id parameter with the value being the id
139+
of the requested ActivityStreams object."))
140+
141+
(define-public oauthAuthorizationEndpoint
142+
  (build-as-property
143+
    "oauthAuthorizationEndpoint" endpoints uri?
144+
    #:comment
145+
    "If OAuth 2.0 bearer tokens are being used for authenticating client to
146+
server interactions, this endpoint specifies a URI at which a
147+
browser-authenticated user may obtain a new authorization grant."))
148+
149+
(define-public oauthTokenEndpoint
150+
  (build-as-property
151+
    "oauthTokenEndpoint" endpoints uri?
152+
    #:comment
153+
    "If OAuth 2.0 bearer tokens are being used for authenticating client to
154+
server interactions, this endpoint specifies a URI at which a client may
155+
acquire an access token."))
156+
157+
(define-public provideClientKey
158+
  (build-as-property
159+
    "provideClientKey" endpoints uri?
160+
    #:comment
161+
    "If Linked Data Signatures and HTTP Signatures are being used for
162+
authentication and authorization, this endpoint specifies a URI at which
163+
browser-authenticated users may authorize a client's public key for client to
164+
server interactions."))
165+
166+
(define-public signClientKey
167+
  (build-as-property
168+
    "signClientKey" endpoints uri?
169+
    #:comment
170+
    "If Linked Data Signatures and HTTP Signatures are being used for
171+
authentication and authorization, this endpoint specifies a URI at which a
172+
client key may be signed by the actor's key for a time window to act on behalf
173+
of the actor in interacting with foreign servers."))
174+
175+
(define-public sharedInbox
176+
  (build-as-property
177+
    "sharedInbox" endpoints uri?
178+
    #:comment
179+
    "An optional endpoint used for wide delivery of publicly addressed
180+
activities and activities sent to followers.  sharedInbox endpoints SHOULD also
181+
be publicly readable OrderedCollection objects containing objects addressed to
182+
the Public special collection.  Reading from the sharedInbox endpoint MUST NOT
183+
present objects which are not addressed to the Public endpoint."))
184+
185+
(define activitypub-ontology
186+
  (merge-ontologies activitystreams-ontology
187+
                    (make-ontology
188+
                      '()
189+
                      '()
190+
                      (list source content mediaType inbox outbox following
191+
                            followers liked streams preferredUsername
192+
                            endpoints proxyUrl oauthAuthorizationEndpoint
193+
                            oauthTokenEndpoint provideClientKey signClientKey
194+
                            sharedInbox))))

activitystreams/activitystreams.scm unknown status 2

1-
;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu>
2-
;;;; 
3-
;;;; This library is free software; you can redistribute it and/or
4-
;;;; modify it under the terms of the GNU Lesser General Public
5-
;;;; License as published by the Free Software Foundation; either
6-
;;;; version 3 of the License, or (at your option) any later version.
7-
;;;; 
8-
;;;; This library is distributed in the hope that it will be useful,
9-
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
10-
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11-
;;;; Lesser General Public License for more details.
12-
;;;; 
13-
;;;; You should have received a copy of the GNU Lesser General Public
14-
;;;; License along with this library; if not, write to the Free Software
15-
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16-
;;;; 
17-
18-
(define-module (activitystreams activitystreams)
19-
  #:use-module (ice-9 match)
20-
  #:use-module (srfi srfi-9)
21-
  #:export (as:type
22-
            as:type?
23-
            as:type-label
24-
            as:type-uri
25-
            as:type-comment
26-
            as:type-subclass-of
27-
28-
            as:property
29-
            as:property?
30-
            as:property-label
31-
            as:property-uri
32-
            as:property-range
33-
            as:property-domain
34-
            as:property-functional?
35-
            as:property-subproperty-of
36-
            as:property-comment
37-
38-
            make-as-type
39-
            make-as-property
40-
41-
            make-ontological-parser
42-
            as-ref
43-
            as:type-of-type?
44-
            as:property-of-type?))
45-
46-
(define as:vocab "https://www.w3.org/ns/activitystreams#")
47-
48-
(define-record-type as:type
49-
  (make-as:type label uri comment subclass-of)
50-
  as:type?
51-
  (label       as:type-label)
52-
  (uri         as:type-uri)
53-
  (comment     as:type-comment)
54-
  (subclass-of as:type-subclass-of))
55-
56-
(define* (make-as-type label #:key (uri (string-append as:vocab label))
57-
                       (comment "") (subclass-of '()))
58-
  (make-as:type label uri comment subclass-of))
59-
60-
(define-record-type as:property
61-
  (make-as:property label uri range domain functional? subproperty-of comment)
62-
  as:property?
63-
  (label          as:property-label)
64-
  (uri            as:property-uri)
65-
  (domain         as:property-domain)
66-
  (range          as:property-range)
67-
  (functional?    as:property-functional?)
68-
  (subproperty-of as:property-subproperty-of)
69-
  (comment        as:property-comment))
70-
71-
(define* (make-as-property label domain range
72-
                           #:key (uri (string-append as:vocab label))
73-
                           (functional? #f) (subproperty-of '()) (comment ""))
74-
  (make-as:property label uri range domain functional? subproperty-of comment))
75-
76-
(define (make-ontological-parser ontology)
77-
  "Creates a parser from an ontology: takes json document as input and outputs
78-
the best possible document as an alist (or array of alists) whose keys are an
79-
as:property and value is the associated expanded value.  It also perfoms type
80-
checking to ensure the document is well-parsed.  When the document doesn't respect
81-
the ontology, throws an exception.  Type is in the key @type and its value
82-
is a as:type."
83-
  (define (candidate-type type)
84-
    (filter
85-
      (lambda (o)
86-
        (and
87-
          (as:type? o)
88-
          (equal? (as:type-uri o) type)))
89-
      ontology))
90-
91-
  (define (candidate-property name)
92-
    (filter
93-
      (lambda (p)
94-
        (and
95-
          (as:property? p)
96-
          (equal? (as:property-uri p) name)))
97-
      ontology))
98-
99-
  (define (in-range property value)
100-
    (match (as:property-range property)
101-
      ((? string? type)
102-
       (as:type-of-type? (assoc-ref value "@type") type))
103-
      ((? procedure? proc)
104-
       (proc value))
105-
      (()
106-
       #f)
107-
      ((? list? l)
108-
       (or (in-range (car l) value) (in-range (cdr l) value)))
109-
      (range (throw 'invalid-property-range range))))
110-
111-
  (define (in-domain property type)
112-
    (match (as:property-domain property)
113-
      ((? string? parent)
114-
       (as:type-of-type? type parent))
115-
      ((? procedure? proc)
116-
       (proc type))
117-
      (()
118-
       #f)
119-
      ((? list? l)
120-
       (or (in-domain (car l) type) (in-domain (cdr l) type)))))
121-
122-
  (define (parse json)
123-
    (if (assoc-ref json "@value")
124-
      json
125-
      ;; TODO: there might be more than one @type...
126-
      (let ((type (car (candidate-type (assoc-ref json "@type")))))
127-
        (let loop ((result `(("@type" . ,type))) (json json))
128-
          (match json
129-
            (() result)
130-
            (((k . v) json ...)
131-
             (let ((candidates (candidate-property k)))
132-
               (cond
133-
                 ((equal? k "@type")
134-
                  (loop result json))
135-
                 ((null? candidates)
136-
                  (loop result json))
137-
                 (else
138-
                   (let ((property (car candidates))
139-
                         (value (parse v)))
140-
                     (unless (in-range property value)
141-
                       (throw 'value-type-mismatch property value))
142-
                     (unless (in-domain property type)
143-
                       (throw 'property-not-supported property value))
144-
                     (loop (cons (cons property value) result) json)))))))))))
145-
146-
  parse)
147-
148-
(define (as:property-of-type? property label)
149-
  (or (equal? (as:property-label property) label)
150-
      (let loop ((subproperties (as:property-subproperty-of property)))
151-
        (match subproperties
152-
          (() #f)
153-
          ((property subproperties ...)
154-
           (or (as:property-of-type? property label)
155-
               (loop subproperties)))))))
156-
157-
(define (as:type-of-type? type label)
158-
  (or (equal? (as:type-label type) label)
159-
      (let loop ((subclasses (as:type-subclass-of type)))
160-
        (match subclasses
161-
          (() #f)
162-
          ((type subclasses ...)
163-
           (or (as:type-of-type? type label)
164-
               (loop subclasses)))))))
165-
166-
(define (as-ref document key)
167-
  "Takes a parsed document and returns the value associated with the property.
168-
This takes care of subproperties: if you look for a property that's not in the
169-
document directly, but the document has a subproperty of it, this will be
170-
returned.  The key must be a proper label as defined in the ontology."
171-
  (define (is-candidate kv)
172-
    (match kv
173-
      ((k . v)
174-
       (as:property-of-type? k key))))
175-
  (let ((candidates (filter is-candidate document)))
176-
    (map cdr candidates)))

activitystreams/ontology.scm

1-
;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu>
1+
;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu>
22
;;;; 
33
;;;; This library is free software; you can redistribute it and/or
44
;;;; modify it under the terms of the GNU Lesser General Public

…

1414
;;;; License along with this library; if not, write to the Free Software
1515
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1616
;;;; 
17-
;;;;
18-
;;;;
19-
;;;; Note that most of this file is a direct translation of the activitystreams
20-
;;;; vocabulary specification (esp. comments in as:type and as:property) which
21-
;;;; is under these terms:
22-
;;;;
23-
;;;;    Copyright ?? 2017 Activity Streams Working Group, IBM & W3C?? (MIT,
24-
;;;;    ERCIM, Keio, Beihang). W3C liability, trademark and permissive
25-
;;;;    document license rules apply.
26-
;;;;
27-
;;;; You should have received a copy of the Permissive Document License along
28-
;;;; with this library; if not, that document license is accessible online at:
29-
;;;; https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
30-
;;;;
31-
;;;; The origin document used to develop this can be found at:
32-
;;;; https://www.w3.org/TR/activitystreams-vocabulary
3317
3418
(define-module (activitystreams ontology)
35-
  #:use-module (activitystreams activitystreams)
3619
  #:use-module (ice-9 match)
20+
  #:use-module (srfi srfi-1)
21+
  #:use-module (srfi srfi-9)
22+
  #:use-module (jsonld)
3723
  #:use-module (jsonld json)
38-
  #:use-module (web uri)
39-
  #:export (activitystreams-ontology))
40-
41-
;; Core types
42-
43-
(define as:Object
44-
  (make-as-type
45-
    "Object"
46-
    #:comment
47-
    "Describes an object of any kind.  The Object type serves as the base type
48-
for most of the other kinds of objects defined in the Activity Vocabulary,
49-
including other Core types such as Activity, IntransitiveActivity, Collection
50-
and OrderedCollection."))
51-
52-
(define as:Link
53-
  (make-as-type
54-
    "Link"
55-
    #:comment
56-
    "A Link is an indirect, qualified reference to a resource identified by a
57-
URL.  The fundamental model for links is established by [RFC5988].  Many of the
58-
properties defined by the Activity Vocabulary allow values that are either
59-
instances of Object or Link.  When a Link is used, it establishes a qualified
60-
relation connecting the subject (the containing object) to the resource
61-
identified by the href.  Properties of the Link are properties of the
62-
reference as opposed to properties of the resource."))
63-
64-
(define as:Activity
65-
  (make-as-type
66-
    "Activity"
67-
    #:subclass-of (list as:Object)
68-
    #:comment
69-
    "An Activity is a subtype of Object that describes some form of action that
70-
may happen, is currently happening, or has already happened.  The Activity type
71-
itself serves as an abstract base type for all types of activities.  It is
72-
important to note that the Activity type itself does not carry any specific
73-
semantics about the kind of action being taken."))
74-
75-
(define as:IntransitiveActivity
76-
  (make-as-type
77-
    "IntrasitiveActivity"
78-
    #:subclass-of (list as:Activity)
79-
    #:comment
80-
    "Instances of IntransitiveActivity are a subtype of Activity representing
81-
intransitive actions.  The object property is therefore inappropriate for
82-
these activities."))
83-
84-
(define as:Collection
85-
  (make-as-type
86-
    "Collection"
87-
    #:subclass-of (list as:Object)
88-
    #:comment
89-
    "A Collection is a subtype of Object that represents ordered or unordered
90-
sets of Object or Link instances.  Refer to the Activity Streams 2.0 Core
91-
specification for a complete description of the Collection type."))
92-
93-
(define as:OrderedCollection
94-
  (make-as-type
95-
    "OrderedCollection"
96-
    #:subclass-of (list as:Collection)
97-
    #:comment
98-
    "A subtype of Collection in which members of the logical collection are
99-
assumed to always be strictly ordered."))
100-
101-
(define as:CollectionPage
102-
  (make-as-type
103-
    "CollectionPage"
104-
    #:subclass-of (list as:Collection)
105-
    #:comment
106-
    "Used to represent distinct subsets of items from a Collection.  Refer to
107-
the Activity Streams 2.0 Core for a complete description of the CollectionPage
108-
object."))
109-
110-
(define as:OrderedCollectionPage
111-
  (make-as-type
112-
    "OrderedCollectionPage"
113-
    #:subclass-of (list as:OrderedCollection as:CollectionPage)
114-
    #:comment
115-
    "Used to represent ordered subsets of items from an OrderedCollection.
116-
Refer to the Activity Streams 2.0 Core for a complete description of the
117-
OrderedCollectionPage object."))
118-
119-
(define as-core-types (list as:Object as:Link as:Activity as:IntransitiveActivity
120-
                            as:Collection as:OrderedCollection as:CollectionPage
121-
                            as:OrderedCollectionPage))
122-
123-
;; Extended Types
124-
;; Activity Types
125-
126-
(define as:Accept
127-
  (make-as-type
128-
    "Accept"
129-
    #:subclass-of (list as:Activity)
130-
    #:comment
131-
    "Indicates that the actor accepts the object.  The target property can be
132-
used in certain circumstances to indicate the context into which the object has
133-
been accepted."))
134-
135-
(define as:TentativeAccept
136-
  (make-as-type
137-
    "TentativeAccept"
138-
    #:subclass-of (list as:Accept)
139-
    #:comment
140-
    "A specialization of Accept indicating that the acceptance is tentative."))
141-
142-
(define as:Add
143-
  (make-as-type
144-
    "Add"
145-
    #:subclass-of (list as:Activity)
146-
    #:comment
147-
    "Indicates that the actor has added the object to the target.  If the target
148-
property is not explicitly specified, the target would need to be determined
149-
implicitly by context.  The origin can be used to identify the context from
150-
which the object originated."))
151-
152-
(define as:Arrive
153-
  (make-as-type
154-
    "Arrive"
155-
    #:subclass-of (list as:IntransitiveActivity)
156-
    #:comment
157-
    "An IntransitiveActivity that indicates that the actor has arrived at the
158-
location.  The origin can be used to identify the context from which the actor
159-
originated.  The target typically has no defined meaning."))
160-
161-
(define as:Create
162-
  (make-as-type
163-
    "Create"
164-
    #:subclass-of (list as:Activity)
165-
    #:comment
166-
    "Indicates that the actor has created the object."))
167-
168-
(define as:Delete
169-
  (make-as-type
170-
    "Delete"
171-
    #:subclass-of (list as:Activity)
172-
    #:comment
173-
    "Indicates that the actor has deleted the object.  If specified, the origin
174-
indicates the context from which the object was deleted."))
175-
176-
(define as:Follow
177-
  (make-as-type
178-
    "Follow"
179-
    #:subclass-of (list as:Activity)
180-
    #:comment
181-
    "Indicates that the actor is ``following'' the object.  Following is defined
182-
in the sense typically used within Social systems in which the actor is
183-
interested in any activity performed by or on the object.  The target and
184-
origin typically have no defined meaning."))
185-
186-
(define as:Ignore
187-
  (make-as-type
188-
    "Ignore"
189-
    #:subclass-of (list as:Activity)
190-
    #:comment
191-
    "Indicates that the actor is ignoring the object.  The target and origin
192-
typically have no defined meaning."))
193-
194-
(define as:Join
195-
  (make-as-type
196-
    "Join"
197-
    #:subclass-of (list as:Activity)
198-
    #:comment
199-
    "Indicates that the actor has joined the object.  The target and origin
200-
typically have no defined meaning."))
201-
202-
(define as:Leave
203-
  (make-as-type
204-
    "Leave"
205-
    #:subclass-of (list as:Activity)
206-
    #:comment
207-
    "Indicates that the actor has left the object.  The target and origin
208-
typically have no meaning."))
209-
210-
(define as:Like
211-
  (make-as-type
212-
    "Like"
213-
    #:subclass-of (list as:Activity)
214-
    #:comment
215-
    "Indicates that the actor likes, recommends or endorses the object.  The
216-
target and origin typically have no defined meaning."))
217-
218-
(define as:Offer
219-
  (make-as-type
220-
    "Offer"
221-
    #:subclass-of (list as:Activity)
222-
    #:comment
223-
    "Indicates that the actor is offering the object.  If specified, the target
224-
indicates the entity to which the object is being offered."))
225-
226-
(define as:Invite
227-
  (make-as-type
228-
    "Invite"
229-
    #:subclass-of (list as:Offer)
230-
    #:comment
231-
    "A specialization of Offer in which the actor is extending an invitation
232-
for the object to the target."))
233-
234-
(define as:Reject
235-
  (make-as-type
236-
    "Reject"
237-
    #:subclass-of (list as:Activity)
238-
    #:comment
239-
    "Indicates that the actor is rejecting the object.  The target and origin
240-
typically have no defined meaning."))
241-
242-
(define as:TentativeReject
243-
  (make-as-type
244-
    "TentativeReject"
245-
    #:subclass-of (list as:Reject)
246-
    #:comment
247-
    "A specialization of Reject in which the rejection is considered tentative."))
248-
249-
(define as:Remove
250-
  (make-as-type
251-
    "Remove"
252-
    #:subclass-of (list as:Activity)
253-
    #:comment
254-
    "Indicates that the actor is removing the object.  If specified, the
255-
origin indicates the context from which the object is being removed."))
256-
257-
(define as:Undo
258-
  (make-as-type
259-
    "Undo"
260-
    #:subclass-of (list as:Activity)
261-
    #:comment
262-
    "Indicates that the actor is undoing the object.  In most cases, the object
263-
will be an Activity describing some previously performed action (for instance,
264-
a person may have previously ``liked'' an article but, for whatever reason,
265-
might choose to undo that like at some later point in time).  The target and
266-
origin typically have no defined meaning."))
267-
268-
(define as:Update
269-
  (make-as-type
270-
    "Update"
271-
    #:subclass-of (list as:Activity)
272-
    #:comment
273-
    "Indicates that the actor has updated the object.  Note, however, that this
274-
vocabulary does not define a mechanism for describing the actual set of
275-
modifications made to object.  The target and origin typically have no defined
276-
meaning."))
277-
278-
(define as:View
279-
  (make-as-type
280-
    "View"
281-
    #:subclass-of (list as:Activity)
282-
    #:comment
283-
    "Indicates that the actor has viewed the object."))
284-
285-
(define as:Listen
286-
  (make-as-type
287-
    "Listen"
288-
    #:subclass-of (list as:Activity)
289-
    #:comment
290-
    "Indicates that the actor has listened to the object."))
291-
292-
(define as:Read
293-
  (make-as-type
294-
    "Read"
295-
    #:subclass-of (list as:Activity)
296-
    #:comment
297-
    "Indicates that the actor has read the object."))
298-
299-
(define as:Move
300-
  (make-as-type
301-
    "Move"
302-
    #:subclass-of (list as:Activity)
303-
    #:comment
304-
    "Indicates that the actor has moved object from origin to target.  If the
305-
origin or target are not specified, either can be determined by context."))
306-
307-
(define as:Travel
308-
  (make-as-type
309-
    "Travel"
310-
    #:subclass-of (list as:IntransitiveActivity)
311-
    #:comment
312-
    "Indicates that the actor is traveling to target from origin.  Travel is
313-
an IntransitiveObject whose actor specifies the direct object.  If the target
314-
or origin are not specified, either can be determined by context."))
315-
316-
(define as:Announce
317-
  (make-as-type
318-
    "Announce"
319-
    #:subclass-of (list as:Activity)
320-
    #:comment
321-
    "Indicates that the actor is calling the target's attention the object.  The
322-
origin typically has no defined meaning."))
323-
324-
(define as:Block
325-
  (make-as-type
326-
    "Block"
327-
    #:subclass-of (list as:Ignore)
328-
    #:comment
329-
    "Indicates that the actor is blocking the object.  Blocking is a stronger
330-
form of Ignore.  The typical use is to support social systems that allow one
331-
user to block activities or content of other users.  The target and origin
332-
typically have no defined meaning."))
333-
334-
(define as:Flag
335-
  (make-as-type
336-
    "Flag"
337-
    #:subclass-of (list as:Activity)
338-
    #:comment
339-
    "Indicates that the actor is ``flagging'' the object.  Flagging is defined
340-
in the sense common to many social platforms as reporting content as being
341-
inappropriate for any number of reasons."))
342-
343-
(define as:Dislike
344-
  (make-as-type
345-
    "Dislike"
346-
    #:subclass-of (list as:Activity)
347-
    #:comment
348-
    "Indicates that the actor dislikes the object."))
349-
350-
(define as:Question
351-
  (make-as-type
352-
    "Question"
353-
    #:subclass-of (list as:IntransitiveActivity)
354-
    #:comment
355-
    "Represents a question being asked.  Question objects are an extension of
356-
IntransitiveActivity.  That is, the Question object is an Activity, but the
357-
direct object is the question itself and therefore it would not contain an
358-
object property.  Either of the anyOf and oneOf properties MAY be used to
359-
express possible answers, but a Question object MUST NOT have both properties."))
360-
361-
(define as-activity-types
362-
  (list as:Accept as:Add as:Announce as:Arrive as:Block as:Create as:Delete
363-
        as:Dislike as:Flag as:Follow as:Ignore as:Invite as:Join as:Leave
364-
        as:Like as:Listen as:Move as:Offer as:Question as:Reject as:Read
365-
        as:Remove as:TentativeReject as:TentativeAccept as:Travel as:Undo
366-
        as:Update as:View))
367-
368-
;; Actor Types
369-
(define as:Application
370-
  (make-as-type
371-
    "Application"
372-
    #:subclass-of (list as:Object)
373-
    #:comment
374-
    "Describes a software application."))
375-
376-
(define as:Group
377-
  (make-as-type
378-
    "Group"
379-
    #:subclass-of (list as:Object)
380-
    #:comment
381-
    "Represents a formal or informal collective of Actors."))
382-
383-
(define as:Organisation
384-
  (make-as-type
385-
    "Organisation"
386-
    #:subclass-of (list as:Object)
387-
    #:comment
388-
    "Represents an organization."))
389-
390-
(define as:Person
391-
  (make-as-type
392-
    "Person"
393-
    #:subclass-of (list as:Object)
394-
    #:comment
395-
    "Represents an individual person."))
396-
397-
(define as:Service
398-
  (make-as-type
399-
    "Service"
400-
    #:subclass-of (list as:Object)
401-
    #:comment
402-
    "Represents a service of any kind."))
403-
404-
(define as-actor-types
405-
  (list as:Application as:Group as:Organisation as:Person as:Service))
406-
407-
;; 
408-
409-
(define as:Relationship
410-
  (make-as-type
411-
    "Relationship"
412-
    #:subclass-of (list as:Object)
413-
    #:comment
414-
    "Describes a relationship between two individuals.  The subject and object
415-
properties are used to identify the connected individuals.  See 5.2 Representing
416-
Relationships Between Entities for additional information."))
417-
418-
(define as:Article
419-
  (make-as-type
420-
    "Article"
421-
    #:subclass-of (list as:Object)
422-
    #:comment
423-
    "Represents any kind of multi-paragraph written work."))
424-
425-
(define as:Document
426-
  (make-as-type
427-
    "Document"
428-
    #:subclass-of (list as:Object)
429-
    #:comment
430-
    "Represents a document of any kind."))
431-
432-
(define as:Audio
433-
  (make-as-type
434-
    "Audio"
435-
    #:subclass-of (list as:Document)
436-
    #:comment
437-
    "Represents an audio document of any kind."))
438-
439-
(define as:Image
440-
  (make-as-type
441-
    "Image"
442-
    #:subclass-of (list as:Document)
443-
    #:comment
444-
    "An image document of any kind."))
445-
446-
(define as:Video
447-
  (make-as-type
448-
    "Video"
449-
    #:subclass-of (list as:Document)
450-
    #:comment
451-
    "Represents a video document of any kind."))
452-
453-
(define as:Note
454-
  (make-as-type
455-
    "Note"
456-
    #:subclass-of (list as:Object)
457-
    #:comment
458-
    "Represents a short written work typically less than a single paragraph in
459-
length."))
460-
461-
(define as:Page
462-
  (make-as-type
463-
    "Page"
464-
    #:subclass-of (list as:Document)
465-
    #:comment
466-
    "Represents a Web Page."))
467-
468-
(define as:Event
469-
  (make-as-type
470-
    "Event"
471-
    #:subclass-of (list as:Object)
472-
    #:comment
473-
    "Represents any kind of event."))
474-
475-
(define as:Place
476-
  (make-as-type
477-
    "Place"
478-
    #:subclass-of (list as:Object)
479-
    #:comment
480-
    "Represents a logical or physical location.  See 5.3 Representing Places
481-
for additional information."))
482-
483-
(define as:Mention
484-
  (make-as-type
485-
    "Mention"
486-
    #:subclass-of (list as:Link)
487-
    #:comment
488-
    "A specialized Link that represents an @mention."))
489-
490-
(define as:Profile
491-
  (make-as-type
492-
    "Profile"
493-
    #:subclass-of (list as:Object)
494-
    #:comment
495-
    "A Profile is a content object that describes another Object, typically
496-
used to describe Actor Type objects.  The describes property is used to
497-
reference the object being described by the profile"))
498-
499-
(define as:Tombstone
500-
  (make-as-type
501-
    "Tombstone"
502-
    #:subclass-of (list as:Object)
503-
    #:comment
504-
    "A Tombstone represents a content object that has been deleted.  It can be
505-
used in Collections to signify that there used to be an object at this
506-
position, but it has been deleted."))
507-
508-
(define as-object-and-link-types
509-
  (list as:Article as:Audio as:Document as:Event as:Image as:Note as:Page
510-
        as:Place as:Profile as:Relationship as:Tombstone as:Video as:Mention))
511-
512-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
513-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
514-
;;                                Properties                                 ;;
515-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
516-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
517-
518-
;; procedures for type checking
519-
520-
(define (any l proc)
521-
  (match l
522-
    (() #t)
523-
    ((p l ...)
524-
     (or (proc p) (any l proc)))
525-
    (#(p l ...)
526-
     (or (proc p) (any l proc)))))
527-
528-
(define (forall l proc)
529-
  (match l
530-
    (() #t)
531-
    ((p l ...)
532-
     (and (proc p) (forall l proc)))
533-
    (#(p l ...)
534-
     (and (proc p) (forall l proc)))))
535-
536-
(define (string-or-lang-string? s)
537-
  (match s
538-
    ((("@value" . s)) (string? s))
539-
    ((("@value" . s) ("@language" . l)) (string? s))
540-
    ((("@language" . l) ("@value" . s)) (string? s))))
541-
542-
(define (uri? s)
543-
  (if (list? s)
544-
      (forall s uri?)
545-
      (and (string? s) (string->uri s))))
546-
547-
(define (bool? s)
548-
  (and (json-object? s)
549-
       (json-has-key? s "@value")
550-
       (member (assoc-ref s "@value") '(#t #f))))
551-
552-
;; TODO: really specify these
553-
(define (date? s)
554-
  (and (json-object? s)
555-
       (json-has-key? s "@value")
556-
       (string? (assoc-ref s "@value"))))
557-
558-
(define (link-relation? s)
559-
  (and (json-object? s)
560-
       (json-has-key? s "@value")
561-
       (string? (assoc-ref s "@value"))))
562-
563-
(define (duration? s)
564-
  (and (json-object? s)
565-
       (json-has-key? s "@value")
566-
       (string? (assoc-ref s "@value"))))
567-
568-
(define (langtag? s)
569-
  (and (json-object? s)
570-
       (json-has-key? s "@value")
571-
       (string? (assoc-ref s "@value"))))
572-
573-
(define (mime-type? s)
574-
  (and (json-object? s)
575-
       (json-has-key? s "@value")
576-
       (string? (assoc-ref s "@value"))))
577-
578-
(define (non-negative-integer? i)
579-
  (and (integer? i)
580-
       (>= i 0)))
581-
582-
(define (float? i)
583-
  (number? i))
584-
585-
;; Properties
586-
587-
(define as:id
588-
  (make-as-property
589-
    "id" '("Object" "Link") uri?
590-
    #:uri "@id"
591-
    #:comment "Provides the globally unique identifier for an Object or Link."
592-
    #:functional? #t))
593-
594-
(define as:type
595-
  (make-as-property
596-
    "type" '("Object" "Link") uri?
597-
    #:uri "@type"
598-
    #:comment "Identifies the Object or Link type.  Multiple values may be
599-
specified."))
600-
601-
(define as:actor
602-
  (make-as-property
603-
    "actor" "Activity" '("Object" "Link")
604-
    #:subproperty-of '("attributedTo")
605-
    #:comment
606-
    "Describes one or more entities that either performed or are expected to
607-
perform the activity.  Any single activity can have multiple actors.  The actor
608-
MAY be specified using an indirect Link."))
609-
610-
(define as:attachment
611-
  (make-as-property
612-
    "attachment" "Object" '("Object" "Link")
613-
    #:comment
614-
    "Identifies a resource attached or related to an object that potentially
615-
requires special handling.  The intent is to provide a model that is at least
616-
semantically similar to attachments in email."))
617-
618-
(define as:attributedTo
619-
  (make-as-property
620-
    "attributedTo" '("Link" "Object") '("Link" "Object")
621-
    #:comment
622-
    "Identifies one or more entities to which this object is attributed.  The
623-
attributed entities might not be Actors.  For instance, an object might be
624-
attributed to the completion of another activity."))
625-
626-
(define as:audience
627-
  (make-as-property
628-
    "audience" "Object" '("Object" "Link")
629-
    #:comment
630-
    "Identifies one or more entities that represent the total population of
631-
entities for which the object can considered to be relevant."))
632-
633-
(define as:bcc
634-
  (make-as-property
635-
    "bcc" "Object" '("Object" "Link")
636-
    #:comment
637-
    "Identifies one or more Objects that are part of the private secondary
638-
audience of this Object."))
639-
640-
(define as:bto
641-
  (make-as-property
642-
    "bto" "Object" '("Object" "Link")
643-
    #:comment
644-
    "Identifies an Object that is part of the private primary audience of this
645-
Object."))
646-
647-
(define as:cc
648-
  (make-as-property
649-
    "cc" "Object" '("Object" "Link")
650-
    #:comment
651-
    "Identifies an Object that is part of the public secondary audience of
652-
this Object."))
653-
654-
(define as:context
655-
  (make-as-property
656-
    "context" "Object" '("Object" "Link")
657-
    #:comment
658-
    "Identifies the context within which the object exists or an activity was
659-
performed.  The notion of ``context'' used is intentionally vague.  The
660-
intended function is to serve as a means of grouping objects and activities
661-
that share a common originating context or purpose.  An example could be all
662-
activities relating to a common project or event."))
663-
664-
(define as:current
665-
  (make-as-property
666-
    "current" "Collection" '("CollectionPage" "Link")
667-
    #:functional? #t
668-
    #:comment
669-
    "In a paged Collection, indicates the page that contains the most recently
670-
updated member items."))
671-
672-
(define as:first
673-
  (make-as-property
674-
    "first" "Collection" '("CollectionPage" "Link")
675-
    #:functional? #t
676-
    #:comment
677-
    "In a paged Collection, indicates the furthest preceeding page of items in
678-
the collection."))
679-
680-
(define as:generator
681-
  (make-as-property
682-
    "generator" "Object" '("Object" "Link")
683-
    #:comment
684-
    "Identifies the entity (e.g. an application) that generated the object."))
685-
686-
(define as:icon
687-
  (make-as-property
688-
    "icon" "Object" '("Image" "Link")
689-
    #:comment
690-
    "Indicates an entity that describes an icon for this object.  The image
691-
should have an aspect ratio of one (horizontal) to one (vertical) and should
692-
be suitable for presentation at a small size."))
693-
694-
(define as:image
695-
  (make-as-property
696-
    "image" "Object" '("Image" "Link")
697-
    #:comment
698-
    "Indicates an entity that describes an image for this object.  Unlike the
699-
icon property, there are no aspect ratio or display size limitations assumed."))
700-
701-
(define as:inReplyTo
702-
  (make-as-property
703-
    "inReplyTo" "Object" '("Object" "Link")
704-
    #:comment
705-
    "Indicates one or more entities for which this object is considered a
706-
response."))
707-
708-
(define as:instrument
709-
  (make-as-property
710-
    "instrument" "Activity" '("Object" "Link")
711-
    #:comment
712-
    "Identifies one or more objects used (or to be used) in the completion of
713-
an Activity."))
714-
715-
(define as:last
716-
  (make-as-property
717-
    "last" "Collection" '("CollectionPage" "Link")
718-
    #:functional? #t
719-
    #:comment
720-
    ""))
721-
722-
(define as:location
723-
  (make-as-property
724-
    "location" "Object" '("Object" "Link")
725-
    #:comment
726-
    "Indicates one or more physical or logical locations associated with the
727-
object."))
728-
729-
(define as:items
730-
  (make-as-property
731-
    "items" "Collection" '("Object" "Link")
732-
    #:comment
733-
    "Identifies the items contained in a collection. The items might be ordered
734-
or unordered."))
735-
736-
(define as:oneOf
737-
  (make-as-property
738-
    "oneOf" "Question" '("Object" "Link")
739-
    #:comment
740-
    "Identifies an exclusive option for a Question.  Use of oneOf implies that
741-
the Question can have only a single answer.  To indicate that a Question can
742-
have multiple answers, use anyOf."))
743-
744-
(define as:anyOf
745-
  (make-as-property
746-
    "oneOf" "Question" '("Object" "Link")
747-
    #:comment
748-
    "Identifies an inclusive option for a Question.  Use of anyOf implies that
749-
the Question can have multiple answers.  To indicate that a Question can have
750-
only one answer, use oneOf."))
751-
752-
(define as:closed
753-
  (make-as-property
754-
    "closed" "Question" '("Object" "Link" date? boolean?)
755-
    #:comment
756-
    "Indicates that a question has been closed, and answers are no longer
757-
accepted."))
758-
759-
(define as:origin
760-
  (make-as-property
761-
    "origin" "Activity" '("Object" "Link")
762-
    #:comment
763-
    "Describes an indirect object of the activity from which the activity is
764-
directed.  The precise meaning of the origin is the object of the English
765-
preposition ``from''.  For instance, in the activity ``John moved an item to
766-
List B from List A'', the origin of the activity is ``List A''."))
767-
768-
(define as:next
769-
  (make-as-property
770-
    "next" "CollectionPage" '("CollectionPage" "Link")
771-
    #:functional? #t
772-
    #:comment
773-
    "In a paged Collection, indicates the next page of items."))
774-
775-
(define as:object
776-
  (make-as-property
777-
    "object" '("Activity" "Relationship") '("Object" "Link")
778-
    #:comment
779-
    "When used within an Activity, describes the direct object of the activity.
780-
For instance, in the activity ``John added a movie to his wishlist'', the
781-
object of the activity is the movie added.  When used within a Relationship
782-
describes the entity to which the subject is related."))
783-
784-
(define as:prev
785-
  (make-as-property
786-
    "prev" "CollectionPage" '("CollectionPage" "Link")
787-
    #:functional? #t
788-
    #:comment
789-
    "In a paged Collection, identifies the previous page of items."))
790-
791-
(define as:preview
792-
  (make-as-property
793-
    "preview" '("Object" "Link") '("Object" "Link")
794-
    #:comment
795-
    "Identifies an entity that provides a preview of this object."))
796-
797-
(define as:result
798-
  (make-as-property
799-
    "result" "Activity" '("Object" "Link")
800-
    #:comment
801-
    "Describes the result of the activity.  For instance, if a particular
802-
action results in the creation of a new resource, the result property can be
803-
used to describe that new resource."))
804-
805-
(define as:replies
806-
  (make-as-property
807-
    "replise" "Object" "Collection"
808-
    #:functional? #t
809-
    #:comment
810-
    "Identifies a Collection containing objects considered to be responses to
811-
this object."))
812-
813-
(define as:tag
814-
  (make-as-property
815-
    "tag" "Object" '("Object" "Link")
816-
    #:comment
817-
    "One or more ``tags'' that have been associated with an object.  A tag can
818-
be any kind of Object.  The key difference between attachment and tag is that
819-
the former implies association by inclusion, while the latter implies
820-
associated by reference."))
821-
822-
(define as:target
823-
  (make-as-property
824-
    "target" "Activity" '("Object" "Link")
825-
    #:comment
826-
    "Describes the indirect object, or target, of the activity.  The precise
827-
meaning of the target is largely dependent on the type of action being
828-
described but will often be the object of the English preposition ``to''.  For
829-
instance, in the activity ``John added a movie to his wishlist'', the target
830-
of the activity is John's wishlist. An activity can have more than one target."))
831-
832-
(define as:to
833-
  (make-as-property
834-
    "to" "Object" '("Object" "Link")
835-
    #:comment
836-
    "Identifies an entity considered to be part of the public primary audience
837-
of an Object."))
838-
839-
(define as:url
840-
  (make-as-property
841-
    "url" "Object" '(uri? "Link")
842-
    #:comment
843-
    "Identifies one or more links to representations of the object."))
844-
845-
(define as:accuracy
846-
  (make-as-property
847-
    "accuracy" "Place" float?
848-
    #:comment
849-
    "Indicates the accuracy of position coordinates on a Place objects.
850-
Expressed in properties of percentage.  e.g. ``94.0'' means ``94.0% accurate''."))
851-
852-
(define as:altitude
853-
  (make-as-property
854-
    "altitude" "Object" float?
855-
    #:functional? #t
856-
    #:comment
857-
    "Indicates the altitude of a place.  The measurement units is indicated
858-
using the units property.  If units is not specified, the default is assumed
859-
to be ``m'' indicating meters."))
860-
861-
(define as:content
862-
  (make-as-property
863-
    "content" "Object" string-or-lang-string?
864-
    #:comment
865-
    "The content or textual representation of the Object encoded as a JSON
866-
string.  By default, the value of content is HTML.  The mediaType property can
867-
be used in the object to indicate a different content type.  The content MAY
868-
be expressed using multiple language-tagged values."))
869-
870-
(define as:name
871-
  (make-as-property
872-
    "name" '("Object" "Link") string-or-lang-string?
873-
    #:comment
874-
    "A simple, human-readable, plain-text name for the object.  HTML markup
875-
MUST NOT be included.  The name MAY be expressed using multiple language-tagged
876-
values."))
877-
878-
(define as:duration
879-
  (make-as-property
880-
    "duration" "Object" duration?
881-
    #:functional? #t
882-
    #:comment
883-
    "When the object describes a time-bound resource, such as an audio or video,
884-
a meeting, etc, the duration property indicates the object's approximate
885-
duration.  The value MUST be expressed as an xsd:duration as defined by
886-
[xmlschema11-2], section 3.3.6 (e.g. a period of 5 seconds is represented as
887-
``PT5S'')."))
888-
889-
(define as:height
890-
  (make-as-property
891-
    "height" "Link" non-negative-integer?
892-
    #:functional? #t
893-
    #:comment
894-
    "On a Link, specifies a hint as to the rendering height in device-independent
895-
pixels of the linked resource."))
896-
897-
(define as:href
898-
  (make-as-property
899-
    "href" "Link" uri?
900-
    #:functional? #t
901-
    #:comment
902-
    "The target resource pointed to by a Link."))
903-
904-
(define as:hreflang
905-
  (make-as-property
906-
    "hreflang" "Link" langtag?
907-
    #:functional? #t
908-
    #:comment
909-
    "Hints as to the language used by the target resource.  Value MUST be a
910-
[BCP47] Language-Tag."))
911-
912-
(define as:partOf
913-
  (make-as-property
914-
    "partOf" "CollectionPage" '("Collection" "Link")
915-
    #:functional? #t
916-
    #:comment
917-
    "Identifies the Collection to which a CollectionPage objects items belong."))
918-
919-
(define as:latitude
920-
  (make-as-property
921-
    "latitude" "Place" float?
922-
    #:functional? #t
923-
    #:comment
924-
    "The latitude of a place."))
925-
926-
(define as:longitude
927-
  (make-as-property
928-
    "longitude" "Place" float?
929-
    #:functional? #t
930-
    #:comment
931-
    "The longitude of a place."))
932-
933-
(define as:mediaType
934-
  (make-as-property
935-
    "mediaType" '("Link" "Object") mime-type?
936-
    #:functional? #t
937-
    #:comment
938-
    "When used on a Link, identifies the MIME media type of the referenced
939-
resource.  When used on an Object, identifies the MIME media type of the value
940-
of the content property.  If not specified, the content property is assumed to
941-
contain text/html content."))
942-
943-
(define as:endTime
944-
  (make-as-property
945-
    "endTime" "Object" date?
946-
    #:functional? #t
947-
    #:comment
948-
    "The date and time describing the actual or expected ending time of the
949-
object.  When used with an Activity object, for instance, the endTime property
950-
specifies the moment the activity concluded or is expected to conclude."))
951-
952-
(define as:published
953-
  (make-as-property
954-
    "published" "Object" date?
955-
    #:functional? #t
956-
    #:comment
957-
    "The date and time at which the object was published."))
958-
959-
(define as:startTime
960-
  (make-as-property
961-
    "startTime" "Object" date?
962-
    #:functional? #t
963-
    #:comment
964-
    "The date and time describing the actual or expected starting time of the
965-
object.  When used with an Activity object, for instance, the startTime
966-
property specifies the moment the activity began or is scheduled to begin."))
967-
968-
(define as:radius
969-
  (make-as-property
970-
    "radius" "Place" float?
971-
    #:functional? #t
972-
    #:comment
973-
    "The radius from the given latitude and longitude for a Place.  The units
974-
is expressed by the units property.  If units is not specified, the default is
975-
assumed to be ``m'' indicating ``meters''."))
976-
977-
(define as:rel
978-
  (make-as-property
979-
    "rel" "Link" link-relation?
980-
    #:comment
981-
    "A link relation associated with a Link.  The value MUST conform to both the
982-
[HTML5] and [RFC5988] ``link relation'' definitions.  In the [HTML5], any
983-
string not containing the ``space'' U+0020, ``tab'' (U+0009), ``LF'' (U+000A),
984-
``FF'' (U+000C), ``CR'' (U+000D) or ``,'' (U+002C) characters can be used as a
985-
valid link relation."))
986-
987-
(define as:startIndex
988-
  (make-as-property
989-
    "startIndex" "OrderedCollectionPage" non-negative-integer?
990-
    #:functional? #t
991-
    #:comment
992-
    "A non-negative integer value identifying the relative position within the
993-
logical view of a strictly ordered collection."))
994-
995-
(define as:summary
996-
  (make-as-property
997-
    "summary" "Object" string-or-lang-string?
998-
    #:comment
999-
    "A natural language summarization of the object encoded as HTML.  Multiple
1000-
language tagged summaries MAY be provided."))
1001-
1002-
(define as:totalItems
1003-
  (make-as-property
1004-
    "totalItems" "Collection" non-negative-integer?
1005-
    #:functional? #t
1006-
    #:comment
1007-
    "A non-negative integer specifying the total number of objects contained by
1008-
the logical view of the collection.  This number might not reflect the actual
1009-
number of items serialized within the Collection object instance."))
1010-
1011-
(define as:units
1012-
  (make-as-property
1013-
    "units" "Place" (list uri? (lambda (s) (member s '("cm" "feet" "inches" "km"
1014-
                                                       "m" "miles"))))
1015-
    #:functional? #t
1016-
    #:comment
1017-
    "Specifies the measurement units for the radius and altitude properties on
1018-
a Place object.  If not specified, the default is assumed to be ``m'' for
1019-
``meters''."))
1020-
1021-
(define as:updated
1022-
  (make-as-property
1023-
    "updated" "Object" date?
1024-
    #:functional? #t
1025-
    #:comment
1026-
    "The date and time at which the object was updated."))
1027-
1028-
(define as:width
1029-
  (make-as-property
1030-
    "width" "Link" non-negative-integer?
1031-
    #:functional? #t
1032-
    #:comment
1033-
    "On a Link, specifies a hint as to the rendering width in device-independent
1034-
pixels of the linked resource."))
1035-
1036-
(define as:subject
1037-
  (make-as-property
1038-
    "subject" "Relationship" '("Link" "Object")
1039-
    #:functional? #t
1040-
    #:comment
1041-
    "On a Relationship object, the subject property identifies one of the
1042-
connected individuals.  For instance, for a Relationship object describing
1043-
``John is related to Sally'', subject would refer to John."))
1044-
1045-
(define as:relationship
1046-
  (make-as-property
1047-
    "relationship" "Relationship" "Object"
1048-
    #:comment
1049-
    "On a Relationship object, the relationship property identifies the kind of
1050-
relationship that exists between subject and object."))
1051-
1052-
(define as:describes
1053-
  (make-as-property
1054-
    "describes" "Profile" "Object"
1055-
    #:functional? #t
1056-
    #:comment
1057-
    "On a Profile object, the describes property identifies the object described
1058-
by the Profile."))
1059-
1060-
(define as:formerType
1061-
  (make-as-property
1062-
    "formerType" "Tombstone" "Object"
1063-
    #:comment
1064-
    "On a Tombstone object, the formerType property identifies the type of the
1065-
object that was deleted."))
1066-
1067-
(define as:deleted
1068-
  (make-as-property
1069-
    "deleted" "Tombstone" date?
1070-
    #:functional? #t
1071-
    #:comment
1072-
    "On a Tombstone object, the deleted property is a timestamp for when the
1073-
object was deleted."))
1074-
1075-
(define as-properties
1076-
  (list as:actor as:attachment as:attributedTo as:audience as:bcc as:bto
1077-
        as:cc as:context as:current as:first as:generator as:icon as:id
1078-
        as:image as:inReplyTo as:instrument as:last as:location as:items
1079-
        as:oneOf as:anyOf as:closed as:origin as:next as:object as:prev
1080-
        as:preview as:result as:replies as:tag as:target as:to as:type
1081-
        as:url as:accuracy as:altitude as:content as:name as:duration
1082-
        as:height as:href as:hreflang as:partOf as:latitude as:longitude
1083-
        as:mediaType as:endTime as:published as:startTime as:radius
1084-
        as:rel as:startIndex as:summary as:totalItems as:units as:updated
1085-
        as:width as:subject as:relationship as:describes as:formerType
1086-
        as:deleted))
1087-
1088-
(define activitystreams-ontology
1089-
  (append as-core-types as-activity-types as-actor-types as-object-and-link-types
1090-
          as-properties))
1091-
24+
  #:export (make-ontology
25+
            ontology?
26+
            ontology-context
27+
            ontology-datatypes
28+
            ontology-properties
29+
30+
            make-as-type
31+
            as-type?
32+
            as-type-label
33+
            as-type-uri
34+
            as-type-comment
35+
            as-type-subclass-of
36+
            build-as-type
37+
38+
            make-as-property
39+
            as-property?
40+
            as-property-label
41+
            as-property-uri
42+
            as-property-domain
43+
            as-property-range
44+
            as-property-functional?
45+
            as-property-subproperty-of
46+
            as-property-comment
47+
            build-as-property
48+
49+
            make-as-document
50+
            as-document?
51+
            as-document-types
52+
            as-document-properties
53+
54+
            make-as-string
55+
            as-string?
56+
            as-string-value
57+
            as-string-language
58+
            as-string-direction
59+
60+
            make-as-typed-value
61+
            as-typed-value?
62+
            as-typed-value-value
63+
            as-typed-value-type
64+
65+
            merge-ontologies
66+
            subproperty?
67+
            subtype?
68+
            as-ref
69+
            json->as-document
70+
            uri->as-document
71+
            as-document->json
72+
            as-document->graphviz))
73+
74+
(define-record-type <ontology>
75+
  (make-ontology context datatypes properties)
76+
  ontology?
77+
  (context    ontology-context)
78+
  (datatypes  ontology-datatypes)
79+
  (properties ontology-properties))
80+
81+
(define as-vocab "https://www.w3.org/ns/activitystreams#")
82+
83+
(define-record-type as-type
84+
  (make-as-type label uri comment subclass-of)
85+
  as-type?
86+
  (label       as-type-label)
87+
  (uri         as-type-uri)
88+
  (comment     as-type-comment)
89+
  (subclass-of as-type-subclass-of))
90+
91+
(define* (build-as-type label #:key (uri (string-append as-vocab label))
92+
                        (comment "") (subclass-of '()))
93+
  (make-as-type label uri comment subclass-of))
94+
95+
(define-record-type as-property
96+
  (make-as-property label uri range domain functional? subproperty-of comment)
97+
  as-property?
98+
  (label          as-property-label)
99+
  (uri            as-property-uri)
100+
  (domain         as-property-domain)
101+
  (range          as-property-range)
102+
  (functional?    as-property-functional?)
103+
  (subproperty-of as-property-subproperty-of)
104+
  (comment        as-property-comment))
105+
106+
(define* (build-as-property label domain range
107+
                            #:key (uri (string-append as-vocab label))
108+
                            (functional? #f) (subproperty-of '()) (comment ""))
109+
  (make-as-property label uri range domain functional? subproperty-of comment))
110+
111+
(define-record-type as-document
112+
  (make-as-document types properties)
113+
  as-document?
114+
  (types      as-document-types)
115+
  (properties as-document-properties))
116+
117+
(define-record-type as-string
118+
  (make-as-string value language direction)
119+
  as-string?
120+
  (value     as-string-value)
121+
  (language  as-string-language)
122+
  (direction as-string-direction))
123+
124+
(define-record-type as-typed-value
125+
  (make-as-typed-value value type)
126+
  as-typed-value?
127+
  (value as-typed-value-value)
128+
  (type  as-typed-value-type))
129+
130+
(define (uniq lst)
131+
  (let loop ((lst lst) (result '()))
132+
    (match lst
133+
      (() result)
134+
      ((elem lst ...)
135+
       (if (member elem result)
136+
           (loop lst result)
137+
           (loop lst (cons elem result)))))))
138+
139+
(define (alist-set lst key value)
140+
  (match lst
141+
    (() `((,key . ,value)))
142+
    (((k . v) lst ...)
143+
     (if (equal? k key)
144+
         (cons (cons key value) lst)
145+
         (cons (cons k v) (alist-set lst key value))))))
146+
147+
(define (merge-domains d1 d2)
148+
  (uniq
149+
    (if (list? d1)
150+
        (if (list? d2)
151+
            (append d1 d2)
152+
            (cons d2 d1))
153+
        (if (list? d2)
154+
            (cons d1 d2)
155+
            (list d1 d2)))))
156+
157+
(define (merge-ranges r1 r2)
158+
  (uniq
159+
    (if (list? r1)
160+
        (if (list? r2)
161+
            (append r1 r2)
162+
            (cons r2 r1))
163+
        (if (list? r2)
164+
            (cons r1 r2)
165+
            (list r1 r2)))))
166+
167+
(define (fix-types datatypes)
168+
  (define (fix-datatype type)
169+
    (if (as-type? type)
170+
        (let ((candidates
171+
                (filter (lambda (t) (equal? (as-type-uri t) (as-type-uri type)))
172+
                        datatypes)))
173+
          (if (null? candidates)
174+
              type
175+
              (car candidates)))
176+
        type))
177+
178+
  (let loop ((to-fix datatypes) (result '()))
179+
    (match to-fix
180+
      (() result)
181+
      ((type to-fix ...)
182+
       (loop
183+
         to-fix
184+
         (cons
185+
           (make-as-type
186+
             (as-type-label type)
187+
             (as-type-uri type)
188+
             (as-type-comment type)
189+
             (map fix-datatype (as-type-subclass-of type)))
190+
           result))))))
191+
192+
(define (merge-datatypes datatypes)
193+
  (let loop ((result '()) (datatypes (apply append datatypes)))
194+
    (match datatypes
195+
      (() (map cdr result))
196+
      ((type datatypes ...)
197+
       (loop
198+
         (let ((previous (assoc-ref result (as-type-uri type))))
199+
           (if previous
200+
               (alist-set result
201+
                 (as-type-uri type)
202+
                 (make-as-type
203+
                   (as-type-label type)
204+
                   (as-type-uri type)
205+
                   (or (as-type-comment previous) (as-type-comment type))
206+
                   (uniq (append (as-type-subclass-of previous)
207+
                                 (as-type-subclass-of type)))))
208+
               (cons (cons (as-type-uri type) type) result)))
209+
         datatypes)))))
210+
211+
(define (fix-properties datatypes properties)
212+
  (define (fix-datatype type)
213+
    (if (as-type? type)
214+
        (let ((candidates
215+
                (filter (lambda (t) (equal? (as-type-uri t) (as-type-uri type)))
216+
                        datatypes)))
217+
          (if (null? candidates)
218+
              type
219+
              (car candidates)))
220+
        type))
221+
222+
  (define (fix-property prop)
223+
    (if (as-property? prop)
224+
        (let ((candidates
225+
                (filter (lambda (p) (equal? (as-property-uri p) (as-property-uri prop)))
226+
                        properties)))
227+
          (if (null? candidates)
228+
              prop
229+
              (car candidates)))
230+
        prop))
231+
232+
  (let loop ((to-fix properties) (result '()))
233+
    (match to-fix
234+
      (() result)
235+
      ((prop to-fix ...)
236+
       (let ((domain (as-property-domain prop))
237+
             (range (as-property-range prop)))
238+
         (loop
239+
           to-fix
240+
           (cons
241+
             (make-as-property
242+
               (as-property-label prop)
243+
               (as-property-uri prop)
244+
               (if (list? domain)
245+
                   (map fix-property (map fix-datatype domain))
246+
                   (fix-property (fix-datatype domain)))
247+
               (if (list? range)
248+
                   (map fix-property (map fix-datatype range))
249+
                   (fix-property (fix-datatype range)))
250+
               (as-property-functional? prop)
251+
               (map fix-property (as-property-subproperty-of prop))
252+
               (as-property-comment prop))
253+
             result)))))))
254+
255+
(define (merge-properties properties)
256+
  (let loop ((result '()) (properties (apply append properties)))
257+
    (match properties
258+
      (() (map cdr result))
259+
      ((prop properties ...)
260+
       (loop
261+
         (let ((previous (assoc-ref result (as-property-uri prop))))
262+
           (if previous
263+
               (alist-set result
264+
                 (as-property-uri prop)
265+
                 (make-as-property
266+
                   (as-property-label prop)
267+
                   (as-property-uri prop)
268+
                   (merge-domains (as-property-domain previous)
269+
                                  (as-property-domain prop))
270+
                   (merge-ranges (as-property-range previous)
271+
                                 (as-property-range prop))
272+
                   (and (as-property-functional? previous)
273+
                        (as-property-functional? prop))
274+
                   (uniq (append (as-property-subproperty-of previous)
275+
                                 (as-property-subproperty-of prop)))
276+
                   (or (as-property-comment previous)
277+
                       (as-property-comment prop))))
278+
               (cons (cons (as-property-uri prop) prop) result)))
279+
         properties)))))
280+
281+
(define* (merge-ontologies . ontologies)
282+
  (let ((datatypes (merge-datatypes (map ontology-datatypes ontologies)))
283+
        (properties (merge-properties (map ontology-properties ontologies))))
284+
    (make-ontology
285+
      (filter (lambda (a) a) (append-map ontology-context ontologies))
286+
      (fix-types datatypes)
287+
      (fix-properties datatypes properties))))
288+
289+
(define (subproperty? property other)
290+
  "Is @code{property} a subproperty of @code{other}?"
291+
  (or
292+
    (equal? property other)
293+
    (equal? (as-property-uri property) other)
294+
    (let loop ((superproperties (as-property-subproperty-of property)))
295+
      (match superproperties
296+
        (() #f)
297+
        ((superproperty superproperties ...)
298+
         (if (subproperty? superproperty other)
299+
             #t
300+
             (loop superproperties)))))))
301+
302+
(define (subtype? type other)
303+
  "Is @code{type} a subtype of @code{other}?"
304+
  (or
305+
    (equal? type other)
306+
    (let loop ((supertypes (as-type-subclass-of type)))
307+
      (match supertypes
308+
        (() #f)
309+
        ((supertype supertypes ...)
310+
         (if (subtype? supertype other)
311+
             #t
312+
             (loop supertypes)))))))
313+
314+
(define (as-ref document key)
315+
  "Takes a parsed document and returns the value associated with the property.
316+
This takes care of subproperties: if you look for a property that's not in the
317+
document directly, but the document has a subproperty of it, this will be
318+
returned.  The key must be a proper label as defined in the ontology."
319+
  (define (is-candidate kv)
320+
    (match kv
321+
      ((k . v)
322+
       (subproperty? k key))))
323+
  (let ((candidates (filter is-candidate document)))
324+
    (map cdr candidates)))
325+
326+
(define (json->as-document ontology document)
327+
  (define (uri->datatype type)
328+
    (let ((candidates (filter (lambda (t) (equal? (as-type-uri t) type))
329+
                              (ontology-datatypes ontology))))
330+
      (cond
331+
        ((null? candidates)
332+
         #f)
333+
        ((> (length candidates) 1)
334+
         (throw 'multiple-datatypes-with-same-uri candidates))
335+
        (else
336+
         (car candidates)))))
337+
338+
  (define (uri->property property)
339+
    (let ((candidates (filter (lambda (p) (equal? (as-property-uri p) property))
340+
                              (ontology-properties ontology))))
341+
      (cond
342+
        ((null? candidates)
343+
         #f)
344+
        ((> (length candidates) 1)
345+
         (throw 'multiple-properties-with-same-uri candidates))
346+
        (else (car candidates)))))
347+
348+
  (define (scalar->as-value value)
349+
    (cond
350+
      ((or (json-has-key? value "@language") (json-has-key? value "@direction"))
351+
       (make-as-string
352+
         (assoc-ref value "@value")
353+
         (assoc-ref value "@language")
354+
         (assoc-ref value "@direction")))
355+
      ((json-has-key? value "@type")
356+
       (let* ((types (assoc-ref value "@type"))
357+
              (types (if (string? types) (list types) (array->list types)))
358+
              (types (map uri->datatype types)))
359+
         (make-as-typed-value (assoc-ref value "@value") types)))
360+
      (else
361+
        (assoc-ref value "@value"))))
362+
363+
  (cond
364+
    ((scalar? document)
365+
     document)
366+
    ((json-has-key? document "@value")
367+
     (scalar->as-value document))
368+
    ((json-array? document)
369+
     ;; XXX: this filter is not correct if one of the values is the litteral
370+
     ;; "false"
371+
     (list->array 1
372+
       (filter
373+
         (lambda (a) a)
374+
         (map (lambda (doc) (json->as-document ontology doc))
375+
              (array->list document)))))
376+
    ((json-has-key? document "@type")
377+
     (let* ((types (assoc-ref document "@type"))
378+
            (types (if (string? types) (list types) (array->list types)))
379+
            (types (filter (lambda (a) a) (map uri->datatype types))))
380+
       (if (null? types)
381+
           #f
382+
           (make-as-document
383+
             types
384+
             (filter
385+
               (lambda (a) a)
386+
               (map
387+
                 (match-lambda
388+
                   ((key . value)
389+
                    (let ((property (uri->property key))
390+
                          (value (json->as-document ontology value)))
391+
                      (if (and property (not (equal? key "@type")) value)
392+
                          (cons (uri->property key) value)
393+
                          #f))))
394+
                 document))))))
395+
    (else
396+
      (map
397+
        (match-lambda
398+
          ((key . value)
399+
           (cons key (json->as-document ontology value))))
400+
        document))))
401+
402+
(define (uri->as-document ontology uri)
403+
  (json->as-document ontology (expand uri)))
404+
405+
(define (as-document->json ontology doc)
406+
  (define (as-document->proper-json doc)
407+
    (append
408+
      `(("@type" . ,(list->array 1 (map as-type-uri (as-document-types doc)))))
409+
      (map
410+
        (match-lambda
411+
          ((key . value)
412+
           (cons (as-property-uri key) (as-value->proper-json value))))
413+
        (as-document-properties doc))))
414+
415+
  (define (as-value->proper-json doc)
416+
    (cond
417+
      ((as-document? doc)
418+
       (as-document->proper-json doc))
419+
      ((list? doc)
420+
       (map
421+
         (match-lambda
422+
           ((key . value)
423+
            (cons
424+
              (if (string? key)
425+
                  key
426+
                  (as-property-uri key))
427+
              (as-value->proper-json value))))
428+
         doc))
429+
      ((string? doc)
430+
       doc)
431+
      ((array? doc)
432+
       (list->array 1 (map as-value->proper-json (array->list doc))))
433+
      ((as-typed-value? doc)
434+
       `(("@value" . ,(as-typed-value-value doc))
435+
         ("@type" . ,(as-type-uri (as-typed-value-type doc)))))
436+
      ((as-string? doc)
437+
       `(("@value" . ,(as-string-value doc))
438+
         ,@(if (as-string-direction doc)
439+
               `(("@direction" . ,(as-string-direction doc)))
440+
               '())
441+
         ,@(if (as-string-language doc)
442+
               `(("@language" . ,(as-string-language doc)))
443+
               '())))
444+
      (else doc)))
445+
446+
  (compact (as-value->proper-json doc)
447+
           `(("@context" . ,(list->array 1 (ontology-context ontology))))))
448+
449+
(define* (as-document->graphviz doc #:key (label "n"))
450+
  (cond
451+
    ((as-document? doc)
452+
     (let* ((id (as-ref (as-document-properties doc) "@id"))
453+
            (id (if (string? id) id (if (null? id) "" (car id))))
454+
            (types (as-document-types doc))
455+
            (name (if (null? types)
456+
                      id
457+
                      (string-append id " ("
458+
                                     (string-join (map as-type-label types) ", ")
459+
                                     ")"))))
460+
       (format #t "  ~a [label=\"~a\"];~%" label name)
461+
       (let loop ((children (as-document-properties doc)) (suffix 0))
462+
         (match children
463+
           (() (format #t "~%"))
464+
           (((key . value) children ...)
465+
            (let ((child-label (string-append label (number->string suffix))))
466+
              (format #t "  ~a -> ~a [label=\"~a\"];~%"
467+
                      label child-label
468+
                      (if (string? key) key (as-property-label key)))
469+
              (as-document->graphviz value #:label child-label)
470+
              (loop children (+ suffix 1))))))))
471+
    ((list? doc)
472+
     (format #t "  ~a [label=\"\"];~%" label)
473+
     (let loop ((children doc) (suffix 0))
474+
       (match children
475+
         (() (format #t "~%"))
476+
         (((key . value) children ...)
477+
          (let ((child-label (string-append label (number->string suffix))))
478+
            (format #t "  ~a -> ~a [label=\"~a\"];~%"
479+
                    label child-label
480+
                    (if (string? key) key (as-property-label key)))
481+
            (as-document->graphviz value #:label child-label)
482+
            (loop children (+ suffix 1)))))))
483+
    ((string? doc)
484+
     (format #t "  ~a [label=\"~a\"];~%" label doc))
485+
    ((array? doc)
486+
     (let loop ((children (array->list doc)) (suffix 0))
487+
       (match children
488+
         (() (format #t "~%"))
489+
         ((value children ...)
490+
          (let ((child-label (string-append label (number->string suffix))))
491+
            (format #t "  ~a -> ~a;~%" label child-label)
492+
            (as-document->graphviz value #:label child-label)
493+
            (loop children (+ suffix 1)))))))
494+
    ((as-typed-value? doc)
495+
     (format #t "  ~a [label=\"~a\"];~%"
496+
             label (string-append (as-typed-value-value doc) "^^"
497+
                                (as-type-label (as-typed-value-type doc)))))
498+
    ((as-string? doc)
499+
     (let* ((str (as-string-value doc))
500+
            (str (if (or (as-string-language doc) (as-string-direction doc))
501+
                     (string-append str "@")
502+
                     str))
503+
            (str (string-append str (as-string-language doc)))
504+
            (str (if (as-string-direction doc)
505+
                     (string-append str "_" (as-string-direction doc))
506+
                     str)))
507+
     (format #t "  ~a [label=\"~a\"];~%"
508+
             label str)))
509+
    (else doc)))

activitystreams/predicates.scm unknown status 1

1+
;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu>
2+
;;;; 
3+
;;;; This library is free software; you can redistribute it and/or
4+
;;;; modify it under the terms of the GNU Lesser General Public
5+
;;;; License as published by the Free Software Foundation; either
6+
;;;; version 3 of the License, or (at your option) any later version.
7+
;;;; 
8+
;;;; This library is distributed in the hope that it will be useful,
9+
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11+
;;;; Lesser General Public License for more details.
12+
;;;; 
13+
;;;; You should have received a copy of the GNU Lesser General Public
14+
;;;; License along with this library; if not, write to the Free Software
15+
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16+
17+
(define-module (activitystreams predicates)
18+
  #:use-module (activitystreams ontology)
19+
  #:use-module (ice-9 match)
20+
  #:use-module (jsonld json)
21+
  #:use-module (web uri)
22+
  #:export (uri? float? mime-type? date? string-or-lang-string? duration?
23+
            langtag? link-relation? non-negative-integer?))
24+
25+
(define (uri? s)
26+
  (and (string? s) (string->uri s)))
27+
28+
(define (float? s)
29+
  (or (number? s)
30+
      (and (string? s) (string->number s))))
31+
32+
(define (mime-type? s)
33+
  (string? s))
34+
35+
(define (date? s)
36+
  (string? s))
37+
38+
(define (string-or-lang-string? s)
39+
  (or (string? s) (as-string? s)))
40+
41+
(define (duration? s)
42+
  (string? s))
43+
44+
(define (langtag? s)
45+
  (string? s))
46+
47+
(define (link-relation? s)
48+
  (string? s))
49+
50+
(define (non-negative-integer? s)
51+
  (and (number? s) (>= s 0)))

activitystreams/vocabulary.scm unknown status 1

1+
;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu>
2+
;;;; 
3+
;;;; This library is free software; you can redistribute it and/or
4+
;;;; modify it under the terms of the GNU Lesser General Public
5+
;;;; License as published by the Free Software Foundation; either
6+
;;;; version 3 of the License, or (at your option) any later version.
7+
;;;; 
8+
;;;; This library is distributed in the hope that it will be useful,
9+
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11+
;;;; Lesser General Public License for more details.
12+
;;;; 
13+
;;;; You should have received a copy of the GNU Lesser General Public
14+
;;;; License along with this library; if not, write to the Free Software
15+
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16+
;;;; 
17+
;;;;
18+
;;;;
19+
;;;; Note that most of this file is a direct translation of the activitystreams
20+
;;;; vocabulary specification (esp. comments in type and property) which
21+
;;;; is under these terms:
22+
;;;;
23+
;;;;    Copyright ?? 2017 Activity Streams Working Group, IBM & W3C?? (MIT,
24+
;;;;    ERCIM, Keio, Beihang). W3C liability, trademark and permissive
25+
;;;;    document license rules apply.
26+
;;;;
27+
;;;; You should have received a copy of the Permissive Document License along
28+
;;;; with this library; if not, that document license is accessible online at:
29+
;;;; https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
30+
;;;;
31+
;;;; The origin document used to develop this can be found at:
32+
;;;; https://www.w3.org/TR/activitystreams-vocabulary
33+
34+
(define-module (activitystreams vocabulary)
35+
  #:use-module (activitystreams ontology)
36+
  #:use-module (activitystreams predicates)
37+
  #:use-module (ice-9 match)
38+
  #:use-module (jsonld json)
39+
  #:use-module (web uri)
40+
  #:export (activitystreams-ontology))
41+
42+
;; Core types
43+
44+
(define-public Object
45+
  (build-as-type
46+
    "Object"
47+
    #:comment
48+
    "Describes an object of any kind.  The Object type serves as the base type
49+
for most of the other kinds of objects defined in the Activity Vocabulary,
50+
including other Core types such as Activity, IntransitiveActivity, Collection
51+
and OrderedCollection."))
52+
53+
(define-public Link
54+
  (build-as-type
55+
    "Link"
56+
    #:comment
57+
    "A Link is an indirect, qualified reference to a resource identified by a
58+
URL.  The fundamental model for links is established by [RFC5988].  Many of the
59+
properties defined by the Activity Vocabulary allow values that are either
60+
instances of Object or Link.  When a Link is used, it establishes a qualified
61+
relation connecting the subject (the containing object) to the resource
62+
identified by the href.  Properties of the Link are properties of the
63+
reference as opposed to properties of the resource."))
64+
65+
(define-public Activity
66+
  (build-as-type
67+
    "Activity"
68+
    #:subclass-of (list Object)
69+
    #:comment
70+
    "An Activity is a subtype of Object that describes some form of action that
71+
may happen, is currently happening, or has already happened.  The Activity type
72+
itself serves as an abstract base type for all types of activities.  It is
73+
important to note that the Activity type itself does not carry any specific
74+
semantics about the kind of action being taken."))
75+
76+
(define-public IntransitiveActivity
77+
  (build-as-type
78+
    "IntrasitiveActivity"
79+
    #:subclass-of (list Activity)
80+
    #:comment
81+
    "Instances of IntransitiveActivity are a subtype of Activity representing
82+
intransitive actions.  The object property is therefore inappropriate for
83+
these activities."))
84+
85+
(define-public Collection
86+
  (build-as-type
87+
    "Collection"
88+
    #:subclass-of (list Object)
89+
    #:comment
90+
    "A Collection is a subtype of Object that represents ordered or unordered
91+
sets of Object or Link instances.  Refer to the Activity Streams 2.0 Core
92+
specification for a complete description of the Collection type."))
93+
94+
(define-public OrderedCollection
95+
  (build-as-type
96+
    "OrderedCollection"
97+
    #:subclass-of (list Collection)
98+
    #:comment
99+
    "A subtype of Collection in which members of the logical collection are
100+
assumed to always be strictly ordered."))
101+
102+
(define-public CollectionPage
103+
  (build-as-type
104+
    "CollectionPage"
105+
    #:subclass-of (list Collection)
106+
    #:comment
107+
    "Used to represent distinct subsets of items from a Collection.  Refer to
108+
the Activity Streams 2.0 Core for a complete description of the CollectionPage
109+
object."))
110+
111+
(define-public OrderedCollectionPage
112+
  (build-as-type
113+
    "OrderedCollectionPage"
114+
    #:subclass-of (list OrderedCollection CollectionPage)
115+
    #:comment
116+
    "Used to represent ordered subsets of items from an OrderedCollection.
117+
Refer to the Activity Streams 2.0 Core for a complete description of the
118+
OrderedCollectionPage object."))
119+
120+
(define as-core-types (list Object Link Activity IntransitiveActivity
121+
                            Collection OrderedCollection CollectionPage
122+
                            OrderedCollectionPage))
123+
124+
;; Extended Types
125+
;; Activity Types
126+
127+
(define-public Accept
128+
  (build-as-type
129+
    "Accept"
130+
    #:subclass-of (list Activity)
131+
    #:comment
132+
    "Indicates that the actor accepts the object.  The target property can be
133+
used in certain circumstances to indicate the context into which the object has
134+
been accepted."))
135+
136+
(define-public TentativeAccept
137+
  (build-as-type
138+
    "TentativeAccept"
139+
    #:subclass-of (list Accept)
140+
    #:comment
141+
    "A specialization of Accept indicating that the acceptance is tentative."))
142+
143+
(define-public Add
144+
  (build-as-type
145+
    "Add"
146+
    #:subclass-of (list Activity)
147+
    #:comment
148+
    "Indicates that the actor has added the object to the target.  If the target
149+
property is not explicitly specified, the target would need to be determined
150+
implicitly by context.  The origin can be used to identify the context from
151+
which the object originated."))
152+
153+
(define-public Arrive
154+
  (build-as-type
155+
    "Arrive"
156+
    #:subclass-of (list IntransitiveActivity)
157+
    #:comment
158+
    "An IntransitiveActivity that indicates that the actor has arrived at the
159+
location.  The origin can be used to identify the context from which the actor
160+
originated.  The target typically has no defined meaning."))
161+
162+
(define-public Create
163+
  (build-as-type
164+
    "Create"
165+
    #:subclass-of (list Activity)
166+
    #:comment
167+
    "Indicates that the actor has created the object."))
168+
169+
(define-public Delete
170+
  (build-as-type
171+
    "Delete"
172+
    #:subclass-of (list Activity)
173+
    #:comment
174+
    "Indicates that the actor has deleted the object.  If specified, the origin
175+
indicates the context from which the object was deleted."))
176+
177+
(define-public Follow
178+
  (build-as-type
179+
    "Follow"
180+
    #:subclass-of (list Activity)
181+
    #:comment
182+
    "Indicates that the actor is ``following'' the object.  Following is defined
183+
in the sense typically used within Social systems in which the actor is
184+
interested in any activity performed by or on the object.  The target and
185+
origin typically have no defined meaning."))
186+
187+
(define-public Ignore
188+
  (build-as-type
189+
    "Ignore"
190+
    #:subclass-of (list Activity)
191+
    #:comment
192+
    "Indicates that the actor is ignoring the object.  The target and origin
193+
typically have no defined meaning."))
194+
195+
(define-public Join
196+
  (build-as-type
197+
    "Join"
198+
    #:subclass-of (list Activity)
199+
    #:comment
200+
    "Indicates that the actor has joined the object.  The target and origin
201+
typically have no defined meaning."))
202+
203+
(define-public Leave
204+
  (build-as-type
205+
    "Leave"
206+
    #:subclass-of (list Activity)
207+
    #:comment
208+
    "Indicates that the actor has left the object.  The target and origin
209+
typically have no meaning."))
210+
211+
(define-public Like
212+
  (build-as-type
213+
    "Like"
214+
    #:subclass-of (list Activity)
215+
    #:comment
216+
    "Indicates that the actor likes, recommends or endorses the object.  The
217+
target and origin typically have no defined meaning."))
218+
219+
(define-public Offer
220+
  (build-as-type
221+
    "Offer"
222+
    #:subclass-of (list Activity)
223+
    #:comment
224+
    "Indicates that the actor is offering the object.  If specified, the target
225+
indicates the entity to which the object is being offered."))
226+
227+
(define-public Invite
228+
  (build-as-type
229+
    "Invite"
230+
    #:subclass-of (list Offer)
231+
    #:comment
232+
    "A specialization of Offer in which the actor is extending an invitation
233+
for the object to the target."))
234+
235+
(define-public Reject
236+
  (build-as-type
237+
    "Reject"
238+
    #:subclass-of (list Activity)
239+
    #:comment
240+
    "Indicates that the actor is rejecting the object.  The target and origin
241+
typically have no defined meaning."))
242+
243+
(define-public TentativeReject
244+
  (build-as-type
245+
    "TentativeReject"
246+
    #:subclass-of (list Reject)
247+
    #:comment
248+
    "A specialization of Reject in which the rejection is considered tentative."))
249+
250+
(define-public Remove
251+
  (build-as-type
252+
    "Remove"
253+
    #:subclass-of (list Activity)
254+
    #:comment
255+
    "Indicates that the actor is removing the object.  If specified, the
256+
origin indicates the context from which the object is being removed."))
257+
258+
(define-public Undo
259+
  (build-as-type
260+
    "Undo"
261+
    #:subclass-of (list Activity)
262+
    #:comment
263+
    "Indicates that the actor is undoing the object.  In most cases, the object
264+
will be an Activity describing some previously performed action (for instance,
265+
a person may have previously ``liked'' an article but, for whatever reason,
266+
might choose to undo that like at some later point in time).  The target and
267+
origin typically have no defined meaning."))
268+
269+
(define-public Update
270+
  (build-as-type
271+
    "Update"
272+
    #:subclass-of (list Activity)
273+
    #:comment
274+
    "Indicates that the actor has updated the object.  Note, however, that this
275+
vocabulary does not define a mechanism for describing the actual set of
276+
modifications made to object.  The target and origin typically have no defined
277+
meaning."))
278+
279+
(define-public View
280+
  (build-as-type
281+
    "View"
282+
    #:subclass-of (list Activity)
283+
    #:comment
284+
    "Indicates that the actor has viewed the object."))
285+
286+
(define-public Listen
287+
  (build-as-type
288+
    "Listen"
289+
    #:subclass-of (list Activity)
290+
    #:comment
291+
    "Indicates that the actor has listened to the object."))
292+
293+
(define-public Read
294+
  (build-as-type
295+
    "Read"
296+
    #:subclass-of (list Activity)
297+
    #:comment
298+
    "Indicates that the actor has read the object."))
299+
300+
(define-public Move
301+
  (build-as-type
302+
    "Move"
303+
    #:subclass-of (list Activity)
304+
    #:comment
305+
    "Indicates that the actor has moved object from origin to target.  If the
306+
origin or target are not specified, either can be determined by context."))
307+
308+
(define-public Travel
309+
  (build-as-type
310+
    "Travel"
311+
    #:subclass-of (list IntransitiveActivity)
312+
    #:comment
313+
    "Indicates that the actor is traveling to target from origin.  Travel is
314+
an IntransitiveObject whose actor specifies the direct object.  If the target
315+
or origin are not specified, either can be determined by context."))
316+
317+
(define-public Announce
318+
  (build-as-type
319+
    "Announce"
320+
    #:subclass-of (list Activity)
321+
    #:comment
322+
    "Indicates that the actor is calling the target's attention the object.  The
323+
origin typically has no defined meaning."))
324+
325+
(define-public Block
326+
  (build-as-type
327+
    "Block"
328+
    #:subclass-of (list Ignore)
329+
    #:comment
330+
    "Indicates that the actor is blocking the object.  Blocking is a stronger
331+
form of Ignore.  The typical use is to support social systems that allow one
332+
user to block activities or content of other users.  The target and origin
333+
typically have no defined meaning."))
334+
335+
(define-public Flag
336+
  (build-as-type
337+
    "Flag"
338+
    #:subclass-of (list Activity)
339+
    #:comment
340+
    "Indicates that the actor is ``flagging'' the object.  Flagging is defined
341+
in the sense common to many social platforms as reporting content as being
342+
inappropriate for any number of reasons."))
343+
344+
(define-public Dislike
345+
  (build-as-type
346+
    "Dislike"
347+
    #:subclass-of (list Activity)
348+
    #:comment
349+
    "Indicates that the actor dislikes the object."))
350+
351+
(define-public Question
352+
  (build-as-type
353+
    "Question"
354+
    #:subclass-of (list IntransitiveActivity)
355+
    #:comment
356+
    "Represents a question being asked.  Question objects are an extension of
357+
IntransitiveActivity.  That is, the Question object is an Activity, but the
358+
direct object is the question itself and therefore it would not contain an
359+
object property.  Either of the anyOf and oneOf properties MAY be used to
360+
express possible answers, but a Question object MUST NOT have both properties."))
361+
362+
(define as-activity-types
363+
  (list Accept Add Announce Arrive Block Create Delete
364+
        Dislike Flag Follow Ignore Invite Join Leave
365+
        Like Listen Move Offer Question Reject Read
366+
        Remove TentativeReject TentativeAccept Travel Undo
367+
        Update View))
368+
369+
;; Actor Types
370+
(define-public Application
371+
  (build-as-type
372+
    "Application"
373+
    #:subclass-of (list Object)
374+
    #:comment
375+
    "Describes a software application."))
376+
377+
(define-public Group
378+
  (build-as-type
379+
    "Group"
380+
    #:subclass-of (list Object)
381+
    #:comment
382+
    "Represents a formal or informal collective of Actors."))
383+
384+
(define-public Organisation
385+
  (build-as-type
386+
    "Organisation"
387+
    #:subclass-of (list Object)
388+
    #:comment
389+
    "Represents an organization."))
390+
391+
(define-public Person
392+
  (build-as-type
393+
    "Person"
394+
    #:subclass-of (list Object)
395+
    #:comment
396+
    "Represents an individual person."))
397+
398+
(define-public Service
399+
  (build-as-type
400+
    "Service"
401+
    #:subclass-of (list Object)
402+
    #:comment
403+
    "Represents a service of any kind."))
404+
405+
(define as-actor-types
406+
  (list Application Group Organisation Person Service))
407+
408+
;; 
409+
410+
(define-public Relationship
411+
  (build-as-type
412+
    "Relationship"
413+
    #:subclass-of (list Object)
414+
    #:comment
415+
    "Describes a relationship between two individuals.  The subject and object
416+
properties are used to identify the connected individuals.  See 5.2 Representing
417+
Relationships Between Entities for additional information."))
418+
419+
(define-public Article
420+
  (build-as-type
421+
    "Article"
422+
    #:subclass-of (list Object)
423+
    #:comment
424+
    "Represents any kind of multi-paragraph written work."))
425+
426+
(define-public Document
427+
  (build-as-type
428+
    "Document"
429+
    #:subclass-of (list Object)
430+
    #:comment
431+
    "Represents a document of any kind."))
432+
433+
(define-public Audio
434+
  (build-as-type
435+
    "Audio"
436+
    #:subclass-of (list Document)
437+
    #:comment
438+
    "Represents an audio document of any kind."))
439+
440+
(define-public Image
441+
  (build-as-type
442+
    "Image"
443+
    #:subclass-of (list Document)
444+
    #:comment
445+
    "An image document of any kind."))
446+
447+
(define-public Video
448+
  (build-as-type
449+
    "Video"
450+
    #:subclass-of (list Document)
451+
    #:comment
452+
    "Represents a video document of any kind."))
453+
454+
(define-public Note
455+
  (build-as-type
456+
    "Note"
457+
    #:subclass-of (list Object)
458+
    #:comment
459+
    "Represents a short written work typically less than a single paragraph in
460+
length."))
461+
462+
(define-public Page
463+
  (build-as-type
464+
    "Page"
465+
    #:subclass-of (list Document)
466+
    #:comment
467+
    "Represents a Web Page."))
468+
469+
(define-public Event
470+
  (build-as-type
471+
    "Event"
472+
    #:subclass-of (list Object)
473+
    #:comment
474+
    "Represents any kind of event."))
475+
476+
(define-public Place
477+
  (build-as-type
478+
    "Place"
479+
    #:subclass-of (list Object)
480+
    #:comment
481+
    "Represents a logical or physical location.  See 5.3 Representing Places
482+
for additional information."))
483+
484+
(define-public Mention
485+
  (build-as-type
486+
    "Mention"
487+
    #:subclass-of (list Link)
488+
    #:comment
489+
    "A specialized Link that represents an @mention."))
490+
491+
(define-public Profile
492+
  (build-as-type
493+
    "Profile"
494+
    #:subclass-of (list Object)
495+
    #:comment
496+
    "A Profile is a content object that describes another Object, typically
497+
used to describe Actor Type objects.  The describes property is used to
498+
reference the object being described by the profile"))
499+
500+
(define-public Tombstone
501+
  (build-as-type
502+
    "Tombstone"
503+
    #:subclass-of (list Object)
504+
    #:comment
505+
    "A Tombstone represents a content object that has been deleted.  It can be
506+
used in Collections to signify that there used to be an object at this
507+
position, but it has been deleted."))
508+
509+
(define as-object-and-link-types
510+
  (list Article Audio Document Event Image Note Page
511+
        Place Profile Relationship Tombstone Video Mention))
512+
513+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
514+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
515+
;;                                Properties                                 ;;
516+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
517+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
518+
519+
(define-public id
520+
  (build-as-property
521+
    "id" (list Object Link) uri?
522+
    #:uri "@id"
523+
    #:comment "Provides the globally unique identifier for an Object or Link."
524+
    #:functional? #t))
525+
526+
(define-public type
527+
  (build-as-property
528+
    "type" (list Object Link) uri?
529+
    #:uri "@type"
530+
    #:comment "Identifies the Object or Link type.  Multiple values may be
531+
specified."))
532+
533+
(define-public attributedTo
534+
  (build-as-property
535+
    "attributedTo" (list Object Link) (list Object Link)
536+
    #:comment
537+
    "Identifies one or more entities to which this object is attributed.  The
538+
attributed entities might not be Actors.  For instance, an object might be
539+
attributed to the completion of another activity."))
540+
541+
(define-public actor
542+
  (build-as-property
543+
    "actor" (list Object Link) (list Object Link)
544+
    #:subproperty-of (list attributedTo)
545+
    #:comment
546+
    "Describes one or more entities that either performed or are expected to
547+
perform the activity.  Any single activity can have multiple actors.  The actor
548+
MAY be specified using an indirect Link."))
549+
550+
(define-public attachment
551+
  (build-as-property
552+
    "attachment" Object (list Object Link)
553+
    #:comment
554+
    "Identifies a resource attached or related to an object that potentially
555+
requires special handling.  The intent is to provide a model that is at least
556+
semantically similar to attachments in email."))
557+
558+
(define-public audience
559+
  (build-as-property
560+
    "audience" Object (list Object Link)
561+
    #:comment
562+
    "Identifies one or more entities that represent the total population of
563+
entities for which the object can considered to be relevant."))
564+
565+
(define-public bcc
566+
  (build-as-property
567+
    "bcc" Object (list Object Link)
568+
    #:comment
569+
    "Identifies one or more Objects that are part of the private secondary
570+
audience of this Object."))
571+
572+
(define-public bto
573+
  (build-as-property
574+
    "bto" Object (list Object Link)
575+
    #:comment
576+
    "Identifies an Object that is part of the private primary audience of this
577+
Object."))
578+
579+
(define-public cc
580+
  (build-as-property
581+
    "cc" Object (list Object Link)
582+
    #:comment
583+
    "Identifies an Object that is part of the public secondary audience of
584+
this Object."))
585+
586+
(define-public context
587+
  (build-as-property
588+
    "context" Object (list Object Link)
589+
    #:comment
590+
    "Identifies the context within which the object exists or an activity was
591+
performed.  The notion of ``context'' used is intentionally vague.  The
592+
intended function is to serve as a means of grouping objects and activities
593+
that share a common originating context or purpose.  An example could be all
594+
activities relating to a common project or event."))
595+
596+
(define-public current
597+
  (build-as-property
598+
    "current" Collection (list CollectionPage Link)
599+
    #:functional? #t
600+
    #:comment
601+
    "In a paged Collection, indicates the page that contains the most recently
602+
updated member items."))
603+
604+
(define-public first
605+
  (build-as-property
606+
    "first" Collection (list CollectionPage Link)
607+
    #:functional? #t
608+
    #:comment
609+
    "In a paged Collection, indicates the furthest preceeding page of items in
610+
the collection."))
611+
612+
(define-public generator
613+
  (build-as-property
614+
    "generator" Object (list Object Link)
615+
    #:comment
616+
    "Identifies the entity (e.g. an application) that generated the object."))
617+
618+
(define-public icon
619+
  (build-as-property
620+
    "icon" Object (list Image Link)
621+
    #:comment
622+
    "Indicates an entity that describes an icon for this object.  The image
623+
should have an aspect ratio of one (horizontal) to one (vertical) and should
624+
be suitable for presentation at a small size."))
625+
626+
(define-public image
627+
  (build-as-property
628+
    "image" Object (list Image Link)
629+
    #:comment
630+
    "Indicates an entity that describes an image for this object.  Unlike the
631+
icon property, there are no aspect ratio or display size limitations assumed."))
632+
633+
(define-public inReplyTo
634+
  (build-as-property
635+
    "inReplyTo" Object (list Object Link)
636+
    #:comment
637+
    "Indicates one or more entities for which this object is considered a
638+
response."))
639+
640+
(define-public instrument
641+
  (build-as-property
642+
    "instrument" Activity (list Object Link)
643+
    #:comment
644+
    "Identifies one or more objects used (or to be used) in the completion of
645+
an Activity."))
646+
647+
(define-public last
648+
  (build-as-property
649+
    "last" Collection (list CollectionPage Link)
650+
    #:functional? #t
651+
    #:comment
652+
    ""))
653+
654+
(define-public location
655+
  (build-as-property
656+
    "location" Object (list Object Link)
657+
    #:comment
658+
    "Indicates one or more physical or logical locations associated with the
659+
object."))
660+
661+
(define-public items
662+
  (build-as-property
663+
    "items" Collection (list Object Link)
664+
    #:comment
665+
    "Identifies the items contained in a collection. The items might be ordered
666+
or unordered."))
667+
668+
(define-public oneOf
669+
  (build-as-property
670+
    "oneOf" Question (list Object Link)
671+
    #:comment
672+
    "Identifies an exclusive option for a Question.  Use of oneOf implies that
673+
the Question can have only a single answer.  To indicate that a Question can
674+
have multiple answers, use anyOf."))
675+
676+
(define-public anyOf
677+
  (build-as-property
678+
    "anyOf" Question (list Object Link)
679+
    #:comment
680+
    "Identifies an inclusive option for a Question.  Use of anyOf implies that
681+
the Question can have multiple answers.  To indicate that a Question can have
682+
only one answer, use oneOf."))
683+
684+
(define-public closed
685+
  (build-as-property
686+
    "closed" Question (list Object Link date? boolean?)
687+
    #:comment
688+
    "Indicates that a question has been closed, and answers are no longer
689+
accepted."))
690+
691+
(define-public origin
692+
  (build-as-property
693+
    "origin" Activity (list Object Link)
694+
    #:comment
695+
    "Describes an indirect object of the activity from which the activity is
696+
directed.  The precise meaning of the origin is the object of the English
697+
preposition ``from''.  For instance, in the activity ``John moved an item to
698+
List B from List A'', the origin of the activity is ``List A''."))
699+
700+
(define-public next
701+
  (build-as-property
702+
    "next" CollectionPage (list CollectionPage Link)
703+
    #:functional? #t
704+
    #:comment
705+
    "In a paged Collection, indicates the next page of items."))
706+
707+
(define-public object
708+
  (build-as-property
709+
    "object" (list Activity Relationship) (list Object Link)
710+
    #:comment
711+
    "When used within an Activity, describes the direct object of the activity.
712+
For instance, in the activity ``John added a movie to his wishlist'', the
713+
object of the activity is the movie added.  When used within a Relationship
714+
describes the entity to which the subject is related."))
715+
716+
(define-public prev
717+
  (build-as-property
718+
    "prev" CollectionPage (list CollectionPage Link)
719+
    #:functional? #t
720+
    #:comment
721+
    "In a paged Collection, identifies the previous page of items."))
722+
723+
(define-public preview
724+
  (build-as-property
725+
    "preview" (list Object Link) (list Object Link)
726+
    #:comment
727+
    "Identifies an entity that provides a preview of this object."))
728+
729+
(define-public result
730+
  (build-as-property
731+
    "result" Activity (list Object Link)
732+
    #:comment
733+
    "Describes the result of the activity.  For instance, if a particular
734+
action results in the creation of a new resource, the result property can be
735+
used to describe that new resource."))
736+
737+
(define-public replies
738+
  (build-as-property
739+
    "replise" Object Collection
740+
    #:functional? #t
741+
    #:comment
742+
    "Identifies a Collection containing objects considered to be responses to
743+
this object."))
744+
745+
(define-public tag
746+
  (build-as-property
747+
    "tag" Object (list Object Link)
748+
    #:comment
749+
    "One or more ``tags'' that have been associated with an object.  A tag can
750+
be any kind of Object.  The key difference between attachment and tag is that
751+
the former implies association by inclusion, while the latter implies
752+
associated by reference."))
753+
754+
(define-public target
755+
  (build-as-property
756+
    "target" Activity (list Object Link)
757+
    #:comment
758+
    "Describes the indirect object, or target, of the activity.  The precise
759+
meaning of the target is largely dependent on the type of action being
760+
described but will often be the object of the English preposition ``to''.  For
761+
instance, in the activity ``John added a movie to his wishlist'', the target
762+
of the activity is John's wishlist. An activity can have more than one target."))
763+
764+
(define-public to
765+
  (build-as-property
766+
    "to" Object (list Object Link)
767+
    #:comment
768+
    "Identifies an entity considered to be part of the public primary audience
769+
of an Object."))
770+
771+
(define-public url
772+
  (build-as-property
773+
    "url" Object (list uri? Link)
774+
    #:comment
775+
    "Identifies one or more links to representations of the object."))
776+
777+
(define-public accuracy
778+
  (build-as-property
779+
    "accuracy" Place float?
780+
    #:comment
781+
    "Indicates the accuracy of position coordinates on a Place objects.
782+
Expressed in properties of percentage.  e.g. ``94.0'' means ``94.0% accurate''."))
783+
784+
(define-public altitude
785+
  (build-as-property
786+
    "altitude" Object float?
787+
    #:functional? #t
788+
    #:comment
789+
    "Indicates the altitude of a place.  The measurement units is indicated
790+
using the units property.  If units is not specified, the default is assumed
791+
to be ``m'' indicating meters."))
792+
793+
(define-public content
794+
  (build-as-property
795+
    "content" Object string-or-lang-string?
796+
    #:comment
797+
    "The content or textual representation of the Object encoded as a JSON
798+
string.  By default, the value of content is HTML.  The mediaType property can
799+
be used in the object to indicate a different content type.  The content MAY
800+
be expressed using multiple language-tagged values."))
801+
802+
(define-public name
803+
  (build-as-property
804+
    "name" (list Object Link) string-or-lang-string?
805+
    #:comment
806+
    "A simple, human-readable, plain-text name for the object.  HTML markup
807+
MUST NOT be included.  The name MAY be expressed using multiple language-tagged
808+
values."))
809+
810+
(define-public duration
811+
  (build-as-property
812+
    "duration" Object duration?
813+
    #:functional? #t
814+
    #:comment
815+
    "When the object describes a time-bound resource, such as an audio or video,
816+
a meeting, etc, the duration property indicates the object's approximate
817+
duration.  The value MUST be expressed as an xsd:duration as defined by
818+
[xmlschema11-2], section 3.3.6 (e.g. a period of 5 seconds is represented as
819+
``PT5S'')."))
820+
821+
(define-public height
822+
  (build-as-property
823+
    "height" Link non-negative-integer?
824+
    #:functional? #t
825+
    #:comment
826+
    "On a Link, specifies a hint as to the rendering height in device-independent
827+
pixels of the linked resource."))
828+
829+
(define-public href
830+
  (build-as-property
831+
    "href" Link uri?
832+
    #:functional? #t
833+
    #:comment
834+
    "The target resource pointed to by a Link."))
835+
836+
(define-public hreflang
837+
  (build-as-property
838+
    "hreflang" Link langtag?
839+
    #:functional? #t
840+
    #:comment
841+
    "Hints as to the language used by the target resource.  Value MUST be a
842+
[BCP47] Language-Tag."))
843+
844+
(define-public partOf
845+
  (build-as-property
846+
    "partOf" CollectionPage (list Collection Link)
847+
    #:functional? #t
848+
    #:comment
849+
    "Identifies the Collection to which a CollectionPage objects items belong."))
850+
851+
(define-public latitude
852+
  (build-as-property
853+
    "latitude" Place float?
854+
    #:functional? #t
855+
    #:comment
856+
    "The latitude of a place."))
857+
858+
(define-public longitude
859+
  (build-as-property
860+
    "longitude" Place float?
861+
    #:functional? #t
862+
    #:comment
863+
    "The longitude of a place."))
864+
865+
(define-public mediaType
866+
  (build-as-property
867+
    "mediaType" (list Link Object) mime-type?
868+
    #:functional? #t
869+
    #:comment
870+
    "When used on a Link, identifies the MIME media type of the referenced
871+
resource.  When used on an Object, identifies the MIME media type of the value
872+
of the content property.  If not specified, the content property is assumed to
873+
contain text/html content."))
874+
875+
(define-public endTime
876+
  (build-as-property
877+
    "endTime" Object date?
878+
    #:functional? #t
879+
    #:comment
880+
    "The date and time describing the actual or expected ending time of the
881+
object.  When used with an Activity object, for instance, the endTime property
882+
specifies the moment the activity concluded or is expected to conclude."))
883+
884+
(define-public published
885+
  (build-as-property
886+
    "published" Object date?
887+
    #:functional? #t
888+
    #:comment
889+
    "The date and time at which the object was published."))
890+
891+
(define-public startTime
892+
  (build-as-property
893+
    "startTime" Object date?
894+
    #:functional? #t
895+
    #:comment
896+
    "The date and time describing the actual or expected starting time of the
897+
object.  When used with an Activity object, for instance, the startTime
898+
property specifies the moment the activity began or is scheduled to begin."))
899+
900+
(define-public radius
901+
  (build-as-property
902+
    "radius" Place float?
903+
    #:functional? #t
904+
    #:comment
905+
    "The radius from the given latitude and longitude for a Place.  The units
906+
is expressed by the units property.  If units is not specified, the default is
907+
assumed to be ``m'' indicating ``meters''."))
908+
909+
(define-public rel
910+
  (build-as-property
911+
    "rel" Link link-relation?
912+
    #:comment
913+
    "A link relation associated with a Link.  The value MUST conform to both the
914+
[HTML5] and [RFC5988] ``link relation'' definitions.  In the [HTML5], any
915+
string not containing the ``space'' U+0020, ``tab'' (U+0009), ``LF'' (U+000A),
916+
``FF'' (U+000C), ``CR'' (U+000D) or ``,'' (U+002C) characters can be used as a
917+
valid link relation."))
918+
919+
(define-public startIndex
920+
  (build-as-property
921+
    "startIndex" OrderedCollectionPage non-negative-integer?
922+
    #:functional? #t
923+
    #:comment
924+
    "A non-negative integer value identifying the relative position within the
925+
logical view of a strictly ordered collection."))
926+
927+
(define-public summary
928+
  (build-as-property
929+
    "summary" Object string-or-lang-string?
930+
    #:comment
931+
    "A natural language summarization of the object encoded as HTML.  Multiple
932+
language tagged summaries MAY be provided."))
933+
934+
(define-public totalItems
935+
  (build-as-property
936+
    "totalItems" Collection non-negative-integer?
937+
    #:functional? #t
938+
    #:comment
939+
    "A non-negative integer specifying the total number of objects contained by
940+
the logical view of the collection.  This number might not reflect the actual
941+
number of items serialized within the Collection object instance."))
942+
943+
(define-public units
944+
  (build-as-property
945+
    "units" Place (list uri? (lambda (s) (member s '("cm" "feet" "inches" "km"
946+
                                                     "m" "miles"))))
947+
    #:functional? #t
948+
    #:comment
949+
    "Specifies the measurement units for the radius and altitude properties on
950+
a Place object.  If not specified, the default is assumed to be ``m'' for
951+
``meters''."))
952+
953+
(define-public updated
954+
  (build-as-property
955+
    "updated" Object date?
956+
    #:functional? #t
957+
    #:comment
958+
    "The date and time at which the object was updated."))
959+
960+
(define-public width
961+
  (build-as-property
962+
    "width" Link non-negative-integer?
963+
    #:functional? #t
964+
    #:comment
965+
    "On a Link, specifies a hint as to the rendering width in device-independent
966+
pixels of the linked resource."))
967+
968+
(define-public subject
969+
  (build-as-property
970+
    "subject" Relationship (list Object Link)
971+
    #:functional? #t
972+
    #:comment
973+
    "On a Relationship object, the subject property identifies one of the
974+
connected individuals.  For instance, for a Relationship object describing
975+
``John is related to Sally'', subject would refer to John."))
976+
977+
(define-public relationship
978+
  (build-as-property
979+
    "relationship" Relationship Object
980+
    #:comment
981+
    "On a Relationship object, the relationship property identifies the kind of
982+
relationship that exists between subject and object."))
983+
984+
(define-public describes
985+
  (build-as-property
986+
    "describes" Profile Object
987+
    #:functional? #t
988+
    #:comment
989+
    "On a Profile object, the describes property identifies the object described
990+
by the Profile."))
991+
992+
(define-public formerType
993+
  (build-as-property
994+
    "formerType" Tombstone Object
995+
    #:comment
996+
    "On a Tombstone object, the formerType property identifies the type of the
997+
object that was deleted."))
998+
999+
(define-public deleted
1000+
  (build-as-property
1001+
    "deleted" Tombstone date?
1002+
    #:functional? #t
1003+
    #:comment
1004+
    "On a Tombstone object, the deleted property is a timestamp for when the
1005+
object was deleted."))
1006+
1007+
(define as-properties
1008+
  (list actor attachment attributedTo audience bcc bto
1009+
        cc context current first generator icon id
1010+
        image inReplyTo instrument last location items
1011+
        oneOf anyOf closed origin next object prev
1012+
        preview result replies tag target to type
1013+
        url accuracy altitude content name duration
1014+
        height href hreflang partOf latitude longitude
1015+
        mediaType endTime published startTime radius
1016+
        rel startIndex summary totalItems units updated
1017+
        width subject relationship describes formerType
1018+
        deleted))
1019+
1020+
(define activitystreams-ontology
1021+
  (make-ontology
1022+
    '("https://www.w3.org/ns/activitystreams")
1023+
    (append as-core-types as-activity-types as-actor-types as-object-and-link-types)
1024+
    as-properties))
1025+

guix.scm

2323
  (guix packages)
2424
  (guix utils)
2525
  (gnu packages autotools)
26+
  (gnu packages gnupg)
2627
  (gnu packages guile)
2728
  (gnu packages pkg-config)
28-
  (gnu packages texinfo))
29+
  (gnu packages texinfo)
30+
  (gnu packages tls))
2931
30-
(define-public guile-jsonld
32+
(define guile3.0-rdf
33+
  (package
34+
    (name "guile-rdf")
35+
    (version "1.0")
36+
    (source
37+
      (origin
38+
        (method git-fetch)
39+
        (uri (git-reference
40+
               (url "https://framagit.org/tyreunom/guile-rdf")
41+
               (commit "382d5dcb66fbf770445f329fc3db3fa789b45867")))
42+
        (file-name (git-file-name name version))
43+
        (sha256
44+
         (base32
45+
          "1gjhrgqbsf1nhvmrz2fy9a4351yiyxb4kl81hc0bqilacnqr5p7g"))))
46+
    (build-system gnu-build-system)
47+
    (arguments
48+
     `(#:tests? #f)); require network
49+
    (inputs
50+
     `(("guile" ,guile-next)))
51+
    (native-inputs
52+
     `(("automake" ,automake)
53+
       ("autoconf" ,autoconf)
54+
       ("pkg-config" ,pkg-config)
55+
       ("texinfo" ,texinfo)))
56+
    (home-page "https://framagit.org/tyreunom/guile-rdf")
57+
    (synopsis "Guile implementation of the RDF abstract syntax and the Turtle syntax")
58+
    (description "Resource Description Framework (RDF) is a general-purpose
59+
language for representing information in the Web.  Multiple languages can be
60+
used to represent RDF data, turtle is one of them.")
61+
    (license license:gpl3+)))
62+
63+
(define-public guile3.0-jsonld
3164
  (package
3265
    (name "guile-jsonld")
33-
    (version "0.1.0")
66+
    (version "1.0.0")
3467
    (source
3568
      (origin
3669
        (method git-fetch)
3770
        (uri (git-reference
3871
               (url "https://framagit.org/tyreunom/guile-jsonld")
39-
               (commit "b6cf6ab99a398828943b7034191f2e8ed67b26f9")))
72+
               (commit version)))
4073
        (file-name (git-file-name name version))
4174
        (sha256
4275
         (base32
43-
          "1j3q0ysi8cyv07zp6adkpn9kyhdxdfds417ifickv304b9cxk873"))))
76+
          "0jd08kx0ipl3ad89r0h9fhim6ch8pw4n6fv9rka1zmv70r0n1b58"))))
4477
    (build-system gnu-build-system)
4578
    (arguments
46-
     `(#:tests? #f))
79+
     `(#:tests? #f)); require network
4780
    (inputs
48-
     `(("guile" ,guile-2.2)
49-
       ("guile-json" ,guile-json-3)))
81+
     `(("guile" ,guile-next)))
82+
    (propagated-inputs
83+
     `(("guile-gnutls" ,guile3.0-gnutls)
84+
       ("guile-json" ,guile3.0-json)
85+
       ("guile-rdf" ,guile3.0-rdf)))
5086
    (native-inputs
5187
     `(("automake" ,automake)
5288
       ("autoconf" ,autoconf)
5389
       ("pkg-config" ,pkg-config)
5490
       ("texinfo" ,texinfo)))
5591
    (home-page "https://framagit.org/tyreunom/guile-jsonld")
56-
    (synopsis "Implementation of the Json Linked-Data algorithms")
57-
    (description "")
58-
    (license license:lgpl3+)))
92+
    (synopsis "Guile implementation of the JsonLD API specification")
93+
    (description "Guile JsonLD is an implementation of the JsonLD API defined
94+
by the W3C for GNU Guile.  JsonLD stands for Json for Linked Data.  Linked Data
95+
is a representation for the semantic web.  It allows you to express links
96+
between data, in a way that is very similar to WikiData for instance.  An object
97+
can have relations (in the form of an IRI) that relates it to one or more objects
98+
or strings, represented by a Json object or an IRI.")
99+
    (license license:gpl3+)))
59100
60101
(package
61102
  (name "guile-fediverse")

…

72113
        "00l03j8ajkd1a7sg1zycbpdaz71mscrncw7rwjzqk2ia6j04rwxm"))))
73114
  (build-system gnu-build-system)
74115
  (inputs
75-
   `(("guile" ,guile-2.2)
76-
     ("guile-json" ,guile-json-3)
77-
     ("guile-jsonld" ,guile-jsonld)))
116+
   `(("guile" ,guile-next)
117+
     ("guile-json" ,guile3.0-json)
118+
     ("guile-jsonld" ,guile3.0-jsonld)
119+
     ("guile-gcrypt" ,guile3.0-gcrypt)))
78120
  (native-inputs
79121
   `(("automake" ,automake)
80122
     ("autoconf" ,autoconf)

http-signature/crypto.scm unknown status 1

1+
;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu>
2+
;;;; 
3+
;;;; This library is free software; you can redistribute it and/or
4+
;;;; modify it under the terms of the GNU Lesser General Public
5+
;;;; License as published by the Free Software Foundation; either
6+
;;;; version 3 of the License, or (at your option) any later version.
7+
;;;; 
8+
;;;; This library is distributed in the hope that it will be useful,
9+
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11+
;;;; Lesser General Public License for more details.
12+
;;;; 
13+
;;;; You should have received a copy of the GNU Lesser General Public
14+
;;;; License along with this library; if not, write to the Free Software
15+
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16+
;;;; 
17+
18+
(define-module (http-signature crypto)
19+
  #:use-module (gcrypt base64)
20+
  #:use-module (gcrypt pk-crypto)
21+
  #:use-module (ice-9 match)
22+
  #:use-module (srfi srfi-1)
23+
  #:use-module (srfi srfi-9)
24+
  #:use-module (rnrs bytevectors)
25+
  #:export (;; this file provides some functions to deal with asn.1, der and pem.
26+
            asn.1?
27+
            make-asn.1
28+
            asn.1-type
29+
            asn.1-len
30+
            asn.1-val
31+
32+
            asn.1-compute-len
33+
            asn.1->bv
34+
            ;; this file also provides higher-level functions that produce
35+
            ;; pem-encoded strings from gcrypt keys.
36+
            pem-encode-public))
37+
38+
(define-record-type asn.1
39+
  (make-asn.1 type len val)
40+
  asn.1?
41+
  (type asn.1-type)
42+
  (len  asn.1-len)
43+
  (val  asn.1-val))
44+
45+
(define (asn.1-compute-len asn)
46+
  "Computes the length of values in an asn.1 record.  Return that record, where
47+
lengths are updated."
48+
  (match asn
49+
    (($ asn.1 type len val)
50+
     (match type
51+
       ('bool
52+
        (match val
53+
          ((? boolean? val)
54+
           (make-asn.1 type 1 val))))
55+
       ('int
56+
        (match val
57+
         ((? bytevector? val)
58+
          (make-asn.1 type (bytevector-length val) val))))
59+
       ('null
60+
        (make-asn.1 type 0 val))
61+
       ('sequence
62+
        (let ((nval (map asn.1-compute-len val)))
63+
          (make-asn.1 type (fold + 0 (map asn.1-full-length nval)) nval)))))))
64+
65+
(define (asn.1-full-length asn)
66+
  "Compute the length of an asn.1 record, including the length of its length
67+
field."
68+
  (match asn
69+
    (($ asn.1 type len val)
70+
     (+ len 1 1 (if (> len 127) (nbits len) 0)))))
71+
72+
(define (nbits len)
73+
  (if (< len 256) 1 (+ 1 (nbits (quotient len 256)))))
74+
75+
(define (asn.1->bv asn)
76+
  "Take an asn.1 where lengths are computed and returns a bytevector that
77+
corresponds to the DER encoding of that content."
78+
  (let ((bv (make-bytevector (asn.1-full-length asn))))
79+
    (match asn
80+
      (($ asn.1 type len val)
81+
       (let ((val-pos (if (> len 127) (+ 2 (nbits len)) 2)))
82+
         (bytevector-u8-set! bv 1 (if (> len 127) (+ 128 (nbits len)) len))
83+
         (when (> len 127)
84+
           (let loop ((val len) (pos (- val-pos 1)))
85+
             (when (> val 0)
86+
               (bytevector-u8-set! bv pos (modulo val 256))
87+
               (loop (quotient val 256) (- pos 1)))))
88+
         (match type
89+
           ('bool
90+
            (begin
91+
              (bytevector-u8-set! bv 0 #x01)
92+
              (bytevector-u8-set! bv val-pos (if val 255 0))))
93+
           ('int
94+
            (begin
95+
              (bytevector-u8-set! bv 0 #x02)
96+
              (bytevector-copy! val 0 bv val-pos (bytevector-length val))))
97+
           ('null
98+
            (bytevector-u8-set! bv 0 #x05))
99+
           ('sequence
100+
            (begin
101+
              (bytevector-u8-set! bv 0 #x30)
102+
              (let loop ((val (map asn.1->bv val)) (pos val-pos))
103+
                (when (not (null? val))
104+
                  (bytevector-copy! (car val) 0 bv pos (bytevector-length (car val)))
105+
                  (loop (cdr val) (+ pos (bytevector-length (car val))))))))))))
106+
    bv))
107+
108+
(define (asn.1->string asn)
109+
  "Return the PEM-encoded representation of the @var{asn} record."
110+
  (base64-encode (asn.1->bv asn)))
111+
112+
(define (public-key->pkcs1-asn.1 pk)
113+
  "Return the ASN.1 representation of @var{pk}, an RSA public key, using the
114+
PKCS#1 representation."
115+
  (asn.1-compute-len
116+
    (match (canonical-sexp->sexp pk)
117+
      (('public-key ('rsa ('n n) ('e e)))
118+
       (make-asn.1
119+
         'sequence #f
120+
         (list
121+
           (make-asn.1 'int #f n)
122+
           (make-asn.1 'int #f e))))))))
123+
124+
(define (public-key->pkcs8-asn.1 pk)
125+
  "Return the ASN.1 representation of @var{pk}, a public key, using the PKCS#8
126+
representation.  Currently only RSA keys can be transformed."
127+
  (asn.1-compute-len
128+
    (match (canonical-sexp->sexp pk)
129+
      (('public-key ('rsa ('n n) ('e e)))
130+
       (make-asn.1
131+
         'sequence #f
132+
         (list
133+
           (make-asn.1)
134+
           (make-asn.1))))))
135+
136+
(define (cut-str str n)
137+
  "Cut a string @var{str} at @var{n} characters by placing a @code{\\n}, so that
138+
the string is aligned to @var{n} characters."
139+
  (let loop ((str str))
140+
    (if (< (string-length str) (+ n 1))
141+
        str
142+
        (string-append
143+
          (substring str 0 n)
144+
          "\n"
145+
          (loop (substring str n))))))
146+
147+
(define (pem-encode-public keypair)
148+
  "Return the PEM-encoded version of the public key in @var{keypair}, an RSA
149+
keypair."
150+
  (let* ((public (find-sexp-token keypair 'public-key))
151+
         (asn (public-key->pkcs1-asn.1 public)))
152+
    (string-append
153+
      "-----BEGIN RSA PUBLIC KEY-----\n"
154+
      (cut-str (asn.1->string asn) 64)
155+
      "\n-----END RSA PUBLIC KEY-----")))

http-signature/ontology.scm unknown status 2

1-
;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu>
2-
;;;; 
3-
;;;; This library is free software; you can redistribute it and/or
4-
;;;; modify it under the terms of the GNU Lesser General Public
5-
;;;; License as published by the Free Software Foundation; either
6-
;;;; version 3 of the License, or (at your option) any later version.
7-
;;;; 
8-
;;;; This library is distributed in the hope that it will be useful,
9-
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
10-
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11-
;;;; Lesser General Public License for more details.
12-
;;;; 
13-
;;;; You should have received a copy of the GNU Lesser General Public
14-
;;;; License along with this library; if not, write to the Free Software
15-
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16-
;;;; 
17-
18-
(define-module (http-signature ontology)
19-
  #:use-module (activitystreams activitystreams)
20-
  #:use-module (ice-9 match)
21-
  #:use-module (jsonld json)
22-
  #:use-module (web uri)
23-
  #:export (security-ontology))
24-
25-
(define sec:vocab "https://w3id.org/security#")
26-
27-
(define* (make-sec-type label #:key (uri (string-append sec:vocab label))
28-
                        (comment "") (subclass-of '()))
29-
  (make-as-type label #:uri uri #:comment comment #:subclass-of subclass-of))
30-
31-
(define* (make-sec-property label domain range
32-
                           #:key (uri (string-append sec:vocab label))
33-
                           (functional? #f) (subproperty-of '()) (comment ""))
34-
  (make-as-property label domain range #:uri uri #:functional? functional?
35-
                    #:subproperty-of subproperty-of #:comment comment))
36-
37-
(define date? (@@ (activitystreams ontology) date?))
38-
(define iri? (@@ (activitystreams ontology) iri?))
39-
40-
;; Classes
41-
42-
(define sec:Digest
43-
  (make-sec-type
44-
    "Digest"
45-
    #:comment
46-
    "This class represents a message digest that may be used for data integrity
47-
verification.  The digest algorithm used will determine the cryptographic
48-
properties of the digest."))
49-
50-
(define sec:EncryptedMessage
51-
  (make-sec-type
52-
    "EncryptedMessage"
53-
    #:comment
54-
    "A class of messages that are obfuscated in some cryptographic manner.
55-
These messages are incredibly difficult to decrypt without the proper
56-
decryption key."))
57-
58-
(define sec:Signature
59-
  (make-sec-type
60-
    "Signature"
61-
    #:comment
62-
    "This class represents a digital signature on serialized data.  It is an
63-
abstract class and should not be used other than for Semantic Web reasoning
64-
purposes, such as by a reasoning agent."))
65-
66-
(define sec:GraphSignature2012
67-
  (make-sec-type
68-
    "GraphSignature2012"
69-
    #:subclass-of (list sec:Signature)
70-
    #:comment
71-
    "A graph signature is used for digital signatures on RDF graphs.  The
72-
default canonicalization mechanism is specified in the RDF Graph normalization
73-
specification, which effectively deterministically names all unnamed nodes.
74-
The default signature mechanism uses a SHA-256 digest and RSA to perform the
75-
digital signature."))
76-
77-
(define sec:LinkedDataSignature2015
78-
  (make-sec-type
79-
    "LinkedDataSignature2015"
80-
    #:subclass-of (list sec:Signature)
81-
    #:comment
82-
    "A Linked Data signature is used for digital signatures on RDF Datasets.
83-
The default canonicalization mechanism is specified in the RDF Dataset
84-
Normalization specification, which effectively deterministically names all
85-
unnamed nodes.  The default signature mechanism uses a SHA-256 digest and RSA
86-
to perform the digital signature.  This signature uses a algorithm for
87-
producing the data that it signs and verifies that is different from other
88-
Linked Data signatures."))
89-
90-
(define sec:LinkedDataSignature2016
91-
  (make-sec-type
92-
    "LinkedDataSignature2016"
93-
    #:subclass-of (list sec:Signature)
94-
    #:comment
95-
    "A Linked Data signature is used for digital signatures on RDF Datasets.
96-
The default canonicalization mechanism is specified in the RDF Dataset
97-
Normalization specification, which effectively deterministically names all
98-
unnamed nodes. The default signature mechanism uses a SHA-256 digest and RSA
99-
to perform the digital signature."))
100-
101-
(define sec:Key
102-
  (make-sec-type
103-
    "Key"
104-
    #:comment
105-
    "This class represents a cryptographic key that may be used for encryption,
106-
decryption, or digitally signing data."))
107-
108-
(define sec-types (list sec:Digest sec:EncryptedMessage sec:Signature
109-
                        sec:GraphSignature2012 sec:LinkedDataSignature2015
110-
                        sec:LinkedDataSignature2016 sec:Key))
111-
112-
(define sec:authenticationTag
113-
  (make-sec-property
114-
    "authenticationTag" "EncryptedMessage" string?
115-
    #:comment
116-
    "Not specified"))
117-
118-
(define sec:creator
119-
  (make-sec-property
120-
    "creator" "Signature" iri?
121-
    #:comment
122-
    "Not specified"))
123-
124-
(define sec:cipherAlgorithm
125-
  (make-sec-property
126-
    "cipherAlgorithm" "EncryptedMessage" string?
127-
    #:comment
128-
    "The cipher algorithm describes the mechanism used to encrypt a message.
129-
It is typically a string expressing the cipher suite, the strength of the
130-
cipher, and a block cipher mode."))
131-
132-
(define sec:cipherData
133-
  (make-sec-property
134-
    "cipherData" "EncryptedMessage" string?
135-
    #:comment
136-
    "Cipher data an opaque blob of information that is used to specify an
137-
encrypted message."))
138-
139-
(define sec:digestAlgorithm
140-
  (make-sec-property
141-
    "digestAlgorithm" "Digest" string?
142-
    #:comment
143-
    "The digest algorithm is used to specify the cryptographic function to use
144-
when generating the data to be digitally signed.  Typically, data that is to be
145-
signed goes through three steps: 1) canonicalization, 2) digest, and
146-
3) signature.  This property is used to specify the algorithm that should be
147-
used for step #2.  A signature class typically specifies a default digest
148-
method, so this property is typically used to specify information for a
149-
signature algorithm."))
150-
151-
(define sec:digestValue
152-
  (make-sec-property
153-
    "digestValue" "Digest" string?
154-
    #:comment
155-
    "The digest value is used to express the output of the digest algorithm
156-
expressed in Base-16 (hexadecimal) format."))
157-
158-
(define sec:cipherKey
159-
  (make-sec-property
160-
    "cipherKey" "EncryptedMessage" string?
161-
    #:comment
162-
    "A cipher key is a symmetric key that is used to encrypt or decrypt a
163-
piece of information.  The key itself may be expressed in clear text or
164-
encrypted."))
165-
166-
(define sec:expires
167-
  (make-sec-property
168-
    "expires" "" string?
169-
    #:comment
170-
    "The expiration time is typically associated with a Key and specifies when
171-
the validity of the key will expire.  It is considered a best practice to only
172-
create keys that have very definite expiration periods.  This period is
173-
typically set to between six months and two years.  An digital signature
174-
created using an expired key MUST be marked as invalid by any software
175-
attempting to verify the signature."))
176-
177-
(define sec:initializationVector
178-
  (make-sec-property
179-
    "initializationVector" "EncryptedMessage" string?
180-
    #:comment
181-
    "The initialization vector (IV) is a byte stream that is typically used to
182-
initialize certain block cipher encryption schemes.  For a receiving
183-
application to be able to decrypt a message, it must know the decryption key
184-
and the initialization vector.  The value is typically base-64 encoded."))
185-
186-
(define sec:nonce
187-
  (make-sec-property
188-
    "nonce" "" string?
189-
    #:comment
190-
    "This property is used in conjunction with the input to the signature
191-
hashing function in order to protect against replay attacks.  Typically,
192-
receivers need to track all nonce values used within a certain time period
193-
in order to ensure that an attacker cannot merely re-send a compromised
194-
packet in order to execute a privileged request."))
195-
196-
(define sec:canonicalizationAlgorithm
197-
  (make-sec-property
198-
    "canonicalizationAlgorithm" "" (list iri? string?)
199-
    #:comment
200-
    "The canonicalization algorithm is used to transform the input data into a
201-
form that can be passed to a cryptographic digest method.  The digest is then
202-
digitally signed using a digital signature algorithm.  Canonicalization ensures
203-
that a piece of software that is generating a digital signature is able to do
204-
so on the same set of information in a deterministic manner."))
205-
206-
(define sec:owner
207-
  (make-sec-property
208-
    "owner" "Key" iri?
209-
    #:comment
210-
    "An owner is an entity that claims control over a particular resource.
211-
Note that ownership is best validated as a two-way relationship where the
212-
owner claims ownership over a particular resource, and the resource clearly
213-
identifies its owner."))
214-
215-
(define sec:password
216-
  (make-sec-property
217-
    "password" "" string?
218-
    #:comment
219-
    "A secret that is used to generate a key that can be used to encrypt or
220-
decrypt message.  It is typically a string value."))
221-
222-
(define sec:privateKeyPem
223-
  (make-sec-property
224-
    "privateKeyPem" "Key" string?
225-
    #:comment
226-
    "A private key PEM property is used to specify the PEM-encoded version of
227-
the private key.  This encoding is compatible with almost every Secure Sockets
228-
Layer library implementation and typically plugs directly into functions
229-
intializing private keys."))
230-
231-
(define sec:publicKey
232-
  (make-sec-property
233-
    "publicKey" "EncryptedMessage" iri?
234-
    #:comment
235-
    "A public key property is used to specify a URL that contains information
236-
about a public key."))
237-
238-
(define sec:publicKeyPem
239-
  (make-sec-property
240-
    "publicKeyPem" "Key" string?
241-
    #:comment
242-
    "A public key PEM property is used to specify the PEM-encoded version of
243-
the public key.  This encoding is compatible with almost every Secure Sockets
244-
Layer library implementation and typically plugs directly into functions
245-
intializing public keys."))
246-
247-
(define sec:publicKeyService
248-
  (make-sec-property
249-
    "publicKeyService" "" string?
250-
    #:comment
251-
    "The publicKeyService property is used to express the REST URL that provides
252-
public key management services as defined by the Web Key specification."))
253-
254-
(define sec:revoked
255-
  (make-sec-property
256-
    "revoked" "" date?
257-
    #:comment
258-
    "The revocation time is typically associated with a Key that has been
259-
marked as invalid as of the date and time associated with the property.  Key
260-
revocations are often used when a key is compromised, such as the theft of the
261-
private key, or during the course of best-practice key rotation schedules."))
262-
263-
(define sec:signature
264-
  (make-sec-property
265-
    ;; XXX: not correct, there is no defined domain
266-
    "signature" "Object" "Signature"
267-
    #:comment
268-
    "The signature property is used to associate a signature with a graph of
269-
information.  The signature property is typically not included in the
270-
canonicalized graph that is then digested, and digitally signed."))
271-
272-
(define sec:signatureValue
273-
  (make-sec-property
274-
    "signatureValue" "Signature" string?
275-
    #:comment
276-
    "The signature value is used to express the output of the signature
277-
algorithm expressed in base-64 format."))
278-
279-
(define sec:signatureAlgorithm
280-
  (make-sec-property
281-
    "signatureAlgorithm" "Signature" string?
282-
    #:comment
283-
    "The signature algorithm is used to specify the cryptographic signature
284-
function to use when digitally signing the digest data.  Typically, text to be
285-
signed goes through three steps: 1) canonicalization, 2) digest, and
286-
3) signature.  This property is used to specify the algorithm that should be
287-
used for step #3.  A signature class typically specifies a default signature
288-
algorithm, so this property rarely needs to be used in practice when
289-
specifying digital signatures."))
290-
291-
(define sec-properties
292-
  (list sec:cipherAlgorithm sec:cipherData sec:digestAlgorithm sec:digestValue
293-
        sec:cipherKey sec:expires sec:initializationVector sec:nonce
294-
        sec:canonicalizationAlgorithm sec:owner sec:password
295-
        sec:privateKeyPem sec:publicKey sec:publicKeyPem sec:publicKeyService
296-
        sec:revoked sec:signature sec:signatureValue sec:signatureAlgorithm))
297-
298-
(define security-ontology (append sec-types sec-properties))

http-signature/vocabulary.scm unknown status 1

1+
;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu>
2+
;;;; 
3+
;;;; This library is free software; you can redistribute it and/or
4+
;;;; modify it under the terms of the GNU Lesser General Public
5+
;;;; License as published by the Free Software Foundation; either
6+
;;;; version 3 of the License, or (at your option) any later version.
7+
;;;; 
8+
;;;; This library is distributed in the hope that it will be useful,
9+
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11+
;;;; Lesser General Public License for more details.
12+
;;;; 
13+
;;;; You should have received a copy of the GNU Lesser General Public
14+
;;;; License along with this library; if not, write to the Free Software
15+
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16+
;;;; 
17+
18+
(define-module (http-signature vocabulary)
19+
  #:use-module (activitystreams ontology)
20+
  #:use-module (activitystreams predicates)
21+
  #:use-module (ice-9 match)
22+
  #:use-module (jsonld json)
23+
  #:use-module (web uri)
24+
  #:export (security-ontology))
25+
26+
(define-public vocab "https://w3id.org/security#")
27+
28+
(define* (make-sec-type label #:key (uri (string-append vocab label))
29+
                        (comment "") (subclass-of '()))
30+
  (build-as-type label #:uri uri #:comment comment #:subclass-of subclass-of))
31+
32+
(define* (make-sec-property label domain range
33+
                           #:key (uri (string-append vocab label))
34+
                           (functional? #f) (subproperty-of '()) (comment ""))
35+
  (build-as-property label domain range #:uri uri #:functional? functional?
36+
                    #:subproperty-of subproperty-of #:comment comment))
37+
38+
;; Classes
39+
40+
(define-public Digest
41+
  (make-sec-type
42+
    "Digest"
43+
    #:comment
44+
    "This class represents a message digest that may be used for data integrity
45+
verification.  The digest algorithm used will determine the cryptographic
46+
properties of the digest."))
47+
48+
(define-public EncryptedMessage
49+
  (make-sec-type
50+
    "EncryptedMessage"
51+
    #:comment
52+
    "A class of messages that are obfuscated in some cryptographic manner.
53+
These messages are incredibly difficult to decrypt without the proper
54+
decryption key."))
55+
56+
(define-public Signature
57+
  (make-sec-type
58+
    "Signature"
59+
    #:comment
60+
    "This class represents a digital signature on serialized data.  It is an
61+
abstract class and should not be used other than for Semantic Web reasoning
62+
purposes, such as by a reasoning agent."))
63+
64+
(define-public GraphSignature2012
65+
  (make-sec-type
66+
    "GraphSignature2012"
67+
    #:subclass-of (list Signature)
68+
    #:comment
69+
    "A graph signature is used for digital signatures on RDF graphs.  The
70+
default canonicalization mechanism is specified in the RDF Graph normalization
71+
specification, which effectively deterministically names all unnamed nodes.
72+
The default signature mechanism uses a SHA-256 digest and RSA to perform the
73+
digital signature."))
74+
75+
(define-public LinkedDataSignature2015
76+
  (make-sec-type
77+
    "LinkedDataSignature2015"
78+
    #:subclass-of (list Signature)
79+
    #:comment
80+
    "A Linked Data signature is used for digital signatures on RDF Datasets.
81+
The default canonicalization mechanism is specified in the RDF Dataset
82+
Normalization specification, which effectively deterministically names all
83+
unnamed nodes.  The default signature mechanism uses a SHA-256 digest and RSA
84+
to perform the digital signature.  This signature uses a algorithm for
85+
producing the data that it signs and verifies that is different from other
86+
Linked Data signatures."))
87+
88+
(define-public LinkedDataSignature2016
89+
  (make-sec-type
90+
    "LinkedDataSignature2016"
91+
    #:subclass-of (list Signature)
92+
    #:comment
93+
    "A Linked Data signature is used for digital signatures on RDF Datasets.
94+
The default canonicalization mechanism is specified in the RDF Dataset
95+
Normalization specification, which effectively deterministically names all
96+
unnamed nodes. The default signature mechanism uses a SHA-256 digest and RSA
97+
to perform the digital signature."))
98+
99+
(define-public Key
100+
  (make-sec-type
101+
    "Key"
102+
    #:comment
103+
    "This class represents a cryptographic key that may be used for encryption,
104+
decryption, or digitally signing data."))
105+
106+
(define-public sec-types (list Digest EncryptedMessage Signature
107+
                        GraphSignature2012 LinkedDataSignature2015
108+
                        LinkedDataSignature2016 Key))
109+
110+
(define-public authenticationTag
111+
  (make-sec-property
112+
    "authenticationTag" "EncryptedMessage" string?
113+
    #:comment
114+
    "Not specified"))
115+
116+
(define-public creator
117+
  (make-sec-property
118+
    "creator" "Signature" uri?
119+
    #:comment
120+
    "Not specified"))
121+
122+
(define-public cipherAlgorithm
123+
  (make-sec-property
124+
    "cipherAlgorithm" "EncryptedMessage" string?
125+
    #:comment
126+
    "The cipher algorithm describes the mechanism used to encrypt a message.
127+
It is typically a string expressing the cipher suite, the strength of the
128+
cipher, and a block cipher mode."))
129+
130+
(define-public cipherData
131+
  (make-sec-property
132+
    "cipherData" "EncryptedMessage" string?
133+
    #:comment
134+
    "Cipher data an opaque blob of information that is used to specify an
135+
encrypted message."))
136+
137+
(define-public digestAlgorithm
138+
  (make-sec-property
139+
    "digestAlgorithm" "Digest" string?
140+
    #:comment
141+
    "The digest algorithm is used to specify the cryptographic function to use
142+
when generating the data to be digitally signed.  Typically, data that is to be
143+
signed goes through three steps: 1) canonicalization, 2) digest, and
144+
3) signature.  This property is used to specify the algorithm that should be
145+
used for step #2.  A signature class typically specifies a default digest
146+
method, so this property is typically used to specify information for a
147+
signature algorithm."))
148+
149+
(define-public digestValue
150+
  (make-sec-property
151+
    "digestValue" "Digest" string?
152+
    #:comment
153+
    "The digest value is used to express the output of the digest algorithm
154+
expressed in Base-16 (hexadecimal) format."))
155+
156+
(define-public cipherKey
157+
  (make-sec-property
158+
    "cipherKey" "EncryptedMessage" string?
159+
    #:comment
160+
    "A cipher key is a symmetric key that is used to encrypt or decrypt a
161+
piece of information.  The key itself may be expressed in clear text or
162+
encrypted."))
163+
164+
(define-public expires
165+
  (make-sec-property
166+
    "expires" "" string?
167+
    #:comment
168+
    "The expiration time is typically associated with a Key and specifies when
169+
the validity of the key will expire.  It is considered a best practice to only
170+
create keys that have very definite expiration periods.  This period is
171+
typically set to between six months and two years.  An digital signature
172+
created using an expired key MUST be marked as invalid by any software
173+
attempting to verify the signature."))
174+
175+
(define-public initializationVector
176+
  (make-sec-property
177+
    "initializationVector" "EncryptedMessage" string?
178+
    #:comment
179+
    "The initialization vector (IV) is a byte stream that is typically used to
180+
initialize certain block cipher encryption schemes.  For a receiving
181+
application to be able to decrypt a message, it must know the decryption key
182+
and the initialization vector.  The value is typically base-64 encoded."))
183+
184+
(define-public nonce
185+
  (make-sec-property
186+
    "nonce" "" string?
187+
    #:comment
188+
    "This property is used in conjunction with the input to the signature
189+
hashing function in order to protect against replay attacks.  Typically,
190+
receivers need to track all nonce values used within a certain time period
191+
in order to ensure that an attacker cannot merely re-send a compromised
192+
packet in order to execute a privileged request."))
193+
194+
(define-public canonicalizationAlgorithm
195+
  (make-sec-property
196+
    "canonicalizationAlgorithm" "" (list uri? string?)
197+
    #:comment
198+
    "The canonicalization algorithm is used to transform the input data into a
199+
form that can be passed to a cryptographic digest method.  The digest is then
200+
digitally signed using a digital signature algorithm.  Canonicalization ensures
201+
that a piece of software that is generating a digital signature is able to do
202+
so on the same set of information in a deterministic manner."))
203+
204+
(define-public owner
205+
  (make-sec-property
206+
    "owner" "Key" uri?
207+
    #:comment
208+
    "An owner is an entity that claims control over a particular resource.
209+
Note that ownership is best validated as a two-way relationship where the
210+
owner claims ownership over a particular resource, and the resource clearly
211+
identifies its owner."))
212+
213+
(define-public password
214+
  (make-sec-property
215+
    "password" "" string?
216+
    #:comment
217+
    "A secret that is used to generate a key that can be used to encrypt or
218+
decrypt message.  It is typically a string value."))
219+
220+
(define-public privateKeyPem
221+
  (make-sec-property
222+
    "privateKeyPem" "Key" string?
223+
    #:comment
224+
    "A private key PEM property is used to specify the PEM-encoded version of
225+
the private key.  This encoding is compatible with almost every Secure Sockets
226+
Layer library implementation and typically plugs directly into functions
227+
intializing private keys."))
228+
229+
(define-public publicKey
230+
  (make-sec-property
231+
    "publicKey" "EncryptedMessage" uri?
232+
    #:comment
233+
    "A public key property is used to specify a URL that contains information
234+
about a public key."))
235+
236+
(define-public publicKeyPem
237+
  (make-sec-property
238+
    "publicKeyPem" "Key" string?
239+
    #:comment
240+
    "A public key PEM property is used to specify the PEM-encoded version of
241+
the public key.  This encoding is compatible with almost every Secure Sockets
242+
Layer library implementation and typically plugs directly into functions
243+
intializing public keys."))
244+
245+
(define-public publicKeyService
246+
  (make-sec-property
247+
    "publicKeyService" "" string?
248+
    #:comment
249+
    "The publicKeyService property is used to express the REST URL that provides
250+
public key management services as defined by the Web Key specification."))
251+
252+
(define-public revoked
253+
  (make-sec-property
254+
    "revoked" "" date?
255+
    #:comment
256+
    "The revocation time is typically associated with a Key that has been
257+
marked as invalid as of the date and time associated with the property.  Key
258+
revocations are often used when a key is compromised, such as the theft of the
259+
private key, or during the course of best-practice key rotation schedules."))
260+
261+
(define-public signature
262+
  (make-sec-property
263+
    ;; XXX: not correct, there is no defined domain
264+
    "signature" "Object" "Signature"
265+
    #:comment
266+
    "The signature property is used to associate a signature with a graph of
267+
information.  The signature property is typically not included in the
268+
canonicalized graph that is then digested, and digitally signed."))
269+
270+
(define-public signatureValue
271+
  (make-sec-property
272+
    "signatureValue" "Signature" string?
273+
    #:comment
274+
    "The signature value is used to express the output of the signature
275+
algorithm expressed in base-64 format."))
276+
277+
(define-public signatureAlgorithm
278+
  (make-sec-property
279+
    "signatureAlgorithm" "Signature" string?
280+
    #:comment
281+
    "The signature algorithm is used to specify the cryptographic signature
282+
function to use when digitally signing the digest data.  Typically, text to be
283+
signed goes through three steps: 1) canonicalization, 2) digest, and
284+
3) signature.  This property is used to specify the algorithm that should be
285+
used for step #3.  A signature class typically specifies a default signature
286+
algorithm, so this property rarely needs to be used in practice when
287+
specifying digital signatures."))
288+
289+
(define sec-properties
290+
  (list cipherAlgorithm cipherData digestAlgorithm digestValue
291+
        cipherKey expires initializationVector nonce
292+
        canonicalizationAlgorithm owner password
293+
        privateKeyPem publicKey publicKeyPem publicKeyService
294+
        revoked signature signatureValue signatureAlgorithm))
295+
296+
(define security-ontology
297+
  (make-ontology '("https://w3id.org/security/v1") sec-types sec-properties))