CQ5 - 根据用户组隐藏组件对话框中的选项卡?

问题描述:

任何想法如何隐藏或显示对话框选项卡面板取决于用户属于哪个用户组?CQ5 - 根据用户组隐藏组件对话框中的选项卡?

我试图通过CRX内容探索者(ACL's)来做到这一点。但我没有得到太多的运气。

干杯

正如anthonyh指出的那样,ACL方法是走的路(如果这种行为真的有必要)。

例如,隐藏基页面组件的 “图像” 选项卡:

请注意,如果选项卡包含在xtype=cqinclude中,则必须将其设置为包含本身,而不是包含的定义。因为在运行时它会抱怨包含丢失的目标,并且根本不呈现对话框。

这可以用一个自定义的servlet和一个对话框事件监听器来完成。

侦听器函数向servlet发出一个请求,传递当前用户ID和所需的组。然后可以基于servlet响应隐藏对话框选项卡。

这里是一个CQ5组件为例dialog.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<jcr:root 
    xmlns:cq="http://www.day.com/jcr/cq/1.0" 
    xmlns:jcr="http://www.jcp.org/jcr/1.0" 
    jcr:primaryType="cq:Dialog" 
    xtype="dialog"> 
    <listeners jcr:primaryType="nt:unstructured" 
     loadcontent="function(dialog) { 
      var url = '/bin/member.json'; 

      // check if current user belongs to administrators group 
      url = CQ.HTTP.addParameter(url, 'userId', CQ.User.getUserID()); 
      url = CQ.HTTP.addParameter(url, 'groupId', 'administrators'); 

      var result = CQ.HTTP.eval(url); 

      if (!result.isMember) { 
       // hide "tab2" if user is not an administrator 
       dialog.findByType('tabpanel')[0].hideTabStripItem(1); 
      } 
     }" /> 
    <items jcr:primaryType="cq:WidgetCollection"> 
     <tab1 jcr:primaryType="cq:Widget" title="Text" xtype="panel"> 
      <items jcr:primaryType="cq:WidgetCollection"> 
       ... 
      </items> 
     </tab1> 
     <tab2 jcr:primaryType="cq:Widget" title="Image" xtype="panel"> 
      <items jcr:primaryType="cq:WidgetCollection"> 
       ... 
      </items> 
     </tab2> 
    </items> 
</jcr:root> 

这里是相应的servlet:

import java.io.IOException; 

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.Service; 
import org.apache.sling.api.SlingHttpServletRequest; 
import org.apache.sling.api.SlingHttpServletResponse; 
import org.apache.sling.api.servlets.SlingAllMethodsServlet; 
import org.codehaus.jackson.JsonFactory; 
import org.codehaus.jackson.JsonGenerationException; 
import org.codehaus.jackson.JsonGenerator; 
import org.codehaus.jackson.JsonGenerator.Feature; 
import org.codehaus.jackson.map.JsonMappingException; 
import org.codehaus.jackson.map.ObjectMapper; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

import com.day.cq.security.Group; 
import com.day.cq.security.User; 
import com.day.cq.security.UserManager; 
import com.google.common.collect.ImmutableMap; 

@Component(immediate = true) 
@Service 
@Properties({ 
    @Property(name = "service.description", value = "Group Member servlet checks if a user is a member of a group."), 
    @Property(name = "sling.servlet.paths", value = "/bin/member") 
}) 
public class GroupMemberServlet extends SlingAllMethodsServlet { 

    /** Required. */ 
    private static final long serialVersionUID = 1L; 

    /** Logger */ 
    private static final Logger LOG = LoggerFactory.getLogger(GroupMemberServlet.class); 

    private static final JsonFactory FACTORY = new JsonFactory().disable(Feature.AUTO_CLOSE_TARGET); 

    private static final ObjectMapper MAPPER = new ObjectMapper(); 

    @Override 
    protected void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response) { 
     final UserManager userManager = request.getResourceResolver().adaptTo(UserManager.class); 

     final String userId = request.getRequestParameter("userId").getString(); 
     final String groupId = request.getRequestParameter("groupId").getString(); 

     final Group group = (Group) userManager.get(groupId); 

     final User user = (User) userManager.get(userId); 

     writeJsonResponse(response, ImmutableMap.of("isMember", group.isMember(user))); 
    } 

    private void writeJsonResponse(final SlingHttpServletResponse response, final Object object) { 
     response.setContentType("application/json"); 
     response.setCharacterEncoding("utf-8"); 

     try { 
      final JsonGenerator generator = FACTORY.createJsonGenerator(response.getWriter()); 

      MAPPER.writeValue(generator, object); 
     } catch (final JsonGenerationException jge) { 
      LOG.error("error generating JSON response", jge); 
     } catch (final JsonMappingException jme) { 
      LOG.error("error mapping JSON response", jme); 
     } catch (final IOException ioe) { 
      LOG.error("error writing JSON response", ioe); 
     } 
    } 
} 

一个问题涌现在脑海里......你为什么要限制创作对话框的控制并删除选项卡?

没有理由为什么ACL不会为此工作。你有没有将它们设置为足够限制该标签?您是否使用非管理员用户进行测试?我会谨慎使用代码繁重的方法来解决访问问题。

就个人而言,如果ACL无法正常工作,我会探索基于tabpanel xtype而不是代码解决方案创建一个新的小部件,该解决方案可能最终只针对CQ5的一个版本。

我的答案:使用ACL。

请看看这些隐约有关正式文件 - 原理相同,但不同的目标:

http://dev.day.com/content/kb/home/cq5/CQ5SystemAdministration/CQ53HowToHideCQNavigationButtons.html

http://dev.day.com/docs/en/cq/current/administering/security.html