Listening Script to hide User Groups pages from non-group members

I am looking to adapt a listening script that was designed for hiding user profiles (grants XWiki-Admin group ‘View’ and ‘Edit’ access to User Profile upon page creation, to implicitly deny view access to other users).

I would like to update the script so that ‘View’ and ‘Edit’ access is also granted only to the XWiki-Admin group, when a group is created, but when I added this updated script to XWiki it did not make any updates to the group page’s access rights.

I was wondering if anyone has suggestions on what I am missing? I am concerned that the error message handling at the end in particular is not correctly adapted.

Snippet to be adapted:

Original java script:


import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.slf4j.Logger;
import org.xwiki.bridge.event.DocumentCreatingEvent;
import org.xwiki.component.annotation.Component;
import org.xwiki.model.EntityType;
import org.xwiki.model.reference.DocumentReferenceResolver;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.model.reference.EntityReferenceSerializer;
import org.xwiki.observation.AbstractEventListener;
import org.xwiki.observation.event.Event;

import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.objects.BaseProperty;
import com.xpn.xwiki.objects.classes.PropertyClass;

/**
 * Listener handling: allow some extra rights to the user pages when they're created. <br>
 * Note: failure to add these rights does not block the creation of the user profile page, it will be created but
 * without the extra rights.
 *
 * @version $Id$
 */
@Component
@Named(UserAndGroupEventListener.LISTENER_NAME)
@Singleton
public class UserAndGroupEventListener extends AbstractEventListener
{
    static final Map<String, List<String>> extraAllowRightsMap = new HashMap<>();

    static {
        extraAllowRightsMap.put("XWiki.XWikiAdminGroup", Arrays.asList("view", "edit"));
    }

    static final EntityReference RIGHT_CLASS_REFERENCE =
        new EntityReference("XWikiRights", EntityType.DOCUMENT, new EntityReference("XWiki", EntityType.SPACE));

    static final EntityReference RIGHT_CLASS_REFERENCE =
        new EntityReference("XWikiUsers", EntityType.DOCUMENT, new EntityReference("XWiki", EntityType.SPACE));

    static final EntityReference USER_CLASS_REFERENCE =
        new EntityReference("XWikiGroups", EntityType.DOCUMENT, new EntityReference("XWiki", EntityType.SPACE));

    static final String LISTENER_NAME = "usersandgroupsrightslistener";

    @Inject
    protected Logger logger;

    @Inject
    @Named("compactwiki")
    protected EntityReferenceSerializer<String> compactWikiSerializer;

    @Inject
    @Named("currentmixed")
    protected DocumentReferenceResolver<String> referenceResolver;

    public UserAndGroupEventListener()
    {
        super(LISTENER_NAME, new DocumentCreatingEvent());
    }

    @Override
    public void onEvent(Event event, Object source, Object data)
    {
        logger.debug("Event: [{}] - Source: [{}] - Data: [{}]", LISTENER_NAME, event, source, data);

        XWikiContext context = (XWikiContext) data;
        XWikiDocument page = (XWikiDocument) source;
        if (page != null) {
            BaseObject userOrGroup = page.getXObject(USER_CLASS_REFERENCE);
            if (userOrGroup == null) {
                userOrGroup = page.getXObject(GROUP_CLASS_REFERENCE);
            }
            if (userOrGroup != null) {
                try {
                    updateAccessRights(page, context);
                } catch (XWikiException e) {
                    logger.error("Error while updating access rights for: [{}].",
                        page.getDocumentReference(), e);
                }
            }
        }
    }

