Assigning edit roles to widgets by owner

Topics: Administration
Feb 17, 2011 at 8:44 AM

Is it going to be possible to assign roles to widgets? At the moment we are creating widgets with different owners but can only grant edit privileges to all widgets. Ideally I'd like to be able to assign  role against an individual widget but would be happy in the short term if we could restrict the editing of the widget to the widget owner? Any ideas what the plan and timescales are, if any, for this enhancement?

Feb 17, 2011 at 4:59 PM

Widgets being content items, this is essentially the same problem as restricting access to content items. I believe there is a project to build that as a module.

Feb 19, 2011 at 5:04 PM

Yes, there is:) I'm currently developing a module for content-level permissions, so stay tuned. It will be available on Codeplex soon.

May 12, 2011 at 4:26 PM

Piotr - is this now on codeplex?

May 12, 2011 at 4:31 PM

Not yet... I was very busy lately and had to shelve the project:/ I'll return to this by the end of next week.

12-05-2011 18:27 użytkownik "moranic" <> napisał:
May 12, 2011 at 4:44 PM

Hi, I actually just got a module working that will do this. The code is at - there are a number of modules there but the ones you need are "Mechanics" and "Quanta", then enable "Quanta: Effectors" feature. You can give users roles over specific content items or widgets, and also create "groups" which multiple users can be members of and then assign group roles to content. So it's pretty flexible how you can use it.

I haven't released it to gallery yet because I haven't published documentation but I can help directly in the mean time if you need it.

Piotr - not sure how much of this is repeating stuff you've already done. But if you had anything in mind this doesn't do I'm open to suggestions / collaboration!

May 13, 2011 at 10:10 AM

Great - thanks both. I'll go and check out the modules on codeplex now, Pete - much appreciated!

May 13, 2011 at 10:58 AM

No probs. Just to note, the UI is a bit clunky (although it all works); I'm currently implementing some way better UI and should have it done by the end of today.

May 23, 2011 at 2:02 AM

Pete, I've just read through your code and I think there's not much repeating functionality. And btw - it looks awesome!:)

My approach is a bit different, although it'd perfectly complement your module, both making a really powerful security management feature. What I'm trying to achieve is to:

  • Deliver a generic content authorization feature, which would be taken into account at the content manager level (so Get, Query and other methods would be also affected and return only the items user is authorized to deal with)
  • Create an extension point to allow plugging in custom per-item authorization logic (just like Content Handlers do with item lifetime events). I'm in the process of building a system with rather complex authorization scheme which has to be done in code, as it depends on lots of things.
  • Override the default Orchard.Core.Contents.Controllers.ItemController to display 404 error when not authorized. At the moment, everyone is allowed to view virtually every content item which makes Orchard "content types" pretty unusable if authorization is necessary. As an example: If you place a widget in Authenticated layer, you can still access it directly via /Contents/Item/Display/<item_id>, even if not authenticated...
  • Take much care about the performance. Content filtering has to happen at the lowest possible level to prevent further unnecessary processing.

I guess both modules can work together at the authorization logic level, taking the UI-based permission granting from your module and low-level content filtering from mine. What do you think?


May 23, 2011 at 9:19 AM

Thanks for your comments!

Some further thoughts on your points;

  • You can already hook into Orchard permissions events; the content item is actually passed in for edit/delete/publish permissions, so that extension point is already there! All that's needed is a "View" permission to actually be checked from the ItemController - and to be honest this should be patched to Orchard core instead of overriding the controller; I raised a workitem for it because the AccessFrontEnd permission isn't checked anywhere and could actually be used for this purpose
  • Your point about widgets is a very serious one, and a good reason why this needs urgently fixing in Orchard. I wonder if this applies to, for instance, User objects as well?
  • Instead of 404, returning a HttpUnauthorized would be preferable as this would redirect to the login page (and is what other secured actions tend to do)
  • It'd be nice if the view permission could be implemented in the content manager. This of course would require either core modifications or a complete reimplementation. But there is still one problem with this - sometimes you need to read an object from the database, not to display it, but to do certain processing; e.g. reading a User object to check some detail about them, even though the current user might not have permission to view that object. So I think you'd sometimes need to be able to ignore permissions checks when you Get content.

Now in Mechanics I'm actually implementing an entirely custom routing system (which is why the release I talked about has been delayed). So I have an ItemController where I can check View permissions. But I still need to suppress that pesky /Contents/Item/Display/<item_id> route!

May 23, 2011 at 12:33 PM

Yes, that route surely needs to be overwritten - I meant that by "overriding a controller". Suppressing that route is fairly easy to do - just create your own route that overrides those from ItemController (with higher priority) and redirect to your controller. That is basically what I've just done:)

  • Yes, I know that there already is a permission check in item CRUD actions via IAuthorizationService. I've seen you created a custom AuthorizationServiceEventHandler that allows dynamic permissions handling. But my point is a bit different. I need to be able to add custom authorization logic, that can be different for different content items. Eg. for one content type, the authorization status would rely on the current date, for some others - on payment status, on some data fetched from WCF service, and so on. This cannot be handled by statically assigned permissions. I needed a very simple way to provide a code snippet to do that checks and set an appropriate authorization status. I've overridden the default ContentHandler adding OnAuthorization and OnAuthorized/OnNotAuthorized methods that both take a single action that does just that. My point was to provide the most easy-to-use extension point, that wouldn't involve overriding any existing stuff.
  • It applies to every content item, so User objects are affected as well. It's a giant security hole... I found a workaround to this just by doing a check inside a driver Display method and return null if user don't have a permission to access that object. But this applies only to my custom part - if you create a content item with other parts (whether third-party or core, like BodyPart) that don't do that check - those will always get displayed...
  • Yes, HttpUnauthorized would be better most of the time:) But returning 404 has an advantage in that it obscures the existence of an object.
  • It's not necessarily a problem. I created my own implementation that extends the default ContentManager class so implementation of all methods stays the same and can be a subject to further updates without corrupting the module. Calls to appropriate base methods are simply wrapped with authorization code. I totally understand and agree with your point that certain processing is needed for every object (whether user is authorized or not). Information on location where authorization takes place is also passed to content handler's OnAuthorization method (via context object property), so this can be taken into account.



May 23, 2011 at 1:07 PM

Yeah I knew what you meant about overriding the controller; was just stating where I'm at so far. Your last point about inheriting from existing classes is very interesting and for some reason something I didn't really consider! Either way I'm still thinking there should be core changes in Orchard to support view permissions and close that security hole. Having authorization events on content handlers seems a logical and consistent way to do things, certainly much easier than IAuthorizationEventHandler (where unfortunately I had to replicate a lot of code to plug in the per-item permissions).

Actually instead of a Driver, you could have a Handler that will nullify *all* display shapes if a permissions check fails. But it's a pretty ugly way to do things; and something I pointed out elsewhere is that a lot of code will still run in those circumstances. An example would be your view count feature; it would register an item view even though it didn't get displayed!

I can see your point about 404; but realistically the admin areas already use HttpUnauthorized - what actual use is it to know that there's a URL called /Admin/Contents that I'm not allowed to access?

Where the 404 could actually produce a detrimental user experience, is if someone's session has timed out and they try to access a page that's normally there; suddenly they hit a big 404 instead of just being prompted to log in.

Putting it another way: can you outline a specific case where it would actually be a problem for someone to know there was a "secret Url" that they couldn't access? Because if so, then all the existing controllers should be changed to 404 instead of unauthorized :)