summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVivien Kraus <vivien@planete-kraus.eu>2021-06-25 17:03:54 +0200
committerVivien Kraus <vivien@planete-kraus.eu>2021-06-27 00:19:51 +0200
commitfdcf468169983cafe603f125b5521e38018d808d (patch)
tree9f3c1a07d1e4e6225e35da3f2de91eb8287a7274
parent225749ff12fb1e78ae956296c9b42eca10489615 (diff)
fixup! Implement the GET, HEAD, OPTIONS methods for the server
-rw-r--r--src/scm/webid-oidc/server/read.scm308
1 files changed, 142 insertions, 166 deletions
diff --git a/src/scm/webid-oidc/server/read.scm b/src/scm/webid-oidc/server/read.scm
index bff241a..895be46 100644
--- a/src/scm/webid-oidc/server/read.scm
+++ b/src/scm/webid-oidc/server/read.scm
@@ -32,25 +32,6 @@
))
-(define (check-mode server-name path owner user http-get expected-mode)
- (let ((modes (wac-get-modes server-name path user #:http-get http-get)))
- (define (check-modes modes)
- (if (null? modes)
- (raise-exception
- (make-forbidden path user owner expected-mode))
- (or
- (equal? (car modes) expected-mode)
- (check-modes (cdr modes)))))
- (check-modes modes)))
-
-(define (check-acl-can-read server-name path owner user http-get)
- (check-mode server-name path owner user http-get
- (string->uri "http://www.w3.org/ns/auth/acl#Read")))
-
-(define (check-acl-can-control server-name path owner user http-get)
- (check-mode server-name path owner user http-get
- (string->uri "http://www.w3.org/ns/auth/acl#Control")))
-
(define* (read server-name owner user path
#:key
(http-get http-get))
@@ -58,150 +39,145 @@
(with-session
(lambda (load-content-type load-contained load-static-content
do-create do-delete)
- (let ((acl? (string-suffix? ".acl" path))
- (description? (string-suffix? ".meta" path))
- (base-path
- (cond
- ((string-suffix? ".acl" path)
- (substring path 0 (- (string-length path) (string-length ".acl"))))
- ((string-suffix? ".meta" path)
- (substring path 0 (- (string-length path) (string-length ".meta"))))
- (else path)))
- (container? (string-suffix? path "/"))
- (root? (equal? path "/")))
- (unless (equal? user owner)
- (if acl?
- (check-acl-can-control server-name base-path owner user http-get)
- (check-acl-can-read server-name path owner user http-get)))
- (receive (main-etag auxiliary)
- (read-path base-path)
- (let ((relevant-etag
- (cond
- (acl?
- (assoc-ref auxiliary
- (string->uri "http://www.w3.org/ns/auth/acl#accessControl")))
- (description?
- (assoc-ref auxiliary
- (string->uri "https://www.w3.org/ns/iana/link-relations/relation#describedby")))
- (else
- main-etag)))
- (non-rdf? (not (eq? (load-content-type main-etag) 'text/turtle)))
- (auxiliary? (or acl? description?))
- (allow (cond (root? '(GET HEAD OPTIONS POST PUT))
- (container? '(GET HEAD OPTIONS POST PUT DELETE))
- (else '(GET HEAD OPTIONS PUT DELETE)))))
- (unless relevant-etag
- (raise-exception
- (make-auxiliary-resource-absent
- base-path
- (cond
- (acl?
- (assoc-ref auxiliary
- (string->uri "http://www.w3.org/ns/auth/acl#accessControl")))
- (description?
- (assoc-ref auxiliary
- (string->uri "https://www.w3.org/ns/iana/link-relations/relation#describedby")))))))
- (let ((description (and non-rdf? (string-append path ".meta")))
- (accept-put (if (or container? auxiliary?) "text/turtle" "*/*")))
- (values
- ;; Headers
- (let ((links
- (let ((type
- (cons
- (if container?
- (string->uri "http://www.w3.org/ns/ldp#BasicContainer")
- (string->uri "http://www.w3.org/ns/ldp#Resource"))
- '((rel . "type"))))
- (acl
- (and (not acl?)
- (cons
- (build-uri
- 'https
- #:userinfo (uri-userinfo server-name)
- #:host (uri-host server-name)
- #:port (uri-port server-name)
- #:path (string-append path ".acl"))
- '((rel . "acl")))))
- (describedby
- (and non-rdf?
- (cons
- (build-uri
- 'https
- #:userinfo (uri-userinfo server-name)
- #:host (uri-host server-name)
- #:port (uri-port server-name)
- #:path (string-append path ".acl"))
- '((rel . "describedby")))))
- (describes
- (and description?
- (cons
- (build-uri
- 'https
- #:userinfo (uri-userinfo server-name)
- #:host (uri-host server-name)
- #:port (uri-port server-name)
- #:path (string-append path ".acl"))
- '((rel . "https://www.w3.org/ns/iana/link-relations/relation#describes")))))
- (storage
- (and root?
- (list
- (list
- (string->uri "http://www.w3.org/ns/pim/space#Storage")
- '(rel . "type"))
- (list
- owner
- '(rel . "http://www.w3.org/ns/solid/terms#owner"))))))
- (append
- (list type)
- (if acl (list acl) '())
- (if describedby (list describedby) '())
- (if describes (list describes) '())
- (or storage '())))))
- `((link . ,links)
- (allow . ,allow)
- (accept-put . ,accept-put)
- (content-type
- . (,(if container?
- 'text/turtle
- (load-content-type relevant-etag))))
- (etag . (,relevant-etag . #f))))
- ;; Content
- (if container?
- (let ((static-graph
- (fetch
- (build-uri
- 'https
- #:userinfo (uri-userinfo server-name)
- #:host (uri-host server-name)
- #:port (uri-port server-name)
- #:path path)
- #:http-get
- (lambda (uri . args)
- (values
- (build-response
- #:headers `((content-type ,(load-content-type relevant-etag))))
- (load-static-content relevant-etag))))))
- (let ((final-graph
- (reverse
- (append
- (map (lambda (contained-path)
- (make-rdf-triple
- (uri->string
- (build-uri
- 'https
- #:userinfo (uri-userinfo server-name)
- #:host (uri-host server-name)
- #:port (uri-port server-name)
- #:path path))
- "http://www.w3.org/ns/ldp#contains"
- (uri->string
- (build-uri
- 'https
- #:userinfo (uri-userinfo server-name)
- #:host (uri-host server-name)
- #:port (uri-port server-name)
- #:path contained-path))))
- (load-contained relevant-etag))
- static-graph))))
- (rdf->turtle final-graph)))
- (load-static-content relevant-etag))))))))))
+ (check-acl-can-read server-name path owner user #:http-get http-get)
+ (receive (base-path path-type)
+ (base-path path)
+ (let ((container? (container-path? path))
+ (root? (root-path? path))
+ (acl?
+ (equal? path-type
+ (string->uri
+ "http://www.w3.org/ns/auth/acl#accessControl")))
+ (description?
+ (equal?
+ path-type
+ (string->uri
+ "https://www.w3.org/ns/iana/link-relations/relation#describedby"))))
+ (receive (main-etag auxiliary)
+ (read-path base-path)
+ (let ((relevant-etag
+ (if path-type
+ (assoc-ref auxiliary path-type)
+ main-etag))
+ (needs-meta?
+ (case (load-content-type main-etag)
+ ((text/turtle)
+ #f)
+ (else #t)))
+ (needs-acl?
+ (not acl?))
+ (allow (cond (root? '(GET HEAD OPTIONS POST PUT))
+ (container? '(GET HEAD OPTIONS POST PUT DELETE))
+ (else '(GET HEAD OPTIONS PUT DELETE)))))
+ (unless relevant-etag
+ (raise-exception
+ (make-auxiliary-resource-absent base-path path-type)))
+ (let ((accept-put (if (or container? path-type) "text/turtle" "*/*")))
+ (values
+ ;; Headers
+ (let ((links
+ (let ((type
+ (cons
+ (if container?
+ (string->uri "http://www.w3.org/ns/ldp#BasicContainer")
+ (string->uri "http://www.w3.org/ns/ldp#Resource"))
+ '((rel . "type"))))
+ (acl
+ (and needs-acl?
+ (cons
+ (build-uri
+ 'https
+ #:userinfo (uri-userinfo server-name)
+ #:host (uri-host server-name)
+ #:port (uri-port server-name)
+ #:path (derive-path
+ base-path
+ (string->uri
+ "http://www.w3.org/ns/auth/acl#accessControl")))
+ '((rel . "acl")))))
+ (describedby
+ (and needs-meta?
+ (cons
+ (build-uri
+ 'https
+ #:userinfo (uri-userinfo server-name)
+ #:host (uri-host server-name)
+ #:port (uri-port server-name)
+ #:path (derive-path
+ base-path
+ (string->uri
+ "https://www.w3.org/ns/iana/link-relations/relation#describedby")))
+ '((rel . "describedby")))))
+ (describes
+ (and description?
+ (cons
+ (build-uri
+ 'https
+ #:userinfo (uri-userinfo server-name)
+ #:host (uri-host server-name)
+ #:port (uri-port server-name)
+ #:path base-path)
+ '((rel . "https://www.w3.org/ns/iana/link-relations/relation#describes")))))
+ (storage
+ (and root?
+ (list
+ (list
+ (string->uri "http://www.w3.org/ns/pim/space#Storage")
+ '(rel . "type"))
+ (list
+ owner
+ '(rel . "http://www.w3.org/ns/solid/terms#owner"))))))
+ (append
+ (list type)
+ (if acl (list acl) '())
+ (if describedby (list describedby) '())
+ (if describes (list describes) '())
+ (or storage '())))))
+ `((link . ,links)
+ (allow . ,allow)
+ (accept-put . ,accept-put)
+ (content-type
+ . (,(if container?
+ 'text/turtle
+ (load-content-type relevant-etag))))
+ (etag . (,relevant-etag . #f))))
+ ;; Content
+ (if container?
+ (let ((static-graph
+ (fetch
+ (build-uri
+ 'https
+ #:userinfo (uri-userinfo server-name)
+ #:host (uri-host server-name)
+ #:port (uri-port server-name)
+ #:path path)
+ #:http-get
+ (lambda (uri . args)
+ (values
+ (build-response
+ #:headers `((content-type ,(load-content-type relevant-etag))))
+ (load-static-content relevant-etag))))))
+ (let ((final-graph
+ (reverse
+ (append
+ (map (lambda (contained-path)
+ (make-rdf-triple
+ (uri->string
+ (build-uri
+ 'https
+ #:userinfo (uri-userinfo server-name)
+ #:host (uri-host server-name)
+ #:port (uri-port server-name)
+ #:path path))
+ "http://www.w3.org/ns/ldp#contains"
+ (uri->string
+ (build-uri
+ 'https
+ #:userinfo (uri-userinfo server-name)
+ #:host (uri-host server-name)
+ #:port (uri-port server-name)
+ #:path contained-path))))
+ (load-contained relevant-etag))
+ static-graph))))
+ (rdf->turtle final-graph)))
+ (load-static-content relevant-etag)))))))))))