Filtering images based on the User

Topics: General
Jan 21, 2012 at 3:27 AM
Edited Jan 23, 2012 at 8:18 AM

I'm new to Orchard and need to test my understanding so far and hopefully get some advice from you Orchard gurus. 

My objective is to implement an 'Image Bank' where the images displayed are filtered by the current user. In other words, you need to be logged on to see your own images and you cannot see anyone else's. 

Ideally I'd like to base this on the existing User. I tried adding some Fields to the User Content Type (the name of a ImageGallery) but that crashed the runtime when I tried to add a user (see Issue Tracker). Eventually, I added the Profile Module, and that seems to provide the functionality I need.

The next part of the puzzle was to provide detailed information about gallery entries. I added a new ContentType: GalleryEntry and added some fields to it. Then I created a List called Gallery that contains GalleryEntries. Good, I can now add Gallery Entries and display them.

Now I want to restrict the GalleryEntries that are displayed to just the logged on user. If the user is not logged on then they should not be able to see any GalleryEntries. So I make a newRole 'Artist' and set the only permission to 'Access site front-end'. Now I create a couple of Artists: 'guest' and 'test', and I set one of the GalleryEntries so the Owner is 'test' and the other entry is owned by 'guest'.   

Unfortunately, no matter who I log in as I can see all Gallery Entries, regardless of Owner. 

I've written a couple of simple modules but I can't say I understand the orchard architecture yet. So it's possible I'm doing this entirely the wrong way! Your patience, guidance and suggestions would be greatly appreciated.




Jan 24, 2012 at 3:44 AM

Today I installed the Projection Module and was able to implement half a solution to the problem above. I created a 'GalleryEntry' Content Type and added an 'Artist' Field. Using the Projector I can then create a Filter based on the User Name (ie Artist == User Name). 

This works but has no security. Items can be displayed with a URL such as /OrchardLocal/Contents/Item/Display/21 regardless whether the Artist on item 21 is the currently logged on user or not. Which is only to be expected of course. So I am still looking for a secure solution to my problem. Any suggestions?


Jan 24, 2012 at 11:02 AM

Easiest method is to write a Content Handler, then in a Display event you can validate the user and throw an OrchardSecurityException if they can't view it.

Jan 24, 2012 at 8:11 PM
Edited Jan 24, 2012 at 8:18 PM

Thanks for your reply! OK, I will see if I can put together a module. 

What is the intention of the 'Owner' field on content items? It doesn't seem to do anything. A quick search of the code left me no wiser. What am I missing? Do you foresee any problems basing security on comparing Current User to the Owner?


Jan 25, 2012 at 12:25 AM

That's definitely the intent of the Owner field, it tells you who created the content. I'd suggest following the model of existing content permissions, i.e. ViewContent and ViewOwnContent (for all content types) then View[x]Content and ViewOwn[x]Content so you can apply permissions per type per role.

Jan 25, 2012 at 5:32 AM

Sorry, I don't understand the 'model of existing content permissions'. The following code works but is awfully ugly.

 public class UserPermitHandler : ContentHandler
        private readonly RequestContext _requestContext;

        public UserPermitHandler(RequestContext requestContext)
            _requestContext = requestContext;

        private void AuthorizedUser(BuildShapeContext context, ContentItem item)
            const string contentType = "Artwork";
            var owner = item.As<CommonPart>().Owner;
            var user = _requestContext.HttpContext.User;
            if (item.ContentType == contentType && user.Identity.Name != owner.UserName)
                throw new OrchardSecurityException(new Orchard.Localization.LocalizedString("Attempt to view unauthorized " + contentType));

Can you point me at any existing examples? Or suggest how I SHOULD be approaching this?


Jan 25, 2012 at 11:29 AM

The problem with doing it that way is that even an Admin user will trigger the exception.

Orchard has a very rich roles / permissions model. Have you seen the "Roles" screen in admin? You can add your own permissions, have a look at Orchard.Core\Contents\Permissions.cs