[ 
https://issues.apache.org/jira/browse/OAK-7997?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16748049#comment-16748049
 ] 

angela commented on OAK-7997:
-----------------------------

[~snj], i extracted a test case based on your description (directly operating 
on oak QueryEngine and oak API for simplicity) and i added some additional 
variants:

a) your case: single policy on /node with single entry + rep:glob restriction 
with empty value => unexpected result
b) policy on /node (allow) and another policy on /node/subnode (deny) => 
expected result (but obviously not practical in real life... just for the 
limited test-setup that's equivalent)

and while writing the summary i noticed a potential reason for the failure in 
a): with the ""-rep:glob we not only deny access to the child node but also to 
all properties of /node because the glob restriction is just a simple 
path-matching and doesn't differentiate between child properties and child 
nodes. to illustrate this (and because I suspect that the query looks at 
jcr:primaryType property) i added yet another test case 

c) same as a) but additionally granting property-read at /node/jcr:primaryType 
=> expected result.

that's just for an initial illustration. i don't think that extra entry should 
be needed because in the JCR API implementation in Oak we added some extra 
logic to make sure a Node and its primary type information is accessible even 
if the {{jcr:primaryType}} property is not. So, with your setup 
{{Session.getNode("/node")}} succeeds and I think so does  
{{Session.getNode("/node").getPrimaryNodeType()}}. but afaik 
{{Session.getNode("/node").getProperty("jcr:primaryType")}} and 
{{Session.getProperty("/node/jcr:primaryType")}} will fail because your 
test-session doesn't have the ability to read that property because of the 
""-glob-restriction.

what i didn't find out until now is where exactly the query engine misses 
(skips) the result and if it's really because of the primary-type 
property...the only thing i found was 
{{org.apache.jackrabbit.oak.query.index.FilterImpl.isAccessible(String path)}} 
but somehow i never got there when debugging. that's what i will next (and 
reach out to the query team in case i get stuck)... more tomorrow.
 


> Adding restrictions to ACLs yields empty results for queries in Jackrabbit Oak
> ------------------------------------------------------------------------------
>
>                 Key: OAK-7997
>                 URL: https://issues.apache.org/jira/browse/OAK-7997
>             Project: Jackrabbit Oak
>          Issue Type: Bug
>          Components: query, security
>    Affects Versions: 1.10.0, 1.8.10
>            Reporter: Søren Jensen
>            Priority: Major
>         Attachments: OAK-7997.patch
>
>
> Using Jackrabbit Oak, I've been attempting to configure security through 
> {{SecurityProvider}} and {{SecurityConfiguration's. In particular, I've been 
> using the restrictions which generally works as expected. However, when 
> dealing with JCR-SQL2}} queries, more gets filtered out than expected.
> *Details*
> It can be reproduced with the repository below.
> {code:java}
> / 
>   node      [nt:unstructured]
>     subnode [nt:unstructured] {code}
> On {{node}}, I add an access control entry with privilege {{JCR_ALL}} for 
> "{{user"}} together with a restriction for {{rep:glob}} -> {{""}}, such that 
> {{user}} do not have access to any children of {{node - in this case, only 
> subnode}}.
> It works as expected when using {{session.getNode}}:
>  * {{session.getNode("/node")}} returns the node
>  * {{session.getNode("/node/subnode")}} throws {{PathNotFoundException}} as 
> expected due to the restriction.
> However, when I execute the following {{JCR-SQL2}} query:
> {code:java}
> SELECT * FROM [nt:unstructured]{code}
> I get *no results back*. Here I would have expected to get {{/node}}, as it 
> is otherwise available when using {{session.getNode}}. Removing the 
> restriction yields the expected result of both _/node_ and _/node/subnode_.
> As discussed with [~anchela] on the _users_ mailing list, this may either be 
> an actual bug, or it is a conscious decision - in which case it would be nice 
> to have it documented for the security.
> *Code for reproducing:*
> The code for reproducing the error is shown below. The "_restrictions"_ map 
> below seems to be the problem, as this is what results in both _/node_ and 
> _/node/subnode_ being filtered out.
>  
> {code:java}
> public static void main(String[] args) throws Exception {
>     Repository repository = new Jcr().with(new 
> MySecurityProvider()).createRepository();
>     Session session = repository.login(new UserIdCredentials(""));    // 
> principal is "SystemPrincipal.INSTANCE"
>     // Create nodes
>     Node node = session.getRootNode().addNode("node", "nt:unstructured");
>     node.addNode("subnode", "nt:unstructured");
>     // Add access control entry + restriction
>     AccessControlManager acm = session.getAccessControlManager();
>     JackrabbitAccessControlList acl = (JackrabbitAccessControlList) acm
>         .getApplicablePolicies("/node").nextAccessControlPolicy();
>     Privilege[] privileges = new 
> Privilege[]{acm.privilegeFromName(Privilege.JCR_ALL)};
>     Map<String, Value> restrictions = new HashMap<String, Value>() 
> {{put("rep:glob", new StringValue(""));}};
>     acl.addEntry(new PrincipalImpl("user"), privileges, true, restrictions);
>     acm.setPolicy("/node", acl);
>     session.save();
>     // executes query
>     RowIterator rows = repository.login(new 
> UserIdCredentials("user")).getWorkspace().getQueryManager()
>         .createQuery("SELECT * FROM [nt:unstructured]", 
> Query.JCR_SQL2).execute().getRows();
>         System.out.println("Number of rows: " + rows.getSize());  //Prints 0
> }
> {code}
> *Code for security configuration:*
> The above code makes use of "MySecurityProvider". I do not suspect this to be 
> the root cause, but please let me know if it can be helpful to have. The 
> security provider has the configuration set to 
> "ConfigurationParameters.EMPTY", and it uses all the default implementations 
> present within the Jackrabbit Oak project. The only exception is the 
> _AuthenticationConfiguration_ which uses a custom implementation using 
> pre-authentication:
>  
> {code:java}
> class MyAuthenticationConfiguration extends AuthenticationConfigurationImpl {
>     public MyAuthenticationConfiguration(SecurityProvider securityProvider) {
>         super(securityProvider);
>     }
>     @NotNull
>     @Override
>     public LoginContextProvider getLoginContextProvider(ContentRepository 
> contentRepository) {
>         return new LoginContextProvider() {
>             @NotNull
>             public LoginContext getLoginContext(Credentials credentials, 
> String workspaceName) {
>                 String userId = ((UserIdCredentials) credentials).getUserId();
>                 Set<Principal> principalSets = new HashSet<>();
>                 if (userId.isEmpty()) {
>                     principalSets.add(SystemPrincipal.INSTANCE);
>                 } else {
>                     principalSets.add(new PrincipalImpl(userId));
>                 }
>                 Map<String, ? extends Principal> publicPrivileges = new 
> HashMap<>();
>                 AuthInfoImpl authInfoImpl = new AuthInfoImpl(userId, 
> publicPrivileges, principalSets);
>                 Subject subject = new Subject(true, principalSets, 
> Collections.singleton(authInfoImpl), new HashSet<Principal>());
>                 return new PreAuthContext(subject);
>             }
>         };
>     }
> }
> {code}
>  



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to