11'use strict'
22/* eslint-disable node/no-deprecated-api */
33
4- // const { dirname } = require('path')
4+ const { dirname } = require ( 'path' )
55const rdf = require ( 'rdflib' )
66const debug = require ( './debug' ) . ACL
77// const debugCache = require('./debug').cache
@@ -77,12 +77,21 @@ class ACLChecker {
7777 parentResource = resource
7878 if ( ! thisResource . endsWith ( '/' ) ) parentResource = rdf . sym ( ACLChecker . getDirectory ( thisResource ) )
7979 }
80+ /* let resource = rdf.sym(this.resource)
81+ if (this.resource.endsWith('/' + this.suffix)) {
82+ resource = rdf.sym(ACLChecker.getDirectory(this.resource))
83+ }
84+ // If this is an ACL, Control mode must be present for any operations
85+ if (this.isAcl(this.resource)) {
86+ mode = 'Control'
87+ resource = rdf.sym(this.resource.substring(0, this.resource.length - this.suffix.length))
88+ } */
8089 // If the slug is an acl, reject
8190 /* if (this.isAcl(this.slug)) {
8291 this.aclCached[cacheKey] = Promise.resolve(false)
8392 return this.aclCached[cacheKey]
8493 } */
85- const directory = acl . isContainer ? rdf . sym ( ACLChecker . getDirectory ( acl . docAcl ) ) : null
94+ let directory = acl . isContainer ? rdf . sym ( ACLChecker . getDirectory ( acl . docAcl ) ) : null
8695 const aclFile = rdf . sym ( acl . docAcl )
8796 const aclGraph = acl . docGraph
8897 const agent = user ? rdf . sym ( user ) : null
@@ -102,6 +111,12 @@ class ACLChecker {
102111 let accessDenied = aclCheck . accessDenied ( aclGraph , resource , directory , aclFile , agent , modes , agentOrigin , trustedOrigins , originTrustedModes )
103112
104113 function accessDeniedForAccessTo ( mode ) {
114+ const accessDeniedAccessTo = aclCheck . accessDenied ( aclGraph , directory , null , aclFile , agent , [ ACL ( mode ) ] , agentOrigin , trustedOrigins , originTrustedModes )
115+ const accessResult = ! accessDenied && ! accessDeniedAccessTo
116+ accessDenied = accessResult ? false : accessDenied || accessDeniedAccessTo
117+ // debugCache('accessDenied result ' + accessDenied)
118+ }
119+ function accessDeniedForAccessToParent ( mode ) {
105120 const parentAclDirectory = ACLChecker . getDirectory ( acl . parentAcl )
106121 const parentDirectory = parentResource === parentAclDirectory ? null : rdf . sym ( parentAclDirectory )
107122 const accessDeniedAccessTo = aclCheck . accessDenied ( acl . parentGraph , parentResource , parentDirectory , rdf . sym ( acl . parentAcl ) , agent , [ ACL ( mode ) ] , agentOrigin , trustedOrigins , originTrustedModes )
@@ -110,16 +125,26 @@ class ACLChecker {
110125 // debugCache('accessDenied result ' + accessDenied)
111126 }
112127 // For create and update HTTP methods
113- if ( ( method === 'PUT' || method === 'PATCH' || method === 'COPY' ) ) { // && !aclFile.value.endsWith('/.acl')) {
114- // accessTo Append from parent is required
115- accessDeniedForAccessTo ( 'Append' )
128+ if ( ( method === 'PUT' || method === 'PATCH' || method === 'COPY' ) ) {
129+ // if resource and acl have same parent container,
130+ // and resource does not exist, then accessTo Append from parent is required
131+ if ( directory && directory . value === dirname ( aclFile . value ) + '/' && ! resourceExists ) {
132+ accessDeniedForAccessTo ( 'Append' )
133+ }
116134 }
117135
118136 // For delete HTTP method
119- if ( ( method === 'DELETE' ) ) { // } && !aclFile.value.endsWith('/.acl')) {
120- // accessTo Write from parent is required
121- accessDeniedForAccessTo ( 'Write' )
137+ if ( ( method === 'DELETE' ) ) {
138+ // if resource and acl have same parent container,
139+ // then accessTo Write from parent is required
140+ if ( ! directory && aclFile . value . endsWith ( '/.acl' ) ) directory = rdf . sym ( dirname ( aclFile . value ) + '/' )
141+ if ( ( directory && directory . value === dirname ( aclFile . value ) + '/' ) ) {
142+ accessDeniedForAccessTo ( 'Write' )
143+ } else {
144+ accessDeniedForAccessToParent ( 'Write' )
145+ }
122146 }
147+
123148 if ( accessDenied && user ) {
124149 this . messagesCached [ cacheKey ] . push ( HTTPError ( 403 , accessDenied ) )
125150 } else if ( accessDenied ) {
@@ -150,12 +175,13 @@ class ACLChecker {
150175 const possibleACLs = this . getPossibleACLs ( )
151176 const acls = [ ...possibleACLs ]
152177 let returnAcl = null
153- let returnParentAcl = null
178+ // let returnParentAcl = null
154179 let parentAcl = null
155180 let parentGraph = null
156181 let docAcl = null
157182 let docGraph = null
158- while ( possibleACLs . length > 0 && ! returnParentAcl ) {
183+ // while (possibleACLs.length > 0 && !returnParentAcl) {
184+ while ( possibleACLs . length > 0 && ! returnAcl ) {
159185 const acl = possibleACLs . shift ( )
160186 let graph
161187 try {
@@ -174,19 +200,21 @@ class ACLChecker {
174200 if ( ! docAcl ) {
175201 docAcl = acl
176202 docGraph = graph
177- if ( ( possibleACLs . length === 0 ) || docAcl . endsWith ( '/.acl' ) ) {
203+ /* if ((possibleACLs.length === 0)) { // || docAcl.endsWith('/.acl')) {
178204 parentAcl = acl // alain
179205 parentGraph = graph // alain
180206 returnParentAcl = true
181- }
207+ } */
182208 } else {
183209 parentAcl = acl
184210 parentGraph = graph
185- returnParentAcl = true
211+ returnAcl = true
186212 }
213+ // returnParentAcl = true
214+
187215 returnAcl = { docAcl, docGraph, isContainer, parentAcl, parentGraph }
188216 }
189- if ( ! returnParentAcl ) {
217+ if ( ! returnAcl ) {
190218 throw new HTTPError ( 500 , `No ACL found for ${ resource } , searched in \n- ${ acls . join ( '\n- ' ) } ` )
191219 }
192220 const groupNodes = returnAcl . docGraph . statementsMatching ( null , ACL ( 'agentGroup' ) , null )
@@ -197,7 +225,10 @@ class ACLChecker {
197225 this . requests [ groupUrl ] = this . requests [ groupUrl ] || docGraph
198226 } catch ( e ) { } // failed to fetch groupUrl
199227 } ) )
200-
228+ if ( ! parentAcl ) { // alain is it needed
229+ parentAcl = docAcl
230+ parentGraph = docGraph
231+ }
201232 return returnAcl
202233 }
203234
0 commit comments