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.


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
- All administrators from the group “ContentAdmins” shouldn’t have access to any components of the content slot “Footer”.
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.

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:

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);
}
}
In addition to that, you need to:
- Redeclare the bean
cmsPageLockingService. - Add a system user with
uid = “PermissionManager”.
Video
© Rauf Aliev, January 2017