Immediately after you implement the VirtualPathProvider proxy from my previous post you will notice a one fairly serious lack in it. Namely all the files within that provider will be hiding behind the registration form. That is not cool for a couple of reasons…

  • You may want to keep all of the files in one store – being forced to put them into a designated folder is not desired.
  • You may want to make some file freely available for some time and lock it after a while, or the other way around (e.g. to allow the robots to crawl it initially). having to move them is just silly and defeats the purpose.

So how do you discriminate the files that you want locked from those that you want to be publically available, and potentially from those that you want only the logged in users to be able to get?

Specifying the EPiServer File Metadata sweetness

One of the potential solutions would be to define a special rights group and check for that group for the people that have your “registered” magic-cookie. That however introduces a bogus group, and I would rather like to avoid that. However if you look into the FileSummary.config file that’s located in your web application folder you will find a slightly mysterious content. A bit of hacking reveals that you can actually add your own metadata to the file. For example adding the access rights based on what I’ve established above would look as follows (the content you can already find in the file that comes with the public templates that-we-all-oh-so-love is skipped):

<root xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <model> <instance> ... <AccessLevel /> </instance> </model> ... <xforms:select1 appearance="full" ref="AccessLevel" id="id_field51"> <xforms:item> <xforms:label>Unrestricted</xforms:label> <xforms:value>Unrestricted</xforms:value> </xforms:item> <xforms:item> <xforms:label>Requires Registration</xforms:label> <xforms:value>RequireRegistration</xforms:value> </xforms:item> <xforms:item> <xforms:label>Requires CMS Login</xforms:label> <xforms:value>LoggedUserAccess</xforms:value> </xforms:item> </xforms:select1> ... </root>

Great. So what does it look in the file manager now?

metadata-editor

Splendid!

Accessing the metadata

Now that we gave the user to specify the metadata, we need the VPP to act upon them. For the benefit of automation of parsing I’ve specified the enum defining the access levels as follows:

enum FileAccessLevel { Unrestricted, RequireRegistration, LoggedUserAccess }

Now we need to update the GetFile method to discriminate the access levels (I have decorated the core lines with >) those are the lines that access the meta data based on their format specified in the FileSummary.config.

public override VirtualFile GetFile(string virtualPath)
{
    string handledPath;

    if (TryGetHandledAbsolutePath(virtualPath, out handledPath))
    {
        UnifiedFile file = base.GetFile(virtualPath) as UnifiedFile;

        if (file != null)
        {
            string strAccessLevel = (string) file.Summary.Dictionary["AccessLevel"] ??
                                    FileAccessLevel.RequireRegistration.ToString();
            FileAccessLevel accessLevel = (FileAccessLevel) Enum.Parse(typeof (FileAccessLevel), strAccessLevel);

            bool isLoggedIn = HttpContext.Current.Profile != null && !HttpContext.Current.Profile.IsAnonymous;
            bool isRegistered = HttpContext.Current.Request.Cookies.AllKeys.Contains(PASS_COOKIE_NAME);
            string email = isRegistered ? HttpContext.Current.Request.Cookies[PASS_COOKIE_NAME].Value :
                (isLoggedIn ? HttpContext.Current.Profile.UserName : "unregistered");

            switch (accessLevel)
            {
                case (FileAccessLevel.Unrestricted):
                    return file;
                    break;
                case(FileAccessLevel.RequireRegistration):
                    if (!isRegistered && ! isLoggedIn)
                    {
                        HttpContext.Current.Response.Redirect(
                            string.Format(registrationFormUrl,
                                          HttpContext.Current.Server.HtmlEncode(virtualPath)));
                        return null;
                    }
                    return file;
                    break;
                case(FileAccessLevel.LoggedUserAccess):
                    if (isLoggedIn)
                    {
                        return file;
                    }
                    return null;
                    break;
                default:
                    return file;
            }
        }
    }
    return Previous.GetFile(virtualPath);
}

Now the user is really in control of what is published to the general public and robots, what is protected with the registration form and what is only available to logged in users. (now you may add more granularity with file rights naturally, this is just a basic setting that an editor without administrative rights can add.

1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5.00 out of 5)
Loading...Loading...



This entry (Permalink) was posted on Tuesday, March 17th, 2009 at 1:18 am and is filed under .Net Framework, ASP.NET, C#, Code Samples, EPiServer, Internet Information Services, Software, Software Development, Solution, Web applications. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response , or trackback from your own site.



  • Mattias

    Nice post!
    However, fileSummary.config shouldn’t be a mystery to an EMVP ;)
    Also, in later versions (R2) of CMS 5 it is possible to have a (custom) file summary per VPP, which might be needed.

  • http://www.najmanowicz.com/ Adam Najmanowicz

    Thanks Mattias,

    You know… one has to spice their article up a bit, ;) I realize it’s just an XForm, but it’s still REALLY cool you can define a custom one here!

    True about the differenttiation being possible now, it’s a fairly serious omission not to mention that.