Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

Page which is enable in closed user group is not detected by Page class

Avatar

Level 4
 
    
Hi ,

We are facing one more issue based on the issue.

import com.day.cq.wcm.api.Page;

Page basePage = null;

Iterator<Page> it = basePage.listChildren(new PageFilter());

while (it.hasNext()) {
LOG.info("the it {}",(String)it.next().getPath());
}


We find the page which has been checked for enable closed user group is not getting detected in the while loop but other child pages come up.please let us know what could be done
as this is a existing code we are using for quite some time.
1 Accepted Solution

Avatar

Correct answer by
Level 10

I got this to work - here is the OUTPUT:

5.05.2016 16:10:28.478 *INFO* [0:0:0:0:0:0:0:1 [1462479028291] GET /content/SlingQuery.html HTTP/1.1] com.community.aem.impl.QueryImp **** CUG Child pages are: /content/geometrixx/en/toolbar/contacts/Test1
05.05.2016 16:10:28.478 *INFO* [0:0:0:0:0:0:0:1 [1462479028291] GET /content/SlingQuery.html HTTP/1.1] com.community.aem.impl.QueryImp **** CUG Child pages are: /content/geometrixx/en/toolbar/contacts/Test2
05.05.2016 16:10:28.478 *INFO* [0:0:0:0:0:0:0:1 [1462479028291] GET /content/SlingQuery.html HTTP/1.1] com.community.aem.impl.QueryImp **** CUG Child pages are: /content/geometrixx/en/toolbar/contacts/Test3
05.05.2016 16:10:28.478 *INFO* [0:0:0:0:0:0:0:1 [1462479028291] GET /content/SlingQuery.html HTTP/1.1] com.community.aem.impl.QueryImp **** CUG Child pages are: /content/geometrixx/en/toolbar/contacts/Test4
05.05.2016 16:10:28.478 *INFO* [0:0:0:0:0:0:0:1 [1462479028291] GET /content/SlingQuery.html HTTP/1.1] com.community.aem.impl.QueryImp **** CUG Child pages are: /content/geometrixx/en/toolbar/contacts/Test5

 

Here is the pages that belong to a CUG:

They belong to a CUG named membersonly. See: 

Notice that a System user (not an AEM USER) named datacug belongs to this group. 

Now we map the System user to the OSGI bunlde using Sling Mapping: 

Now you can use the System user you configured in Sling Mapping to access the CUG Pages in the Java code-- see: 

 

package com.community.aem.impl;


import org.w3c.dom.Document;
import org.w3c.dom.Element;
  
  
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
  
import java.io.StringWriter;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap; 
import java.util.Map; 
  
import javax.jcr.Repository; 
import javax.jcr.SimpleCredentials; 
import javax.jcr.Node; 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
   
import org.apache.jackrabbit.commons.JcrUtils;
  
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
  
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import javax.jcr.RepositoryException;
import org.apache.felix.scr.annotations.Reference;
import org.apache.jackrabbit.commons.JcrUtils;
  
import javax.jcr.Session;
import javax.jcr.Node; 
import com.community.aem.*; 
 
 //Sling Imports
import org.apache.sling.api.resource.ResourceResolverFactory ; 
import org.apache.sling.api.resource.ResourceResolver; 
import org.apache.sling.api.resource.Resource; 
import com.day.cq.wcm.api.Page; 
import com.day.cq.wcm.api.PageFilter; 
 
//This is a component so it can provide or consume services
@Component
 
  
@Service
public class QueryImp implements Query {
 
//Inject a Sling ResourceResolverFactory
    //Inject a Sling ResourceResolverFactory
    @Reference
    private ResourceResolverFactory resolverFactory;
    
    /** Default log. */
    protected final Logger log = LoggerFactory.getLogger(this.getClass());
     
@Override
public String getJCRData(String location) {
    
    
    Map<String, Object> param = new HashMap<String, Object>();
    param.put(ResourceResolverFactory.SUBSERVICE, "datacug");
    
      
    try {
                 
        
        //Get the title of the AEM web page at this specific location - assume its a value such as /content/geometrixx/en/services
         ResourceResolver resourceResolver = resolverFactory.getServiceResourceResolver(param);
         Resource res = resourceResolver.getResource(location);
        
        
                     
    //Adapts the resource to another type - in this example to a     com.day.cq.wcm.api.page
Page page = res.adaptTo(Page.class);

String title = page.getTitle(); // Get the title of the web page


//Write out the CUG Pages - the user datacug belongs to the UCG that has access to these pages 
Iterator<Page> it = page.listChildren() ;

while (it.hasNext()) {
    
    String name = (String) it.next().getPath(); 
    log.info("**** CUG Child pages are: "+name);
}

 

 


return title ; 
}
catch (Exception e)
{
    e.printStackTrace()  ; 
}
         
return null;
    }
 
}

 

