Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • David Conlisk 432 posts 1008 karma points
    Sep 19, 2013 @ 17:48
    David Conlisk
    0

    Serving mobile-specific login page with MediaProtect

    Hi all,

    I thought this might help someone. I've implemented the mobile version of a site using an alt template - all mobile page requests should end in /m, and my alt template, called "m", will handle laying it out for mobile. So when a mobile user requests a protected pdf that they don't have access to, they should be bounced to /login/m (rather than /login). Here's how I did it, by hooking into the Request_FileRequesting event.

    One question though, I'd love to not have to hardcode the urls (i.e. /login and /login/m). How could I retrieve the RedirectPage as specified by the client when they are protecting their media items? That way I wouldn't rely on the login page always being called "login" :)

    Thanks,

    David

    Note: You'll need to add references to both MediaProtect and MediaProtect.Library dlls in your project for this to compile.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web;
    using System.Web.Security;
    using MediaProtect.Library;
    using umbraco.BusinessLogic;
    using umbraco.NodeFactory;
    namespace CharlesTaylor.SharedLogic
    {
        public class MediaProtectForMobileHandler : ApplicationBase
        {
            ///  
            /// Example code for the Requesting event ///  
            public class ProtectedFolderRequest : ApplicationBase 
            { 
                ///  
                /// Constructor to wire up the requesting event 
                /// Make sure your class derives from ApplicationBase otherwise this constructor never gets hit 
                ///  
                public ProtectedFolderRequest()
                {
                    Request.FileRequesting += Request_FileRequesting;
                }
                
                ///  
                /// Handles the FileRequesting event to check if the user has access 
                ///  
                private void Request_FileRequesting(object sender, MediaProtect.Library.EventArgs.FileRequestingEventArgs e) { 
                    
                    if (!MediaProtect.Access.MediaAccess.HasAccess(e.MediaId, Membership.GetUser()))
                    {
                        // Check if the request is on the mobile site or not by comparing the path with the mobile url for the site from the Homepage node
                        var server = HttpContext.Current.Request.ServerVariables["SERVER_NAME"].ToLower();
                        var homeNode = Node.GetNodeByXpath("/root/Homepage");
                        if (homeNode != null && homeNode.GetProperty("mobileUrl") != null && !string.IsNullOrEmpty(homeNode.GetProperty("mobileUrl").Value))
                        {
                            // If it's a mobile request then bounce to the mobile version of the login page 
                           if (homeNode.GetProperty("mobileUrl").Value.Contains(server))
                           {
                               e.RedirectPage = "/login/m";
                           }
                           else
                           {
                               e.RedirectPage = "/login/";
                           }
                        }
                        e.Cancel = true;
                    }
                } 
            }
        }
    }
  • Richard Soeteman 4035 posts 12842 karma points MVP
    Sep 20, 2013 @ 07:06
    Richard Soeteman
    100

    Hi David,

    Thanks for sharing this. The reason why there is no API support from the library is that usually you only validate something different than an Umbraco media item. Then you don't know what the media item was.

    But I had the exact same issue when implementing support for ImageGen :) So I think the code below will work

     ValidationResult result = ValidationHelper.Validate(e.Path);
    
                    e.Cancel = !result.HasAccess;
                    if (e.Cancel)
                    {
                        e.RedirectPage = result.RedirectPage;
                    }
    

    You only need to append /m to the mobile login page. I will add a work item for me to support this in the library itself since you have all the Methods in one place then

    Thanks,

    Richard

  • David Conlisk 432 posts 1008 karma points
    Sep 20, 2013 @ 10:23
    David Conlisk
    0

    Thanks Richard, that's excellent, here is my re-factored class which uses the user-defined login path:

    using System;
    using System.Web;
    using MediaProtect.Helpers;
    using MediaProtect.Library;
    using umbraco.BusinessLogic;
    using umbraco.NodeFactory;
    
    namespace CharlesTaylor.SharedLogic
    {
    public class MediaProtectForMobileHandler : ApplicationBase
    {
        /// <summary> 
        /// Example code for the Requesting event 
        /// </summary> 
        public class ProtectedFolderRequest : ApplicationBase
        {
            /// <summary> 
            /// Constructor to wire up the requesting event 
            /// Make sure your class derives from ApplicationBase otherwise this constructor never gets hit 
            /// </summary> 
            public ProtectedFolderRequest()
            {
                Request.FileRequesting += Request_FileRequesting;
            }
    
            /// <summary> 
            /// Handles the FileRequesting event to check if the user has access 
            /// </summary> 
            private void Request_FileRequesting(object sender, MediaProtect.Library.EventArgs.FileRequestingEventArgs e)
            {
                // Check if the current user has access or not
                var result = ValidationHelper.Validate(e.Path);
    
                e.Cancel = !result.HasAccess;
    
                if (e.Cancel)
                {
                    // Check if the request is on the mobile site or not by comparing the path with the mobile url for the site from the Homepage node
                    var server = HttpContext.Current.Request.ServerVariables["SERVER_NAME"].ToLower();
    
                    var homeNode = Node.GetNodeByXpath("/root/Homepage");
                    if (homeNode != null && homeNode.GetProperty("mobileUrl") != null && !string.IsNullOrEmpty(homeNode.GetProperty("mobileUrl").Value))
                    {
                        // If it's a mobile request then bounce to the mobile version of the login page, as chosen by the user 
                        e.RedirectPage = homeNode.GetProperty("mobileUrl").Value.Contains(server) ? String.Format("{0}m/", result.RedirectPage) : result.RedirectPage;
                    }
                }
            }
        }
    }
    }
    

    Cheers,

    David

  • David Conlisk 432 posts 1008 karma points
    Sep 20, 2013 @ 11:36
    David Conlisk
    0

    Two further things:

    1. I realise that my code, above, has nested classes, see below for updated code with the unnecessary nesting removed
    2. There is a far more elegant approach which solves my particular problem here (but may not work for everyone): http://our.umbraco.org/forum/developers/api-questions/44855-override-login-page-url-for-protected-content

    Cheers,

    David

    Updated code:

    using System;
    using System.Web;
    using MediaProtect.Helpers;
    using MediaProtect.Library;
    using umbraco.BusinessLogic;
    using umbraco.NodeFactory;
    
    namespace SharedLogic
    {
    public class MediaProtectForMobileHandler : ApplicationBase
    {
        /// <summary> 
        /// Constructor to wire up the requesting event 
        /// Make sure your class derives from ApplicationBase otherwise this constructor never gets hit 
        /// </summary> 
        public MediaProtectForMobileHandler()
        {
            Request.FileRequesting += Request_FileRequesting;
        }
    
        /// <summary> 
        /// Handles the FileRequesting event to check if the user has access 
        /// </summary> 
        private void Request_FileRequesting(object sender, MediaProtect.Library.EventArgs.FileRequestingEventArgs e)
        {
            // Check if the current user has access or not
            // http://our.umbraco.org/projects/website-utilities/media-protect/mediaprotect-general/44854-Serving-mobile-specific-login-page-with-MediaProtect
            var result = ValidationHelper.Validate(e.Path);
    
            e.Cancel = !result.HasAccess;
    
            if (e.Cancel)
            {
                // Check if the request is on the mobile site or not by comparing the path with the mobile url for the site from the Homepage node
                var server = HttpContext.Current.Request.ServerVariables["SERVER_NAME"].ToLower();
    
                var homeNode = Node.GetNodeByXpath("/root/Homepage");
                if (homeNode != null && homeNode.GetProperty("mobileUrl") != null && !string.IsNullOrEmpty(homeNode.GetProperty("mobileUrl").Value))
                {
                    // If it's a mobile request then bounce to the mobile version of the login page, as chosen by the user 
                    e.RedirectPage = homeNode.GetProperty("mobileUrl").Value.Contains(server) ? String.Format("{0}m/", result.RedirectPage) : result.RedirectPage;
                }
            }
        }
    }
    }
    
Please Sign in or register to post replies

Write your reply to:

Draft