| 171 | // DELETE uses docAcl when docAcl is parent to the resource |
| 172 | // or docAcl and parentAcl when docAcl is the ACL of the Resource |
| 173 | async getNearestACL (method) { |
| 174 | const { resource } = this |
| 175 | let isContainer = false |
| 176 | const possibleACLs = this.getPossibleACLs() |
| 177 | const acls = [...possibleACLs] |
| 178 | let returnAcl = null |
| 179 | let returnParentAcl = null |
| 180 | let parentAcl = null |
| 181 | let parentGraph = null |
| 182 | let docAcl = null |
| 183 | let docGraph = null |
| 184 | while (possibleACLs.length > 0 && !returnParentAcl) { |
| 185 | const acl = possibleACLs.shift() |
| 186 | let graph |
| 187 | try { |
| 188 | this.requests[acl] = this.requests[acl] || this.fetch(acl) |
| 189 | graph = await this.requests[acl] |
| 190 | } catch (err) { |
| 191 | if (err && (err.code === 'ENOENT' || err.status === 404)) { |
| 192 | // only set isContainer before docAcl |
| 193 | if (!docAcl) isContainer = true |
| 194 | continue |
| 195 | } |
| 196 | debug(err) |
| 197 | throw err |
| 198 | } |
| 199 | // const relative = resource.replace(acl.replace(/[^/]+$/, ''), './') |
| 200 | // debug(`Using ACL ${acl} for ${relative}`) |
| 201 | if (!docAcl) { |
| 202 | docAcl = acl |
| 203 | docGraph = graph |
| 204 | // parentAcl is only needed for DELETE |
| 205 | if (method !== 'DELETE') returnParentAcl = true |
| 206 | } else { |
| 207 | parentAcl = acl |
| 208 | parentGraph = graph |
| 209 | returnParentAcl = true |
| 210 | } |
| 211 | |
| 212 | returnAcl = { docAcl, docGraph, isContainer, parentAcl, parentGraph } |
| 213 | } |
| 214 | if (!returnAcl) { |
| 215 | throw new HTTPError(500, `No ACL found for ${resource}, searched in \n- ${acls.join('\n- ')}`) |
| 216 | } |
| 217 | // fetch group |
| 218 | let groupNodes = returnAcl.docGraph.statementsMatching(null, ACL('agentGroup'), null) |
| 219 | let groupUrls = groupNodes.map(node => node.object.value.split('#')[0]) |
| 220 | await Promise.all(groupUrls.map(async groupUrl => { |
| 221 | try { |
| 222 | const docGraph = await this.fetch(groupUrl, returnAcl.docGraph) |
| 223 | this.requests[groupUrl] = this.requests[groupUrl] || docGraph |
| 224 | } catch (e) {} // failed to fetch groupUrl |
| 225 | })) |
| 226 | if (parentAcl) { |
| 227 | groupNodes = returnAcl.parentGraph.statementsMatching(null, ACL('agentGroup'), null) |
| 228 | groupUrls = groupNodes.map(node => node.object.value.split('#')[0]) |
| 229 | await Promise.all(groupUrls.map(async groupUrl => { |
| 230 | try { |