@@ -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+
2550async 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
4297function putValidRdf ( req , res , next ) {
0 commit comments