Grab all Users with Permission to Publish Content

Topics: Administration, Customizing Orchard
Sep 27, 2014 at 9:55 PM
Is it possible to somehow create an array or list of users with the permission to publish content. So far I have only been able to find a way to grab a user by their username or by the currently logged in user. I need to create a list of users with the ability to publish that I can stick into a token. I also need to create a list of their emails, this is actually more important than just a list of their usernames, but from my understanding you could grab the emails based off of the username.
Sep 27, 2014 at 10:41 PM

I think
var users = _contentManager.Query<UserPart, UserPartRecord>().List();
should do the trick.
Sep 27, 2014 at 11:01 PM
Edited Sep 27, 2014 at 11:38 PM
Awesome thank you I was having a problem putting the query into a list. My next problem is trying to determine if the user has the permission to publish so I can add them to a list of users that can publish content. I don't see a member function for the var users that looks like it will do this. Can I use the .has function?

Edit: I've been looking into this further and have found a class that has a member function you can use to test if a user is in a certain role. This could work but a better solution would be if the same thing existed but to check if a user has a certain permission. Is this already built into orchard?
Sep 28, 2014 at 1:52 AM

As far as I know Orchard has a RoleBased permission system and maybe you should rethink your solution and create a role and list all users who have this role.

You can get the role of the user like this:
 var users = _contentManager.Query<UserPart, UserPartRecord>().List();

 var user = users.FirstOrDefault();

 var roles = user.As<UserRolesPart>().Roles;
If you really like to check on a permission you can do that with the IAuthorizationService. Get this service from the IoC and use it like this:
var result = _authService.TryCheckAccess(Permission.Named("PublishContent"), user, null);
I am not sure if its the most elegent way but it should work.
Sep 30, 2014 at 3:37 PM
So this is what I am doing to set my tokens but they are coming up as blank or empty when I try to use them within Orchard.

public void Evaluate(dynamic context) {
        var forContent = context.For<ISite>("Site", (Func<ISite>)(() => _orchardServices.WorkContext.CurrentSite));

        //Grab a list of all the users
        var users = _orchardServices.ContentManager.Query<UserPart, UserPartRecord>().List();

        //Implement the OrchardRoleProvider class to determine if a user is in a role that can publish content
        OrchardRoleProvider roleProvider = new OrchardRoleProvider(); 

        //Create two lists to contain the usernames and emails of users who can publish content
        List<string> publisherUserNames = new List<string>();
        List<string> publisherUserEmails = new List<string>();

        //Determine if users are in a role that can publish content and if they are add their username and email to separate lists
        foreach (var user in users)

            if (roleProvider.IsUserInRole(user.UserName, "Publisher") || 
                roleProvider.IsUserInRole(user.UserName, "Administrator") ||
                roleProvider.IsUserInRole(user.UserName, "Institution Admin")) 


        //Convert lists to comma separated strings
        string publisherUserEmailsString = String.Join(",", publisherUserEmails);
        string publisherUserNamesString = String.Join(",", publisherUserNames);

        //Prevent string from being empty
        if (string.IsNullOrEmpty(publisherUserEmailsString))
            publisherUserEmailsString = "Email was empty";

        if (string.IsNullOrEmpty(publisherUserNamesString))
            publisherUserNamesString = "Names were empty";

            .Token("Publishers", (Func<ISite, object>)(content => publisherUserNamesString))
            .Chain("Publishers", "Text", (Func<ISite, object>)(content => publisherUserNamesString))
            .Token("PublishersEmail", (Func<ISite, object>)(content => publisherUserEmailsString))
            .Chain("PublishersEmail", "Text", (Func<ISite, object>)(content => publisherUserEmailsString))
            .Token("SuperUserEmail", (Func<ISite, object>)(content => _membershipService.GetUser(content.SuperUser).Email))
            .Chain("SuperUserEmail", "User", (Func<ISite, object>)(content => _membershipService.GetUser(content.SuperUser).Email))

        if (context.Target == "Site") {
            // is there a content available in the context ?
            if (forContent.Data != null && forContent.Data.ContentItem != null) {
                var customSettingsPart = _contentDefinitionManager.GetTypeDefinition("Site");
                foreach (var partField in customSettingsPart.Parts.SelectMany(x => x.PartDefinition.Fields)) {
                    var field = partField;
                    var tokenName = partField.Name;
                        (Func<IContent, object>)(content => LookupField(content, field.Name).Storage.Get<string>()));
                        (Func<IContent, object>)(content => LookupField(content, field.Name)));
Any ideas why this isn't working? Thank you.
Sep 30, 2014 at 11:06 PM
Did you try setting a breakpoint and follow the execution?
Oct 1, 2014 at 4:20 PM
I think part of my problem is in using the IsUserInRole method of the class OrchardRoleProvider. The class doesn't actually seem to do anything other than throw a new exception:

public override bool IsUserInRole(string username, string roleName) {
        throw new NotImplementedException();
Does this mean the method hasn't actually been implemented yet?

Thank you.
Oct 1, 2014 at 4:27 PM
Edited Oct 1, 2014 at 4:27 PM
Can you try something like this:
foreach (var user in users)
 var roles = user.As<UserRolesPart>().Roles;
 if (roles.Contains("Publisher") || 
  roles.Contains("Administrator") ||
  roles.Contains("Institution Admin")) 
Code not tested but hopefully should work :)
Marked as answer by emeraldarcher on 10/1/2014 at 9:47 AM