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?
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.
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)
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.
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.
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
Hi Rasb,
Here's some xslt extensions which can be used from xslt (also from code of course):
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
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
Thanks Dirk,
I had looked at the
But that has been deprecated. I found out that you should instead use the
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.
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
RoleBasedNavigation.ascx.cs
There are two properties on the UserControl.
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.
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.
Comments are very welcome!
All the best,
Rasb
is working on a reply...