    /**
     * Allow the rights from the extraAllowRightsMap.
     *
     * @param userOrGroup
     * @param context
     * @throws XWikiException
     */
    public void updateAccessRights(XWikiDocument page, XWikiContext context) throws XWikiException
    {
        if (userOrGroup != null) {
            for (Map.Entry<String, List<String>> extraAllowRight : extraAllowRightsMap.entrySet()) {
                BaseObject rightObj = page.newXObject(RIGHT_CLASS_REFERENCE, context);
                rightObj.setLargeStringValue("groups", extraAllowRight.getKey());
                BaseProperty levelsProp = ((PropertyClass) rightObj.getXClass(context).get("levels"))
                    .fromStringArray(extraAllowRight.getValue().toArray(new String[0]));
                rightObj.set("levels", levelsProp.getValue(), context);
                // always set only allow rights
                rightObj.setIntValue("allow", 1);
            }
        }
    }
}

Found the solution after some testing:

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.slf4j.Logger;
import org.xwiki.bridge.event.DocumentCreatingEvent;
import org.xwiki.component.annotation.Component;
import org.xwiki.model.EntityType;
import org.xwiki.model.reference.DocumentReferenceResolver;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.model.reference.EntityReferenceSerializer;
import org.xwiki.observation.AbstractEventListener;
import org.xwiki.observation.event.Event;

import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.objects.BaseProperty;
import com.xpn.xwiki.objects.classes.PropertyClass;

/**
 * Listener handling: allow some extra rights to the group pages when they're created. <br>
 * Note: failure to add these rights does not block the creation of the group page, it will be created but
 * without the extra rights.
 *
 * @version $Id$
 */
@Component
@Named(GroupRightsInitializerListener.LISTENER_NAME)
@Singleton
public class GroupRightsInitializerListener extends AbstractEventListener
{
    static final Map<String, List<String>> extraAllowRightsMap = new HashMap<>();

    static {
        extraAllowRightsMap.put("XWiki.XWikiAdminGroup", Arrays.asList("view", "edit"));
    }

    static final EntityReference RIGHT_CLASS_REFERENCE =
        new EntityReference("XWikiRights", EntityType.DOCUMENT, new EntityReference("XWiki", EntityType.SPACE));

    static final EntityReference GROUP_CLASS_REFERENCE =
        new EntityReference("XWikiGroups", EntityType.DOCUMENT, new EntityReference("XWiki", EntityType.SPACE));

    static final String LISTENER_NAME = "grouprightsinitializer";

    @Inject
    protected Logger logger;

    @Inject
    @Named("compactwiki")
    protected EntityReferenceSerializer<String> compactWikiSerializer;

    @Inject
    @Named("currentmixed")
    protected DocumentReferenceResolver<String> referenceResolver;

    public GroupRightsInitializerListener()
    {
        super(LISTENER_NAME, new DocumentCreatingEvent());
    }

    @Override
    public void onEvent(Event event, Object source, Object data)
    {
        logger.debug("Event: [{}] - Source: [{}] - Data: [{}]", LISTENER_NAME, event, source, data);

        XWikiContext context = (XWikiContext) data;
        XWikiDocument page = (XWikiDocument) source;
        if (page != null) {
            BaseObject groupObj = page.getXObject(GROUP_CLASS_REFERENCE);
            if (groupObj != null) {
                try {
                    updateAccessRights(page, context);
                } catch (XWikiException e) {
                    logger.error("Error while allowing additional access rights for: [{}].",
                        page.getDocumentReference(), e);
                }
            }
        }
    }

    /**
     * Allow the rights from the extraAllowRightsMap.
     *
     * @param page
     * @param context
     * @throws XWikiException
     */
    public void updateAccessRights(XWikiDocument page, XWikiContext context) throws XWikiException
    {
        if (page != null) {
            for (Map.Entry<String, List<String>> extraAllowRight : extraAllowRightsMap.entrySet()) {
                BaseObject rightObj = page.newXObject(RIGHT_CLASS_REFERENCE, context);
                rightObj.setLargeStringValue("groups", extraAllowRight.getKey());
                BaseProperty levelsProp = ((PropertyClass) rightObj.getXClass(context).get("levels"))
                    .fromStringArray(extraAllowRight.getValue().toArray(new String[0]));
                rightObj.set("levels", levelsProp.getValue(), context);
                // always set only allow rights
                rightObj.setIntValue("allow", 1);
            }
        }
    }
}