More granular website security based on user roles
Since the very beginning of Sulu, we were wondering how to properly handle security on the website with our permission system. We’ve put some thought into it with this release and are quite happy with the results.
The first issue to solve was that it was not possible to see which permissions belonged to which system. A system could either be the Sulu administration interface, or a system you have defined as part of your application. The most common way to define your own system is to use the “system” tag in the “security” part of our webspace XML configuration.
Now in Sulu 2.2, the permissions for different systems are grouped, and they can be activated separately. This not only fixes the problem — making it possible to see which permissions belong to which system — it’s now also possible to deactivate permissions and remove them completely on an object level.
Previously it was not possible to restore the general permissions for the context the object was in, the closest thing that the content manager could do was to set the permissions to the same values as in the security context. And this includes the drawback that the permissions of the object do not change when the permissions of the security context change.
The system group in the permission tab will only appear if the “permission-check” flag from the XML configuration above is set to true. In that case, Sulu will also check the permissions for you on the website. That means:
- Visitors get appropriate “Access Denied” responses or a login screen if they request a restricted page.
- If the visitor does not have the required permissions, that restricted page will not be listed in the navigation, in smart content or in the page selection content type.
For each system, there will also be an anonymous user role, which enables the content manager to also restrict access to pages or collection for visitors who are not logged in.
And the best thing is: you can also make use of this functionality if you build your own business objects.
Better permission handling by leveraging inheritance
Until now permissions on an object-level were only set on a single object, and there was no way to pass these permissions to its children in a tree hierarchy. In practice, this meant that if a content manager wanted to have the same permissions on an entire subtree (which is a quite common requirement), they had to click through every element in the subtree and manually adjust the permissions.
The issue describing that problem dates back to 2016, and more or less existed since we introduced our permission system. Our main problem was that we did not know how to implement that in a simple and performant way. We thought about a checkbox which determines if the permissions should be inherited to the children in our permission tab, but that comes with two downsides:
- It would be hard to implement that in a performant way, since we would not only have to check that permission for the object itself, but also for all of its parents.
- It would also be confusing for the user, since they don’t know from looking at the permission tab where these permissions are actually coming from.
So we’ve decided to solve this issue at a different point in runtime, namely when the permissions are written. This solves both of the above problems:
- Performance is not an issue anymore when the permissions are checked, since they are already resolved for the current object.
- The user always knows that the permissions they are seeing in the administration UI are only valid for the currently opened object. We still added a few more dialogs explaining this mechanism in more detail when appropriate.
The other question that might pop into your head is how we implemented that in order to make that as easy as possible for the user. There are two important decisions here:
- Whenever the user saves some permissions using the permission tab for an object that has some children, another dialog will open to ask the user if these permissions should also be applied to all children. If the user confirms by activating the checkbox in the dialog, then the existing permissions of all children are overridden.
- When a new object is created, the permissions are not empty anymore. Starting with this release the permissions from the parent object will be also used as the initial permissions for the newly created object.
We thoroughly tested this behavior, and it seems very logical to us, and should not hit the users of our system by surprise. Please don’t hesitate to tell us your experiences (via Slack or our contact form), especially if you found situations where this behavior is confusing.
Use image maps for engaging visualizations
Lately, we have heard of many projects that want to make use of some kind of image map, for example, to present products to customers in a more appealing way. With the very flexible content management structure that comes with Sulu, this was already possible, although it might have been a bit cumbersome to deal with, especially for the content manager.
That was reason enough for us to think about a better solution. What we finally came up with, was a separate content type for image maps. It enables the content manager to manage the image maps with a straightforward interface.
- Assign an image and define multiple regions (points, circles and rectangles) to it.
- Resize and move the regions as needed.
Each of these regions has a separate sub form, which is defined by the developer and can hold as many content types as you wish. This makes it a very powerful addition to your toolbelt!
Split your website into different segments
Tourism websites are a perfect example of websites making use of Sulu segments. These websites often differ a lot depending on the current season, both styling and content-wise. Therefore we’ve implemented a feature, that allows the visitor to switch between different segments. In addition, the developers can decide which of the segments is the default one when a visitor sees the website for the very first time.
But what exactly can you control with a change of the segment?
A different look and feel per segment: The easiest thing a developer can do is to include a different stylesheet based on the current segment, which is also passed to the twig template.
Control what content and navigation will appear within each segment: Moreover, and that’s the more powerful part, the system will provide the twig template with the correct information for the selected segment. There are multiple ways of making use of that, one is pictured in the screenshot above. By adding a segment to a page in its excerpt tab, the system knows which pages belong to which segment, and therefore can filter all the output. Sulu will make sure that a page from the “summer” segment will not show up in the navigation or smart content if the website currently runs the “winter” segment.
Give users control over switching segments: The visitor can also switch among all existing segments on the website if the developer provides a segment switcher (the necessary URLs for that are passed into the twig template). Technically this is implemented by a cookie, which remembers the current segment the visitor has chosen. Sulu will correctly handle the HTTP caching for that cookie. This works out of the box for the Symfony HTTP Cache. For Varnish it is required to use the VCL we are providing with Sulu, which you should be using anyway. Check the documentation on caching with Varnish.
How is this different from the AudienceTargetingBundle?
Some of you might spot some similarities between this and the existing AudienceTargetingBundle. The biggest difference between these two is the way the assignment is handled.
- A segment has a default value that is being assigned to the visitor, but the visitor can switch to another segment at any time.
- Audience Targeting works differently: It will assign a target group to each visitor, based on a defined set of rules. This is invisible to the visitor, and by just looking at the website’s content the visitor won’t realize that they have been targeted.
New powerful block display settings
Much of the flexibility of our content structure comes from our blocks content type. They allow the repetition of content and give the content manager more flexibility in an otherwise rigid structure. Since we are convinced that blocks are one of the most important features of our content management functionality, we decided to improve them with a new feature: Block settings.
The block settings differ based on the configuration of your installation. It currently comes with up to three different sections.
- Don’t display on the public website: This is a simple toggle that allows you to temporarily hide the block on the website, and the only section that is always available.
- Assign segment: In this section, content editors can assign a block to the segments described previously. The block will only display on the selected segment. With this feature, it is possible to show different content on the same page based on the segment that is currently selected.
- Assign target groups: We are confident that this section will make the Audience Targeting feature we have already introduced in Sulu 1.6 more popular. It helps to further customize the content of a page using Audience Targeting. Previously that was only possible by using smart content or implementing something on your own, whereby both approaches can be cumbersome in certain situations.
Improved UX on forms
Of course, we didn’t neglect existing components in this release. The form view, which can be used also in combination with your custom entities, received some improvements as well:
- A “SaveWithFormDialogToolbarAction” has been added for the permission inheritance feature mentioned above. It allows to show another form in a dialog after the save button has been clicked, to ask for further information, which will then be attached to the HTTP request.
- The ResourceLocator has a new button to regenerate the URL based on the current content
- The templates shown in the template dropdown are now sorted alphabetically
- The tabs do not break anymore with long titles and a dropdown is shown on the right if more tabs than can be shown are defined
Enhanced list configuration and display
Along with the form, the list is one of the most crucial components in Sulu.
- A new transformer has been added to properly show colors and icons in lists
- The list for pages shows if there is an error with the page and if some permissions have been set
- The webspaces in the page list are now ordered alphabetically
- The export functionality on lists now also considers filters and searches
- The table list is now available in the overlay of the media selection
- A “User locked” column has been added to the contacts list
Other miscellaneous improvements
There have been a few more improvements to make it easier to build and manage applications with Sulu.
- Added a new command to regenerate all generated image formats
- The “localizations” variable has been added to twig, which should be used instead of the “urls” variable
- The settings for creating a shadow page in the page’s settings tab are hidden if no second language exists in the webspace
- It is now possible to copy pages between different webspaces
And there’s even more bugfixes and updated dependencies, so make sure to check the release notes for more details!
Sulu 2.2 contains some very interesting new features, so I suggest that you should check them out! I am sure there’s loads of potential for these features, so I’m looking forward to seeing what you create.
A special thank you goes to thenetexperts for sponsoring a bugfix regarding the URL generation of a page after it has been copied, and to MADSACK Mediengruppe for sponsoring the implementation of copying pages across webspaces. Kudos also go to MASSIVE ART for the sponsorship of the Image Map content type. You are the best!
Finally, I want to say that we are eagerly awaiting your feedback, preferably on Slack, about this release and especially its new features.