CQ5 - 根据用户组隐藏组件对话框中的选项卡?
问题描述:
答
正如anthonyh指出的那样,ACL方法是走的路(如果这种行为真的有必要)。
例如,隐藏基页面组件的 “图像” 选项卡:
- 编辑的ACL为
/libs/foundation/components/page/dialog/items/tabs/items/image
- 添加
deny jcr:read
为author
- 登录为作者
- 去http://localhost:4502/content/geometrixx/en.html和打开页面属性
- 图片标签应该消失
请注意,如果选项卡包含在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