Question

Sitecore 6.5 system: In code, is there a way to determine which roles have access to a specific item?

I have an extranet set up, some items are "protected" - meaning the anonymous account has had the inheritance broken, and certain roles have been granted read access. I already have a custom pipeline built, so I can determine when user attempts to view a protected item, but I need to determine what role(s) has access to view the item so I can direct them appropriately.

Thanks, Thad

edit:

Here is the relevant code - there may be a better way of doing this (I inherited the system & code), but I am attempting to utilize what was already in place. The problem with the code below is that Sitecore.Context.Item is null when the user doesn't have permission.

public class NotFoundProcessor : Sitecore.Pipelines.HttpRequest.HttpRequestProcessor
{
    public override void Process(Sitecore.Pipelines.HttpRequest.HttpRequestArgs args)
    {
        if (args.PermissionDenied)
        {
            //determine what role would give the user access
            foreach(Sitecore.Security.Accounts.Role role in Sitecore.Security.Accounts.RolesInRolesManager.GetAllRoles())
            {
                bool roleCanRead = Sitecore.Context.Item.Security.CanRead(role);

                //... do stuff here

            }
        }
    }
}
Was it helpful?

Solution

Just from the top of my head, you can check all the roles if they have read access to chosen item:

foreach (Role role in RolesInRolesManager.GetAllRoles())
{
  bool roleCanRead = item.Security.CanRead(role);
}

EDIT after code sample provided:

You need to try to resolve the item in the same way as ItemResolver does but wrapped it with SecurityDisabler and without setting it to Sitecore Context afterwards. This will allow you to find the requested item despite the fact the user doesn't have access to it:

public class NotFoundProcessor : HttpRequestProcessor
{
    public override void Process(HttpRequestArgs args)
    {
        if (args.PermissionDenied)
        {
            Item item = GetItemUsingSecurityDisabler(args);

            //determine what role would give the user access
            foreach(Role role in RolesInRolesManager.GetAllRoles())
            {
                bool roleCanRead = item.Security.CanRead(role);

                //... do stuff here

            }
        }
    }
}

private Item GetItemUsingSecurityDisabler(HttpRequestArgs args)
{
    using (new SecurityDisabler())
    {
        string path = MainUtil.DecodeName(args.Url.ItemPath);
        Item item = args.GetItem(path);
        if (item == null)
        {
            path = args.Url.ItemPath;
            item = args.GetItem(path);
        }
        if (item == null)
        {
            path = args.LocalPath;
            item = args.GetItem(path);
        }
        if (item == null)
        {
            path = MainUtil.DecodeName(args.LocalPath);
            item = args.GetItem(path);
        }
        SiteContext site = Sitecore.Context.Site;

        string rootPath = site != null ? site.RootPath : string.Empty;

        if (item == null)
        {
            path = FileUtil.MakePath(rootPath, args.LocalPath, '/');
            item = args.GetItem(path);
        }
        if (item == null)
        {
            path = MainUtil.DecodeName(FileUtil.MakePath(rootPath, args.LocalPath, '/'));
            item = args.GetItem(path);
        }

        // I've ommited resolving item using DisplayName but you can add if necessary here

        return item;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top