forked from solid/solid-spec
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
497 lines (296 loc) · 34.8 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SoLiD</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
<style>
body {
font-size: 2em;
font-weight: 200;
}
</style>
</head>
<body><div class="container"><h1 id="solid-social-linked-data-platform">SoLiD - Social Linked Data platform</h1>
<p>This document contains design notes on individual components used by SoLiD. They are intended to be a guide for developers who plan to build social linked data servers and applications.</p>
<p>SoLiD was designed from the ground up to be modular and openly extensible. It relies as much as possible on existing <a href="http://www.w3.org/">W3C</a> standards. Among the technologies it uses, you can find:</p>
<ul>
<li><a href="#rdf">RDF</a></li>
<li><a href="#reading-and-writing-data-using-ldp">LDP</a></li>
<li><a href="#websockets">Websockets</a></li>
<li><a href="#identity-management-based-on-webid">WebID</a></li>
<li><a href="#webid-tls">WebID-TLS</a></li>
<li><a href="#webid-rsa">WebID-RSA</a></li>
<li><a href="#web-access-control">WebAccessControl</a></li>
</ul>
<h2 id="rdf">RDF</h2>
<p>The Resource Description Framework (RDF) is a framework for representing information in the Web [<a href="http://www.w3.org/TR/rdf11-concepts/">RDF1.1</a>], originally designed as a graph-based data model, where the core structure of the abstract syntax is a set of triples, each consisting of a subject, a predicate and an object.</p>
<p>SoLiD uses several serialization syntaxes for storing and exchanging RDF such as <a href="http://www.w3.org/TR/turtle/">Turtle</a> and <a href="http://www.w3.org/TR/json-ld/">JSON-LD</a>. When creating new RDF resources, the preferred <strong>default</strong> serialization is Turtle. SoLiD-compliant servers should implement content negotiation in order to handle different serialization formats.</p>
<h2 id="reading-and-writing-data-using-ldp">Reading and writing data using LDP</h2>
<p>To simplify data portability, we opted for a design that follows the classic POSIX standards. For instance, resources are stored directly on the file system instead of using a database. This allows people to read/write data both using desktop applications as well as Web-based ones, and also to share the same disk drive between different machines/servers.</p>
<p>For this precise reason, we decided to use a fairly recent spec proposed by the W3C, called Linked Data Platform. </p>
<p>The <a href="http://www.w3.org/TR/ldp/">LDP specification</a> defines a set of rules for HTTP operations on Web resources, some based on RDF, to provide an architecture for reading and writing Linked Data on the Web. The most important feature of LDP is that it provides us with a standard way of RESTfully writing resources (documents) on the Web, without having to rely on less flexible conventions (APIs) based around sending form-encoded data using POST.</p>
<p>To find out how LDP works, you can take a look at the examples in the LDP <a href="http://www.w3.org/TR/ldp-primer/">Primer document</a>. </p>
<p>However, we have found that while LDP is usually sufficient, there are some cases where it doesn’t cover some of our use cases, and therefore we had to extend it.</p>
<h3 id="getting-information-on-resources-and-server-capabilities">Getting information on resources and server capabilities</h3>
<p>Our existing servers support the following HTTP methods for reading data:</p>
<h4 id="the-head-method">The HEAD method</h4>
<p>Returns a list of headers related to the resource in question. Among these headers, two very important Link headers contain pointers to corresponding ACL and metadata resources. More information on naming conventions for these resources can be found <a href="#wac">here</a>.</p>
<p>REQUEST:</p>
<pre class="prettyprint"><code class=" hljs http"><span class="hljs-request">HEAD <span class="hljs-string">/data/</span> HTTP/1.1</span>
<span class="hljs-attribute">Host</span>: <span class="hljs-string">example.org</span></code></pre>
<p>RESPONSE:</p>
<pre class="prettyprint"><code class=" hljs livecodeserver">HTTP/<span class="hljs-number">1.1</span> <span class="hljs-number">200</span> OK
....
Link: <<span class="hljs-keyword">https</span>://example.org/data/.acl>; <span class="hljs-built_in">rel</span>=<span class="hljs-string">"acl"</span>
Link: <<span class="hljs-keyword">https</span>://example.org/data/.meta>; <span class="hljs-built_in">rel</span>=<span class="hljs-string">"describedby"</span></code></pre>
<h4 id="the-options-method">The OPTIONS method</h4>
<p>Returns a list of headers describing the server’s capabilities.</p>
<p>REQUEST:</p>
<pre class="prettyprint"><code class=" hljs http"><span class="hljs-request">OPTIONS <span class="hljs-string">/data/</span> HTTP/1.1</span>
<span class="hljs-attribute">Host</span>: <span class="hljs-string">example.org</span></code></pre>
<p>RESPONSE:</p>
<pre class="prettyprint"><code class=" hljs lasso">HTTP/<span class="hljs-number">1.1</span> <span class="hljs-number">200</span> OK
Accept<span class="hljs-attribute">-Patch</span>: application/json, application/sparql<span class="hljs-attribute">-update</span>
Accept<span class="hljs-attribute">-Post</span>: text/turtle, application/ld<span class="hljs-subst">+</span>json
Access<span class="hljs-attribute">-Control</span><span class="hljs-attribute">-Allow</span><span class="hljs-attribute">-Credentials</span>: <span class="hljs-literal">true</span>
Access<span class="hljs-attribute">-Control</span><span class="hljs-attribute">-Allow</span><span class="hljs-attribute">-Methods</span>: OPTIONS, HEAD, GET, PATCH, POST, PUT, MKCOL, DELETE, COPY, MOVE, LOCK, UNLOCK
Access<span class="hljs-attribute">-Control</span><span class="hljs-attribute">-Allow</span><span class="hljs-attribute">-Origin</span>: <span class="hljs-subst">*</span>
Access<span class="hljs-attribute">-Control</span><span class="hljs-attribute">-Expose</span><span class="hljs-attribute">-Headers</span>: User, Triples, Location, <span class="hljs-keyword">Link</span>, Vary, Last<span class="hljs-attribute">-Modified</span>, Content<span class="hljs-attribute">-Length</span>
Allow: OPTIONS, HEAD, GET, PATCH, POST, PUT, MKCOL, DELETE, COPY, MOVE, LOCK, UNLOCK</code></pre>
<h3 id="creating-new-resources">Creating new resources</h3>
<p>When creating new resources (directories or documents) using LDP, the client must indicate the type of the new resource that is going to be created. LDP uses Link headers with specific URI values, which in turn can be dereferenced to obtain additional information about each type of resource. Currently, our LDP implementation supports only <a href="http://www.w3.org/TR/ldp/#ldpbc">Basic Containers</a>.</p>
<p>LDP also offers a mechanism through which clients can provide a preferred name for the new resource through a header called <strong>Slug</strong>.</p>
<h4 id="creating-containers-directories">Creating containers (directories)</h4>
<p>To create a new <strong>basic container</strong> resource, the Link header value must be set to the following value: <br>
<code>Link: <https://www.w3.org/ns/ldp#BasicContainer>; rel="type"</code></p>
<p>For example, to create a basic container called <strong>data</strong> under <a href="https://example.org/">https://example.org/</a>, the client will need to send the following POST request, with the Content-Type header set to <code>text/turtle</code>:</p>
<p>REQUEST:</p>
<pre class="prettyprint"><code class=" hljs http"><span class="hljs-request">POST <span class="hljs-string">/</span> HTTP/1.1</span>
<span class="hljs-attribute">Host</span>: <span class="hljs-string">example.org</span>
<span class="hljs-attribute">Content-Type</span>: <span class="hljs-string">text/turtle</span>
<span class="hljs-attribute">Slug</span>: <span class="hljs-string">data</span>
<span class="livecodeserver"><> <span class="hljs-operator">a</span> <<span class="hljs-keyword">http</span>://www.w3.org/ns/ldp<span class="hljs-comment">#BasicContainer> ;</span>
<<span class="hljs-keyword">http</span>://purl.org/dc/terms/title> <span class="hljs-string">"Basic container"</span> .</span></code></pre>
<p>RESPONSE:</p>
<pre class="prettyprint"><code class=" hljs http"><span class="hljs-status">HTTP/1.1 <span class="hljs-number">201</span> Created</span></code></pre>
<h4 id="creating-documents-files">Creating documents (files)</h4>
<p>To create a new resource, the Link header value must be set to the following value: <br>
<code>Link: <http://www.w3.org/ns/ldp#Resource>; rel="type"</code></p>
<p>For example, to create a resource called <strong>test</strong> under <a href="https://example.org/data/">https://example.org/data/</a>, the client will need to send the following POST request, with the Content-Type header set to <code>text/turtle</code>:</p>
<p>REQUEST:</p>
<pre class="prettyprint"><code class=" hljs http"><span class="hljs-request">POST <span class="hljs-string">/</span> HTTP/1.1</span>
<span class="hljs-attribute">Host</span>: <span class="hljs-string">example.org</span>
<span class="hljs-attribute">Content-Type</span>: <span class="hljs-string">text/turtle</span>
<span class="hljs-attribute">Slug</span>: <span class="hljs-string">test</span>
<span class="livecodeserver"><> <span class="hljs-operator">a</span> <<span class="hljs-keyword">http</span>://www.w3.org/ns/ldp<span class="hljs-comment">#Resource> ;</span>
<<span class="hljs-keyword">http</span>://purl.org/dc/terms/title> <span class="hljs-string">"This is a test file"</span> .</span></code></pre>
<p>RESPONSE:</p>
<pre class="prettyprint"><code class=" hljs http"><span class="hljs-status">HTTP/1.1 <span class="hljs-number">201</span> Created</span></code></pre>
<p>More examples can be found in the LDP <a href="http://www.w3.org/TR/ldp-primer/">Primer document</a>.</p>
<p>An alternative, though not standard way of creating new resources is to use HTTP PUT. Although HTTP PUT is commonly used to overwrite resources, this way is usually preferred when creating new non-RDF resources (i.e. using a mime type different than <em>text/turtle</em>).</p>
<p>REQUEST:</p>
<pre class="prettyprint"><code class=" hljs r">PUT / HTTP/<span class="hljs-number">1.1</span>
Host: example.org
Content-Type: image/jpeg
<span class="hljs-keyword">...</span></code></pre>
<p>RESPONSE :</p>
<pre class="prettyprint"><code class=" hljs http"><span class="hljs-status">HTTP/1.1 <span class="hljs-number">201</span> Created</span></code></pre>
<h4 id="handling-metadata-for-non-rdf-resources">Handling metadata for non-RDF resources</h4>
<p>The metadata (i.e. extra RDF triples such as types, titles, comments, etc.) about non-RDF resources (e.g. containers, images, binaries, etc.) will be stored in a corresponding <em>meta</em> resources. SoLiD servers use a specific naming convention when referring to these meta resources. Basically, every non-RDF resource may have a corresponding metadata resource, with a name composed of the resource’s name together with a <strong>.meta</strong> suffix.</p>
<p>For example, the corresponding metadata resource for the newly created container will be accessible through this URI: <code>https://example.org/data/.meta</code>. Alternatively, the photo at <code>https://example.org/data/image.jpg</code> will have it’s metadata stored in <code>https://example.org/data/image.jpg.meta</code>.</p>
<p>Metadata resources are a “special” type of resources, which are not publicly listed by the server when browsing files (typically when doing a GET on an LDP container). However, they can still be modified by client apps using the methods described in this section. The corresponding metadata resources are advertised and can be discovered when doing HTTP GET/HEAD on regular resources, as mentioned before.</p>
<h3 id="reading-resources">Reading resources</h3>
<p>Resources can be commonly accessed (i.e. read) using HTTP GET requests. SoLiD servers are encouraged to perform content negotiation for RDF resources, depending on the value of the <em>Accept</em> header.</p>
<p><strong>IMPORTANT:</strong> a default <strong>text/turtle</strong> Content-Type will be used for requests for RDF resources or views (e.g. containers) that do not have an <em>Accept</em> header.</p>
<h2 id="reading-and-writing-data-using-sparql">Reading and writing data using SPARQL</h2>
<p>Another possible way of reading and writing data is to use SPARQL. Currently, our SoLiD servers support a subset of <a href="http://www.w3.org/TR/rdf-sparql-query/">SPARQL 1.0</a>, where each resource is its own SPARQL endpoint, accepting basic SELECT, INSERT and DELETE statements.</p>
<h3 id="reading-data-using-sparql">Reading data using SPARQL</h3>
<p>To read (query) a resource, the client can send a SPARQL SELECT query through an HTTP GET request. The server will use the given resource as the default graph that is being queried. The resource can be an RDF document or even a container. The response will be serialized using <code>application/json</code> mime type.</p>
<p>For instance, the client can send the following form-encoded query:</p>
<p>REQUEST:</p>
<pre class="prettyprint"><code class=" hljs http"><span class="hljs-request">GET <span class="hljs-string">/data/</span> HTTP/1.1</span>
<span class="hljs-attribute">Host</span>: <span class="hljs-string">example.org</span>
<span class="hljs-attribute">Query</span>: <span class="hljs-string">SELECT * WHERE { ?s ?p ?o . }</span></code></pre>
<p>RESPONSE:</p>
<pre class="prettyprint"><code class=" hljs http"><span class="hljs-status">HTTP/1.1 <span class="hljs-number">200</span> OK</span>
<span class="json">{
"<span class="hljs-attribute">head</span>": <span class="hljs-value">{
"<span class="hljs-attribute">vars</span>": <span class="hljs-value">[ <span class="hljs-string">"s"</span>, <span class="hljs-string">"p"</span>, <span class="hljs-string">"o"</span> ]
</span>}</span>,
"<span class="hljs-attribute">results</span>": <span class="hljs-value">{
"<span class="hljs-attribute">ordered</span>" : <span class="hljs-value"><span class="hljs-literal">false</span></span>,
"<span class="hljs-attribute">distinct</span>" : <span class="hljs-value"><span class="hljs-literal">false</span></span>,
"<span class="hljs-attribute">bindings</span>" : <span class="hljs-value">[
{
"<span class="hljs-attribute">s</span>" : <span class="hljs-value">{ "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"uri"</span></span>, "<span class="hljs-attribute">value</span>": <span class="hljs-value"><span class="hljs-string">"https://example.org/data/"</span> </span>}</span>,
"<span class="hljs-attribute">p</span>" : <span class="hljs-value">{ "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"uri"</span></span>, "<span class="hljs-attribute">value</span>": <span class="hljs-value"><span class="hljs-string">"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"</span> </span>}</span>,
"<span class="hljs-attribute">o</span>" : <span class="hljs-value">{ "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"uri"</span></span>, "<span class="hljs-attribute">value</span>": <span class="hljs-value"><span class="hljs-string">"http://www.w3.org/ns/ldp#BasicContainer"</span> </span>}
</span>},
{
"<span class="hljs-attribute">s</span>" : <span class="hljs-value">{ "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"uri"</span></span>, "<span class="hljs-attribute">value</span>": <span class="hljs-value"><span class="hljs-string">"https://example.org/data/"</span> </span>}</span>,
"<span class="hljs-attribute">p</span>" : <span class="hljs-value">{ "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"uri"</span></span>, "<span class="hljs-attribute">value</span>": <span class="hljs-value"><span class="hljs-string">"http://purl.org/dc/terms/title"</span> </span>}</span>,
"<span class="hljs-attribute">o</span>" : <span class="hljs-value">{ "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"literal"</span></span>, "<span class="hljs-attribute">value</span>": <span class="hljs-value"><span class="hljs-string">"Basic container"</span> </span>}
</span>}
]
</span>}
</span>}</span></code></pre>
<h3 id="writingdeleting-data-using-sparql">Writing/deleting data using SPARQL</h3>
<p>To write data, clients can send an HTTP PATCH request with a SPARQL payload to the resource in question. If the resource doesn’t exist, it should be created through an LDP POST or through a PUT.</p>
<p>For instance, to update the <em>title</em> of the container from the previous example, the client would have to send a DELETE statement, followed by an INSERT statement. Multiple statements (delimited by a <strong>;</strong>) can be sent in the same PATCH request.</p>
<p>REQUEST:</p>
<pre class="prettyprint"><code class=" hljs http"><span class="hljs-request">PATCH <span class="hljs-string">/data/</span> HTTP/1.1</span>
<span class="hljs-attribute">Host</span>: <span class="hljs-string">example.org</span>
<span class="hljs-attribute">Content-Type</span>: <span class="hljs-string">application/sparql-update</span>
<span class="css"><span class="hljs-tag">DELETE</span> <span class="hljs-tag">DATA</span> <span class="hljs-rules">{ <span class="hljs-rule"><> <<span class="hljs-attribute">http</span>:<span class="hljs-value">//purl.org/dc/terms/title> <span class="hljs-string">"Basic container"</span> </span></span></span>};
<span class="hljs-tag">INSERT</span> <span class="hljs-tag">DATA</span> <span class="hljs-rules">{ <span class="hljs-rule"><> <<span class="hljs-attribute">http</span>:<span class="hljs-value">//purl.org/dc/terms/title> <span class="hljs-string">"My data container"</span> </span></span></span>}</span></code></pre>
<p>RESPONSE:</p>
<pre class="prettyprint"><code class=" hljs http"><span class="hljs-status">HTTP/1.1 <span class="hljs-number">200</span> OK</span></code></pre>
<p><strong>IMPORTANT:</strong> There is currently no support for blank nodes and RDF lists in our SPARQL patches.</p>
<h2 id="cors-cross-origin-resource-sharing">CORS - Cross Origin Resource Sharing</h2>
<p>There are two different ways CORS support must be implemented on SoLiD servers. First, when the request is sent through a browser that sets the Origin header. And second, when clients do not set an Origin header (e.g. curl or non-browser clients).</p>
<p>When the Origin header is set:</p>
<ol>
<li><p>Client (browser) loads an app from <a href="https://app.org">https://app.org</a> and wants to send an XHR (ajax) request to the server at <a href="https://example.org">https://example.org</a>. Before sending the request over the wire, the browser adds the Origin header: <code>Origin: https://app.org</code>, which corresponds to the domain from where the app was loaded.</p></li>
<li><p>The server running on <a href="https://example.org">https://example.org</a> receives the request and looks at the Origin header. It sees <a href="https://app.org">https://app.org</a>, stores the value and handles the request.</p></li>
<li><p>The server responds to the request and sets the value of the request Origin header to the CORS header in the HTTP response: <br>
Access-Control-Allow-Origin: <a href="https://app.org">https://app.org</a></p></li>
</ol>
<p>Without an Origin header:</p>
<ol>
<li><p>A curl request is sent from the terminal to <a href="https://example.org">https://example.org</a>. Unless explicitly specified though a curl parameter, the Origin header will not be set.</p></li>
<li><p>The server running on <a href="https://example.org">https://example.org</a> receives the request and does not find an Origin header.</p></li>
<li><p>The server responds to the request and sets a default “all” value for the Access-Control-Allow-Origin header in the HTTP response: <br>
Access-Control-Allow-Origin: *</p></li>
</ol>
<p>The star character (*) signifies “allow all”. If you want to learn more about CORS, please visit this page: <a href="http://enable-cors.org/">http://enable-cors.org/</a></p>
<h2 id="live-updates">Live updates</h2>
<h3 id="websockets">Websockets</h3>
<p>Live updates are currently only supported through websockets. There are two ways in which clients can be notified in real time of changes affecting a give resource. One possible way is through a subscription mechanism, while the other way is through SPARQL patches.</p>
<h4 id="pubsub-notifications">PubSub notifications</h4>
<p>The PubSub system is very basic. Clients only need to open a websocket connection and <em>sub</em>(scribe) to a given resource URI. If any change occurs in that resource, a <em>pub</em>(lish) event will be sent to all the subscribed clients. </p>
<p>The websocket server URI is the same for any resource located on a given data space (same hostname). To discover the URI of the websocket server, clients can send an HTTP OPTIONS. The server will then include an <strong>Updates-Via</strong> header in the response:</p>
<p>REQUEST:</p>
<pre class="prettyprint"><code class=" hljs http"><span class="hljs-request">OPTIONS <span class="hljs-string">/data/test</span> HTTP/1.1</span>
<span class="hljs-attribute">Host</span>: <span class="hljs-string">example.org</span></code></pre>
<p>RESPONSE:</p>
<pre class="prettyprint"><code class=" hljs r">HTTP/<span class="hljs-number">1.1</span> <span class="hljs-number">200</span> OK
<span class="hljs-keyword">...</span>
Updates-Via: wss://example.org/</code></pre>
<p>To subscribe to a resource, clients will need to send the keyword <strong>sub</strong> followed by an empty space and then the URI of the resource:</p>
<p><code>sub https://example.org/data/test</code></p>
<p>If a change occurs and the client is subscribed to that resource, it will receive a websocket message composed of the keyword <strong>pub</strong>, followed by an empty space and the URI of the resource that has changed:</p>
<p><code>pub https://example.org/data/test</code></p>
<p>Here is a Javascript example on how to subscribe to live updates for our <em>test</em> resource at <code>https://example.org/data/test</code>:</p>
<pre class="prettyprint"><code class=" hljs javascript"><span class="hljs-keyword">var</span> socket = <span class="hljs-keyword">new</span> WebSocket(<span class="hljs-string">'wss://example.org/'</span>);
socket.onopen = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
<span class="hljs-keyword">this</span>.send(<span class="hljs-string">'sub https://example.org/data/test'</span>);
};
socket.onmessage = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(msg)</span> {</span>
<span class="hljs-keyword">if</span> (msg.data && msg.data.slice(<span class="hljs-number">0</span>, <span class="hljs-number">3</span>) === <span class="hljs-string">'pub'</span>) {
<span class="hljs-comment">// resource updated, refetch resource</span>
}
};</code></pre>
<h4 id="sparql-patches">SPARQL patches</h4>
<p>@@@TODO </p>
<h2 id="identity-management-based-on-webid">Identity management based on WebID</h2>
<p>Identity management as well as unique identifiers are the core of any social system. SoLiD uses <a href="http://www.w3.org/2005/Incubator/webid/spec/identity/">WebID</a>, an HTTP(S) URI, to uniquely refer to users (people or agents). The advantage of WebID is that the URI can be dereferenced to a WebID profile document, in order to reveal useful information about the user. Also, since WebID profiles can be hosted anywhere (including your basement server), users are no longer trapped inside Identity Provider Silos (e.g. Twitter, Facebook, Google+, etc.).</p>
<h3 id="creating-new-accounts">Creating new accounts</h3>
<h4 id="client-server-api">Client - server API</h4>
<p>SoLiD-compliant servers must implement a very simple API, indicating whether an account name is available or not on the server. Clients (e.g. the signup Web component) send an HTTP POST request containing the following JSON structure, where <em>accountName</em> contains the target account name (e.g. a preferred username):</p>
<pre class="prettyprint"><code class=" hljs css"><span class="hljs-rules">{
<span class="hljs-rule"><span class="hljs-attribute">method</span>:<span class="hljs-value"> <span class="hljs-string">"accountStatus"</span>,
accountName: <span class="hljs-string">"alice"</span>
</span></span></span>}</code></pre>
<p>The server response has to contain the following JSON structure:</p>
<pre class="prettyprint"><code class=" hljs css"><span class="hljs-rules">{
<span class="hljs-rule"><span class="hljs-attribute">method</span>:<span class="hljs-value"> <span class="hljs-string">"accountStatus"</span>,
status: <span class="hljs-string">"success"</span>,
formURI: <span class="hljs-string">"https://example.org/api/spkac"</span>,
loginURI: <span class="hljs-string">"https://example.org/"</span>,
response: {
accountURL: <span class="hljs-string">"https://user.example.org/"</span>,
available: true
</span></span></span>}
}</code></pre>
<p><strong>Attention!</strong> Because creating client certificates requires the <KEYGEN> HTML element, which does not work with AJAX requests, the client must submit a form to the <em>formURI</em> it receives from the server. This restriction means that a predefined set of form element names must be respected on the server. Here is a list of form element names (case sensitive!) that are sent by the signup component:</p>
<ul>
<li><code>spkac</code> - SPKAC containing the public key generated by the KEYGEN element</li>
<li><code>username</code> - account user name</li>
<li><code>name</code> - user’s full name</li>
<li><code>email</code> - user’s email address</li>
<li><code>img</code> - user’s picture URL</li>
</ul>
<p>Finally, if the <em>status</em> indicates success, and the <em>available</em> flag is set to <em>true</em>, then the form containing user details can be submitted, using the URI provided by the server (i.e. the value of <em>formuri</em>).</p>
<p>The value of <em>loginURI</em> is used to indicate where the app can fake a WebID-TLS login, in order to find the user’s WebID.</p>
<p>Once the WebID certificate is installed in the browser, the user is presented with a button that finishes setting up the account when clicked. At the end, the user ends up with a series of default workspaces, access control policies (ACLs) for them, and also a <em>preferences</em> document (file).</p>
<h3 id="personal-data-workspaces">Personal data workspaces</h3>
<p>Upon account creation, a series of dedicated workspaces (i.e. LDP containers) are created in the user’s data space, together with their corresponding ACL resources. At the moment, the list contains the following workspaces:</p>
<ul>
<li>Public</li>
<li>Private</li>
<li>Work</li>
<li>Family</li>
<li>Friends</li>
<li>Preferences</li>
</ul>
<p>You can consider workspaces to be dedicated containers, which store application-specific data. For example, one of the reasons we decided to use this concept of workspaces is that complicated ACL logic can be set per workspace, and then all data inside the workspace will inherit the same policies.</p>
<h3 id="preferences-document">Preferences document</h3>
<p>The <em>preferences</em> document is used to describe useful information about the user and the data server, which can later on be used by applications. This resource currently lists the workspaces that were just created. In the future it may contain user preferences such as a preferred language, date format, etc.</p>
<p>By default, the preferences resource will be created in the <em>Preferences</em> workspaces – i.e. <code>https://user.example.org/Preferences/prefs</code>.</p>
<p>A triple pointing to the preferences file will also be added to the user’s WebID profile.</p>
<h2 id="authentication">Authentication</h2>
<h3 id="webid-tls">WebID-TLS</h3>
<p>The WebID-TLS protocol (<a href="http://www.w3.org/2005/Incubator/webid/spec/tls/">W3C draft</a>) enables secure, efficient authentication on the Web. It enables users to authenticate onto any site by simply choosing one of the certificates proposed to them by their browser. These certificates can be created by any Web Site for any purpose. A user may have multiple client certificates, bound to one or multiple WebIDs.</p>
<p>Basically, WebID-TLS relies on matching a public key received from a client certificate, to the public key published in the WebID profile obtained by dereferencing the WebID included in the SubjectAlternativeName field of the client certificate. In other words, users must prove they own a public key they publish in their WebID profiles.</p>
<p>WebID-TLS is currently the preferred authentication mechanism in SoLiD. </p>
<p>More information on WebID-TLS can be found here: <a href="http://www.w3.org/2005/Incubator/webid/spec/tls/">http://www.w3.org/2005/Incubator/webid/spec/tls/</a>.</p>
<h3 id="webid-rsa">WebID-RSA</h3>
<p>WebID-RSA is somehow similar to WebID-TLS, in that a public RSA key is published in the WebID profile, and the user will sign a token with the corresponding private key that matches the public key in the profile.</p>
<p>The client receives a secure token from the server, which it signs and then sends back to the server. The implementation of WebID-RSA is somehow similar to <a href="https://tools.ietf.org/html/rfc2617">Digest access authentication</a> in HTTP, in that it reuses the same headers.</p>
<p>Here is a step by step example that covers the authentication handshake. </p>
<p>First, the client attempts to access a protected resource at <code>https://example.org/data/</code>.</p>
<p>REQUEST:</p>
<pre class="prettyprint"><code class=" hljs http"><span class="hljs-request">GET <span class="hljs-string">/data/</span> HTTP/1.1</span>
<span class="hljs-attribute">Host</span>: <span class="hljs-string">example.org</span></code></pre>
<p>RESPONSE:</p>
<pre class="prettyprint"><code class=" hljs http"><span class="hljs-status">HTTP/1.1 <span class="hljs-number">401</span> Unauthorized</span>
<span class="hljs-attribute">WWW-Authenticate</span>: <span class="hljs-string">WebID-RSA nonce="securestring"</span></code></pre>
<p>Next, the client sets the username value to the user’s WebID and signs the concatenated value of <strong>WebID + nonce</strong> before resending the request.</p>
<p>REQUEST:</p>
<pre class="prettyprint"><code class=" hljs avrasm">GET /data/ HTTP/<span class="hljs-number">1.1</span>
<span class="hljs-label">Host:</span> example<span class="hljs-preprocessor">.org</span>
<span class="hljs-label">Authorization:</span> Digest username=<span class="hljs-string">"https://alice.example.org/card#me"</span>,
nonce=<span class="hljs-string">"securestring"</span>,
sig=<span class="hljs-string">"signatureOverUsernamePlusNonce"</span></code></pre>
<p>RESPONSE:</p>
<pre class="prettyprint"><code class=" hljs http"><span class="hljs-status">HTTP/1.1 <span class="hljs-number">200</span> OK</span></code></pre>
<p>One important advantage of WebID-RSA over WebID-TLS is that the same keys can also be used to sign and encrypt data. The way client certificate management is currently implemented in browsers, it does not offer the means to access the certificate keys for purposes other than authentication.</p>
<h2 id="access-control">Access Control</h2>
<h3 id="web-access-control">Web Access Control</h3>
<p>Web Access Control (WAC) is a decentralized system that allows different users and groups various forms of access to resources where users and groups are identified by HTTP URIs. The system is similar to the access control system used within many file systems except that the documents controlled, the users and the groups are all identified by URIs. Users are identified by WebIDs. Groups of users are identified by the URI of a class of users which, if you look it up, returns a list of users in the class. This means a WebID hosted by any server can be a member of a group hosted some other server.</p>
<p><strong>IMPORTANT:</strong> Users do not need to have an account (i.e. WebID) on a given server to have access to documents on it.</p>
<p>Same as for metadata resources, ACL resources are not publicly listed by the server when browsing files (typically when doing a GET on an LDP container). However, they can still be read/written by client apps using the above mentioned ways of writing data. The corresponding ACL resources are advertised and can be discovered when doing HTTP GET/HEAD on regular resources.</p>
<p>Similar to the metadata resource naming convention, SoLiD servers use a specific naming convention for ACL resources. This convention relies on appending a <strong>.acl</strong> suffix to its corresponding resource.</p>
<p>For example, the container <code>https://example.org/data/</code> will have a corresponding ACL resource with the URI: <code>https://example.org/data/.acl</code>. A resource <code>https://example.org/data/test</code> will have a corresponding ACL resource at <code>https://example.org/data/test.acl</code></p>
<p>More information on Web Access Control can be found here: <a href="https://www.w3.org/wiki/WebAccessControl">https://www.w3.org/wiki/WebAccessControl</a>.</p>
<h1 id="software-implementing-solid">Software implementing SoLiD</h1>
<h2 id="servers">Servers</h2>
<ul>
<li>gold – <a href="https://github.com/linkeddata/gold">https://github.com/linkeddata/gold</a></li>
<li>ldphp <strong>[not maintained]</strong> – <a href="https://github.com/linkeddata/ldphp">https://github.com/linkeddata/ldphp</a></li>
<li>ld-node [partial support] – <a href="https://github.com/linkeddata/node-ldp-httpd">https://github.com/linkeddata/node-ldp-httpd</a></li>
<li>meccano [partial support] – <a href="https://github.com/Qatar-Computing-Research-Institute/qcri-crosscloudP/tree/meccano">https://github.com/Qatar-Computing-Research-Institute/qcri-crosscloudP/tree/meccano</a></li>
</ul>
<h2 id="applications">Applications</h2>
<ul>
<li>Warp – <a href="https://github.com/linkeddata/warp">https://github.com/linkeddata/warp</a></li>
<li>Profile editor – <a href="https://github.com/linkeddata/profile-editor">https://github.com/linkeddata/profile-editor</a></li>
<li>Cimba – <a href="https://github.com/linkeddata/cimba">https://github.com/linkeddata/cimba</a></li>
<li>Meeting scheduler – <a href="https://github.com/linkeddata/app-schedule">https://github.com/linkeddata/app-schedule</a></li>
<li>Contacts manager – <a href="https://github.com/mzereba/contacts">https://github.com/mzereba/contacts</a></li>
<li>Todo list – <a href="https://github.com/mzereba/todo">https://github.com/mzereba/todo</a></li>
</ul></div></body>
</html>