How to resolve Dependency or WorkContext in Filter?

Topics: Customizing Orchard, Writing modules
Apr 8, 2011 at 10:55 AM

Hi, 

I'm traing to create custom autorization attribute for work with orchard roles but currenty did not succede. I can't resolve dependency for IOrchardServices

Enitire code  is 

 

public class OrchardUserInRoleAttribute : AuthorizeAttribute
    {
        private string[] authorizedRoles;
        public string[] AuthorizedRoles
        {
            get { return authorizedRoles ?? new string[0]; }
            set { authorizedRoles = value; }
        }
        public IOrchardServices orchardServices;
        
        public OrchardUserInRoleAttribute()
        {
            orchardServices = DependencyResolver.Current.GetService<IOrchardServices>();
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            var baseResult = base.AuthorizeCore(httpContext);
            if (baseResult)
            {
                return this.validateUserByRoles();
            }
            return baseResult;
        }

        private bool validateUserByRoles()
        {
            var currentUser = orchardServices.WorkContext.CurrentUser;
            var userRoles = UserRolesHelper.GetRolesFor(currentUser);
            var hasRequired = false;
            foreach (var role in userRoles)
            {
                if (authorizedRoles.Contains(role,StringComparer.InvariantCultureIgnoreCase)){
                    hasRequired = true;
                }
            }
            return hasRequired;
        }
    }

 

In MVC 3 could use 

DependencyResolver.Current.GetService<IOrchardServices>();

But this does not work in Orchard unfortunatly. Can you help me with this case? 

Apr 8, 2011 at 1:48 PM

At the point when attributes are constructed, I doubt any of the dependencies exist yet. Attributes I believe are constructed extremely early in application start. So you could try calling it in AuthorizeCore(...) instead.

Apr 8, 2011 at 1:50 PM

Actually, that's perhaps not true in Orchard since the modules are dynamically compiled and loaded later on. But it could be a factor.

Apr 11, 2011 at 9:11 AM
randompete wrote:

Actually, that's perhaps not true in Orchard since the modules are dynamically compiled and loaded later on. But it could be a factor.

Well moving to AuthorizeCore did not help. Also attributes in mvc 3 as far as I know are singletones and created when first requested. So it's quite far from app start. 

protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            var baseResult = base.AuthorizeCore(httpContext);
            orchardServices = DependencyResolver.Current.GetService<IOrchardServices>();
            if (baseResult)

It's still  null. My guess is that - problem is not in the place where dependency is resolved. seem like it's because of that orchard in some way does not set Default Dependency resolver in Application.  As far I can see in sources  it was done previously  but now is commened 

 public static class OrchardStarter {
        public static IContainer CreateHostContainer(Action<ContainerBuilder> registrations) {
...

            ControllerBuilder.Current.SetControllerFactory(new OrchardControllerFactory());
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new ThemeAwareViewEngineShim());

            var hostContainer = new DefaultOrchardHostContainer(container);
            //MvcServiceLocator.SetCurrent(hostContainer);
            OrchardHostContainerRegistry.RegisterHostContainer(hostContainer);

            return container;
        }

Anyway, this seem like a bug or something I can not see why if done. Uncommenting does not work unfortunatly. 

Could  any one help me and tell how I can get at least WorkContext in Attribute? 

Apr 11, 2011 at 9:19 AM

Let me just check: you're aware that Orchard uses Autofac for dependency injection, right?

Have you looked at any built-in attributes for security or otherwise in Orchard to see how they obtain their dependencies?

Apr 11, 2011 at 10:27 AM
Edited Apr 11, 2011 at 11:35 AM
Dem87 wrote:

Also attributes in mvc 3 as far as I know are singletones and created when first requested. So it's quite far from app start. 

