Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.

Programmatically evaluating group permission against a certain node

Avatar

Level 2

Hi All,

I am trying to build a report to show permission(of each group) for each cq page in the repository. Basically the table row should look like

| abc_group |  /path/to/page | read,write,update  |

I use admin session to evaluate group permission/privilege against a cq page node.

String path = "/content/path/to/page";
String group = "abc_group";
Session adminSession = repository.loginAdministrative(null);
JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager) adminSession.getAccessControlManager();
UserManager userManager = resourceResolver.adaptTo(UserManager.class);
Authorizable auth  = userManager.getAuthorizable(group);

Set<Principal> principals = new HashSet<Principal>();
principals.add(auth.getPrincipal());

Privilege[] privileges = acm.getPrivileges(path, principals);

for(Privilege p : privileges){
    LOGGER.info("group: "+auth.getID()+" privilege: "+p.getName());
}

The problem is that acm.getPrivileges(path, principals) always return an empty privilege.

I also tried doing below to test a given specific privilege, but always return false even if actual group has read permission.

boolean hasRead = acm.hasPrivileges(path, principals, new Privilege[]{acm.privilegeFromName(Privilege.JCR_READ) });

Any input would be helpful.


Thanks!

6 Replies

Avatar

Level 10

I am looking into this use case. 

Avatar

Level 10

I got the code to work: 

14.03.2016 10:46:11.844 *INFO* [pool-5-thread-14] com.day.cq.wcm.core.impl.components.ComponentCacheImpl Detecting component change. invalidating cache.
14.03.2016 10:46:23.027 *WARN* [0:0:0:0:0:0:0:1 [1457966782457] GET /content/getGroupPermissions.html HTTP/1.1] com.day.cq.wcm.msm.impl.LiveRelationshipManagerImpl StarResource given at /content/getGroupPermissions/jcr:content/par/*: no parent: no LiveCopy
14.03.2016 10:46:23.053 *INFO* [0:0:0:0:0:0:0:1 [1457966782457] GET /content/getGroupPermissions.html HTTP/1.1] com.adobe.cq.user.impl.HelloServiceImpl **** Here are the permissions: group: geometrixx-facebook privilege: jcr:read
14.03.2016 10:46:23.053 *INFO* [0:0:0:0:0:0:0:1 [1457966782457] GET /content/getGroupPermissions.html HTTP/1.1] com.adobe.cq.user.impl.HelloServiceImpl **** Here are the permissions: group: geometrixx-facebook privilege: jcr:modifyAccessControl
14.03.2016 10:46:23.053 *INFO* [0:0:0:0:0:0:0:1 [1457966782457] GET /content/getGroupPermissions.html HTTP/1.1] com.adobe.cq.user.impl.HelloServiceImpl **** Here are the permissions: group: geometrixx-facebook privilege: crx:replicate
14.03.2016 10:46:23.053 *INFO* [0:0:0:0:0:0:0:1 [1457966782457] GET /content/getGroupPermissions.html HTTP/1.1] com.adobe.cq.user.impl.HelloServiceImpl **** Here are the permissions: group: geometrixx-facebook privilege: jcr:versionManagement
14.03.2016 10:46:23.053 *INFO* [0:0:0:0:0:0:0:1 [1457966782457] GET /content/getGroupPermissions.html HTTP/1.1] com.adobe.cq.user.impl.HelloServiceImpl **** Here are the permissions: group: geometrixx-facebook privilege: jcr:lockManagement
14.03.2016 10:46:23.053 *INFO* [0:0:0:0:0:0:0:1 [1457966782457] GET /content/getGroupPermissions.html HTTP/1.1] com.adobe.cq.user.impl.HelloServiceImpl **** Here are the permissions: group: geometrixx-facebook privilege: rep:write
14.03.2016 10:46:23.053 *INFO* [0:0:0:0:0:0:0:1 [1457966782457] GET /content/getGroupPermissions.html HTTP/1.1] com.adobe.cq.user.impl.HelloServiceImpl **** Here are the permissions: group: geometrixx-facebook privilege: jcr:readAccessControl
14.03.2016 10:46:23.213 *WARN* [0:0:0:0:0:0:0:1 [1457966783210] GET /content/getGroupPermissions.html HTTP/1.1] com.day.cq.wcm.msm.impl.LiveRelationshipManagerImpl StarResource given at /content/getGroupPermissions/jcr:content/par/*: no parent: no LiveCopy
14.03.2016 10:46:23.216 *INFO* [0:0:0:0:0:0:0:1 [1457966783210] GET /content/getGroupPermissions.html HTTP/1.1] com.adobe.cq.user.impl.HelloServiceImpl **** Here are the permissions: group: geometrixx-facebook privilege: jcr:read
14.03.2016 10:46:23.216 *INFO* [0:0:0:0:0:0:0:1 [1457966783210] GET /content/getGroupPermissions.html HTTP/1.1] com.adobe.cq.user.impl.HelloServiceImpl **** Here are the permissions: group: geometrixx-facebook privilege: jcr:modifyAccessControl
14.03.2016 10:46:23.216 *INFO* [0:0:0:0:0:0:0:1 [1457966783210] GET /content/getGroupPermissions.html HTTP/1.1] com.adobe.cq.user.impl.HelloServiceImpl **** Here are the permissions: group: geometrixx-facebook privilege: crx:replicate
14.03.2016 10:46:23.216 *INFO* [0:0:0:0:0:0:0:1 [1457966783210] GET /content/getGroupPermissions.html HTTP/1.1] com.adobe.cq.user.impl.HelloServiceImpl **** Here are the permissions: group: geometrixx-facebook privilege: jcr:versionManagement
14.03.2016 10:46:23.216 *INFO* [0:0:0:0:0:0:0:1 [1457966783210] GET /content/getGroupPermissions.html HTTP/1.1] com.adobe.cq.user.impl.HelloServiceImpl **** Here are the permissions: group: geometrixx-facebook privilege: jcr:lockManagement
14.03.2016 10:46:23.216 *INFO* [0:0:0:0:0:0:0:1 [1457966783210] GET /content/getGroupPermissions.html HTTP/1.1] com.adobe.cq.user.impl.HelloServiceImpl **** Here are the permissions: group: geometrixx-facebook privilege: rep:write
14.03.2016 10:46:23.216 *INFO* [0:0:0:0:0:0:0:1 [1457966783210] GET /content/getGroupPermissions.html HTTP/1.1] com.adobe.cq.user.impl.HelloServiceImpl **** Here are the permissions: group: geometrixx-facebook privilege: jcr:readAccessControl

I will write this up in an article and post here. 

Code: 

 

package com.adobe.cq.user.impl;

import javax.jcr.Repository;

import java.io.IOException;
import java.security.Principal;
 
import javax.jcr.PropertyType;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.servlet.Servlet;
 
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
import org.apache.jackrabbit.api.security.user.Authorizable;
import java.util.Set; 
import java.util.HashSet;
import javax.jcr.security.Privilege;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;

import com.adobe.cq.user.HelloService;

/**
 * One implementation of the {@link HelloService}. Note that
 * the repository is injected, not retrieved.
 */
