Skip to content

Commit 93343d2

Browse files
Refactor LDP API middleware
1 parent b80b708 commit 93343d2

1 file changed

Lines changed: 73 additions & 0 deletions

File tree

lib/api/ldp/api.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
'use strict'
2+
3+
const LdpRequest = require('./ldp-request')
4+
const AclChecker = require('../acl-checker')
5+
const LdpFileStore = require('../storage/ldp-file-store')
6+
7+
class LdpApi {
8+
/**
9+
* @param options.host {SolidHost} server host / config object
10+
*
11+
* @param options.store {LdpFileStore|LdpMemoryStore|LdpQuadStore} storage backend
12+
* (either file system based, or in-memory, or SPARQL based quad store, etc)
13+
*
14+
* @param options.fetch {fetch} whatwg fetch, possibly with delegation in the
15+
* future. Needed for COPY operations, etc.
16+
*
17+
* @param options.acl {AclChecker} ACL checker component
18+
*/
19+
constructor (options) {
20+
this.host = options.host
21+
this.fetch = options.fetch
22+
this.store = options.store || new LdpFileStore(options)
23+
this.acl = options.acl ||
24+
new AclChecker({host: this.host, store: this.store, fetch: this.fetch})
25+
}
26+
27+
/**
28+
* Provides an Express handler for LDP API requests.
29+
* Authentication has already happened earlier in the middleware stack, stored
30+
* in session.
31+
* Usage:
32+
* ```
33+
* app.use('/', ldp.middleware)
34+
* ```
35+
*
36+
* @see https://github.com/solid/solid-architecture/blob/master/server/request-flow.md
37+
*
38+
* @throws {Error} 401 If request not authenticated but resource is non-public
39+
*
40+
* @throws {Error} 404 If resource is not found, OR if found and request
41+
* is not authorized to access it (default behavior, can be overridden by
42+
* owner of resource)
43+
*
44+
* @throws {Error} 403 If request is not authorized to access resource and
45+
* user has enabled "Request permission" action
46+
*
47+
* @throws {Error} 400 If invalid parameters (or error parsing request body,
48+
* for cases like PATCH requests)
49+
*
50+
* @throws {Error} 409 If PATCH operation results in conflict
51+
*
52+
* @throws {Error} 406 If no appropriate representation found (for content type)
53+
*
54+
* @throws {Error} 405 If HTTP method not allowed / not implemented
55+
*/
56+
async middleware (req, res, next) {
57+
try {
58+
// parse target, operation, (optionally) body, preferences, store authn
59+
const request = await LdpRequest.from({req, host: this.host})
60+
61+
// check that operation is permitted (throws error if not)
62+
const permissions = await this.acl.allow(request)
63+
64+
// perform the operation and return a response
65+
await request
66+
.handle({res, permissions, store: this.store, fetch: this.fetch})
67+
} catch (error) {
68+
next(error)
69+
}
70+
}
71+
}
72+
73+
module.exports = LdpApi

0 commit comments

Comments
 (0)