@@ -136,14 +136,14 @@ public void filter(ContainerRequestContext request) throws IOException
136136 if (request .getSecurityContext ().getUserPrincipal () instanceof Agent ) agent = ((Agent )(request .getSecurityContext ().getUserPrincipal ()));
137137 else agent = null ; // public access
138138
139- Resource authorization = authorize (request , agent , accessMode );
140- if (authorization == null )
139+ Model authorizations = authorize (request , agent , accessMode );
140+ if (authorizations == null )
141141 {
142142 if (log .isTraceEnabled ()) log .trace ("Access not authorized for request URI: {} and access mode: {}" , request .getUriInfo ().getAbsolutePath (), accessMode );
143143 throw new AuthorizationException ("Access not authorized for request URI" , request .getUriInfo ().getAbsolutePath (), accessMode );
144144 }
145145 else // authorization successful
146- request .setProperty (AuthorizationContext .class .getCanonicalName (), new AuthorizationContext (authorization . getModel () ));
146+ request .setProperty (AuthorizationContext .class .getCanonicalName (), new AuthorizationContext (authorizations ));
147147 }
148148
149149 /**
@@ -152,21 +152,22 @@ public void filter(ContainerRequestContext request) throws IOException
152152 * @param request current request
153153 * @param agent agent resource or null
154154 * @param accessMode ACL access mode
155- * @return authorization resource or null
155+ * @return authorizations model or null if access denied
156156 */
157- public Resource authorize (ContainerRequestContext request , Resource agent , Resource accessMode )
157+ public Model authorize (ContainerRequestContext request , Resource agent , Resource accessMode )
158158 {
159159 Resource accessTo = ResourceFactory .createResource (request .getUriInfo ().getAbsolutePath ().toString ());
160-
161- // special case where the agent is the owner of the requested document - automatically grant acl:Read/acl:Append/acl:Write access
160+ QuerySolutionMap thisQsm = new QuerySolutionMap ();
161+ thisQsm .add (SPIN .THIS_VAR_NAME , accessTo );
162+ Model authorizations = ModelFactory .createDefaultModel ();
163+
164+ // the agent is the owner of the requested document - automatically grant acl:Read/acl:Append/acl:Write access.
165+ // Note: the document does not even need to have a type at this point.
162166 if (agent != null && isOwner (accessTo , agent ))
163167 {
164168 log .debug ("Agent <{}> is the owner of <{}>, granting acl:Read/acl:Append/acl:Write access" , agent , accessTo );
165- return createOwnerAuthorization (accessTo , agent );
169+ createOwnerAuthorization (authorizations , accessTo , agent );
166170 }
167-
168- QuerySolutionMap thisQsm = new QuerySolutionMap ();
169- thisQsm .add (SPIN .THIS_VAR_NAME , accessTo );
170171
171172 ResultSetRewindable docTypesResult = loadResultSet (getApplication ().getService (), getDocumentTypeQuery (), thisQsm );
172173 try
@@ -192,24 +193,30 @@ public Resource authorize(ContainerRequestContext request, Resource agent, Resou
192193 // only root and containers allow child documents. This needs to be checked before checking ownership
193194 if (Collections .disjoint (parentTypes , Set .of (Default .Root , DH .Container ))) return null ;
194195 docTypesResult .reset (); // rewind result set to the beginning - it's used again later on
195-
196- // special case where the agent is the owner of the requested document - automatically grant acl:Read/acl:Append/acl:Write access
196+
197+ // the agent is the owner of the requested document - automatically grant acl:Read/acl:Append/acl:Write access
197198 if (agent != null && isOwner (accessTo , agent ))
198199 {
199200 log .debug ("Agent <{}> is the owner of <{}>, granting acl:Read/acl:Append/acl:Write access" , agent , accessTo );
200- return createOwnerAuthorization (accessTo , agent );
201+ createOwnerAuthorization (authorizations , accessTo , agent );
201202 }
202203 }
204+ // access to non-existing documents is denied if the request method is not PUT *and* the agent has no Write access
203205 else return null ;
204206 }
205-
207+
206208 ParameterizedSparqlString pss = getApplication ().canAs (EndUserApplication .class ) ? getACLQuery () : getOwnerACLQuery ();
207209 Query query = new SetResultSetValues ().apply (pss .asQuery (), docTypesResult );
208210 pss = new ParameterizedSparqlString (query .toString ()); // make sure VALUES are now part of the query string
209211 assert pss .toString ().contains ("VALUES" );
210212
211- Model authModel = loadModel (getAdminService (), pss , new AuthorizationParams (getApplication ().getBase (), accessTo , agent ).get ());
212- return getAuthorizationByMode (authModel , accessMode );
213+ // note we're not setting the $mode value on the ACL queries as we want to provide the AuthorizationContext with all of the agent's authorizations
214+ authorizations .add (loadModel (getAdminService (), pss , new AuthorizationParams (getApplication ().getBase (), accessTo , agent ).get ()));
215+
216+ // access denied if the agent has no authorization to the requested document with the requested ACL mode
217+ if (getAuthorizationByMode (authorizations , accessMode ) == null ) return null ;
218+
219+ return authorizations ;
213220 }
214221 finally
215222 {
@@ -326,17 +333,17 @@ protected ResultSetRewindable loadResultSet(com.atomgraph.linkeddatahub.model.Se
326333
327334 /**
328335 * Creates a special <code>acl:Authorization</code> resource for an owner.
336+ * @param model RDF model
329337 * @param accessTo requested URI
330338 * @param agent authenticated agent
331339 * @return authorization resource
332340 */
333- public Resource createOwnerAuthorization (Resource accessTo , Resource agent )
341+ public Resource createOwnerAuthorization (Model model , Resource accessTo , Resource agent )
334342 {
335343 if (accessTo == null ) throw new IllegalArgumentException ("Document resource cannot be null" );
336344 if (agent == null ) throw new IllegalArgumentException ("Agent resource cannot be null" );
337345
338- return ModelFactory .createDefaultModel ().
339- createResource ().
346+ return model .createResource ().
340347 addProperty (RDF .type , ACL .Authorization ).
341348 addProperty (RDF .type , LACL .OwnerAuthorization ).
342349 addProperty (ACL .accessTo , accessTo ).
0 commit comments