Copied to clipboard

Flag this post as spam?

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


  • rasb 162 posts 218 karma points
    Jul 20, 2009 @ 22:41
    rasb
    0

    Membergroups for protected document

    Hi all,

    I would like to know for a document, if it is protected by using the "Public Access" in the administrative module.

    If I get a nodelist like this, then I would like to know how to tell if a node is protected, and if it is, then tell what member groups have access to it.

    Nodes childNodes = Node.GetCurrent().Children;

    Basically what I want to do is to test for each node, if a logged in member has access to that node. 

    Can I use an XPath to get only the nodes a specific member has access to?

    Thanks,
    Rasb

  • Dirk De Grave 4541 posts 6021 karma points MVP 3x admin c-trib
    Jul 20, 2009 @ 23:02
    Dirk De Grave
    100

    Hi Rasb,

     

    Here's some xslt extensions which can be used from xslt (also from code of course):

     

    public static bool IsProtected(int DocumentId, string Path) {}
    public static bool HasAccess(int NodeId, string Path) {}

     

    First one checks whether a page is protected and gets fed with two params, the id of the node, or in xslt talk $currentPage/@id, and the path, which is also a property on the current page $currentPage/@path (again in xslt slang)

    Second method can be used to verify whether current logged on member has access to a specifi page. Params to this lib function are the same as for the first method (altho names do not correspond)

     

    If you're using these methods from code, just use node.Id and node.Path as parameters to both methods.

     

    Hope this helps.

     

    Regards,

    /Dirk

  • Dirk De Grave 4541 posts 6021 karma points MVP 3x admin c-trib
    Jul 20, 2009 @ 23:17
    Dirk De Grave
    0

    On a sidenote, you could do with some methods in the Access class as well, as both static methods in the library class use those Access class for access control checking (that is, if you're using this in code, if using xslt, you'll have to use the functions as mentioned in prevous post)

     

    Cheers,

    /Dirk

  • rasb 162 posts 218 karma points
    Jul 21, 2009 @ 18:38
    rasb
    0

    Thanks Dirk,

    I had looked at the

     

    public static bool HasAccess(int NodeId, string Path) {}

    But that has been deprecated. I found out that you should instead use the

     

    public static bool HasAccess(int documentId, object memberId) {}

    I have tried to write this method that just one level down finds the allowed nodes. It seems to work. But for some reason my membership provider has stopped working in my development environment after I upgraded it to the latest Umbraco verision. Will start another thread on that if I can't figure it out


     

     

        //Instantiate the xmlwriter

                StringBuilder sb = new StringBuilder();

                XmlWriter xw = XmlWriter.Create(sb);

                xw.WriteStartDocument();

                xw.WriteStartElement("root");

     

                //Get the current member

                Member m = Member.GetCurrentMember(); 

     

                //Get all childnodes to the current

                Nodes childNodes = Node.GetCurrent().Children;

     

                //Loop throug child nodes

                foreach (Node n in childNodes)

                {

                    //Assume that there is no access to begin with

                    bool hasAccess = false;

     

                    if (!Access.IsProtected(n.Id, n.Path) || Access.GetProtectionType(n.Id) == ProtectionType.NotProtected)

                    {

                        hasAccess = true;

                    }

                    else if (m!=null)

                    {

                        hasAccess = Access.HasAccces(n.Id, m.UniqueId);

                    }

     

                    //write xml

                    if (hasAccess)

                    {

                        xw.WriteStartElement("node");

                        xw.WriteAttributeString("name", n.Name);

                        xw.WriteAttributeString("url", n.NiceUrl);

                        xw.WriteEndElement();

                    }

                }

     

                //close up xml

                xw.WriteEndElement(); //root

                xw.WriteEndDocument();

                xw.Flush();

                xw.Close();

     

                navXml.Text = sb.ToString();

     

    When I get it to work as I wan't I thought I would make a package out of it, for others to use. Never done that before, and would like to figure out how to do that.

    /rasb

    PS: How do you insert code like you have done? I just copied from your message to get this.

  • rasb 162 posts 218 karma points
    Jul 21, 2009 @ 22:17
    rasb
    0

    OK! Got it to work, and thought I'd share it here... until I figure out how to share it on the Wiki... please let me know if did all of this for no reason at all because there is a much easier way in Xslt to it.

    I created a UserControl that did the trick for me. Here is the code for the user control.

    RoleBasedNavigation.ascx

    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="RoleBasedNavigation.ascx.cs" Inherits="RoleBasedNavigation.RoleBasedNavigation" %>
    <asp:Literal ID="renderedNavXml" runat="server"></asp:Literal>

    RoleBasedNavigation.ascx.cs

    using System;
    using System.Web;
    using umbraco.presentation.nodeFactory;
    using umbraco.cms.businesslogic.web;
    using System.Xml;
    using System.Text;
    using System.Web.Security;
    using System.Xml.Xsl;
    
    namespace RoleBasedNavigation
    {
        public partial class RoleBasedNavigation : System.Web.UI.UserControl
        {
            private string _XsltFile;
            private int _Depth = 1;
            private MembershipUser CurrentUser;
            private XmlWriter xw;
    
            protected void Page_Load(object sender, EventArgs e)
            {
                //get currentuser
                CurrentUser = Membership.GetUser();
    
                //Instantiate the xmlwriter
                StringBuilder sb = new StringBuilder();
                xw = XmlWriter.Create(sb);
                xw.WriteStartDocument();
                xw.WriteStartElement("root");
    
                //Iterate through all the nodes, starting with the current node
                IterateNodes(Node.GetCurrent(), 1);
    
                //close up xml
                xw.WriteEndElement(); //root
                xw.WriteEndDocument();
                xw.Flush();
                xw.Close();
    
                //Create a DOM object based on the Xml string created
                System.Xml.XmlDocument doc = new XmlDocument();
                doc.LoadXml(sb.ToString());
    
                //Then render the xml using the Xslt provided
                XslCompiledTransform xslt = umbraco.macro.getXslt(XsltFile);
                renderedNavXml.Text = umbraco.macro.GetXsltTransformResult(doc, xslt);
            }
    
            private void IterateNodes(Node currentNode, int level)
            {
                //Get all childnodes to the current
                Nodes childNodes = currentNode.Children;
    
                //Loop throug child nodes
                foreach (Node n in childNodes)
                {
                    //Assume that there is no access to begin with
                    bool hasAccess = false;
    
                    if (!Access.IsProtected(n.Id, n.Path) || Access.GetProtectionType(n.Id) == ProtectionType.NotProtected)
                    {
                        hasAccess = true;
                    }
                    else if (CurrentUser != null)
                    {
                        hasAccess = Access.HasAccces(n.Id, CurrentUser.ProviderUserKey);
                    }
    
                    //write xml
                    if (hasAccess)
                    {
                        xw.WriteStartElement("node");
                        xw.WriteAttributeString("nodeName", n.Name);
                        xw.WriteAttributeString("niceUrl", n.NiceUrl);
                        xw.WriteAttributeString("id", n.Id.ToString());
    
                        //Let's call this method recursively untill the whole tree has been created
                        if (Depth == 0 || Depth > level)
                            IterateNodes(n, level + 1);
    
                        xw.WriteEndElement();
                    }
                }
            }
    
            /// <summary>
            /// XsltFile used to render navigation UI.
            /// </summary>
            public string XsltFile { get { return _XsltFile; } set { _XsltFile = value; } }
    
            /// <summary>
            /// Indicates the depth the iterator will traverse the tree. 
            /// Depth of 0 (zero) will allow the iterator to go as deep as it can.
            /// Default depth is 1 (one).
            /// </summary>
            public int Depth { get { return _Depth; } set { _Depth = value; } }
        }
    }

    There are two properties on the UserControl.

            public string XsltFile { get { return _XsltFile; } set { _XsltFile = value; } }

    This is the name of the Xslt file used for rendering the layout of the navigation menu. Create the Xslt file under the Developer section and use the Filename of the Xsltfile for this property.

            public int Depth { get { return _Depth; } set { _Depth = value; } }

    The depth of the tree can be set her. If set to 0 (zero), then the tree will just go as deep as it can. Otherwise it will go to the depth indicated here.

    To test, use this Xslt document.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
    <xsl:stylesheet 
        version="1.0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        xmlns:msxml="urn:schemas-microsoft-com:xslt" 
        xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" 
        exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets ">
    
    
    <xsl:output method="xml" omit-xml-declaration="yes" />
    
    <xsl:template match="/">
    
    <!-- The fun starts here -->
    <ul>
        <xsl:apply-templates select="root/node"/>
    </ul>
    
    </xsl:template>
    
    <xsl:template match="node">
        <li>
            <a href="{umbraco.library:NiceUrl(@id)}">
                <xsl:value-of select="@nodeName"/>
            </a>
            <xsl:if test="count(./node)&gt;0">
                <ul>
                    <xsl:apply-templates select="./node"/>
                </ul>
            </xsl:if>
        </li>
    </xsl:template>
    
    </xsl:stylesheet>

    Comments are very welcome! 

    All the best,
    Rasb

Please Sign in or register to post replies

Write your reply to:

Draft