Creating a Permissions based Route Authorizer

Topics: Customizing Orchard, General, Writing modules
Sep 27, 2011 at 11:15 PM
Edited Sep 27, 2011 at 11:24 PM

One of the requirements in the site that we are going to be making is that certain users will only be able to see certain content. The best model I came up with for this was to match the URL to a regular expression, authorize based on Orchards built in permissions system, and then do a redirect. I wanted to model these as content parts so I could take advantage of the framework for data management that orchard provides. I modeled my code off of the URL Rewrite module but the URL Rewrite module attaches it's part to an instance of the site content type (I believe there should only be one). That works fine because they only want one instance of the part but I wanted to have more of a list model with CRUD type functionality. My initial modification was then based on the user model and I had a custom controller that would create instances through the content manager and attach them to site like this


            var toCreate = _contentManager.New<PermissionRulePart>("Site");
            toCreate.RouteFilter = model.RouteFilter;
            toCreate.Redirect = model.Redirect;
            toCreate.PermissionToAccess = model.PermissionToAccess;



The problem with this is of course that it creates multiple instances of the site content type which didn't seem to have any ill effects but at the same time seemed a very BAD IDEA. I only found out about this multiple site creation when I tried to use the Import/Export module to export the rules. So I decided to follow another model of creating a custom content type following the model in the Orchard.Blog project which turned out to be not actually that different.


            var blog = Services.ContentManager.New<BlogPart>("Blog");
            _contentManager.Create(blog, VersionOptions.Draft);
            dynamic model = _contentManager.UpdateEditor(blog, this);

            if (!ModelState.IsValid) {
                // Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
                return View((object)model);



So I made my code look like

            var toCreate = _contentManager.New<PermissionRulePart>("PermissionRule");
            toCreate.RouteFilter = model.RouteFilter;
            toCreate.Redirect = model.Redirect;
            toCreate.PermissionToAccess = model.PermissionToAccess;

The problem is that when I export I don't get the permission rule information in the export file:

- <Blog Id="/Route.Slug=ablog" Status="Published">
  <CommonPart Owner="/User.UserName=admin" CreatedUtc="2011-09-27T22:32:40Z" PublishedUtc="2011-09-27T22:32:40Z" ModifiedUtc="2011-09-27T22:32:40Z" />
  <AdminMenuPart AdminMenuPosition="2.1" OnAdminMenu="false" />
  <MenuPart MenuText="A Blog" MenuPosition="2" OnMainMenu="true" />
  <RoutePart Title="ABlog" Slug="ablog" Path="ablog" />
  <BlogPart Description="This is an awesome blog" PostCount="0" />


  <PermissionRule Id="" Status="Published" />
  <PermissionRule Id="" Status="Published" />
  <PermissionRule Id="" Status="Published" />
  <PermissionRule Id="" Status="Published" />

So basically my question is what's going wrong here? I'm guessing that there's something happening in the contentManager.UpdateEditor which appears to be binding the data back to the model. Is there a way for me to bypass this step simply or am i going to far off the rails here? How do I get my content items to behave properly? It's worth noting that the PermissionRulePartRecords are getting persisted to the DB properly but appear to not be being associated to the content item correctly.



Sep 27, 2011 at 11:28 PM

Well, using regexp to validate urls looks like a really dangerous idea. Super scary actually.

Apart from that, without seeing what your Exporting method looks like, it's hard to say why it doesn't export.

Sep 28, 2011 at 12:04 AM

The export is the Import/Export module made by the orchard team.

Sep 28, 2011 at 12:12 AM

I don't think that will cover your custom part.

Sep 28, 2011 at 4:59 PM

Why do you say that using Regexp to identify URLs is a bad idea? Also are you saying that the Import/Export module doesn't cover any custom built or 3rd party parts? I figured it would be generic.

Sep 28, 2011 at 5:08 PM

Because regexps are tricky, and so is path normalization. I suppose if you only white list after normalization by the framework it's probably ok.

Import/Export requires content drivers to implement how they import and export.