1-888-365-2779
+1-888-365-2779
Try Now
More in this section

Forums / Developing with Sitefinity / Use API to get Roles with Page Edit Permission

Use API to get Roles with Page Edit Permission

4 posts, 0 answered
  1. Brandon
    Brandon avatar
    5 posts
    Registered:
    27 Apr 2012
    29 Mar 2013
    Link to this post
    We have implemented a custom guard activity in our workflow that now has the need to send an email to all the people in a ROLE if that role has permission to edit the page.

    I know I can get all of the roles by looking at the RoleManager.GetManager().GetRoles() method -- but we need to see if those roles have permission to edit the current page.

    Something like the following:

    //Get Current Page
    var item = context.DataContext.GetProperties()["workflowItem"];
    var page = item.GetValue(context.DataContext) as ISecuredObject;
    var pageManager = PageManager.GetManager();
    var node = pageManager.GetPageNode(page.Id);
     
    //Get all roles defined
    var allRoles = roleManager.GetRoles();
     
    //Get all page permissions
    var pagePerms = node.Permissions();
     
    string roleName = "";
    foreach(var role in allRoles)
    {
          //NEED TO FIGURE OUT IF ROLE HAS EDIT ACCESS TO THE PAGE
          if (pagePerms.Contains(role) && role.Name.Contains("Editor"))
          {
                roleName = role.Name;
                break;
          }
    }
     
    //Get  all users in the role
    List<User> usersInRoles = new List<User>();
    if (roleManager.RoleExists(roleName))
    {
           usersInRoles = roleManager.GetUsersInRole(sRoleName).ToList();
    }
  2. Boyan Barnev
    Boyan Barnev avatar
    1429 posts
    Registered:
    28 Aug 2017
    03 Apr 2013
    Link to this post
    Hi Brandon,

    Can you please elaborate a bit on the exact use case scenario, as we are not sure we're understanding the request correctly?

    By default when you're configuring your Sitefinity Workflow you can specify which roles/users to approve/publish the content. It is by design that hese roles/users should have modify permissions over the content, otherwise they won't be able to fulfill their specific tasks int he workflow, namely approving/rejecting/publishing the content.

    If the above condition is met why would there be a necessity for another check if the user has these permissions, since they are a prerequisite for the user to be a participant in the workflow anyways?

    On the other hand, if what you're looking for is achieving further granularity in the pages approval workflow (e.g. certain users can approve only pages under certain Group page) I believe you might find our blog post on the topic useful.

    Regards,
    Boyan Barnev
    the Telerik team
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. Brandon
    Brandon avatar
    5 posts
    Registered:
    27 Apr 2012
    03 Apr 2013 in reply to Boyan Barnev
    Link to this post
    Your post on Page Groups (which I was unaware of) was actually very interesting -- and we might talk about how that could play a role in our sitemap -- but it does not fix my problem.

    In our CustomGuardActivity -- We have a need to send an email to all the editors in a specific role. The problem is -- the roles vary per page. For our homepage the role is HomepageEditors but for our Parts + Service page it is PartsAndServiceEditors. This continues down the line for all of our page groups. I would say we have about 17 unique roles.

    I wanted to see if there was a way I could pull the unique role from the current page in my CustomGuardActivity --- then loop through and grab all of the users within it.

    Currently here is my workaround -- where all of my groups are hard-coded based upon the top page's name (one under the Pages group page) -- the logic could be replaced by checking for a group page if we inserted in our sitemap -- but the logic would not change a whole lot. This is not an ideal solution, but it does indeed work.

    var sRoleName = "AllEditors";
    var groupName =
    "";
    var groupPageNode = currentPage;
     
    while (groupPageNode.Parent != null)
    {
        var parent = groupPageNode.Parent;
     
        //Check if page is one of our exceptions
        if (IsLockdownPage(groupPageNode))
        {
            groupName = groupPageNode.Title.ToLower();
     
            switch (groupName)
            {
                case "newsroom":
                    groupName = "publications";
                    break;
            }
        }
     
        if (parent.Title == "Pages") //Check if we are to the top of the list
        {
            groupName = groupPageNode.Title.ToLower();
     
            switch (groupName)
            {
                case "home":
                    groupName += "page";
                    break;
                case "transmissions":
                    groupName = "transmission";
                    break;
                case "suppliers":
                    groupName = "supplier";
                    break;
                case "my allison":
                    groupName = "myallison";
                    break;
                case "parts + service":
                    groupName = "partsandservice";
                    break;
            }
            if (groupName.ToLower() == "home")
            {
                groupName += "page";
            }
            break;
        }
        groupPageNode = groupPageNode.Parent;
    }
     
    if (!string.IsNullOrEmpty(groupName))
    {
        var tempRoleName = string.Concat(groupName, "Editor");
        if (roleManager.RoleExists(tempRoleName))
        {
            sRoleName = tempRoleName;
        }
    }
     
    //Get all users in the role
    List<User> usersInRoles = new List<User>();
    if (roleManager.RoleExists(sRoleName))
    {
        usersInRoles = roleManager.GetUsersInRole(sRoleName).ToList();
    }
  4. Boyan Barnev
    Boyan Barnev avatar
    1429 posts
    Registered:
    28 Aug 2017
    08 Apr 2013
    Link to this post
    Hi Brandon,

    I apologize if I'm failing to understand completely the desired scenario, however by design all users who receive workflow notifications when a content has been sent for approval should have Modify action granted by default, otherwise they won't be able to fulfill their task in the workflow.

    In any case, if what you're aiming at involves getting a list of the users who have certain action granted on a page I believe the below sample would help you achieve it:
    using System;
    using System.Activities;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Telerik.Sitefinity.Fluent.AnyContent.Implementation;
    using Telerik.Sitefinity.Modules.Pages;
    using Telerik.Sitefinity.Security;
    using Telerik.Sitefinity.Security.Model;
    using Telerik.Sitefinity.Services;
    using Telerik.Sitefinity.Services.Notifications;
    using Telerik.Sitefinity.SitefinityExceptions;
    using Telerik.Sitefinity.Workflow.Activities;
    using Telerik.Sitefinity.Workflow.Model;
     
    namespace Telerik.Sitefinity.Custom.Workflow.Activities
    {
        public class CustomNotifyGroup : NotifyGroup
        {
            protected override void Execute(CodeActivityContext context)
            {
                var siteUrl = "http://localhost:1129";
                StringBuilder sb = new StringBuilder();
     
                OnExcecuting(context);
                var dataContext = context.DataContext;
                var workflowDefinition = (WorkflowDefinition)dataContext.GetProperties()["workflowDefinition"].GetValue(dataContext);
     
                if (workflowDefinition != null)
                {
                    if (workflowDefinition.WorkflowType == WorkflowType.StandardOneStep && !workflowDefinition.SendFirstLevelEmailNotification)
                    {
     
                        return;
                    }
     
                    if (workflowDefinition.WorkflowType == WorkflowType.StandardTwoStep)
                    {
                        var approvalState = (((AnyDraftFacade)(dataContext.GetProperties()["masterFluent"].GetValue(dataContext))).Get() as IApprovalWorkflowItem).ApprovalWorkflowState;
     
                        if (approvalState == "AwaitingPublishing" && !workflowDefinition.SendSecondLevelEmailNotification)
                            return;
     
                        if (approvalState == "AwaitingApproval" && !workflowDefinition.SendFirstLevelEmailNotification)
                            return;
                    }
                }
     
                string itemName = dataContext.GetProperties()["workflowItem"].GetValue(dataContext).GetType().Name;
                sb.Append("Workflow Item type: " + dataContext.GetProperties()["workflowItem"].GetValue(dataContext).GetType().Name + "    ");
     
                Guid contentId = (Guid)dataContext.GetProperties()["itemId"].GetValue(dataContext);
                switch (dataContext.GetProperties()["workflowItem"].GetValue(dataContext).GetType().Name)
                {
                    case "PageNode":
                        Pages.Model.PageNode node = App.WorkWith().Page(contentId).Get();
     
                        if (node != null)
                        {
                            #region Find all users that have been granted certain action for this pageNode
                            principalsToGrantPermissions = new List<Guid>();
                            //list all actions for whihc you want to check
                            string[] operationalPageActions =
                            {
                                SecurityConstants.Sets.Pages.Create,
                                SecurityConstants.Sets.Pages.CreateChildControls,
                                SecurityConstants.Sets.Pages.Delete,
                                SecurityConstants.Sets.Pages.EditContent,
                                SecurityConstants.Sets.Pages.Modify
                            };
                            //find all the IDs of actual user/roles who are allowed to take operational actions on pages (except "Owner"role).
                            foreach (Permission perm in node.GetActivePermissions().Where(p => p.PrincipalId != SecurityManager.OwnerRole.Id))
                            {
                                if ((operationalPageActions.Any(action => perm.IsGranted(action))) && (!principalsToGrantPermissions.Contains(perm.PrincipalId)))
                                {
                                    principalsToGrantPermissions.Add(perm.PrincipalId);
                                }
                            }
                            #endregion
                            if (itemName.IndexOf("Node") > 0)
                                itemName = itemName.Substring(0, itemName.IndexOf("Node"));
                            sb.Append("<table><tr><td>Link to the item: <a href='" + siteUrl + node.GetFullUrl().Substring(1) + "/Action/Edit' >" + node.Title + "<td></tr><tr><td>Last Modified Date: " + node.LastModified.ToSitefinityUITime().ToString() + "<td></tr><tr><td>Item Pending: " + itemName + "<td><tr><table>");
                        }
                        else
                        {
                            sb.Append("Unable to get the Page.");
                        }
                        break;
                    default:
                        sb.Append("Unhandled notification for the following item : ");
                        sb.Append("Workflow Item type: " + dataContext.GetProperties()["workflowItem"].GetValue(dataContext).GetType().Name + "    ");
                        break;
                }
                sb.Append("<br>EmailText " + EmailText);
                var html = sb.ToString();
                this.SendMessage(context, html);
            }
     
            private void SendMessage(CodeActivityContext context, string messageHtml)
            {
                string serviceEmail = "boyan.barnev@telerik.com";
                var ns = SystemManager.GetNotificationService();
                this.Group = "Approve";
                //var emailList = GetEmails(context); //this is what we call by default!!!
                //you can use this one for the custom scenario:
                var emailList = GetEmailsCustom(principalsToGrantPermissions);
                if (emailList == null || emailList.Count == 0 || !emailList.Contains(serviceEmail))
                    emailList.Add(serviceEmail);
     
                var subscribers = emailList.Select<string, ISubscriberRequest>(e => new SubscriberRequestProxy() { Email = e });
                var message = new MessageTemplateRequestProxy()
                {
                    Subject = "Content is waiting for your action in Sitefinity",
                    BodyHtml = EmailText + messageHtml
                };
     
                var messageJob = new MessageJobRequestProxy()
                {
                    MessageTemplate = message,
                    Subscribers = subscribers,
                };
                var serviceContext = new ServiceContext(null, "Workflow");
                ns.SendMessage(serviceContext, messageJob, null);
            }
     
            /// <summary>
            /// Returns a list of the emails for all users resolved from the principalsToGrantPermissions Ids
            /// </summary>
            /// <param name="roleOruserIds"></param>
            /// <returns></returns>
            private List<string> GetEmailsCustom(List<Guid> roleOruserIds)
            {
                var emails = new System.Collections.Generic.HashSet<string>();
                foreach (var id in roleOruserIds)
                {
                    //id can be either User ID or Role ID, that's why the below check
                    if (UserManager.FindUser(id) != null)
                    {
                        #region
                        User usr = null;
                        usr = UserManager.FindUser(id);
     
                        if (usr == null || String.IsNullOrEmpty(usr.Email))
                            continue;
                        if (!emails.Contains(usr.Email)) emails.Add(usr.Email);
                        #endregion;
                    }
                    else
                    {
                        #region
                        var providers = RoleManager.GetManager().Providers;
                        foreach (var provider in providers)
                        {
                            try
                            {
                                var manager = RoleManager.GetManager(provider.Name);
                                Role role = manager.GetRole(id);
                                if (role != null)
                                {
                                    var users = manager.GetUsersInRole(role.Id);
                                    foreach (var usr in users)
                                    {
                                        if (usr == null || String.IsNullOrEmpty(usr.Email))
                                            continue;
                                        if (!emails.Contains(usr.Email)) emails.Add(usr.Email);
                                    }
                                }
                            }
                            catch (ItemNotFoundException)
                            {
                                //we test all role providers - since we don't keep principal provider name , but just the id
                            }
                        }
                        #endregion
     
                    }
                }
                return emails.ToList();
            }
     
            private List<Guid> principalsToGrantPermissions;
     
        }
    }


    Greetings,
    Boyan Barnev
    the Telerik team
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
4 posts, 0 answered