| 28 | |
| 29 | // Verifies whether the user is allowed to perform Append PUT on the target |
| 30 | async function checkPermission (request, resourceExists) { |
| 31 | // If no ACL object was passed down, assume permissions are okay. |
| 32 | if (!request.acl) return Promise.resolve() |
| 33 | // At this point, we already assume append access, |
| 34 | // we might need to perform additional checks. |
| 35 | let modes = [] |
| 36 | // acl:default Write is required for PUT when Resource Exists |
| 37 | if (resourceExists) modes = ['Write'] |
| 38 | // if (resourceExists && request.originalUrl.endsWith('.acl')) modes = ['Control'] |
| 39 | const { acl, session: { userId } } = request |
| 40 | |
| 41 | const allowed = await Promise.all(modes.map(mode => acl.can(userId, mode, request.method, resourceExists))) |
| 42 | const allAllowed = allowed.reduce((memo, allowed) => memo && allowed, true) |
| 43 | if (!allAllowed) { |
| 44 | // check owner with Control |
| 45 | // const ldp = request.app.locals.ldp |
| 46 | // if (request.path.endsWith('.acl') && userId === await ldp.getOwner(request.hostname)) return Promise.resolve() |
| 47 | |
| 48 | const errors = await Promise.all(modes.map(mode => acl.getError(userId, mode))) |
| 49 | const error = errors.filter(error => !!error) |
| 50 | .reduce((prevErr, err) => prevErr.status > err.status ? prevErr : err, { status: 0 }) |
| 51 | return Promise.reject(error) |
| 52 | } |
| 53 | return Promise.resolve() |
| 54 | } |
| 55 | |
| 56 | // TODO could be renamed as putResource (it now covers container and non-container) |
| 57 | async function putStream (req, res, next, stream = req) { |