There is a lot here - we will get this into a HELPX article - how to use SLING APIS to query pages that belong to a CUG

Also - as mentioned by Joerg and Lokesh - you cannot do this without using a System user who belongs to the group. 

View solution in original post

12 Replies

Avatar

Level 10

Are you using a session of a user whom has access to the page. I am going to try this use case to see if i can reproduce.  Also what AEM version are you using.

Avatar

Employee Advisor

Hi,

closed user group definitions are "translated" into ACLs on publish. And therefor the usual ACLs are applied when iterating nodes. So if your session is an anonymous session, and you iterate all child nodes, you don't see any pages which require elevated privileges (as mandated by the ACLs / CUGs).

So this is an expected behaviour.

Jörg

Avatar

Level 4

Hi,

Thanks for the input we are in the same  case for CQ5.6.1 on publish instance.We are using the anonymous session and it is not detecting the child CUG page.But we have a use case where it must detect even for anonymous session as we are using this for populating menus items on tab. were we want all child pages to come up as menu items ,So please let us know what could be an alternative for the above problem.

Thanks

Avatar

Level 4

Could you please provide  inputs for the below  problem i am currently facing

For  anonymous user  tried to change to admin (resolveradmin) to get the child pages which has CUG pages,as mentioned below by executing JSP-> bundle based Java code.But i noticed that resolver.close() added  in finally block in Java class is causing a issue as after the final block is executed ,In JSP the code after that is not working.Could you please suggest what could be done as if we don't close the session it will cause leaks right??


            
            try{
            ResourceResolverFactory resourceResolverFactory=getScriptHelper().getService(org.apache.sling.api.resource.ResourceResolverFactory.class);
            resolveradmin = resourceResolverFactory.getAdministrativeResourceResolver(null);
             Page adminPage=resolveradmin.getResource(basePage.getPath()).adaptTo(Page.class);
             Iterator<Page> it = adminPage.listChildren(new PageFilter());
             while (it.hasNext()){
                 LOG.info("the  path  {}",(String)it.next().getPath());
                
              }
        }catch(Exception e){
              LOG.error("an expection occurred {}",e);
              
        }finally{
          if(resolveradmin!=null && resolveradmin.isLive()){
              resolver.close();
              
              
       }
        }
        
    

Avatar

Level 10

For your Jave code, does it work when using without CUGs? 

Avatar

Level 4

Yes , it works without CUG pages as the session is anonymous .But i  want the same to work when we want to detect with CUG pages  so i have currently added  resolveradmin = resourceResolverFactory.getAdministrativeResourceResolver(null);

But i assuming that   when i do the below  resourceResolver is totally removed and  due this the page does not come up.Let me know what could be done??

  if(resolveradmin!=null && resolveradmin.isLive()){
              resolver.close();
              
              
       }

Avatar

Level 10

CUG is used to restrict the access of the page and hence it will not available for the anonymous session. If you want it in your service, then only for the particular service where you are queries the pages for the tab, use the 'Service User' and give access to the service user. This would solve it.

Avatar

Level 10

I am working on code for this. As Lokesh points out - you need to use a System user. WHich means in AEM 6,x - you need to use Slign Mapping. I got the following code to work on the Java side that uses a System user: 

 

