Sitecore User Manager – Filter Users by Profile Type

I recently blogged about How to use Locally Managed Domains in Sitecore which is very useful but I also wanted to go over a couple other cool things I discovered while attempting to extend upon this functionality for a client.

First off, Locally Managed Domains are great because they allow you to restrict access to only a subset of all Sitecore users that are associated with a specific domain. This is extremely helpful when you are working with a multi-site solution in Sitecore because it means you can hide users that belong to a different site (and may be managed by a different department within an organization). That all works out of the box but I also set-up many different custom user profiles for each single domain…

And that’s when I got a client request that I had never thought about before. They wanted the ability to limit user access to a single domain and only for a single user profile type. So that means that when this new user role opens up the Sitecore User Manager, the populated list of users would only contain users from a single domain AND only if the user was of a particular user profile. On top of that this new user role would only be able to create a new user of one specific profile type.

Part 1

Where to start! First, let’s tackle limiting user profile types when creating a new user.

Let me explain this in a bit more detail. Normally when you create a new user you must select their profile type from the “User Profile” multilist as seen below.

user_profile_selection

But what I was looking to achieve was that certain users would not see the full list of user profiles and they would instead only have one option that would be automatically selected when creating new users.

Like this!

user_profile_fixed

I think this is super useful! Not only does it meet my requirements in this scenario but I really like the idea of using this more often to ensure that the correct user profile is selected when creating a new user. In my experience it’s extremely common for admins to forget to choose the correct user profile from the list when creating new users.

How do you achieve this? Simple, just go change the security access rights for the profile items in the Core DB! But before I changed the access rights I created a new role that inherits from the sitecore\Sitecore Client Account Managing role and changed the access rights on the new role.

Switch to the Core DB and select your new role in the Security Editor tool. Navigate down to /sitecore/system/Settings/Security/Profiles to find the user profile items and deny read access to the profiles that you do not want to appear when creating a new user.

deny_read_access

Awesome! Next let’s take a look at how to filter the users that appear in the User Manager based on their profile type.

Part 2

I was hoping that denying read access rights (as I did in step one) would also automatically remove some of the users that appear in the Sitecore User Manager. It didn’t. I knew it was a long shot but I had to double check.

However I knew I was on the right track and I wanted to find a way to filter users based on the access rights I had already set. I had denied read access to all profiles except the Canadian Nurse Member profile (as seen in the last image from part 1) so I wanted to only show users if they were based on that profile. I was lucky and found a great example showing how to override the UserManager class and that pushed me in the right direction.

The following code extends the standard UserManager class to filter out users if their profile type has been denied read access.

public class FilterByProfileUserManager : Sitecore.Shell.Applications.Security.UserManager.UserManager
{
    protected override void OnLoad(EventArgs e)
    {
        Assert.ArgumentNotNull(e, "e");
        base.OnLoad(e);
        Assert.CanRunApplication("Security/User Manager");
        var managedUsers = global::Sitecore.Context.User.Delegation.GetManagedUsers().Where(HasReadAccessToProfile);
        Sitecore.Web.UI.Grids.ComponentArtGridHandler<User>.Manage(Users, new Sitecore.Web.UI.Grids.GridSource<User>(managedUsers), RebindRequired);
        Users.LocalizeGrid();
    }
  
    // Properties
    private bool RebindRequired
    {
        get
        {
            return ((!Page.IsPostBack && (Request.QueryString["Cart_Users_Callback"] != "yes")) || (Page.Request.Params["requireRebind"] == "true"));
        }
    }

    private static bool HasReadAccessToProfile(User user)
    {
        if (user.Profile == null) return false;
        var profileId = user.Profile.ProfileItemId;
        if (profileId == null) return false;
        var coreDb = Sitecore.Configuration.Factory.GetDatabase("core");
        var profileItem = coreDb.GetItem(user.Profile.ProfileItemId);
        return profileItem != null && profileItem.Access.CanRead();
    }
}

The code is nice and succinct but the strange part was figuring out how to hook this up. I was able to get the code to run by changing the namespace and class name in the \sitecore\shell\Applications\Security\UserManager\UserManager.aspx file.

I changed the Inherits parameter in the following snippet from the UserManager.aspx page to use the namespace and classname from the code above. Yes, I found this a little hacky but it did the trick. Let me know if you have a nicer solution!

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UserManager.aspx.cs" Inherits="Sitecore.Shell.Applications.Security.UserManager.UserManager" %>

So after all this I can finally open the Sitecore User Manager and the list of users is now filtered by profile type!

Posted in Customization, Sitecore

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s