Skip to content

Commit 2dd0789

Browse files
committed
allow PUT Append for new resource
1 parent d58fee0 commit 2dd0789

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

lib/handlers/put.js

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,49 @@ async function handler (req, res, next) {
2121
return putStream(req, res, next)
2222
}
2323

24-
// TODO could be renamed as putResource (it now covers container and non-container)
24+
// Verifies whether the user is allowed to perform Append PUT on the target
25+
async function checkPermission (request, resourceExists) {
26+
// If no ACL object was passed down, assume permissions are okay.
27+
if (!request.acl) return Promise.resolve()
28+
// At this point, we already assume append access,
29+
// we might need to perform additional checks.
30+
let modes = []
31+
// acl:default Write is required for PUT when Resource Exists
32+
if (resourceExists) modes = ['Write']
33+
const { acl, session: { userId } } = request
34+
35+
const allowed = await Promise.all(modes.map(mode => acl.can(userId, mode, request.method, resourceExists)))
36+
const allAllowed = allowed.reduce((memo, allowed) => memo && allowed, true)
37+
if (!allAllowed) {
38+
// check owner with Control
39+
const ldp = request.app.locals.ldp
40+
if (request.path.endsWith('.acl') && userId === await ldp.getOwner(request.hostname)) return Promise.resolve()
41+
42+
const errors = await Promise.all(modes.map(mode => acl.getError(userId, mode)))
43+
const error = errors.filter(error => !!error)
44+
.reduce((prevErr, err) => prevErr.status > err.status ? prevErr : err, { status: 0 })
45+
return Promise.reject(error)
46+
}
47+
return Promise.resolve()
48+
}
49+
2550
async function putStream (req, res, next, stream = req) {
2651
const ldp = req.app.locals.ldp
52+
// try {
53+
// Obtain details of the target resource
54+
// const ldp = req.app.locals.ldp
55+
// let path, contentType
56+
let resourceExists = true
2757
try {
58+
// First check if the file already exists
59+
// ({ path, contentType } = await ldp.resourceMapper.mapUrlToFile({ url: req }))
60+
await ldp.resourceMapper.mapUrlToFile({ url: req, createIfNotExists: true })
61+
} catch (err) {
62+
// await ldp.checkItemName(req)
63+
resourceExists = false
64+
}
65+
try {
66+
await checkPermission(req, resourceExists)
2867
debug('test ' + req.get('content-type') + getContentType(req.headers))
2968
await ldp.put(req, stream, getContentType(req.headers))
3069
debug('succeded putting the file/folder')
@@ -37,6 +76,22 @@ async function putStream (req, res, next, stream = req) {
3776
}
3877
}
3978

79+
// TODO could be renamed as putResource (it now covers container and non-container)
80+
/* async function putStream (req, res, next, stream = req) {
81+
const ldp = req.app.locals.ldp
82+
try {
83+
debug('test ' + req.get('content-type') + getContentType(req.headers))
84+
await ldp.put(req, stream, getContentType(req.headers))
85+
debug('succeded putting the file/folder')
86+
res.sendStatus(201)
87+
return next()
88+
} catch (err) {
89+
debug('error putting the file/folder:' + err.message)
90+
err.message = 'Can\'t write file/folder: ' + err.message
91+
return next(err)
92+
}
93+
} */
94+
4095
// needed to avoid breaking access with bad acl
4196
// or breaking containement triples for meta
4297
function putValidRdf (req, res, next) {

lib/ldp-middleware.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function LdpMiddleware (corsSettings) {
2525
router.get('/*', index, allow('Read'), header.addPermissions, get)
2626
router.post('/*', allow('Append'), post)
2727
router.patch('/*', allow('Append'), patch)
28-
router.put('/*', allow('Write'), put)
28+
router.put('/*', allow('Append'), put)
2929
router.delete('/*', allow('Write'), del)
3030

3131
return router

0 commit comments

Comments
 (0)