EventListener as ScriptComponent not working

Hi!

I am trying to implement a custom EventListener to prevent restricted users from changing some specific properties.

I mostly used the documentation and the example on this page:
https://extensions.xwiki.org/xwiki/bin/view/Extension/Script%20Component/

I also had a look at several Script snippets, but couldn’t find a solution, why the Listener is not fired at all.

What I want to do

  • If a document is updated, it should be checked if it is a user profile
  • If the user is in one of the “RESTRICTED_GROUP”, it should reset some properties to a given value.

What I did:

  • I installed the Script Component extension
  • I added a ScriptComponentClass object to my FlamingoTheme page (since this is always loaded) with Language “groovy” and Scope “global”

I use this code, mainly from the examples with some changes

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.xwiki.bridge.event.DocumentUpdatingEvent;
import org.xwiki.observation.AbstractEventListener;
import org.xwiki.observation.event.Event;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.objects.BaseObject;
import java.util.Arrays;
import java.util.List;

@Component
@Named("preventRestrictedUserChangesListener")
@Singleton
public class preventRestrictedUserChanges extends AbstractEventListener {

    static final List<String> RESTRICTED_GROUPS = Arrays.asList(
        "XWiki.GroupA", "XWiki.GroupB", "XWiki.GroupC", "XWiki.GroupD"
    );

    public preventRestrictedUserChanges() {
        super("preventRestrictedUserChangesListener", new DocumentUpdatingEvent());
    }

    @Override
    public void onEvent(Event event, Object source, Object data) {
        XWikiContext xcontext = (XWikiContext) data;
        XWikiDocument doc = (XWikiDocument) source;
        String currentUser = xcontext.getUser();
        
        boolean isRestrictedUser = RESTRICTED_GROUPS.stream().anyMatch(group ->
            xcontext.getWiki().getGroupService(xcontext).isMember(currentUser, group)
        );

        if (isRestrictedUser) {
            BaseObject userObj = doc.getXObject("XWiki.XWikiUsers");
            if (userObj != null) {
                userObj.set("displayHiddenDocuments", "0", xcontext);
                userObj.set("usertype", "Simple", xcontext);
            }
        }
    }
}

The problem is that it is not fired at all.

Anyone any idea what is wrong here?

Thanks in advance
Dalli

I don’t understand what you mean here. The script component is registered automatically when it’s saved (or at startup), you don’t need to access the page.

Did you check the log for any related error (generally when the component page is saved) ?

Thank you for your answer.

I use the PageLogs application and did set org.xwiki.observation and org.xwiki.observation.internal to “DEBUG” in the Admin panel under Logging, but nothing appears. But according to the documentation of the PageLogs application, the panel should be visible if there are any logs.

Since the instance is in the cloud, I have no access to the server files to check the log files there. Where else can I access any server-side logs?

AFAIK, the point of this application is to show you the log produced by the rendering of a page, and not all the server log.

I think https://extensions.xwiki.org/xwiki/bin/view/Extension/Admin%20Tools%20Application provides a tool to access the server log.

Great, that helps!

In the log I see: 2025-02-18 15:32:11,521 [http-nio-8080-exec-3 - …/xwiki/bin/save/Admin/WebHome] ERROR .o.i.DefaultObservationManager - Failed to send event [org.xwiki.bridge.event.DocumentUpdatedEvent@60b58590] to listener [PreventRestrictedUserChangesListener@7329c8d6]

Seems like I use a wrong method for checking the user groups. So I deleted the ScriptComponent again and manually removed the Listener from the ObservationManager. But this log entry persists when I update a document. I emptied the bin, I cleared the chache and there is no other page containing a script component. Why is it still popping up?

I want to fix the script methods and then try again, but as long as I have wrong log entries, it is tough. -.-

I found the issue, it was a wrong method for getGroupService(xcontext). I fixed it and now it works like a charm.