Copied to clipboard

Flag this post as spam?

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


  • Jesper Balle 5 posts 26 karma points
    Jan 03, 2011 @ 15:36
    Jesper Balle
    0

    Hide page for authenticated users

    Hi,

    I am starting a new member site based on umbraco.
    We need some pages which anonymous users can access but authenticated users shouldn't. I was looking into adding a default role in my custom membership provider but it is not called for anonymous users.

    Using plain asp.net I would have made the following configuration in web.config for the proper locations.

      <location path="MyPage.aspx">
        <system.web>
          <authorization>
            <allow users="?"/> <!-- Anonymous users-->
            <deny users="*"/> <!-- All users-->

          </authorization>
        </system.web>
      </location>

    Can we use any umbraco functionality to acheive this? The roles are working perfect to allow only authenticated users but this is the opposite way around.

    For the navigation menu I am using the asp.net menu with the Umbraco MainNavigation sitemap provider (umbraco.presentation.nodeFactory.UmbracoSiteMapProvider) which seems to fit.

    Thank you.
    Kind regards,
    Jesper

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Jan 03, 2011 @ 16:50
    Jan Skovgaard
    0

    Hi Jesper

    I guess it should be possible to use the umbrac.library:IsLoggedOn extension to check if a user is authenticated or not. If false show page otherwise don't...Could this be a solution?

    /Jan

  • Jesper Balle 5 posts 26 karma points
    Jan 03, 2011 @ 16:57
    Jesper Balle
    0

    Hi Jan

    Thank you for your answer.
    And use the check to determine both if the content should be shown and for rendering the navigation?

    I am just using the asp.net menu, I have not a xslt for the navigation, I might have missed that this would require "customizations" - but if that it is the way to go I must start coding a menu (we have a fly-out menu which was out-of-the-box with the asp.net standard control.

    /Jesper

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Jan 03, 2011 @ 17:00
    Jan Skovgaard
    0

    Hi Jesper

    You're welcome and welcome to our by the way.

    Well if you have the .NET skills you should be able to make use of the umbraco.library in your C# code - but must admit that it's not what I'm best at. But you'll need to reference some of the binaries from Umbraco.

    But yes, use the check to determine if a user can both access the page and if it's rendered in navigation.

    There is a free video about it on umbraco.tv if I remember correctly.

    But it's just a suggestion. Maybe there are other options available :-)

  • Jesper Balle 5 posts 26 karma points
    Jan 04, 2011 @ 21:46
    Jesper Balle
    1

    Hi

    Thank for your answer Jan.
    I want to use the standard asp.net navigation control if ever possible, maybe also because that so far my .Net skills are better than my umbraco and so far it is much easier to test the many custom controls with standard asp.net and unit tests - and just make small adjustments to keep content in umbraco.

    I ended with retreiving the source code for the default SiteMap provider and make adjustments to let the IsAccessibleToUser method "deny" access to the item (it is only for the navigation - there is no security in this). The umbraco SiteMapProvider is sealed so it is not possible to just extend it, instead I just copied the code.

    I also made some refactoring and added support for alternative title fields and removal of the top "root" node. If this might be of interest to anyone I put the source for the SiteMapProvider below. With this approach I can still use my controls in a standard asp.net site (with the asp.net xmlsitemapprovider) and maintain content in umbraco and keep same behavior.

    Please note that most of the code is from the umbraco source: http://umbraco.codeplex.com/SourceControl/changeset/view/0b8f67be2ca8#umbraco%2fpresentation%2fumbraco%2fnodeFactory%2fUmbracoSiteMapProvider.cs 

        public class MySitemap : System.Web.StaticSiteMapProvider
        {
            private SiteMapNode m_root;
            private Dictionary<stringSiteMapNode> m_nodes = new Dictionary<stringSiteMapNode>(16);

            public string DefaultDescriptionAlias { getset; }
            public string TitleAlias { getset; }
            public string HideInNavigationAlias { getset; }
            public string OnlyForAnonymousAlias { getset; }

            #region Overriden methods
            public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
            {

                if (config == null)
                    throw new ArgumentNullException("Config is null");

                if (String.IsNullOrEmpty(name))
                    name = "UmbracoSiteMapProvider";

                DefaultDescriptionAlias = config.GetStringValue("defaultDescriptionAlias"null);
                HideInNavigationAlias = config.GetStringValue("hideInNavigationAlias""umbracoNaviHide");
                OnlyForAnonymousAlias = config.GetStringValue("onlyForAnonymousAlias"null);
                TitleAlias = config.GetStringValue("titleAlias"null);

                base.Initialize(name, config);

                // Throw an exception if unrecognized attributes remain
                if (config.Count > 0)
                {
                    string attr = config.GetKey(0);
                    if (!String.IsNullOrEmpty(attr))
                        throw new System.Configuration.Provider.ProviderException
                        (String.Format("Unrecognized attribute: {0}", attr));
                }

                SubscribeToEvents();
            }

            protected override void Clear()
            {
                lock (this)
                {
                    base.Clear();
                    m_root = null;
                    m_nodes.Clear();
                }
            }

            public override System.Web.SiteMapNode BuildSiteMap()
            {
                lock (this)
                {
                    if (m_root != null)
                        return m_root;

                    m_root = CreateRootNode();
                    try
                    {
                        AddNode(m_root, null);
                    }
                    catch (Exception ex)
                    {
                        umbraco.BusinessLogic.Log.Add(
                            umbraco.BusinessLogic.LogTypes.Error,
                            -1,
                            String.Format("Error adding to SiteMapProvider: {0}", ex));
                    }

                    LoadNodes(m_root.Key, m_root);
                }

                return m_root;
            }

            protected override SiteMapNode GetRootNodeCore()
            {
                BuildSiteMap();
                return m_root;
            }

            public override bool IsAccessibleToUser(HttpContext context, SiteMapNode node)
            {
                if (IsAccessibleOnlyForAnonymous(node) && context.User.Identity.IsAuthenticated)
                    return false;

                if (!base.SecurityTrimmingEnabled)
                    return true;

                if (node.Roles == null || node.Roles.Count == -1)
                    return true;

                if (node.Roles[0].ToString() == "*")
                    return true;

                foreach (string role in node.Roles)
                    if (context.User.IsInRole(role))
                        return true;

                return false;
            }
            #endregion

            public void RebuildSiteMap()
            {
                Clear();
                BuildSiteMap();
            }

            public void UpdateNode(Node node)
            {
                lock (this)
                {
                    // validate sitemap
                    BuildSiteMap();

                    SiteMapNode n;
                    if (!m_nodes.ContainsKey(node.Id.ToString()))
                    {
                        n = CreateNode(node.Id.ToString(),
                            (TitleAlias != null && node.GetProperty(TitleAlias) != null) ? node.GetProperty(TitleAlias).Value : node.Name,
                            node.GetProperty(DefaultDescriptionAlias) != null ? node.GetProperty(DefaultDescriptionAlias).Value : "",
                            node.Url,
                            FindRoles(node.Id, node.Path),
                            NodeIsOnlyForAnonymous(node)
                            );
                        string parentNode = node.Parent == null ? "-1" : node.Parent.Id.ToString();

                        try
                        {
                            AddNode(n, m_nodes[parentNode]);
                        }
                        catch (Exception ex)
                        {
                            umbraco.BusinessLogic.Log.Add(
                                umbraco.BusinessLogic.LogTypes.Error,
                                -1,
                                String.Format("Error adding node with url '{0}' to SiteMapProvider: {1}", node.Name, ex));
                        }
                    }
                    else
                    {
                        n = m_nodes[node.Id.ToString()];
                        n.Url = node.Url;
                        n.Description = node.GetProperty(DefaultDescriptionAlias) != null ? node.GetProperty(DefaultDescriptionAlias).Value : "";
                        n.Title = node.Name;
                        n.Roles = FindRoles(node.Id, node.Path).Split(",".ToCharArray());
                        if (n is GmosSiteMapNode)
                        {
                            ((GmosSiteMapNode)n).OnlyForAnonymous = NodeIsOnlyForAnonymous(node);
                        }
                    }
                }
            }

            public void RemoveNode(int nodeId)
            {
                lock (this)
                {
                    if (m_nodes.ContainsKey(nodeId.ToString()))
                        RemoveNode(m_nodes[nodeId.ToString()]);
                }
            }

            private SiteMapNode CreateRootNode()
            {
                var topNode = new Node(-1);
                SiteMapNode result = null;
                if (topNode.Children.Count == 1)
                {
                    // Use this as topnode
                    result = CreateSitemapNode(topNode.Children[0]);
                }
                else
                {
                    result = CreateNode("-1""root""umbraco root""/"nullfalse);
                }

                return result;
            }

            private void LoadNodes(string parentId, SiteMapNode parentNode)
            {
                lock (this)
                {
                    Node n = new Node(int.Parse(parentId));
                    foreach (Node child in n.Children)
                    {
                        if (IncludeNode(child))
                        {
                            SiteMapNode childNode = CreateSitemapNode(child);
                            try
                            {
                                AddNode(childNode, parentNode);
                            }
                            catch (Exception ex)
                            {
                                umbraco.BusinessLogic.Log.Add(
                                    umbraco.BusinessLogic.LogTypes.Error,
                                    child.Id,
                                    String.Format("Error adding to SiteMapProvider: {0}", ex));
                            }

                            LoadNodes(child.Id.ToString(), childNode);
                        }
                    }
                }
            }

            private SiteMapNode CreateSitemapNode(Node child)
            {
                string roles = FindRoles(child.Id, child.Path);
                SiteMapNode childNode = CreateNode(
                    child.Id.ToString(),
                    (TitleAlias != null && child.GetProperty(TitleAlias) != null) ? child.GetProperty(TitleAlias).Value : child.Name,
                    child.GetProperty(DefaultDescriptionAlias) != null ? child.GetProperty(DefaultDescriptionAlias).Value : "",
                    child.Url,
                    roles,
                    NodeIsOnlyForAnonymous(child));
                return childNode;
            }

            private SiteMapNode CreateNode(string id, string name, string description, string url, string roles, bool onlyForAnonymous)
            {
                lock (this)
                {
                    if (m_nodes.ContainsKey(id))
                        throw new System.Configuration.Provider.ProviderException(String.Format("A node with id '{0}' already exists", id));

                    // If roles were specified, turn the list into a string array
                    string[] rolelist = null;
                    if (!String.IsNullOrEmpty(roles))
                        rolelist = roles.Split(new char[] { ','';' }, 512);

                    // Create a SiteMapNode
                    MySiteMapNode node = new MySiteMapNode(this, id, url, name, description, rolelist, nullnullnull);
                    node.OnlyForAnonymous = onlyForAnonymous;

                    m_nodes.Add(id, node);

                    // Return the node
                    return node;
                }
            }

            private string FindRoles(int nodeId, string nodePath)
            {
                // check for roles
                string roles = "";
                if (base.SecurityTrimmingEnabled && !String.IsNullOrEmpty(nodePath) && nodePath.Length > 0)
                {
                    string[] roleArray = umbraco.cms.businesslogic.web.Access.GetAccessingMembershipRoles(nodeId, nodePath);
                    if (roleArray != null)
                        roles = String.Join(",", roleArray);
                    else
                        roles = "*";
                }

                return roles;
            }

            #region Hide in navigation methods
            protected virtual bool IncludeNode(Node node)
            {
                if (HideInNavigationAlias == string.Empty)
                    return true;

                var prop = node.GetProperty(HideInNavigationAlias);
                if (prop != null && prop.Value == "1")
                {
                    return false;
                }

                return true;
            }
            #endregion

            #region Only for anonymous methods
            protected bool NodeIsOnlyForAnonymous(Node node)
            {
                if (OnlyForAnonymousAlias == nullreturn false;
                var prop = node.GetProperty(OnlyForAnonymousAlias);
                return (prop != null && prop.Value == "1");
            }

            protected bool IsAccessibleOnlyForAnonymous(SiteMapNode node)
            {
                if (OnlyForAnonymousAlias == nullreturn false;
                if (node is MySiteMapNode)
                    return ((MySiteMapNode)node).OnlyForAnonymous;
                return false;
            }
            #endregion

            #region Umbraco events
            private void SubscribeToEvents()
            {
                // (global::umbraco.cms.businesslogic.web.Document sender, string role, umbraco.cms.businesslogic.RemoveMemberShipRoleFromDocumentEventArgs e)
                umbraco.cms.businesslogic.web.Access.AfterAddMemberShipRoleToDocument += new umbraco.cms.businesslogic.web.Access.AddMemberShipRoleToDocumentEventHandler(Access_AfterAddMemberShipRoleToDocument);
                umbraco.cms.businesslogic.web.Access.AfterRemoveMemberShipRoleToDocument += new umbraco.cms.businesslogic.web.Access.RemoveMemberShipRoleFromDocumentEventHandler(Access_AfterRemoveMemberShipRoleToDocument);
                umbraco.cms.businesslogic.web.Access.AfterRemoveProtection += new umbraco.cms.businesslogic.web.Access.RemoveProtectionEventHandler(Access_AfterRemoveProtection);
                umbraco.cms.businesslogic.web.Document.AfterPublish += new umbraco.cms.businesslogic.web.Document.PublishEventHandler(Document_AfterPublish);
                umbraco.cms.businesslogic.web.Document.AfterUnPublish += new umbraco.cms.businesslogic.web.Document.UnPublishEventHandler(Document_AfterUnPublish);
            }

            void Access_AfterAddMemberShipRoleToDocument(umbraco.cms.businesslogic.web.Document sender, string role, umbraco.cms.businesslogic.AddMemberShipRoleToDocumentEventArgs e)
            {
                UpdateNode(new Node(sender.Id));
            }

            void Access_AfterRemoveMemberShipRoleToDocument(global::umbraco.cms.businesslogic.web.Document sender, string role, umbraco.cms.businesslogic.RemoveMemberShipRoleFromDocumentEventArgs e)
            {
                UpdateNode(new Node(sender.Id));
            }

            void Access_AfterRemoveProtection(global::umbraco.cms.businesslogic.web.Document sender, umbraco.cms.businesslogic.RemoveProtectionEventArgs e)
            {
                UpdateNode(new Node(sender.Id));
            }

            void Document_AfterPublish(umbraco.cms.businesslogic.web.Document sender, umbraco.cms.businesslogic.PublishEventArgs e)
            {
                RebuildSiteMap();
            }

            void Document_AfterUnPublish(umbraco.cms.businesslogic.web.Document sender, umbraco.cms.businesslogic.UnPublishEventArgs e)
            {
                RebuildSiteMap();
            }
            #endregion
        }

        public class MySiteMapNode : SiteMapNode
        {
            public bool OnlyForAnonymous { getset; }

            public MySiteMapNode(SiteMapProvider provider, string key, string url, string title, string description, IList roles, NameValueCollection attributes, NameValueCollection explicitResourceKeys, string implicitResourceKey)
                : base(provider, key, url, title, description, roles, attributes, explicitResourceKeys, implicitResourceKey)
            { }
        }

        internal static class ConfigExtensions
        {
            public static string GetStringValue(this NameValueCollection config, string key, string defaultValue)
            {
                string returnValue = defaultValue;
                if (!String.IsNullOrEmpty(config[key]))
                {
                    returnValue = config[key].ToString();
                    config.Remove(key);
                }

                return returnValue;
            }
        }

     

    Kind regards,
    Jesper

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Jan 04, 2011 @ 21:51
    Jan Skovgaard
    0

    Hi Jesper

    Glad to hear you found a soltution and happy that you shared it in here.

    It's only natural that you stick to the languages you know. But I think that for stuff like navigation you should look into use XSLT in the future. But of course it all depens on what you're trying to achieve.

    But if you're in doubt about something you know where to ask :-)

    Happy coding

    /Jan

  • Jesper Balle 5 posts 26 karma points
    Jan 04, 2011 @ 22:01
    Jesper Balle
    0

    I know xslt from my previous sitecore projects, so I am not afraid of that. However I think the asp.net menu gives nice, stylable and easy maintainable fly out menu which I haven't seen similar in xslt - but if I have overlooked something please point me in the right direction. Xslt is very flexiable and powerfull, but I always try to use existing controls to avoid re-coding built-in concepts and if the umbraco sitemap had supported this it would have been almost plug-and-play :)

    /Jesper

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Jan 04, 2011 @ 22:07
    Jan Skovgaard
    0

    Haha...no need to be afraid! :-)

    If you have any questions about XSLT I'm sure people in here will be able to help you out. There are quite a few XSLT wizards in here (Chriztian Steinmeier and Lee Kelleher, Warren Buckley etc)

    It should be possible to create the same effect using a combination of XSLT to output the HTML and then style it with CSS and create the effect using JavaScript. As it is now I can imagine that it may appear as M$ tag soup in the HTML source code...:-D

    But I think that for now you should use what you know and keep your menu as it is. I'm sure it's great :-)

    /Jan

Please Sign in or register to post replies

Write your reply to:

Draft