2009-08-24 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web / SiteMapProvider.cs
index 8c22ddc8723ec953ae24abe933c3b7babfb2888f..b0b41dfe607d5d83188f2ada095539a509954cea 100644 (file)
@@ -31,6 +31,7 @@
 //
 
 #if NET_2_0
+using System.ComponentModel;
 using System.Collections;
 using System.Collections.Specialized;
 using System.Text;
@@ -41,6 +42,9 @@ using System.Web.Configuration;
 
 namespace System.Web {
        public abstract class SiteMapProvider : ProviderBase {
+               static readonly object siteMapResolveEvent = new object ();
+               
+               internal object this_lock = new object ();
                
                bool enableLocalization;
                SiteMapProvider parentProvider;
@@ -48,6 +52,13 @@ namespace System.Web {
                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)
                {
@@ -158,8 +169,8 @@ namespace System.Web {
                public override void Initialize (string name, NameValueCollection attributes)
                {
                        base.Initialize (name, attributes);
-                       if (attributes["securityTrimmingEnabled"] != null)
-                               securityTrimming = (bool) Convert.ChangeType (attributes ["securityTrimmingEnabled"], typeof(bool));
+                       if (attributes ["securityTrimmingEnabled"] != null)
+                               securityTrimming = (bool) Convert.ChangeType (attributes ["securityTrimmingEnabled"], typeof (bool));
                }
                
                [MonoTODO ("need to implement cases 2 and 3")]
@@ -171,43 +182,42 @@ namespace System.Web {
                        if (!SecurityTrimmingEnabled)
                                return true;
 
-                       /* the node is accessible (according to msdn2)
-                        * if:
+                       /* The node is accessible (according to msdn2) if:
                         *
-                        * 1. the current user is in the node's Roles.
+                        * 1. The Roles exists on node and the current user is in at least one of the specified roles.
                         *
-                        * 2. the current thread's WindowsIdentity has
-                        * file access to the url. (and the url is
-                        * located within the current application).
+                        * 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 <authorization> configuration element
-                        * lists the current user as being authorized
-                        * for the node's url. (and the url is located
-                        * within the current 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. */
-                       if (node.Roles != null)
-                               foreach (string rolename in node.Roles)
+                       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))
-                               return true;
-                       // TODO check url is located within the current application
+                       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);
+                               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);
+                               AuthorizationSection config = (AuthorizationSection) WebConfigurationManager.GetSection (
+                                       "system.web/authorization",
+                                       url);
+                               if (config != null)
+                                       return config.IsValidUser (context.User, context.Request.HttpMethod);
+                       }
 
                        return false;
                }
@@ -230,7 +240,7 @@ namespace System.Web {
                
                public virtual SiteMapProvider RootProvider {
                        get {
-                               lock (this) {
+                               lock (this_lock) {
                                        if (rootProviderCache == null) {
                                                SiteMapProvider current = this;
                                                while (current.ParentProvider != null)
@@ -245,17 +255,19 @@ namespace System.Web {
                
                protected SiteMapNode ResolveSiteMapNode (HttpContext context)
                {
-                       SiteMapResolveEventArgs args = new SiteMapResolveEventArgs (context, this);
-                       if (SiteMapResolve != null) {
+                       SiteMapResolveEventHandler eh = events [siteMapResolveEvent] as SiteMapResolveEventHandler;
+
+                       if (eh != null) {
                                lock (resolveLock) {
-                                       if (resolving) return null;
+                                       if (resolving)
+                                               return null;
                                        resolving = true;
-                                       SiteMapNode r = SiteMapResolve (this, args);
+                                       SiteMapResolveEventArgs args = new SiteMapResolveEventArgs (context, this);
+                                       SiteMapNode r = eh (this, args);
                                        resolving = false;
                                        return r;
                                }
-                       }
-                       else
+                       } else
                                return null;
                }
                
@@ -281,8 +293,6 @@ namespace System.Web {
                        }
                }
 
-               public event SiteMapResolveEventHandler SiteMapResolve;
-
                internal static SiteMapNode ReturnNodeIfAccessible (SiteMapNode node)
                {
                        if (node.IsAccessibleToUser (HttpContext.Current))