//This is a component so it can provide or consume services
@Component
 
  
@Service
public class QueryImp implements Query {
 
//Inject a Sling ResourceResolverFactory
    //Inject a Sling ResourceResolverFactory
    @Reference
    private ResourceResolverFactory resolverFactory;
     
@Override
public String getJCRData(String location) {
    
    
    Map<String, Object> param = new HashMap<String, Object>();
    param.put(ResourceResolverFactory.SUBSERVICE, "datacug");
    
      
    try {
                 
        
        //Get the title of the AEM web page at this specific location - assume its a value such as /content/geometrixx/en/services
         ResourceResolver resourceResolver = resolverFactory.getServiceResourceResolver(param);
         Resource res = resourceResolver.getResource(location);

        
        
                     
    //Adapts the resource to another type - in this example to a     com.day.cq.wcm.api.page
Page page = res.adaptTo(Page.class);
String title = page.getTitle(); // Get the title of the web page
return title ; 

Avatar

Correct answer by
Level 10

I got this to work - here is the OUTPUT:

5.05.2016 16:10:28.478 *INFO* [0:0:0:0:0:0:0:1 [1462479028291] GET /content/SlingQuery.html HTTP/1.1] com.community.aem.impl.QueryImp **** CUG Child pages are: /content/geometrixx/en/toolbar/contacts/Test1
05.05.2016 16:10:28.478 *INFO* [0:0:0:0:0:0:0:1 [1462479028291] GET /content/SlingQuery.html HTTP/1.1] com.community.aem.impl.QueryImp **** CUG Child pages are: /content/geometrixx/en/toolbar/contacts/Test2
05.05.2016 16:10:28.478 *INFO* [0:0:0:0:0:0:0:1 [1462479028291] GET /content/SlingQuery.html HTTP/1.1] com.community.aem.impl.QueryImp **** CUG Child pages are: /content/geometrixx/en/toolbar/contacts/Test3
05.05.2016 16:10:28.478 *INFO* [0:0:0:0:0:0:0:1 [1462479028291] GET /content/SlingQuery.html HTTP/1.1] com.community.aem.impl.QueryImp **** CUG Child pages are: /content/geometrixx/en/toolbar/contacts/Test4
05.05.2016 16:10:28.478 *INFO* [0:0:0:0:0:0:0:1 [1462479028291] GET /content/SlingQuery.html HTTP/1.1] com.community.aem.impl.QueryImp **** CUG Child pages are: /content/geometrixx/en/toolbar/contacts/Test5

 

Here is the pages that belong to a CUG:

They belong to a CUG named membersonly. See: 

Notice that a System user (not an AEM USER) named datacug belongs to this group. 

Now we map the System user to the OSGI bunlde using Sling Mapping: 

Now you can use the System user you configured in Sling Mapping to access the CUG Pages in the Java code-- see: 

 

package com.community.aem.impl;


import org.w3c.dom.Document;
import org.w3c.dom.Element;
  
  
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
  
import java.io.StringWriter;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap; 
import java.util.Map; 
  
import javax.jcr.Repository; 
import javax.jcr.SimpleCredentials; 
import javax.jcr.Node; 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
   
import org.apache.jackrabbit.commons.JcrUtils;
  
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
  
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import javax.jcr.RepositoryException;
import org.apache.felix.scr.annotations.Reference;
import org.apache.jackrabbit.commons.JcrUtils;
  
import javax.jcr.Session;
import javax.jcr.Node; 
import com.community.aem.*; 
 
 //Sling Imports
import org.apache.sling.api.resource.ResourceResolverFactory ; 
import org.apache.sling.api.resource.ResourceResolver; 
import org.apache.sling.api.resource.Resource; 
import com.day.cq.wcm.api.Page; 
import com.day.cq.wcm.api.PageFilter; 
 
//This is a component so it can provide or consume services
@Component
 
  
@Service
public class QueryImp implements Query {
 
//Inject a Sling ResourceResolverFactory
    //Inject a Sling ResourceResolverFactory
    @Reference
    private ResourceResolverFactory resolverFactory;
    
    /** Default log. */
    protected final Logger log = LoggerFactory.getLogger(this.getClass());
     
@Override
public String getJCRData(String location) {
    
    
    Map<String, Object> param = new HashMap<String, Object>();
    param.put(ResourceResolverFactory.SUBSERVICE, "datacug");
    
      
    try {
                 
        
        //Get the title of the AEM web page at this specific location - assume its a value such as /content/geometrixx/en/services
         ResourceResolver resourceResolver = resolverFactory.getServiceResourceResolver(param);
         Resource res = resourceResolver.getResource(location);
        
        
                     
    //Adapts the resource to another type - in this example to a     com.day.cq.wcm.api.page
Page page = res.adaptTo(Page.class);

String title = page.getTitle(); // Get the title of the web page


//Write out the CUG Pages - the user datacug belongs to the UCG that has access to these pages 
Iterator<Page> it = page.listChildren() ;

while (it.hasNext()) {
    
    String name = (String) it.next().getPath(); 
    log.info("**** CUG Child pages are: "+name);
}

 

 


return title ; 
}
catch (Exception e)
{
    e.printStackTrace()  ; 
}
         
return null;
    }
 
}

 

There is a lot here - we will get this into a HELPX article - how to use SLING APIS to query pages that belong to a CUG

Also - as mentioned by Joerg and Lokesh - you cannot do this without using a System user who belongs to the group. 

Avatar

Level 4

Thanks a lot for the info.

I am currently using AEM 5.6.1 .Can I use the same code snippet. 

Also wanted to know as it is a user session (datacug) used above so in final block no need to   closing the  resourceResolver ??

Please suggest.

Thanks