@Service
@Component(metatype = false)
public class HelloServiceImpl implements HelloService {
    
    private static Logger logger = LoggerFactory.getLogger(HelloServiceImpl.class);
      
    
    @Reference
     ResourceResolverFactory resolverFactory;

    public String getRepositoryPermission() {
        int perCount =0; 
        ResourceResolver adminResolver = null;
        
        try
        {
            
            String path = "/content/geometrixx-outdoors/en/TestPage";
            String group = "geometrixx-facebook";
            //Invoke the adaptTo method to create a Session used to create a QueryManager
            ResourceResolver resourceResolver = resolverFactory.getAdministrativeResourceResolver(null);
            Session adminSession = resourceResolver.adaptTo(Session.class);
            
            JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager) adminSession.getAccessControlManager();
            UserManager userManager = resourceResolver.adaptTo(UserManager.class);
            Authorizable auth  = userManager.getAuthorizable(group);

            Set<Principal> principals = new HashSet<Principal>();
            principals.add(auth.getPrincipal());

            Privilege[] privileges = acm.getPrivileges(path, principals);
            
              
            for(Privilege p : privileges){
                logger.info("**** Here are the permissions: group: "+auth.getID()+" privilege: "+p.getName());
                perCount++; 
            }
            
        
        }
        catch (Exception e)
        { 
            e.printStackTrace(); 
        }
        return "There were this many Privileges: "+ perCount; 
    }

}

Avatar

Level 2

Hi smacdonald2008

Thank for your time looking into this matter. I tried your approach and same case nothing is showing out. Upon digging further I found out that any privilege that has been
inherited from a parent group is not being returned by call acm.getPrivileges. 

Say for instance assuming that group geometrixx-authors has assigned read,update privilege to content /content/geometrixx-outdoors/en/TestPage. Then group geometrixx-facebook is a member of geometrixx-authors. Based on my findings calling the acm.getPrivileges passing geometrixx-facebook as principal wont return any privilege. Please let me know if you have similar findings.

Normally we use inheritance for assigning privileges to groups and it is unfortunate that seems acm.getPrivileges is not able to catch those inherited ones. 

Any other approach to try? 

Thanks!

Avatar

Level 10

The privileges have to to set using ACL functionality. See this new community article that shows successfully getting ACL privileges:

http://scottsdigitalcommunity.blogspot.ca/2016/03/using-jackrabbit-usermanager-apis-to.html

Notice that privileges are set and then written to the AEM Log file. 

Avatar

Level 5

don't mean to nitpick, but in the code, should we have a finally block to close the admin session?Reason to ask is, we got unlosed session detected in our logs and wondering if that is the case since I found out a lot of code written by our vendor with missing close.

More of a question rather than a criticism