(user, mode, method = 'GET', resourceExists = true)
| 46 | // Returns a fulfilled promise when the user can access the resource |
| 47 | // in the given mode; otherwise, rejects with an HTTP error |
| 48 | async can (user, mode, method = 'GET', resourceExists = true) { |
| 49 | const cacheKey = `${mode}-${user}` |
| 50 | if (this.aclCached[cacheKey]) { |
| 51 | return this.aclCached[cacheKey] |
| 52 | } |
| 53 | this.messagesCached[cacheKey] = this.messagesCached[cacheKey] || [] |
| 54 | |
| 55 | // for method DELETE nearestACL and ACL from parent resource |
| 56 | const acl = await this.getNearestACL(method).catch(err => { |
| 57 | this.messagesCached[cacheKey].push(new HTTPError(err.status || 500, err.message || err)) |
| 58 | }) |
| 59 | if (!acl) { |
| 60 | this.aclCached[cacheKey] = Promise.resolve(false) |
| 61 | return this.aclCached[cacheKey] |
| 62 | } |
| 63 | let resource = rdf.sym(this.resource) |
| 64 | let parentResource = resource |
| 65 | if (!this.resource.endsWith('/')) { parentResource = rdf.sym(ACLChecker.getDirectory(this.resource)) } |
| 66 | if (this.resource.endsWith('/' + this.suffix)) { |
| 67 | resource = rdf.sym(ACLChecker.getDirectory(this.resource)) |
| 68 | parentResource = resource |
| 69 | } |
| 70 | // If this is an ACL, Control mode must be present for any operations |
| 71 | if (this.isAcl(this.resource)) { |
| 72 | mode = 'Control' |
| 73 | const thisResource = this.resource.substring(0, this.resource.length - this.suffix.length) |
| 74 | resource = rdf.sym(thisResource) |
| 75 | parentResource = resource |
| 76 | if (!thisResource.endsWith('/')) parentResource = rdf.sym(ACLChecker.getDirectory(thisResource)) |
| 77 | } |
| 78 | const directory = acl.isContainer ? rdf.sym(ACLChecker.getDirectory(acl.docAcl)) : null |
| 79 | const aclFile = rdf.sym(acl.docAcl) |
| 80 | const aclGraph = acl.docGraph |
| 81 | const agent = user ? rdf.sym(user) : null |
| 82 | const modes = [ACL(mode)] |
| 83 | const agentOrigin = this.agentOrigin |
| 84 | const trustedOrigins = this.trustedOrigins |
| 85 | let originTrustedModes = [] |
| 86 | try { |
| 87 | this.fetch(aclFile.doc().value) |
| 88 | originTrustedModes = await aclCheck.getTrustedModesForOrigin(aclGraph, resource, directory, aclFile, agentOrigin, (uriNode) => { |
| 89 | return this.fetch(uriNode.doc().value, aclGraph) |
| 90 | }) |
| 91 | } catch (e) { |
| 92 | // FIXME: https://github.com/solid/acl-check/issues/23 |
| 93 | // console.error(e.message) |
| 94 | } |
| 95 | |
| 96 | function resourceAccessDenied (modes) { |
| 97 | return aclCheck.accessDenied(aclGraph, resource, directory, aclFile, agent, modes, agentOrigin, trustedOrigins, originTrustedModes) |
| 98 | } |
| 99 | function accessDeniedForAccessTo (modes) { |
| 100 | const accessDeniedAccessTo = aclCheck.accessDenied(aclGraph, directory, null, aclFile, agent, modes, agentOrigin, trustedOrigins, originTrustedModes) |
| 101 | const accessResult = !accessDenied && !accessDeniedAccessTo |
| 102 | return accessResult ? false : accessDenied || accessDeniedAccessTo |
| 103 | } |
| 104 | async function accessdeniedFromParent (modes) { |
| 105 | const parentAclDirectory = ACLChecker.getDirectory(acl.parentAcl) |
no test coverage detected