Common Security
Common_Security_CSharp\Default.aspx.cs
// Copyright 2010 ESRI
// 
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
// 
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
// 
// See the use restrictions.
// 


public partial class Default : System.Web.UI.Page
{
    #region Instance Variable Declarations

    // Role allowed use of all layers, tools and tasks
    private string m_fullyEnabledRole = "Managers";

    // Name of resource containing layer to hide from unauthorized users
    private string m_resourceOfLayerToHide = "MapResourceItem0";

    // Name of layer to hide from unauthorized users
    private string m_layerToHide = "Highways";

    // Tool to remove for unauthorized users
    private string m_toolbarItemToRemove = "GetMapInfo";

    // ID of task to remove for unauthorized users
    private string m_taskToRemove = "QueryAttributesTask1";

    #endregion

    #region ASP.NET Page Event Handlers

    protected void Page_PreInit(object sender, System.EventArgs e)
    {           
        // If the user is not in the fully-allowed role, remove QueryAttributesTask1.  Removing the task
        // here will prevent the task from being bound to its buddied menu and simplify the initialization
        // process.
        //if (!User.IsInRole(m_fullyEnabledRole))
        //    RemoveTask(TaskManager1, m_taskToRemove);
    }

    protected void Page_PreRender(object sender, System.EventArgs e)
    {
        // If the user is not in the fully-allowed role, remove QueryAttributesTask1.  Removing the task
        // here will prevent the task from being bound to its buddied menu and simplify the initialization
        // process.
        if (!User.IsInRole(m_fullyEnabledRole))
            RemoveTask(TaskManager1, m_taskToRemove);
    }

    protected void Page_PreRenderComplete(object sender, System.EventArgs e)
    {
        // Check if the logged in user is in the fully-allowed role
        // (Note the PreRenderComplete event only occurs on startup, not
        //  on any callbacks. If using full postbacks, should check if Page.IsPostBack.)
        if (!User.IsInRole(m_fullyEnabledRole))
        {
            // 1) Remove the layer from the Map and associated TOC
            HideLayer(Map1, m_resourceOfLayerToHide, m_layerToHide);

            // 2) Hide Map-info tool
            RemoveItemFromToolbar(Toolbar1, m_toolbarItemToRemove);
        }
    }

    #endregion

    #region ASP.NET WebControl Event Handlers

    protected void LoginStatus1_LoggedOut(object sender, System.EventArgs e)
    {
        /*
        If the user logs out and then logs back in as another user,
        the page should not show layer visibility, task results, etc.
        from the prior user's session. We will find all the keys related
        to the Web ADF session, store them, then actually remove them
        when the user gets redirected back to the Login.aspx page.
        
        NOTE: This may affect other Web ADF applications loaded in the
        same browser session. This includes IE tabs, any Firefox windows,
        and websites opened from Manager. This section may be removed
        if users will not be logging out and then back in with different
        usernames.
        */

        System.Collections.Generic.List<string> keysToRemoveList =
            new System.Collections.Generic.List<string>();
        string[] webAdfKeys = {"ClientScriptsList", "ESRIWebADFHiddenFields",
            "DataSourceManager_State"};

        // Iterate through each key in the session
        foreach (string sessionKey in Session.Keys)
        {
            if (sessionKey.IndexOf(Request.ApplicationPath) >= 0)
            {
                // remove keys specific to the current website path
                keysToRemoveList.Add(sessionKey);
            }
            else if (Session[sessionKey].GetType() == typeof(ESRI.ArcGIS.ADF.Web.MimeData))
            {
                // remove MIME data objects
                keysToRemoveList.Add(sessionKey);
            }
            else 
            {
                // remove various other keys related to the Web ADF
                foreach (string webAdfKey in webAdfKeys)
                    if (sessionKey == webAdfKey)
                        keysToRemoveList.Add(sessionKey);
            }
        }
        
        /*
        We can't actually remove the session keys yet, because
        the Default page will do its Load/Render steps before 
        redirecting to the Login page, and the Map looks for
        its session keys. We'll store the Session keys to remove,
        and actually remove them in the Login.aspx page's 
        Load handler.
        */
        Session["keysToRemove"] = keysToRemoveList;
    }

    #endregion

    #region Instance Methods