BTW; let me just correct a couple of mistakes in that statement.

  • Attributes have nothing to do with MVC 3. They do not have any "special behaviour" in MVC 3. They're just a feature of the .NET framework and the C# / VB.net languages, and MVC happens to leverage this feature for various purposes. So attributes in MVC or Orchard behave exactly the same as in any .NET or ASP.NET application.
  • Attributes are not singletons. You can declare the same attribute multiple times in different places with different constructor parameters and properties; ergo there has to be at least one instance of the attribute per usage, they're far from being singletons...
  • On "created when first requested". What exactly do you mean by "first requested" and from where did you get this information? Actually I just tried to look up some more detail about this and I couldn't find anything with such low-level documentation but I'm sure I remember reading something once. The thing is, attributes are "requested" using reflection which returns a list of all attributes on a given type or property; this list can then be examined for a certain attribute that you're after. We are not initially requesting a specific attribute, all the attributes are simply stored as metadata attached to a given type. An instance of that type hasn't necessarily even been created yet (by this I mean the described type, not its attributes). It therefore makes sense that the attributes must exist from on or around the time that the type itself exists; i.e. when the dll is first loaded by the runtime, which in a normal application - MVC or otherwise - would be necessarily prior to App_Start. Of course, I'm making a number of (semi-informed) assumptions here and it would be good for me as well to know the full story of what's going on behind the scenes ...See following post, I learned something today... :)
  • Finally; Orchard isn't MVC 3. Yes it happens to use and/or support a number of MVC features including some of the new bits from the very recent MVC 3 (for instance, Razor); but things are happening slightly differently here, for instance that Module code is certainly getting loaded by the runtime at a later stage (so in this case most likely after App_Start).

This doesn't exactly have anything to do with your problem anyway.

As you point out, Orchard never (currently) participates in the new MVC 3 DependencyResolver feature.

This isn't a bug; it's just that Orchard is doing its "own thing" when it comes to dependencies. You have to remember that Orchard development started a fair while before MVC 3 came out and it would be a fair bit of work to swap out their entire DI system for another; and it could be that the MVC 3 system wouldn't play nicely with the dynamic module loading or test framework in any case.

Short version; just because a feature is there, don't assume it's supported ;) ...and always check existing Orchard modules to find "best practice" examples for any given task when you're trying something undocumented.

Apr 11, 2011 at 11:31 AM
Edited Apr 11, 2011 at 11:35 AM

Ok ... found out a bit more now about Attribute construction.

Yes; I was wrong ;) ...on the other hand, your statement was still missing something important on this issue.

It would appear in fact that Attributes are constructed every single time they are accessed. Not just when they're first accessed; they are actually created anew each and every time any one of the reflection GetCustomAttribute(s) methods are invoked.

So due to this it seems there's no point (as in your first example) storing dependencies in the constructor and then actually using them in AuthorizeCore. Chances are that both the constructor and AuthorizeCore will get called once each anyway, every single time authorization takes place ... and due to the fact that the attribute could actually get constructed at other times and for many reasons other than authorization (example: possibly even at compile time), there is a certain optimization concern in performing any non-trivial work at all in an attribute constructor.

