-
Notifications
You must be signed in to change notification settings - Fork 307
Expand file tree
/
Copy pathallow.js
More file actions
82 lines (74 loc) · 2.51 KB
/
Copy pathallow.js
File metadata and controls
82 lines (74 loc) · 2.51 KB
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
module.exports = allow
var ACL = require('../acl-checker')
var $rdf = require('rdflib')
var utils = require('../utils')
var debug = require('../debug.js').ACL
var LegacyResourceMapper = require('../legacy-resource-mapper')
function allow (mode) {
return function allowHandler (req, res, next) {
var ldp = req.app.locals.ldp || {}
if (!ldp.webid) {
return next()
}
// Set up URL to filesystem mapping
const rootUrl = utils.getBaseUri(req)
const mapper = new LegacyResourceMapper({
rootUrl,
rootPath: ldp.root,
includeHost: ldp.multiuser
})
// Determine the actual path of the request
var reqPath = res && res.locals && res.locals.path
? res.locals.path
: req.path
// Check whether the resource exists
ldp.exists(req.hostname, reqPath, (err, ret) => {
// Ensure directories always end in a slash
const stat = err ? null : ret.stream
if (!reqPath.endsWith('/') && stat && stat.isDirectory()) {
reqPath += '/'
}
// Obtain and store the ACL of the requested resource
req.acl = new ACL(rootUrl + reqPath, {
origin: req.get('origin'),
host: req.protocol + '://' + req.get('host'),
fetch: fetchFromLdp(mapper, ldp),
suffix: ldp.suffixAcl,
strictOrigin: ldp.strictOrigin
})
// Ensure the user has the required permission
const userId = req.session.userId
req.acl.can(userId, mode)
.then(() => next(), err => {
debug(`${mode} access denied to ${userId || '(none)'}`)
next(err)
})
})
}
}
/**
* Returns a fetch document handler used by the ACLChecker to fetch .acl
* resources up the inheritance chain.
* The `fetch(uri, callback)` results in the callback, with either:
* - `callback(err, graph)` if any error is encountered, or
* - `callback(null, graph)` with the parsed RDF graph of the fetched resource
* @return {Function} Returns a `fetch(uri, callback)` handler
*/
function fetchFromLdp (mapper, ldp) {
return function fetch (url, callback) {
// Convert the URL into a filename
mapper.mapUrlToFile({ url })
// Read the file from disk
.then(({ path }) => new Promise((resolve, reject) => {
ldp.readFile(path, (e, c) => e ? reject(e) : resolve(c))
}))
// Parse the file as Turtle
.then(body => {
const graph = $rdf.graph()
$rdf.parse(body, graph, url, 'text/turtle')
return graph
})
// Return the ACL graph
.then(graph => callback(null, graph), callback)
}
}