CQ5 - Hiding a tab within a component dialog depending on user group?

人走茶凉 提交于 2019-12-07 18:57:05

问题


Any ideas how I would hide or show a dialog tab panel depending on which user group the user belongs to?

I tried to do this through the CRX content explorers (ACL's). But I'm not getting much luck with it.

Cheers


回答1:


As noted by anthonyh, the ACL approach is the way to go (if such a behavior is really necessary).

For example, to hide the "image" tab of the base page component:

  • edit acls for /libs/foundation/components/page/dialog/items/tabs/items/image
  • add deny jcr:read for author
  • login as author
  • go to http://localhost:4502/content/geometrixx/en.html and open the page properties
  • image tab should be gone

Note that in case of tabs included with xtype=cqinclude you have to set it on the include itself, not the included definition. Because at runtime it would complain over the missing target of the include and not render the dialog at all.




回答2:


This can be accomplished with a custom servlet and a dialog event listener.

The listener function makes a request to the servlet, passing the current user ID and the desired group. The dialog tab can then be hidden based on the servlet response.

Here is an example dialog.xml for a CQ5 component:

<?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>

And here is the corresponding 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);
        }
    }
}



回答3:


One question spring to mind...Why do you want to limit control of an authoring dialog and remove a tab?

There's no reason why ACLs wouldn't work for this. Did you set them to be restrictive enough for the tab? Were you testing with a non-admin user? I would be cautious using something so code-heavy to solve an access issue.

Personally if ACLs don't work as well as desired I'd explore creating an new widget based on the tabpanel xtype rather than a code solution which may end up as being specific to one version of CQ5.

My Answer: Use ACLs.

Please have a look at these vaguely related official documents - same principle but different objective:

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

and

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



来源:https://stackoverflow.com/questions/8165800/cq5-hiding-a-tab-within-a-component-dialog-depending-on-user-group

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!