A note from 2026: This article was published in 2017. CMS Cockpit and the older hybris WCMS tooling have been deprecated in SAP Commerce Cloud in favor of Backoffice and SmartEdit, so the implementation classes and UI behavior described here may not apply to current releases.

Situation

Content slots are named areas on a page for CMS components. These areas are not movable or removable, but you are allowed to edit a set of components inside the slots.

CMS Cockpit page with content slots

Content slot structure

The default hybris setup doesn’t allow you to manage editing permissions for specific content slots, such as Header or Footer. Access management in WCMS is available only at the component and page/page-template level, but not at the content-slot level.

It is required to restrict access for specific users or user groups.

Example

Solution

WCMS is not very extensible, so for this solution I extended the existing service, CMSPageLockingService.

There are two methods of CMSPageLockingService to be extended: isContentSlotLockedForUser and getSlotLockers. The first method is used to pretend that the section is locked by other administrators, although in fact it is locked by the configuration. In the default implementation, the method uses another administrator’s locking status, which is dynamically set by CMS Cockpit. So now this logic becomes a bit more comprehensive, because the configuration is used in addition to the default logic.

However, in the straightforward approach, there are some flaws that make the solution tricky. If isContentSlotLockedForUser is true, hybris assumes that getSlotLockers will contain the username of the person who locked the slot, but our change in isContentSlotLockedForUser has nothing in common with that, and getSlotLockers returns an empty set. Certainly, if there are administrators who locked the item, the error will go away. That is why getSlotLockers is also extended. It uses a hashmap created in isContentSlotLockedForUser. The result of the method is used for the popup window with a message.

isContentSlotLockedForUser and getSlotLockers are called one after another in the hybris code; the second method clears the data created by the first method. See the remove statement in the code.

Lock icon in CMS Cockpit

If you block a content slot used in the template, there is a lock icon that locks and unlocks the template-level content slot. There is an event listener that is not replaceable or extendable. This listener displays a message if the slot is blocked by other administrators. I use the same message to indicate that the slot is blocked by permission control. For that, I created a dummy user with the name “Permission Manager”. As a result, the following message is displayed for the content slots disabled for the administrator:

Permission Manager lock message in CMS Cockpit

public class MyCMSPageLockingService extends DefaultCMSPageLockingService {
    @Resource
    private UserService userService;

    private HashMap<ContentSlotModel, UserModel> lockedContentSlot = new HashMap<>();

    public boolean isContentSlotLockedForUser(ContentSlotModel contentSlotModel, UserModel userModel) {
        boolean result = super.isContentSlotLockedForUser(contentSlotModel, userModel);
        UserModel systemUser = userService.getUserForUID("PermissionManager");
        List<PrincipalModel> principals = new ArrayList<>();
        Set<PrincipalGroupModel> groupsOfTheCurrentUser = userModel.getAllGroups();
        principals.add(userModel);
        principals.addAll(groupsOfTheCurrentUser);

        for (PrincipalModel p : contentSlotModel.getNotAllowedFor()) {
            if (principals.contains(p)) {
                lockedContentSlot.put(contentSlotModel, systemUser);
                return true;
            }
        }

        return result;
    }

    @Override
    public Collection<UserModel> getSlotLockers(ContentSlotModel contentSlotModel) {
        if (lockedContentSlot.get(contentSlotModel) != null) {
            return Collections.singletonList(lockedContentSlot.remove(contentSlotModel));
        }

        return super.getSlotLockers(contentSlotModel);
    }
}

Collections

In addition to that, you need to:

Video

© Rauf Aliev, January 2017