CQ5 - Скрытие вкладки в диалоге компонента в зависимости от группы пользователей? - PullRequest
2 голосов
/ 17 ноября 2011

Есть идеи, как мне скрыть или показать панель вкладок диалога в зависимости от того, к какой группе пользователей принадлежит пользователь?

Я пытался сделать это через исследователи контента CRX (ACL).Но мне не очень повезло с этим.

Приветствия

Ответы [ 3 ]

6 голосов
/ 10 февраля 2012

Как отметил anthonyh , подход ACL - это путь к (если такое поведение действительно необходимо).

Например, чтобы скрытьвкладка «изображение» компонента базовой страницы:

  • редактировать acls для /libs/foundation/components/page/dialog/items/tabs/items/image
  • добавить deny jcr:read для author
  • войти как автор
  • перейдите на http://localhost:4502/content/geometrixx/en.html и откройте свойства страницы
  • вкладка с изображением должна исчезнуть

Обратите внимание, что в случае вкладок, включенных в xtype=cqinclude Вы должны установить его на самом включении, а не во включенном определении.Потому что во время выполнения он будет жаловаться на отсутствующую цель включения и не отображать диалог вообще.

5 голосов
/ 07 февраля 2012

Это можно сделать с помощью пользовательского сервлета и прослушивателя событий диалога.

Функция слушателя делает запрос сервлету, передавая текущий идентификатор пользователя и желаемую группу. Вкладка диалога затем может быть скрыта на основе ответа сервлета.

Вот пример dialog.xml для компонента CQ5:

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

А вот соответствующий сервлет:

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);
        }
    }
}
4 голосов
/ 10 февраля 2012

На ум приходит один вопрос ... Почему вы хотите ограничить контроль над авторским диалогом и удалить вкладку?

Нет причин, по которым ACL не будут работать для этого.Вы установили их как достаточно ограничивающие для вкладки?Вы тестировали с пользователем без прав администратора?Я был бы осторожен, используя что-то настолько тяжелое для решения проблемы доступа.

Лично, если ACL работают не так хорошо, как хотелось бы, я бы рассмотрел создание нового виджета на основе табличного элемента 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

...