Fwd: RWW-Play was: Simple WebID, WebID+TLS Protocol, and ACL Dogfood Demo

FYI a new RWW implementation

---------- Forwarded message ----------
From: Henry Story <henry.story@bblfish.net>
Date: 9 August 2013 19:09
Subject: RWW-Play was: Simple WebID, WebID+TLS Protocol, and ACL Dogfood
Demo
To: Hugh Glaser <hg@ecs.soton.ac.uk>
Cc: Kingsley Idehen <kidehen@openlinksw.com>, "public-lod@w3.org Data" <
public-lod@w3.org>, "<public-webid@w3.org>" <public-webid@w3.org>



On 9 Aug 2013, at 18:55, Hugh Glaser <hg@ecs.soton.ac.uk> wrote:

Thanks.
I've looked at quite a bit of this stuff, but still don't see where the ACL
document gets stored and used.

I am beginning to get the sense that I may have to write some code, other
than the ACL rdf to do this.
Surely Apache or something else will do this for me?
Can't I "just" put the ACL in a file (as in htpasswd) and point something
at it?
I certainly don't want to be writing code to make one photo (or simply a
static web site) available.
Or is that the "delegated service" you are talking about?

I've got my fingers crossed here.


You can follow the instructions on installing
https://github.com/stample/rww-play
(It's under the Apache Licence and patches and contributions are welcome )

Then you'll be able to do the following:

An initial implementation of the Linked Data
Platform<http://www.w3.org/2013/ldp/hg/ldp.html> spec
is implemented here. The same way as theApache httpd
server<http://httpd.apache.org/> it
servers resource from the file system and maps them to the web. By default
we map the test_www directory's content to http://localhost:8443/2013/.

The test_www directory starts with a few files to get you going

$ cd test_www$  ls -al
total 48
drwxr-xr-x   4 hjs  admin   340  9 Jul 19:04 .
drwxr-xr-x  15 hjs  admin  1224  9 Jul 19:04 ..
-rw-r--r--   1 hjs  staff   229  1 Jul 08:10 .acl.ttl
-rw-r--r--   1 hjs  admin   109  9 Jul 19:04 .ttl
lrwxr-xr-x   1 hjs  admin     8 27 Jun 20:29 card -> card.ttl
-rw-r--r--   1 hjs  admin   167  7 Jul 22:42 card.acl.ttl
-rw-r--r--   1 hjs  admin   896 27 Jun 21:41 card.ttl
-rw-r--r--   1 hjs  admin   102 27 Jun 22:32 index.ttl
drwxr-xr-x   2 hjs  admin   102 27 Jun 22:56 raw
drwxr-xr-x   3 hjs  admin   204 28 Jun 12:51 test

All files with the same initial name up to the . are considered to work
together, (and in the current implementation are taken care of by the same
agent).

Symbolic links are useful in that they:

   - allow one to write and follow linked data that works on the file
   system without needing to name files by their extensions. For example a
   statement such as [] wac:agent <card#me> can work on the file system
   just as well as on the web.
   - they guide the web agent to which the default representation should be
   - currently they also help the web agent decide which are the resources
   it should serve.

There are three types of resources in this directory:

   - The symbolic links such as card distinguish the default resources that
   can be found by an httpGET on http://localhost:8443/2013/card.
Above the card
   -> card.ttl shows that card has a defaultturtle<http://www.w3.org/TR/turtle/>
    representation.
   - Each resource also comes with a Web Access Control
List<http://www.w3.org/wiki/WebAccessControl>,
   in this example card.acl.ttl, which set access control restrictions on
   resources on the file system.
   - Directories store extra data (in addition to their contents) in the
   .ttl file. (TODO: not quite working)
   - Directories also have their access control list which are published in
   a file named .acl.ttl.

These conventions are provisional implementation decisions, and
improvements are to be expected here . (TODO:

   - updates to the file system are not reflected yet in the server
   - allow symbolic links to point to different default formats )

Let us look at some of these files in more detail

The acl for card just includes the acl for the directory/collection .
(TODO: wac:include has not yet been defined in the Web Access Control
Ontology <http://www.w3.org/ns/auth/acl#>)

$ cat card.acl.ttl
@prefix wac: <http://www.w3.org/ns/auth/acl#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

<> wac:include <.acl> .

The acl for the directory allows access to all resources in the
subdirectories of test_www when accessed from the web as
https://localhost:8443/2013/ only to the user authenticated as<
https://localhost:8443/2013/card#me>. (TODO: wac:regex is not defined in
it's namespace - requires standardisation.)

$ cat .acl.ttl
@prefix acl: <http://www.w3.org/ns/auth/acl#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
[] acl:accessToClass [ acl:regex "https://localhost:8443/2013/.*" ];
   acl:mode acl:Read, acl:Write;
   acl:agent <card#me> .

Since card's acl includes only the above directory acl, <card#me> can read
that file. The following curl <http://curl.haxx.se/docs/>command does not
specify the public and private keys to use for authentication and so fails:

$ curl -i -k https://localhost:8443/2013/card
curl: (56) SSL read: error:14094412:SSL routines:SSL3_READ_BYTES:sslv3
alert bad certificate, errno 0

As curl does not allow WANT TLS connections, but only NEED, a failure to
authenticate closes the connection. Most browsers have the more friendly
behavior allowing the server to return an HTTP error code and an
explanatory body.

Requesting the same resource with a curl that knows which client
certificate to use, the request goes through.

$ curl -i -k --cert ../eg/test-localhost.pem:test
https://localhost:8443/2013/card
HTTP/1.1 200 OK
Link: <https://localhost:8443/2013/card.acl>; rel=acl
Content-Type: text/turtle
Content-Length: 1005


<#me> <http://www.w3.org/ns/auth/cert#key> _:node17vcshtjbx1 ;
    <http://xmlns.com/foaf/0.1/name> "Your
Name"^^<http://www.w3.org/2001/XMLSchema#string> ;
    <http://xmlns.com/foaf/0.1/knows>
<http://bblfish.net/people/henry/card#me> .

_:node17vcshtjbx1 a <http://www.w3.org/ns/auth/cert#RSAPublicKey> ;
    <http://www.w3.org/ns/auth/cert#exponent>
"65537"^^<http://www.w3.org/2001/XMLSchema#integer> ;
    <http://www.w3.org/ns/auth/cert#modulus>
"C13AB88098CF47FCE6B3463FC7E8762036154FE616B956544D50EE63133CC8748D692A00DAFF5331D2564BB1DD5AEF94636ED09EFFA9E776CA6B4A92022BB060BF18FC709936EF43D345289A7FD91C81801A921376D7BCC1C63BD3335FB385A01EC0B71877FCBD1E4525393CCD5F2922D68840945943A675CCAE245222E3EB99B87B180807002063CB78174C1605EA1ECFECF57264F7F60CD8C270175A1D8DD58DFC7D3C56DB273B0494B034EC185B09977CBB530E7E407206107A73CD4B49E17610559F2A81EA8E3F613C3D3C161C06FE5CB114A8522D20DED77CAAA8C761090022F9CD4AF2C8F21DF7CF05287E379225AEA6A3A6610D02C4A44AA7CEED2CC3"^^<http://www.w3.org/2001/XMLSchema#hexBinary>
.

Notice the Link header above. Every resource points to its ACL file in such
a header.

The client certificate in ../eg/test-localhost.pem contains exactly the
private key given in the above cert as you can see by comparing the modulus
and exponents in both representations. This is what allows the
authentication to go through, using the (WebID over TLS protocol)[
http://webid.info/spec/].

$ openssl x509 -in ../eg/test-localhost.pem -inform pem -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 13633800264985240815 (0xbd34fd1b251264ef)
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: O=\xE2\x88\x85, CN=WebID
        Validity
            Not Before: May  3 19:36:33 2013 GMT
            Not After : May  3 19:46:33 2014 GMT
        Subject: O=ReadWriteWeb, CN=test@localhost
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:c1:3a:b8:80:98:cf:47:fc:e6:b3:46:3f:c7:e8:
                    76:20:36:15:4f:e6:16:b9:56:54:4d:50:ee:63:13:
                    3c:c8:74:8d:69:2a:00:da:ff:53:31:d2:56:4b:b1:
                    dd:5a:ef:94:63:6e:d0:9e:ff:a9:e7:76:ca:6b:4a:
                    92:02:2b:b0:60:bf:18:fc:70:99:36:ef:43:d3:45:
                    28:9a:7f:d9:1c:81:80:1a:92:13:76:d7:bc:c1:c6:
                    3b:d3:33:5f:b3:85:a0:1e:c0:b7:18:77:fc:bd:1e:
                    45:25:39:3c:cd:5f:29:22:d6:88:40:94:59:43:a6:
                    75:cc:ae:24:52:22:e3:eb:99:b8:7b:18:08:07:00:
                    20:63:cb:78:17:4c:16:05:ea:1e:cf:ec:f5:72:64:
                    f7:f6:0c:d8:c2:70:17:5a:1d:8d:d5:8d:fc:7d:3c:
                    56:db:27:3b:04:94:b0:34:ec:18:5b:09:97:7c:bb:
                    53:0e:7e:40:72:06:10:7a:73:cd:4b:49:e1:76:10:
                    55:9f:2a:81:ea:8e:3f:61:3c:3d:3c:16:1c:06:fe:
                    5c:b1:14:a8:52:2d:20:de:d7:7c:aa:a8:c7:61:09:
                    00:22:f9:cd:4a:f2:c8:f2:1d:f7:cf:05:28:7e:37:
                    92:25:ae:a6:a3:a6:61:0d:02:c4:a4:4a:a7:ce:ed:
                    2c:c3
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage: critical
                Digital Signature, Non Repudiation, Key Encipherment,
Key Agreement
            Netscape Cert Type:
                SSL Client, S/MIME
            X509v3 Subject Alternative Name: critical
                URI:https://localhost:8443/2013/card#me
            X509v3 Subject Key Identifier:
                3C:1B:CF:F2:E5:59:9A:E8:76:BE:83:1D:64:FB:07:4E:08:C6:FC:14
    Signature Algorithm: sha1WithRSAEncryption
         07:97:78:f5:11:58:00:50:17:91:14:e8:e3:0d:34:22:74:07:
         ae:61:39:87:23:7a:6c:5c:14:af:13:a6:c8:54:ac:55:d4:41:
         25:45:eb:52:90:ff:56:b0:f9:71:be:ec:c8:2c:a1:19:1c:86:
         42:04:3c:55:7c:96:5c:60:70:0a:d7:ed:5b:53:11:56:7e:14:
         32:92:b9:22:a7:c6:ce:ff:77:17:4a:ac:da:02:ac:24:0e:0e:
         35:18:bd:e3:73:00:3b:8a:aa:ec:86:76:66:dd:4b:1b:da:0c:
         c8:a1:d3:27:26:df:bf:6f:55:11:50:3b:8e:04:12:5a:b9:d4:
         7d:7e

We would of course like to make the card world readable so that the
certificate can be used to login to other servers too. To do this the user
<card#me> can append to the <card.acl.ttl> file an authorization
making card world
readable, using an obvious subset of SPARQL
Update<http://www.w3.org/TR/sparql11-update/>

$ cat ../eg/card.acl.update
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
INSERT DATA {[] acl:accessTo <https://localhost:8443/2013/card> ;
   acl:mode acl:Read;
   acl:agentClass foaf:Agent .}$ curl -X PATCH -k -i --data-binary
@../eg/card.acl.update -H "Content-Type: application/sparql-update;
utf-8"  --cert ../eg/test-localhost.pem:test
https://localhost:8443/2013/card.acl

It is now possible to read the card without authentication

$ curl -i -k https://localhost:8443/2013/card
HTTP/1.1 200 OK
Link: <https://localhost:8443/2013/card.acl>; rel=acl
Content-Type: text/turtle[...]

Next we can publish a couch surfing opportunity using HTTP's
POST<http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5>
 method as explained by the LDP
spec<https://dvcs.w3.org/hg/ldpwg/raw-file/default/ldp.html#ldpc-HTTP_POST>

$ curl -X POST -k -i -H "Content-Type: text/turtle; utf-8"  --cert
../eg/test-localhost.pem:test  -H "Slug: couch" -d @../eg/couch.ttl
https://localhost:8443/2013/
HTTP/1.1 201 Created
Location: https://localhost:8443/2013/couch
Content-Length: 0

The Location: header in the above response tells us that the name of the
created resource ishttps://localhost:8443/2013/couch.

We can now look at the contents of the https://localhost:8443/2013/ collection,
where we should see - and do - the new couch resource listed as having been
created by ldp.

$ curl -k -i -X GET --cert ../eg/test-localhost.pem:test
https://localhost:8443/2013/
HTTP/1.1 200 OK
Link: <https://localhost:8443/2013/.acl>; rel=acl
Content-Type: text/turtle
Content-Length: 119


<> <http://www.w3.org/ns/ldp#created> <raw/> , <card> , <test/> , <couch> ;
    a <http://www.w3.org/ns/ldp#Container> .

We can find out about the ACL for this resource using HEAD (TODO: OPTIONS
would be better, but is not implemented yet )

$ curl -X HEAD -k -i --cert ../eg/test-localhost.pem:test
https://localhost:8443/2013/couch
HTTP/1.1 200 OK
Link: <https://localhost:8443/2013/couch.acl>; rel=acl
Content-Type: text/turtle
Content-Length: 0

( TODO: The Content-Length should not be 0 for HEAD. Bug in Play2.0
probably )

So we add the couch acl which gives access to that information in addition
to the default owner of the collection, to two groups of people

$  curl -X PATCH -k -i -H "Content-Type: application/sparql-update;
utf-8"  --cert ../eg/test-localhost.pem:test --data-binary
@../eg/couch.acl.patch https://localhost:8443/2013/couch.acl
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 9

Succeeded

This makes it available to the test user and the members of the WebID and
OuiShare groups. If you have a WebID then try adding yours and test it. You
can also request different formats by changing theAccept: header such as
with the following request for RDF/XML

$ curl -k -i -X GET -H "Accept: application/rdf+xml" --cert
../eg/test-localhost.pem:test https://localhost:8443/2013/couch

or if you prefer rdf/xml over turtle as described by the Content
Negotiation section<http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12>
of
the HTTP1.1 spec:

$ curl -k -i -X GET -H
"Accept:application/rdf+xml;q=0.9,text/turtle;q=0.7" --cert
../eg/test-localhost.pem:test https://localhost:8443/2013/couch

It is then possible to also use SPARQL
queries<http://www.w3.org/TR/sparql11-query/> on
particular resources. (TODO: find a better example)

$ cat ../eg/couch.sparql
PREFIX gr: <http://purl.org/goodrelations/v1#>
SELECT ?D
WHERE {
  [] a <http://bblfish.net/2013/05/10/couch#Surf>;
     gr:description ?D .}
$ curl -X POST -k -i -H "Content-Type: application/sparql-query;
charset=UTF-8" --cert ../eg/test-localhost.pem:test --data-binary
@../eg/couch.sparql https://localhost:8443/2013/couch
HTTP/1.1 200 OK
Content-Type: application/sparql-results+xml
Content-Length: 337

<?xml version='1.0' encoding='UTF-8'?>
<sparql xmlns='http://www.w3.org/2005/sparql-results#'>
    <head>
        <variable name='D'/>
    </head>
    <results>
        <result>
            <binding name='D'>
                <literal
datatype='http://www.w3.org/2001/XMLSchema#string'>Comfortable couch
in Artist Stables</literal>
            </binding>
        </result>
    </results>
</sparql>


Finally if you no longer want the couch surfing opportunity to be published
you can DELETE it. ( It would be better to express that it was sold: DELETEing
resources on the Web is usually bad practice: it breaks the links that
other people set up to your services )

curl -k -i -X DELETE -H "Accept: text/turtle" --cert
../eg/test-localhost.pem:test https://localhost:8443/2013/couch
HTTP/1.1 200 OK
Content-Length: 0

And so the resource no longer is listed in the LDPC

$ curl -k -i -X GET --cert ../eg/test-localhost.pem:test
https://localhost:8443/2013/
HTTP/1.1 200 OK
Link: <https://localhost:8443/2013/.acl>; rel=acl
Content-Type: text/turtle
Content-Length: 109


<> a <http://www.w3.org/ns/ldp#Container> ;
    <http://www.w3.org/ns/ldp#created> <card> , <raw/> , <test/> .

To create a new container one just creates an LDP Resource that contains
the triple<> a ldp:Container.

$ cat ../eg/newContainer.ttl
@prefix ldp: <http://www.w3.org/ns/ldp#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

<> a ldp:Container;
   foaf:topic "A container for some type X of resources";
   foaf:maker <../card#me> .
$ curl -X POST -k -i -H "Content-Type: text/turtle; utf-8"  --cert
../eg/test-localhost.pem:test -H "Slug: XDir" -d
@../eg/newContainer.ttl https://localhost:8443/2013/
HTTP/1.1 201 Created
Location: https://localhost:8443/2013/XDir/
Content-Length: 0

Note that directories can only be deleted if all ldp:created resources were
previously deleted.
<https://github.com/stample/rww-play#creating-a-webid-certificate>Creating
a WebID Certificate

After starting your server you can point your browser to
http://localhost:9000/srv/certgen<http://localhost:9000/srv/certgen?webid=http%3A%2F%2Flocalhost%3A8443%2F2013%2Fcert%23me>
or
to the service over https
<https://localhost:8443/srv/certgen?webid=http%3A%2F%2Flocalhost%3A8443%2F2013%2Fcert%23me>and
create yourself a certificate. For testing purposes and in order to be able
to work without the need for network connectivity use `
http://localhost:8443/2013/cert#me'. The WebID Certificate will be signed
by the agent with Distinguished Name "CN=WebID,O=∅" and added by your
browser to its keychain.

( Todo: later we will add functionality to add create a local webid that
also published the RDF ) To make the WebID valid you will need to publish
the relavant rdf at that document location as explained in the WebID
spec<http://www.w3.org/2005/Incubator/webid/spec/#publishing-the-webid-profile-document>

Received on Saturday, 10 August 2013 00:36:28 UTC