X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Web%2FSystem.Web%2FSiteMapProvider.cs;h=8d005f2aa494e772b318cbbd7e46b891f92ea788;hb=9b87d46bdf11e08d30fe313737bd3822dbc21cbd;hp=7d0d7a66f32fcc3740ea2f20753c2c2b7d91e82c;hpb=d1c09fcc674eb5bf479db2ba41d24c43ad3c6d4e;p=mono.git diff --git a/mcs/class/System.Web/System.Web/SiteMapProvider.cs b/mcs/class/System.Web/System.Web/SiteMapProvider.cs index 7d0d7a66f32..8d005f2aa49 100644 --- a/mcs/class/System.Web/System.Web/SiteMapProvider.cs +++ b/mcs/class/System.Web/System.Web/SiteMapProvider.cs @@ -3,8 +3,10 @@ // // Authors: // Ben Maurer (bmaurer@users.sourceforge.net) +// Lluis Sanchez Gual (lluis@novell.com) // // (C) 2003 Ben Maurer +// (C) 2005-2009 Novell, Inc (http://www.novell.com) // // @@ -28,226 +30,285 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if NET_2_0 +using System.ComponentModel; using System.Collections; using System.Collections.Specialized; using System.Text; using System.Configuration.Provider; using System.Web.Util; using System.Globalization; +using System.Web.Configuration; -namespace System.Web { - public abstract class SiteMapProvider : ISiteMapProvider, IProvider { +namespace System.Web +{ + public abstract class SiteMapProvider : ProviderBase + { + static readonly object siteMapResolveEvent = new object (); - public void AddNode (SiteMapNode node) + internal object this_lock = new object (); + + bool enableLocalization; + SiteMapProvider parentProvider; + SiteMapProvider rootProviderCache; + bool securityTrimming; + object resolveLock = new Object(); + bool resolving; + + EventHandlerList events = new EventHandlerList (); + + public event SiteMapResolveEventHandler SiteMapResolve { + add { events.AddHandler (siteMapResolveEvent, value); } + remove { events.RemoveHandler (siteMapResolveEvent, value); } + } + + protected virtual void AddNode (SiteMapNode node) { AddNode (node, null); } - public void AddNode (SiteMapNode node, SiteMapNode parentNode) + internal protected virtual void AddNode (SiteMapNode node, SiteMapNode parentNode) { - if (node == null) - throw new ArgumentNullException ("node"); - - lock (this) { - string url = node.Url; - if (url != null && url.Length > 0) { - - - if (UrlUtils.IsRelativeUrl (url)) - url = UrlUtils.Combine (HttpRuntime.AppDomainAppVirtualPath, url); - else - url = UrlUtils.ResolveVirtualPathFromAppAbsolute (url); - - if (FindSiteMapNode (url) != null) - throw new InvalidOperationException (); - - UrlToNode [url] = node; - } - - if (parentNode != null) { - NodeToParent [node] = parentNode; - if (NodeToChildren [parentNode] == null) - NodeToChildren [parentNode] = new SiteMapNodeCollection (); - - ((SiteMapNodeCollection) NodeToChildren [parentNode]).Add (node); - } - } + throw new NotImplementedException (); } - - Hashtable nodeToParent; - Hashtable NodeToParent { - get { - if (nodeToParent == null) { - lock (this) { - if (nodeToParent == null) - nodeToParent = new Hashtable (); - } - } - return nodeToParent; - } + + public virtual SiteMapNode FindSiteMapNode (HttpContext context) + { + if (context == null) + return null; + + HttpRequest req = context.Request; + if (req == null) + return null; + + SiteMapNode ret = this.FindSiteMapNode (req.RawUrl); + if (ret == null) + ret = this.FindSiteMapNode (req.Path); + return ret; } + + public abstract SiteMapNode FindSiteMapNode (string rawUrl); - Hashtable nodeToChildren; - Hashtable NodeToChildren { - get { - if (nodeToChildren == null) { - lock (this) { - if (nodeToChildren == null) - nodeToChildren = new Hashtable (); - } - } - return nodeToChildren; - } + public virtual SiteMapNode FindSiteMapNodeFromKey (string key) + { + /* msdn2 says this function always returns + * null, but it seems to just call + * FindSiteMapNode(string rawUrl) */ + return FindSiteMapNode (key); } + + public abstract SiteMapNodeCollection GetChildNodes (SiteMapNode node); - Hashtable urlToNode; - Hashtable UrlToNode { - get { - if (urlToNode == null) { - lock (this) { - if (urlToNode == null) { - urlToNode = new Hashtable ( - new CaseInsensitiveHashCodeProvider (), - new CaseInsensitiveComparer () - ); - } - } - } - return urlToNode; - } + public virtual SiteMapNode GetCurrentNodeAndHintAncestorNodes (int upLevel) + { + if (upLevel < -1) throw new ArgumentOutOfRangeException ("upLevel"); + + return CurrentNode; } - protected virtual void Clear () + public virtual SiteMapNode GetCurrentNodeAndHintNeighborhoodNodes (int upLevel, int downLevel) { - lock (this) { - if (urlToNode != null) - urlToNode.Clear (); - if (nodeToChildren != null) - nodeToChildren.Clear (); - if (nodeToParent != null) - nodeToParent.Clear (); - } + if (upLevel < -1) throw new ArgumentOutOfRangeException ("upLevel"); + if (downLevel < -1) throw new ArgumentOutOfRangeException ("downLevel"); + + return CurrentNode; } - public virtual SiteMapNode FindSiteMapNode (string rawUrl) + public abstract SiteMapNode GetParentNode (SiteMapNode node); + + public virtual SiteMapNode GetParentNodeRelativeToCurrentNodeAndHintDownFromParent (int walkupLevels, int relativeDepthFromWalkup) { - if (rawUrl == null) - throw new ArgumentNullException ("rawUrl"); + if (walkupLevels < 0) throw new ArgumentOutOfRangeException ("walkupLevels"); + if (relativeDepthFromWalkup < 0) throw new ArgumentOutOfRangeException ("relativeDepthFromWalkup"); - if (rawUrl.Length > 0) { - this.BuildSiteMap(); - rawUrl = UrlUtils.ResolveVirtualPathFromAppAbsolute (rawUrl); - return (SiteMapNode) UrlToNode [rawUrl]; - } - return null; + SiteMapNode node = GetCurrentNodeAndHintAncestorNodes (walkupLevels); + for (int n=0; n 0 && UrlToNode.Contains (node.Url)) - UrlToNode.Remove (node.Url); - - if (parent != null) { - SiteMapNodeCollection siblings = (SiteMapNodeCollection) NodeToChildren [node]; - if (siblings != null && siblings.Contains (node)) - siblings.Remove (node); - } - } + if (upLevel < -1) throw new ArgumentOutOfRangeException ("upLevel"); + if (node == null) throw new ArgumentNullException ("node"); } - - public virtual void Initialize (string name, NameValueCollection attributes) - { - this.name = name; - if (attributes != null) - description = attributes ["description"]; + public virtual void HintNeighborhoodNodes (SiteMapNode node, int upLevel, int downLevel) + { + if (upLevel < -1) throw new ArgumentOutOfRangeException ("upLevel"); + if (downLevel < -1) throw new ArgumentOutOfRangeException ("downLevel"); + if (node == null) throw new ArgumentNullException ("node"); } - public virtual SiteMapNode CurrentNode { - get { - SiteMapNode ret; - - if (HttpContext.Current != null) { - ret = this.FindSiteMapNode (HttpContext.Current.Request.RawUrl); - if (ret == null) - ret = this.FindSiteMapNode (HttpContext.Current.Request.Path); + protected virtual void RemoveNode (SiteMapNode node) + { + throw new NotImplementedException (); + } - return ret; - } - - return null; - } + public override void Initialize (string name, NameValueCollection attributes) + { + base.Initialize (name, attributes); + if (attributes ["securityTrimmingEnabled"] != null) + securityTrimming = (bool) Convert.ChangeType (attributes ["securityTrimmingEnabled"], typeof (bool)); } - string description; - public virtual string Description { - get { return description != null ? description : "SiteMapProvider"; } + [MonoTODO ("need to implement cases 2 and 3")] + public virtual bool IsAccessibleToUser (HttpContext context, SiteMapNode node) + { + if (context == null) throw new ArgumentNullException ("context"); + if (node == null) throw new ArgumentNullException ("node"); + + if (!SecurityTrimmingEnabled) + return true; + + /* The node is accessible (according to msdn2) if: + * + * 1. The Roles exists on node and the current user is in at least one of the specified roles. + * + * 2. The current thread has an associated WindowsIdentity that has file access to the requested URL and + * the URL is located within the directory structure for the application. + * + * 3. The current user is authorized specifically for the requested URL in the authorization element for + * the current application and the URL is located within the directory structure for the application. + */ + + /* 1. */ + IList roles = node.Roles; + if (roles != null && roles.Count > 0) { + foreach (string rolename in roles) + if (rolename == "*" || context.User.IsInRole (rolename)) + return true; + } + + /* 2. */ + /* XXX */ + + /* 3. */ + string url = node.Url; + if(!String.IsNullOrEmpty(url)) { + // TODO check url is located within the current application + + if (VirtualPathUtility.IsAppRelative (url) || !VirtualPathUtility.IsAbsolute (url)) + url = VirtualPathUtility.Combine (VirtualPathUtility.AppendTrailingSlash (HttpRuntime.AppDomainAppVirtualPath), url); + + AuthorizationSection config = (AuthorizationSection) WebConfigurationManager.GetSection ( + "system.web/authorization", + url); + if (config != null) + return config.IsValidUser (context.User, context.Request.HttpMethod); + } + + return false; } - string name; - public virtual string Name { - get { return name; } + public virtual SiteMapNode CurrentNode { + get { + if (HttpContext.Current != null) { + SiteMapNode ret = ResolveSiteMapNode (HttpContext.Current); + if (ret != null) return ret; + return FindSiteMapNode (HttpContext.Current); + } else + return null; + } } - ISiteMapProvider parentProvider; - public virtual ISiteMapProvider ParentProvider { + public virtual SiteMapProvider ParentProvider { get { return parentProvider; } set { parentProvider = value; } } - ISiteMapProvider rootProviderCache; - public virtual ISiteMapProvider RootProvider { + public virtual SiteMapProvider RootProvider { get { - if (rootProviderCache == null) { - lock (this) { - if (rootProviderCache == null) { - ISiteMapProvider current = this; - while (current.ParentProvider != null) - current = current.ParentProvider; - - rootProviderCache = current; - } + lock (this_lock) { + if (rootProviderCache == null) { + SiteMapProvider current = this; + while (current.ParentProvider != null) + current = current.ParentProvider; + + rootProviderCache = current; } } return rootProviderCache; } } + + protected SiteMapNode ResolveSiteMapNode (HttpContext context) + { + SiteMapResolveEventHandler eh = events [siteMapResolveEvent] as SiteMapResolveEventHandler; + + if (eh != null) { + lock (resolveLock) { + if (resolving) + return null; + resolving = true; + SiteMapResolveEventArgs args = new SiteMapResolveEventArgs (context, this); + SiteMapNode r = eh (this, args); + resolving = false; + return r; + } + } else + return null; + } + + public bool EnableLocalization { + get { return enableLocalization; } + set { enableLocalization = value; } + } + + public bool SecurityTrimmingEnabled { + get { return securityTrimming; } + } + + string resourceKey; + public string ResourceKey { + get { return resourceKey; } + set { resourceKey = value; } + } + + public virtual SiteMapNode RootNode { + get { + SiteMapNode node = GetRootNodeCore (); + return ReturnNodeIfAccessible (node); + } + } - public abstract SiteMapNode BuildSiteMap (); - public abstract SiteMapNode RootNode { get; } - + internal static SiteMapNode ReturnNodeIfAccessible (SiteMapNode node) + { + if (node.IsAccessibleToUser (HttpContext.Current)) + return node; + else + throw new InvalidOperationException (); /* need + * a + * message + * here */ + } } } -#endif +