@@ -4,8 +4,10 @@ const PermissionSet = require('solid-permissions').PermissionSet
44const rdf = require ( 'rdflib' )
55const debug = require ( './debug' ) . ACL
66const HTTPError = require ( './http-error' )
7+ const aclCheck = require ( 'acl-check' )
78
89const DEFAULT_ACL_SUFFIX = '.acl'
10+ const ACL = rdf . Namespace ( 'http://www.w3.org/ns/auth/acl#' )
911
1012// An ACLChecker exposes the permissions on a specific resource
1113class ACLChecker {
@@ -22,34 +24,77 @@ class ACLChecker {
2224
2325 // Returns a fulfilled promise when the user can access the resource
2426 // in the given mode, or rejects with an HTTP error otherwise
25- can ( user , mode ) {
27+ async can ( user , mode ) {
2628 // If this is an ACL, Control mode must be present for any operations
2729 if ( this . isAcl ( this . resource ) ) {
2830 mode = 'Control'
2931 }
3032
3133 // Obtain the permission set for the resource
32- if ( ! this . _permissionSet ) {
33- this . _permissionSet = this . getNearestACL ( )
34- . then ( acl => this . getPermissionSet ( acl ) )
35- }
34+ // this.acl.graph
35+ // this.resource
36+ // this.acl.isContainer ? this.resource : null
37+ // this.acl.acl
38+ // user
39+ // ACL(mode)
40+ // this.origin
41+ // this.trustedOrigins
42+
43+ // console.log('ACL', this.origin, this.trustedOrigins)
44+ // console.log(aclCheck.accessDenied)
45+ // if (!this._permissionSet) {
46+ // this._permissionSet = this.getNearestACL()
47+ // .then(acl => this.getPermissionSet(acl))
48+ // }
49+
50+ // aclCheck.checkAccess(acl.graph, this.resource)
3651
3752 // Check the resource's permissions
38- return this . _permissionSet
39- . then ( acls => this . checkAccess ( acls , user , mode ) )
40- . catch ( ( ) => {
41- if ( ! user ) {
42- throw new HTTPError ( 401 , `Access to ${ this . resource } requires authorization` )
43- } else {
44- throw new HTTPError ( 403 , `Access to ${ this . resource } denied for ${ user } ` )
45- }
46- } )
53+ this . acl = this . acl || await this . getNearestACL ( )
54+ const resource = rdf . sym ( this . resource )
55+ // const directory = this.acl.isContainer ? this.resource : null
56+ const directory = this . acl . isContainer ? rdf . sym ( ACLChecker . getDirectory ( this . acl . acl ) ) : null
57+ // console.log(ACLChecker.getDirectory(this.acl.acl))
58+ const aclFile = rdf . sym ( this . acl . acl )
59+ // const agent = rdf.sym(user)
60+ const agent = user ? rdf . sym ( user ) : null
61+ // console.log('ACL agent', agent)
62+ // console.log('ACL FILE', this.resource, this.acl.acl)
63+ const modes = [ ACL ( mode ) ]
64+ const origin = this . origin ? rdf . sym ( this . origin ) : null
65+ const trustedOrigins = this . trustedOrigins ? this . trustedOrigins . map ( trustedOrigin => rdf . sym ( trustedOrigin ) ) : null
66+ const accessDenied = aclCheck . accessDenied ( this . acl . graph , resource , directory , aclFile , agent , modes , origin , trustedOrigins )
67+ console . log ( 'ACCESS DENIED' , accessDenied , '\n\n' )
68+ if ( accessDenied && user ) {
69+ throw new HTTPError ( 403 , `Access to ${ this . resource } denied for ${ user } ` )
70+ } else if ( accessDenied ) {
71+ throw new HTTPError ( 401 , `Access to ${ this . resource } requires authorization` )
72+ }
73+ return Promise . resolve ( true )
74+ }
75+
76+ // return Promise.resolve(true)
77+ // return this._permissionSet
78+ // .then(acls => this.checkAccess(acls, user, mode))
79+ // .catch(() => {
80+ // if (!user) {
81+ // throw new HTTPError(401, `Access to ${this.resource} requires authorization`)
82+ // } else {
83+ // throw new HTTPError(403, `Access to ${this.resource} denied for ${user}`)
84+ // }
85+ // })
86+
87+ static getDirectory ( aclFile ) {
88+ const parts = aclFile . split ( '/' )
89+ parts . pop ( )
90+ return `${ parts . join ( '/' ) } /`
4791 }
4892
49- // Gets the ACL that applies to the resource
50- getNearestACL ( ) {
93+ // Gets the ACL that applies to the resource
94+ async getNearestACL ( ) {
5195 const { resource } = this
5296 let isContainer = false
97+ // let directory = null
5398 // Create a cascade of reject handlers (one for each possible ACL)
5499 const nearestACL = this . getPossibleACLs ( ) . reduce ( ( prevACL , acl ) => {
55100 return prevACL . catch ( ( ) => new Promise ( ( resolve , reject ) => {
@@ -68,11 +113,11 @@ class ACLChecker {
68113 return nearestACL . catch ( e => { throw new Error ( 'No ACL resource found' ) } )
69114 }
70115
71- // Gets all possible ACL paths that apply to the resource
116+ // Gets all possible ACL paths that apply to the resource
72117 getPossibleACLs ( ) {
73118 // Obtain the resource URI and the length of its base
74119 let { resource : uri , suffix } = this
75- const [ { length : base } ] = uri . match ( / ^ [ ^ : ] + : \/ * [ ^ / ] + / )
120+ const [ { length : base } ] = uri . match ( / ^ [ ^ : ] + : \/ * [ ^ / ] + / )
76121
77122 // If the URI points to a file, append the file's ACL
78123 const possibleAcls = [ ]
@@ -87,7 +132,7 @@ class ACLChecker {
87132 return possibleAcls
88133 }
89134
90- // Tests whether the permissions allow a given operation
135+ // Tests whether the permissions allow a given operation
91136 checkAccess ( permissionSet , user , mode ) {
92137 const options = { fetchGraph : this . fetchGraph }
93138 return permissionSet . checkAccess ( this . resource , user , mode , options )
@@ -100,7 +145,7 @@ class ACLChecker {
100145 } )
101146 }
102147
103- // Gets the permission set for the given ACL
148+ // Gets the permission set for the given ACL
104149 getPermissionSet ( { acl, graph, isContainer } ) {
105150 if ( ! graph || graph . length === 0 ) {
106151 debug ( 'ACL ' + acl + ' is empty' )
0 commit comments