Common Security
Common_Security_VBNet\Default.aspx.vb
' 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.
' 


Imports Microsoft.VisualBasic
Imports System
Public Partial Class [Default]
  Inherits System.Web.UI.Page
  #Region "Instance Variable Declarations"

  ' Role allowed use of all layers, tools and tasks
  Private m_fullyEnabledRole As String = "Managers"

  ' Name of resource containing layer to hide from unauthorized users
  Private m_resourceOfLayerToHide As String = "MapResourceItem0"

  ' Name of layer to hide from unauthorized users
  Private m_layerToHide As String = "Highways"

  ' Tool to remove for unauthorized users
  Private m_toolbarItemToRemove As String = "GetMapInfo"

  ' ID of task to remove for unauthorized users
  Private m_taskToRemove As String = "QueryAttributesTask1"

  #End Region

  #Region "ASP.NET Page Event Handlers"

  Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs)
    ' 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);
  End Sub

  Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs)
    ' 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 (Not User.IsInRole(m_fullyEnabledRole)) Then
      RemoveTask(TaskManager1, m_taskToRemove)
    End If
  End Sub

  Protected Sub Page_PreRenderComplete(ByVal sender As Object, ByVal e As System.EventArgs)
    ' 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 (Not User.IsInRole(m_fullyEnabledRole)) Then
      ' 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)
    End If
  End Sub

  #End Region

  #Region "ASP.NET WebControl Event Handlers"

  Protected Sub LoginStatus1_LoggedOut(ByVal sender As Object, ByVal e As System.EventArgs)
    '
    '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.
    '

    Dim keysToRemoveList As System.Collections.Generic.List(Of String) = New System.Collections.Generic.List(Of String)()
    Dim webAdfKeys As String() = {"ClientScriptsList", "ESRIWebADFHiddenFields", "DataSourceManager_State"}

    ' Iterate through each key in the session
    For Each sessionKey As String In Session.Keys
      If sessionKey.IndexOf(Request.ApplicationPath) >= 0 Then
        ' remove keys specific to the current website path
        keysToRemoveList.Add(sessionKey)
      ElseIf Session(sessionKey).GetType() Is GetType(ESRI.ArcGIS.ADF.Web.MimeData) Then
        ' remove MIME data objects
        keysToRemoveList.Add(sessionKey)
      Else
        ' remove various other keys related to the Web ADF
        For Each webAdfKey As String In webAdfKeys
          If sessionKey = webAdfKey Then
            keysToRemoveList.Add(sessionKey)
          End If
        Next webAdfKey
      End If
    Next 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
  End Sub

  #End Region

  #Region "Instance Methods"

  ' Hides the layer matching the input name in both the Map and its TOC
  Private Sub HideLayer(ByVal adfMap As ESRI.ArcGIS.ADF.Web.UI.WebControls.Map, ByVal resourceName As String, ByVal layerName As String)
    Try
      Dim commonMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality = adfMap.GetFunctionality(resourceName)
      Dim layerID As String = CustomComponents.Utility.GetLayerID(layerName, commonMapFunctionality)
      commonMapFunctionality.SetLayerVisibility(layerID, False)

      ' Find the Toc Control buddied to the Map, if any
      Dim adfToc As ESRI.ArcGIS.ADF.Web.UI.WebControls.Toc = TryCast(CustomComponents.Utility.FindControlOfType(GetType(ESRI.ArcGIS.ADF.Web.UI.WebControls.Toc), Page.Controls), ESRI.ArcGIS.ADF.Web.UI.WebControls.Toc)

      If Not adfToc Is Nothing AndAlso adfToc.BuddyControl = adfMap.ID Then
        ' Iterate through the nodes at the top level of the Toc.  Each of these should correspond to a resource.
        For Each resourceTreeViewPlusNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode In adfToc.Nodes
          Dim treeViewPlusNodeToRemove As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode = Nothing

          ' Iterate through the nodes below the current top-level node.  Each of these should 
          ' correspond to a layer.
          For Each layerTreeViewPlusNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode 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.
            Dim matchingTreeViewPlusNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode = CustomComponents.Utility.FindNodeRecursive(layerTreeViewPlusNode, layerName)

            ' If a matching node was found, store a reference to it to be accessed outside the loop
            If Not matchingTreeViewPlusNode Is Nothing Then
              treeViewPlusNodeToRemove = matchingTreeViewPlusNode
              Exit For
            End If
          Next layerTreeViewPlusNode

          ' Remove the matching node, if found
          If Not treeViewPlusNodeToRemove Is Nothing Then
            treeViewPlusNodeToRemove.Remove()
          End If
        Next resourceTreeViewPlusNode
      End If
    Catch exception As System.Exception
      Dim jsErrorAlert As String = String.Format("<script>{0}</script>", CustomComponents.Utility.GetJavaScriptErrorString(exception))
      Response.Write(jsErrorAlert)
    End Try
  End Sub

  ' Removes the item with the passed-in name from the passed-in ADF Toolbar.
  Private Sub RemoveItemFromToolbar(ByVal adfToolbar As ESRI.ArcGIS.ADF.Web.UI.WebControls.Toolbar, ByVal toolbarItemName As String)
    Try
      ' Iterate through each item in the passed-in toolbar.  If the current item's name matches the passed-in
      ' name, remove it.
      Dim i As Integer = 0
      Do While i < adfToolbar.ToolbarItems.Count
        If adfToolbar.ToolbarItems(i).Name = toolbarItemName Then
          adfToolbar.ToolbarItems.RemoveAt(i)
          Exit Do
        End If
        i += 1
      Loop
    Catch exception As System.Exception
      Dim jsErrorAlert As String = String.Format("<script>{0}</script>", CustomComponents.Utility.GetJavaScriptErrorString(exception))
      Response.Write(jsErrorAlert)
    End Try
  End Sub

  ' Removes a task from the TaskManager and from its buddied ASP.NET Menu, if any.
  Private Sub RemoveTask(ByVal taskManager As ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskManager, ByVal taskName As String)
    Try
      Dim menuText As String = ""

      ' Iterate through the task manager's controls
      For Each control As System.Web.UI.Control In taskManager.Controls
        ' Check whether the current control's ID matches the name of the task to remove
        If control.ID = taskName Then
          ' get the task's title so can remove it from the Menu
          Dim floatingPanelTask As ESRI.ArcGIS.ADF.Web.UI.WebControls.FloatingPanel = TryCast(control, ESRI.ArcGIS.ADF.Web.UI.WebControls.FloatingPanel)
          If Not floatingPanelTask Is Nothing Then
            menuText = floatingPanelTask.Title
          End If

          ' remove the task from the TaskManager
          taskManager.Controls.Remove(control)
          Exit For
        End If
      Next control

      ' 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
      Dim taskMenu As System.Web.UI.WebControls.Menu = TryCast(CustomComponents.Utility.FindControlRecursive(taskManager.Page, taskManager.BuddyControl), System.Web.UI.WebControls.Menu)
      If Not taskMenu Is Nothing Then
        ' Iterate through the items in the task menu
        Dim i As Integer = 0
        Do While i < taskMenu.Items.Count
          ' 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 Then
            taskMenu.Items.RemoveAt(i)
            Exit Do
          End If
          i += 1
        Loop
      End If
    Catch exception As System.Exception
      Dim jsErrorAlert As String = String.Format("<script>{0}</script>", CustomComponents.Utility.GetJavaScriptErrorString(exception))
      Response.Write(jsErrorAlert)
    End Try
  End Sub

  #End Region
End Class