Last week I've attended an Umbraco 9 Hackathon, and let me tell you, we had a blast! A full day of learning new things involving the latest version of Umbraco, exploring it's new features, and tackling interesting challenges to compete against with one another! One of the challenges I though would be cool to figure out, was to find out how (and if) it is possible to hide specific doctype properties, groups and tabs from our backoffice users, based on their roles... and the answer is, we can! So let's get to sharing! 😄
Okay, the challenge is clear! Let's look at the backoffice and see what we can do! Usually when we hear the word "security" or "permissions", we head over to the Users section. From there, we can either change permissions directly on an individual user, or modify permissions on a group level. I quickly noticed that the only permissions that we can change over here, are based on the Content/Media tree, and not permissions for specific doctypes themselves... the backoffice itself wasn't going to cut it for this challenge. Back to the drawing board, and let's get to coding!
Hide Properties Notification
Since we couldn't solve the challenge from just within the backoffice alone, we could make use of the Umbraco event that gets triggered whenever a content item gets requested (aka opened) to our backoffice user. In Umbraco 9, this is called the SendingContentNotification. From within the Handle method that our notification implements, we get access to all the data that is required to display the information we see of our content item in the backoffice!
Want to learn more about Events & Notifications? Read all about it here: https://cornehoskam.com/posts/umbraco-8-versus-9-events-and-notifications
Our notification has a Content property, which contains one or more variants (for when our item is available in multiple languages). Each one of these variants, has a Tabs property, which contains all information about our Groups and Tabs. Eureka! We should be able to modify the contents from here, to remove the tabs, groups or properties we do not want our backoffice user to see!
Each item in the Tabs property has an alias, which is an unique name which we can use to determine whether it's the full tab itself, or a group within a tab. An easy way to spot which one we are dealing with, is to check the debugger on the available contents on the Tabs property! In this use-case, I've spotted the following tabs:
- content (a tab)
- content/hero (a group)
- content/content (a group)
- superSecretTab (a tab)
- superSecretTab/content (a group)
Have you spotted it? If the alias contains a '/', we are dealing with a group with a tab, if not, we are dealing with the tab itself!
By overriding the Tabs property on our notification.Content.Variants' variant, we can modify/remove the tab, and therefor hide it from our backoffice user!
Now to figure out how to only remove our super secret tab if we don't have the right permissions to access it...
Luckily for me, this one only required some thorough searching on the inter-webs, but was surprisingly easy to implement! We can inject an instance of IBackOfficeSecurityAccessor into the constructor of our Notification using dependency injection, which gives us access to the currently logged in backoffice user. Not just that, one of the many properties we can access on this user, are the groups that the user is in! That should do the trick!
Let's implement our Notification, in which we get the current backoffice user, check if it's within the Sensitive Data access group/role, and if not, remove the superSecretTab from the Tabs so that it will be hidden from our user!
There we go! After registering our NotificationHandler (more details on how to register our NotificationHandler here!), that will be all that is required for us to hide a Tab (or Group!) from our backoffice user!
But what if we want to only hide a specific property or properties, and not a complete tab or group? Just as easy! From within a specific tab in our variant.Tabs property, we have access to the "Properties" property. In the same way we can hide/remove our tab or group, we can hide the specific property too!
🔥 And there you have it! We have successfully completed the challenge! 🚀
If you have any further questions, feel free to contact me over at my socials available at the Contact page, and I'd love to hear about the amazing creations you're able to come up with, with this setup! 😄