    // Hides the layer matching the input name in both the Map and its TOC
    private void HideLayer(ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap, string resourceName, 
        string layerName)
    {
        try
        {
            ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality commonMapFunctionality =
                adfMap.GetFunctionality(resourceName);
            string layerID = CustomComponents.Utility.GetLayerID(layerName, commonMapFunctionality);
            commonMapFunctionality.SetLayerVisibility(layerID, false);

            // Find the Toc Control buddied to the Map, if any
            ESRI.ArcGIS.ADF.Web.UI.WebControls.Toc adfToc =
                CustomComponents.Utility.FindControlOfType(typeof(ESRI.ArcGIS.ADF.Web.UI.WebControls.Toc), 
                Page.Controls) as ESRI.ArcGIS.ADF.Web.UI.WebControls.Toc;

            if (adfToc != null && adfToc.BuddyControl == adfMap.ID)
            {
                // Iterate through the nodes at the top level of the Toc.  Each of these should correspond to a resource.
                foreach (ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode resourceTreeViewPlusNode in
                    adfToc.Nodes)
                {
                    ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode treeViewPlusNodeToRemove = null;

                    // Iterate through the nodes below the current top-level node.  Each of these should 
                    // correspond to a layer.
                    foreach (ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode layerTreeViewPlusNode in
                        resourceTreeViewPlusNode.Nodes)
                    {
                        // Attempt to retrieve a node with text matching the passed-in layer name.  This could be
                        // the current node or any node below it.  Note that we need to search both the current node
                        // and any child nodes to handle group layers.
                        ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode matchingTreeViewPlusNode =
                            CustomComponents.Utility.FindNodeRecursive(layerTreeViewPlusNode, layerName);

                        // If a matching node was found, store a reference to it to be accessed outside the loop
                        if (matchingTreeViewPlusNode != null)
                        {
                            treeViewPlusNodeToRemove = matchingTreeViewPlusNode;
                            break;
                        }
                    }

                    // Remove the matching node, if found
                    if (treeViewPlusNodeToRemove != null)
                        treeViewPlusNodeToRemove.Remove();
                }
            }
        }
        catch (System.Exception exception)
        {
            string jsErrorAlert = string.Format("<script>{0}</script>", 
                CustomComponents.Utility.GetJavaScriptErrorString(exception));
            Response.Write(jsErrorAlert);
        }
    }

    // Removes the item with the passed-in name from the passed-in ADF Toolbar.
    private void RemoveItemFromToolbar(ESRI.ArcGIS.ADF.Web.UI.WebControls.Toolbar adfToolbar, string toolbarItemName)
    {
        try
        {
            // Iterate through each item in the passed-in toolbar.  If the current item's name matches the passed-in
            // name, remove it.
            for (int i = 0; i < adfToolbar.ToolbarItems.Count; i++)
            {
                if (adfToolbar.ToolbarItems[i].Name == toolbarItemName)
                {
                    adfToolbar.ToolbarItems.RemoveAt(i);
                    break;
                }
            }
        }
        catch (System.Exception exception)
        {
            string jsErrorAlert = string.Format("<script>{0}</script>",
                CustomComponents.Utility.GetJavaScriptErrorString(exception));
            Response.Write(jsErrorAlert);
        }
    }

    // Removes a task from the TaskManager and from its buddied ASP.NET Menu, if any.
    private void RemoveTask(ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskManager taskManager, string taskName)
    {
        try
        {
            string menuText = "";

            // Iterate through the task manager's controls
            foreach (System.Web.UI.Control control in taskManager.Controls)
            {
                // Check whether the current control's ID matches the name of the task to remove
                if (control.ID == taskName)
                {
                    // get the task's title so can remove it from the Menu
                    ESRI.ArcGIS.ADF.Web.UI.WebControls.FloatingPanel floatingPanelTask = control as
                        ESRI.ArcGIS.ADF.Web.UI.WebControls.FloatingPanel;
                    if (floatingPanelTask != null)
                        menuText = floatingPanelTask.Title;

                    // remove the task from the TaskManager
                    taskManager.Controls.Remove(control);
                    break;
                }
            }

            // Now that we've removed the Task from its TaskManager, we also need to remove its menu item, 
            // since the Task is already bound to its buddied Menu.  Note that this is unnecessary if the 
            // remove-task code runs at Page_Load or before.

            // Find the menu control buddied to the task manager
            System.Web.UI.WebControls.Menu taskMenu = CustomComponents.Utility.FindControlRecursive(
                taskManager.Page, taskManager.BuddyControl) as System.Web.UI.WebControls.Menu;
            if (taskMenu != null)
            {
                // Iterate through the items in the task menu
                for (int i = 0; i < taskMenu.Items.Count; i++)
                {
                    // Check whether the current item's text matches the task's menu task.  If so, remove the item
                    // from the menu.
                    if (taskMenu.Items[i].Text == menuText)
                    {
                        taskMenu.Items.RemoveAt(i);
                        break;
                    }
                }
            }
        }
        catch (System.Exception exception)
        {
            string jsErrorAlert = string.Format("<script>{0}</script>",
                CustomComponents.Utility.GetJavaScriptErrorString(exception));
            Response.Write(jsErrorAlert);
        }
    }

    #endregion
}