I just thought it was important to understand in detail this aspect of how attributes work (and I'm glad I looked it up!)

Found this information at: http://stackoverflow.com/questions/417275/net-attributes-why-does-getcustomattributes-make-a-new-attribute-instance-eve

Apr 11, 2011 at 12:32 PM
Edited Apr 11, 2011 at 12:32 PM

Basic Idea of Filters (Attributes) in MVC 3 has changhed. And you can see that I use  AuthorizeAttribute so this is a Filter in mvc 3 scope.

http://bradwilson.typepad.com/blog/2010/07/service-location-pt4-filters.html

http://bradwilson.typepad.com/blog/2010/07/aspnet-mvc-filters-and-statefulness.html

And dependencies in mvc 3 are explained http://bradwilson.typepad.com/blog/2010/10/service-location-pt5-idependencyresolver.html

An any way - Orchard starts as MVC 3 Application (Global.asax ets) so it'a more then expected for it to use default mvc 3 conversations. 

Found this information at: http://stackoverflow.com/questions/417275/net-attributes-why-does-getcustomattributes-make-a-new-attribute-instance-eve is from asked Jan 6 '09 at 16:47 And this is MVC 2. 

Filters in mvc 3 has been reworked not to be created each time. this is one of major changes in mvc 3. More at the links at top. 

In Any way, how to get this  ORCHARD WorkContext   IN FILTER ??? 

I've looked in other modules I've not found any filter uses. So can you advise one where filter is create and it uses or dependency resolver or works with orchard WorkContext ? 

Apr 11, 2011 at 1:18 PM
Edited Apr 11, 2011 at 1:20 PM

There are some important differences between what you're saying and what is actually taking place;

  • As I stated, Orchard uses MVC 3 but that does not mean it has to use or support all features of MVC 3.
  • Yes, MVC 3 introduced a new way to define filters that gets around any limitations of Attributes, by letting you create Filters that are not Attributes. The Brad Wilson post you linked to shows this very clearly when he creates a filter by implementing the IActionFilter and IResultFilter interfaces. You will noticed that class is not an Attribute. Orchard supports such types of filter and if you do a source search for IActionFilter and IResultFilter you will find many examples. These filters support Autofac dependency injection in the constructor like everything else in Orchard so you can easily get an IWorkContextAccessor in one of them.
  • I also made it very clear that Attributes are nothing to do with MVC. They are a feature of the .NET framework and any significant changes to their behavour could break many existing applications that relied on them, they are extremely unlikely to have suddenly been changed in any way just to support an MVC 3 feature.
  • As you say, "Filters in mvc 3 has been reworked" - this statement is not equal to "Attributes have been reworked". Filters were previously implemented as attributes; now we have other options.
  • Again: when Orchard started development MVC 3 was not available so they took different routes to implement things like dependency injection. It's not always easy to switch something underlying at a later stage, and as you can see from the commented code you posted, someone has tried this at some point but clearly there were issues it caused and so cannot be supported at this time. So it's reasonable to think that all MVC 2 features might be supported but MVC 3 is a grey area and if something doesn't work then it just doesn't work; simple as that, really. DependencyResolver is not the supported way of getting dependencies and you can see this by the simple fact that SetCurrent(hostContainer) never gets called.

Now onto the "how do I get a WorkContext in an Attribute" question which is what you are really trying to do.

In fact, there's a really huge clue in that code you already looked at:

Dem87 wrote:
 public static class OrchardStarter {
public static IContainer CreateHostContainer(Action<ContainerBuilder> registrations) {
...

ControllerBuilder.Current.SetControllerFactory(new OrchardControllerFactory());
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new ThemeAwareViewEngineShim());

var hostContainer = new DefaultOrchardHostContainer(container);
//MvcServiceLocator.SetCurrent(hostContainer);
OrchardHostContainerRegistry.RegisterHostContainer(hostContainer);

return container;
}

Ok... so the MVC 3 dependency resolver won't work because hostContainer isn't passed into MvcServiceLocator.

Now, can you see in the above any other place that the hostContainer could be getting pushed to and that it might therefore be available from?

Hint: it's in the next line right after the commented one ;)

Apr 11, 2011 at 2:06 PM
Edited Apr 11, 2011 at 2:07 PM

Ok. proper answer for my Question was  use 

Orchard.Mvc.Filters.FilterProvider

because Orchard was so strange to create It's OWN filterProvider. Really why should orchard use proper asp mvc  one ? )

And be repeting once again to me that orchard has started with mvc 2 and not mvc 3 - would not make it good. It mean thath team should spent time to make support of mvc 3 features not just declarative while instalation but also in code? What do you think? I've started working with mvc from release 1 and I know how much it may cost to upgrade to a new version but really it must be done! even if not at first. 

Another point of your holy war - filter are not attributes. And are they? 

look at this 

 

namespace System.Web.Mvc
{
    // Summary:
    //     Represents an attribute that is used to restrict access by callers to an
    //     action method.
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter
    {
        // Summary:
        //     Initializes a new instance of the System.Web.Mvc.AuthorizeAttribute class.

 

and  yet again click - go to defenition - and guess what you will find ? 

 

namespace System.Web.Mvc
{
    // Summary:
    //     Represents the base class for action and result filter attributes.
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public abstract class FilterAttribute : Attribute, IMvcFilter

So you are still saying what base class for filters is not a attribute ?

 

And you could also try to do the same for 

OrchardHostContainerRegistry.RegisterHostContainer(hostContainer);
But what you will find ? It has nothing to do with MVC DependencyResolver.SetResolver(

So this is why it does not work ? 
about your statement " search for IActionFilter and IResultFilter you will find many examples " - i've found  5 in sources. yes really many.I would say more then one. 
But this is not 
AuthorizeAttribute 

Ok. Hope after i rewrite to orchard spike of 
FilterProvider it would work.really why sould not I use proper AuthorizeAttribute that has working code it it 
- i should re-invent the wheel myself ? 

 

Apr 11, 2011 at 2:55 PM
Edited Apr 11, 2011 at 2:56 PM

- Orchard's FilterProvider is an abstract class that makes it easy to inject the MVC filter interfaces. If you look at it's definition, it actually uses those MVC interfaces IRequestFilter, IActionFilter etc. under the surface.

- Since the team have got a system that works (and it does, as long as you do things in the supported way) - do you really want them to spend loads of time rewriting everything to support the MVC 3 dependency injection, when they could otherwise be developing new features? And that's assuming that MVC 3 dependency injection would even work for Orchard, which as I said it might not as Orchard is doing a lot of things "above and beyond" any functionality offered by MVC.

- On "Filters are not attributes". Again please actually read the Brad Wilson post that you yourself pointed out to me (http://bradwilson.typepad.com/blog/2010/07/aspnet-mvc-filters-and-statefulness.html). Those are the new MVC 3 filters. They are not attributes. The FilterAttribute is an attribute (obviously!); but that's the old way and not all filters have to be attributes any more. Actually performing security operations in an attribute seems to me a not-very-clean way to do things; attributes are just decoration, they shouldn't be performing data access, security checks, or any other business logic.

- "It has nothing to do with MVC DependencyResolver.SetResolver(" - you are missing the point of what I said. Orchard uses its own DI container and no, it never calls DependencyResolver.SetResolver. But that is because you have a different way to acquire the container. The container is passed into OrchardHostContainerRegistry.RegisterHostContainer. So I was thinking there would be a way to retrieve the hostContainer from OrchardHostContainerRegistry. I just looked and there's no direct method, but it seems what you can do is make your attribute implement the IShim interface, and then call OrchardHostContainerRegistry.RegisterShim(this), and you will get a reference to HostContainer.

- But I don't think you need to do that anyway. You can just implement a FilterProvider with IAuthorizationFilter, and inject your IWorkContextAccessor in the constructor. See Orchard.UI.Admin.AdminFilter for an example of how this is done. This is the "Orchard way" of doing things and one of many subtle differences between Orchard and pure MVC 3. This is also what I was trying to get at; Orchard isn't MVC and there are often slightly different ways of doing things, to allow for the highly extensible and modular system which gives you much, much more than MVC alone.

BTW; this is not intended to be a "holy war", it just appeared that you had some confusion over what attributes actually are, and the differences between Orchard's dependency injection vs how it works in pure MVC 3. I am just trying to help show you how things work in Orchard, and why they are that way. It's worth learning; you will be incredibly productive. But you can't fight the system ;)

Apr 11, 2011 at 3:18 PM

yes. right before you wrote i've done custom filter provider  and attribute. whole source is beyone. use it like 

[OrchardUserInRole(AuthorizedRoles = new string[]{"Expert"})]

[ExcludeFromCodeCoverage]
    [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class OrchardUserInRoleAttribute : Attribute
    {
        private string[] authorizedRoles;
        public string[] AuthorizedRoles
        {
            get { return authorizedRoles ?? new string[0]; }
            set { authorizedRoles = value; }
        }
    }

    public interface IOrchardUserInRoleFilter : IActionFilter
    {
        bool IsUserInRoles(IUser user, IEnumerable<string> authorizedRoles);
    }

    [ExcludeFromCodeCoverage]
    public class OrchardUserInRoleFilter : FilterProvider, IOrchardUserInRoleFilter
    {
        public IOrchardServices orchardServices;

        public OrchardUserInRoleFilter(IOrchardServices orchardServices)
        {
            this.orchardServices = orchardServices;
        }

        private static IEnumerable<OrchardUserInRoleAttribute> GetUserInRoleAttrributes(ActionDescriptor descriptor)
        {
            return descriptor.GetCustomAttributes(typeof(OrchardUserInRoleAttribute), true)
                .Concat(descriptor.ControllerDescriptor.GetCustomAttributes(typeof(OrchardUserInRoleAttribute), true))
                .OfType<OrchardUserInRoleAttribute>();
        }

        private bool validateUserByRoles(ActionExecutingContext filterContext
                                            , IEnumerable<OrchardUserInRoleAttribute> attributes)
        {
            if (orchardServices == null) { return true; }
            var currentUser = orchardServices.WorkContext.CurrentUser;
            var authorizedRoles = new string[] { };
            foreach (var a in attributes)
            {
                authorizedRoles.Concat(a.AuthorizedRoles);
            }
            return this.IsUserInRoles(currentUser, authorizedRoles);
        }

        public bool IsUserInRoles(IUser user, IEnumerable<string> authorizedRoles)
        {
            var hasRequired = false;
            var userRoles = UserRolesHelper.GetRolesFor(user);
            foreach (var role in userRoles)
            {
                if (authorizedRoles.Contains(role, StringComparer.InvariantCultureIgnoreCase))
                {
                    hasRequired = true;
                }
            }
            return hasRequired;
        }

        public void OnActionExecuted(ActionExecutedContext filterContext)
        {
        }

        public void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var baseResult = (filterContext.HttpContext.User.Identity.IsAuthenticated);
            if (baseResult)
            {
                var attributes = GetUserInRoleAttrributes(filterContext.ActionDescriptor);
                if ((attributes != null) && (attributes.Any()))
                {
                    var isInRole = this.validateUserByRoles(filterContext, attributes);
                    if (!isInRole)
                    {
                        filterContext.Result = new HttpUnauthorizedResult();
                    }
                }
            }
            else { return; }
        }

    }

orchard used default mvc IDependencyResolver for DI. So it is expected that you can use 

DependencyResolver.Current.GetService<IOrchardServices>();
Yes, I've read the article btw. maybe did not pay much attention to some moments and it seem that it has been update for rtm(article if for rc 1) 
Thing is  - that I don't suppose orchard team will have much work to SetDependecyResolver  - is not?  I'm quite sure that it will work. You really have one part of equation -so solve it
and get true mvc 3. It would be much of benefit since there would not be questions like "Oh, it works in hello world  - wtf it does not work it "mvc 3" cms with so much of code ? "

At least it would make Orchard more easy to work with without of digging havily into sources not even just to know it's full functionality. 
Apr 11, 2011 at 3:44 PM
Edited Apr 11, 2011 at 3:47 PM

Yep - that's the way to do it (although I'm wondering is there a reason you used IActionFilter instead of IAuthorizationFilter? - I'm not certain what the difference is except maybe execution order but it would seem more appropriate)

Also you perhaps want to just import IAuthorizationService in the constructor, instead of writing your own logic. The IAuthorizationService performs other logic such as allowing for permission variations per content type and other cunning things, it also fires events off to IAuthorizationServiceEventHandler implementations. For example I'm writing a module that extends the permissions system in certain ways, that will only work when IAuthorizationService is used to perform the authorization.

Where does Orchard use IDependencyResolver? It just happens that the container implements IDependencyResolver, but it's never used like that. It looks to me like they were trying to implement MVC DI and must have run into problems.

There could be actual technical limitations preventing this; things like the module system and testing framework could have been upset. But here I'm just speculating :)

You're right that certain aspects of documentation need work. But this is already happening with the new 1.1 docs.

I knew about FilterProvider mainly from an article on Piotr Szmyd's blog (http://www.szmyd.com.pl/blog/most-useful-orchard-extension-points - you should read that, it details other very useful hooks that otherwise require some digging!)

There are lots of very useful things buried in Orchard and of course it's a huge piece of work to document them all, remember Orchard is still very new and I think a lot of things were changing rapidly up until the 1.0 release. So I am certain it will get there eventually :)

Anyway I'm glad you got there in the end, and sorry about the confusion over a number of points!

IAuthorizationServiceEventHandler
Apr 11, 2011 at 3:55 PM

Further note: What I said and IAuthorizationService wasn't quite right, since I was talking about checking individual permissions, not roles.

Actually what you should probably be doing is creating new Permissions to control whatever security scenario you have. Roles can be completely customised in the Dashboard and as in your example the "Expert" role could be deleted by an admin user.

So instead create an "ExpertUser" permission, and if you like you can create a default "Expert" role that has that permission; but check for the permission, not the role. The point is that any given permission can be assigned to multiple roles, however the administrator wants to manage things. Hardcoding role names into your actions isn't a great thing to do from an extensibility point of view :) You can also use Permissions to do things like show or hide admin menus, which I assume would be useful for the "Expert" mode it sounds like you're describing here.

Apr 11, 2011 at 4:13 PM
randompete wrote:

Further note: What I said and IAuthorizationService wasn't quite right, since I was talking about checking individual permissions, not roles.

Actually what you should probably be doing is creating new Permissions to control whatever security scenario you have. Roles can be completely customised in the Dashboard and as in your example the "Expert" role could be deleted by an admin user.

So instead create an "ExpertUser" permission, and if you like you can create a default "Expert" role that has that permission; but check for the permission, not the role. The point is that any given permission can be assigned to multiple roles, however the administrator wants to manage things. Hardcoding role names into your actions isn't a great thing to do from an extensibility point of view :) You can also use Permissions to do things like show or hide admin menus, which I assume would be useful for the "Expert" mode it sounds like you're describing here.

Well you might have a point in general. But I need roles exactly. I know about permitions and this is not what I need. In here I need to user user roles and I'm aware that is can be customized - this is what we need in fact.

Permitions are the thing that are going to be used futher. And based on permithions dashboad for role is supposed to be build. And working with admin panel is not the thing we need. I know we can customize it. 

 IActionFilter  was not used because I don't what to override it. First of all it will go in conflict with default mvc one. While default mvc one has already implimented such great things like caching and problems with cache and authorisations is soled there.

You should look in the code of AuthorizeAttribute of MVC.  ActionFilter is more approparete in this situation.

Apr 11, 2011 at 4:22 PM

Ok, well I was just looking at the code of AdminFilter which uses IAuthorizationFilter but still works by examining filterContext.ActionDescriptor.

Filters don't override anything, they just run one after another in a pipeline, however many filters you have. That's one thing that makes them so great and also very extensible.

I'm still not sure why you need roles instead of permissions, I would just create a named permission for each of the meta-roles you are filtering on; it would make your system far more flexible and if you wanted to distribute whatever you're doing as a module I think you'd find end users wouldn't like not being able to customise which roles control what.

But, I'm not aware of your specific use case, and if it works for whatever you're doing then fair enough :)

Apr 11, 2011 at 4:35 PM
randompete wrote:

Ok, well I was just looking at the code of AdminFilter which uses IAuthorizationFilter but still works by examining filterContext.ActionDescriptor.

Filters don't override anything, they just run one after another in a pipeline, however many filters you have. That's one thing that makes them so great and also very extensible.

I'm still not sure why you need roles instead of permissions, I would just create a named permission for each of the meta-roles you are filtering on; it would make your system far more flexible and if you wanted to distribute whatever you're doing as a module I think you'd find end users wouldn't like not being able to customise which roles control what.

But, I'm not aware of your specific use case, and if it works for whatever you're doing then fair enough :)

Yes I know that filter don't override anothing. yes, that is because i mosly think of normal mvc one that are still attributes. and that it's simplest way to override required method. but I really don't what to work over with cache moments. 

it's still possible that someone add customatribute without authorized one before and then i would have a hadeicke. that is why overriding with using base() is better since you dont loose any of proper code if don't need to. 

don't bother - working with permitions is to be done. at the moment it is not high in user strories. 

In any way - you are not restricted not to use this attribute, is not? 

Apr 11, 2011 at 4:41 PM

another point of using permitions is that admin or siteowner can do everything. not the thing we need. 

Apr 12, 2011 at 10:31 AM
randompete wrote:

Ok, well I was just looking at the code of AdminFilter which uses IAuthorizationFilter but still works by examining filterContext.ActionDescriptor.

Filters don't override anything, they just run one after another in a pipeline, however many filters you have. That's one thing that makes them so great and also very extensible.

I'm still not sure why you need roles instead of permissions, I would just create a named permission for each of the meta-roles you are filtering on; it would make your system far more flexible and if you wanted to distribute whatever you're doing as a module I think you'd find end users wouldn't like not being able to customise which roles control what.

But, I'm not aware of your specific use case, and if it works for whatever you're doing then fair enough :)

Got one more question - attributes does not allow fields of type Permission or something like this. 

My idea is to set it permssions by name. Is there a way in Orchard to get Permission object by its name ? 

Apr 12, 2011 at 10:39 AM

You can just refer to permission.Name to get its name in the attribute.

Then you'll want to retrieve the original Permission object in your filter; you need IRoleService.GetInstalledPermissions()[name] .

Apr 12, 2011 at 10:52 AM

this helped

IRoleService.GetInstalledPermissions()[name] .

 

Thanks