context: //
  // DO NOT REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  //
  // @Authors:
  //       timop
  //
  // Copyright 2004-2020 by OM International
  //
  // This file is part of OpenPetra.org.
  //
  // OpenPetra.org is free software: you can redistribute it and/or modify
  // it under the terms of the GNU General Public License as published by
  // the Free Software Foundation, either version 3 of the License, or
  // (at your option) any later version.
  //
  // OpenPetra.org is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  // GNU General Public License for more details.
  //
  // You should have received a copy of the GNU General Public License
  // along with OpenPetra.org.  If not, see <http://www.gnu.org/licenses/>.
  //
  using System;
  using System.Data;
  using System.Collections.Generic;
  using System.Collections.Specialized;
  using System.Xml;
  using System.IO;
  using System.Text;
  using GNU.Gettext;
  using Ict.Common;
  using Ict.Common.IO;
  using Ict.Common.DB;
  using Ict.Common.Data;
  using Ict.Common.Exceptions;
  using Ict.Petra.Shared;
  using Ict.Petra.Shared.Security;
  using Ict.Petra.Shared.MFinance.Account.Data;
  using Ict.Petra.Server.MSysMan.Common.WebConnectors;
  using Ict.Petra.Server.MFinance.Setup.WebConnectors;
  
  namespace Ict.Petra.Server.app.JSClient
  {
      /// <summary>
      /// Load navigation from UINavigation.yml and return as json
      /// specific for this user, disabling parts that he does not have access to
      /// </summary>
      public class TUINavigation
      {
          /// <summary>
          /// checks if the user has access to the navigation node
          /// </summary>
          public bool HasAccessPermission(XmlNode ANode, TPetraPrincipal AUserInfo)
          {
              // TODO: if this is an action node, eg. opens a screen, check the static function that tells RequiredPermissions of the screen
  
              string PermissionsRequired = TXMLParser.GetAttributeRecursive(ANode, "PermissionsRequired", true);
  
              try
              {
                  if (PermissionsRequired.StartsWith("\"") && PermissionsRequired.EndsWith("\""))
                  {
                      PermissionsRequired = PermissionsRequired.Substring(1, PermissionsRequired.Length-2);
                  }
  
                  if (PermissionsRequired.Contains(",") && !PermissionsRequired.EndsWith(")"))
                  {
                      PermissionsRequired = "AND(" + PermissionsRequired + ")";
                  }
  
                  if (PermissionsRequired == "")
                  {
                      PermissionsRequired = "USER";
                  }
  
                  TSecurityChecks.CheckUserModulePermissions(PermissionsRequired, "UINavigation");
                  return true;
              }
              catch (ESecurityModuleAccessDeniedException)
              {
                  return false;
              }
              catch (ArgumentException e)
              {
                  TLogging.Log("Issue for node " + ANode.Name + Environment.NewLine +
                      e.ToString());
                  return false;
              }
          }
  
          /// <summary>
          /// build an XML document with the navigation
          /// </summary>
          public XmlNode BuildNavigationXml()
          {
              string UINavigationFile = TAppSettingsManager.GetValue("UINavigation.File");
  
              if (!File.Exists(UINavigationFile))
              {
                  throw new Exception ("cannot find file " + UINavigationFile);
              }
  
              TYml2Xml parser = new TYml2Xml(UINavigationFile);
              XmlDocument UINavigation = parser.ParseYML2XML();
  
              XmlNode OpenPetraNode = UINavigation.FirstChild.NextSibling.FirstChild;
              XmlNode MainMenuNode = OpenPetraNode.FirstChild;
  
              return MainMenuNode;
          }
  
          /// <summary>
          /// load the navigation ready to be converted to JSON
          /// </summary>
          public Dictionary<string, object> LoadNavigationUI()
          {
              TPetraPrincipal userinfo = UserInfo.GetUserInfo();
  
              XmlNode MainMenuNode = BuildNavigationXml();
              XmlNode DepartmentNode = MainMenuNode.FirstChild;
  
              Dictionary<string, object> result = new Dictionary<string, object>();
  
              while (DepartmentNode != null)
              {
                  Dictionary<string, object> Folder = AddFolder(DepartmentNode, userinfo);
  
                  if (Folder != null)
                  {
                      result.Add(DepartmentNode.Name, Folder);
                  }
  
                  DepartmentNode = DepartmentNode.NextSibling;
              }
  
              return result;
          }
  
          private string GetCaption(XmlNode ANode, bool AWithoutBrackets=false)
          {
              if (AWithoutBrackets)
              {
                  return ANode.Name + "_label";
              }
              else
              {
                  return "{" + ANode.Name + "_label}";
              }
          }
  
          private Dictionary<string, object> GetChildItems(XmlNode AFolderNode, string APath, TPetraPrincipal AUserInfo)
          {
              Dictionary<string, object> items = new Dictionary<string, object>();
  
              foreach (XmlNode child in AFolderNode.ChildNodes)
              {
                  if (!HasAccessPermission(child, AUserInfo))
                  {
                      continue;
                  }
  
                  Dictionary<string, object> item = new Dictionary<string, object>();
                  item.Add("caption", GetCaption(child, true));
                  if (child.ChildNodes.Count > 0)
                  {
                      item.Add("items", GetChildItems(child, APath + "/" + child.Name, AUserInfo));
                  }
                  else
                  {
                      item.Add("form", child.Name);
                  }
  
                  string Action = TXMLParser.GetAttribute(child, "Action");
  
                  if (Action.Length > 0)
                  {
                      item.Add("action", Action);
                  }
  
                  string Icon = TXMLParser.GetAttributeRecursive(child, "fa-icon", false);
  
                  if (Icon.Length > 0)
                  {
                      item.Add("icon", Icon);
                  }
  
                  string form = TXMLParser.GetAttribute(child, "Form");
  
                  if (form.Length > 0)
                  {
                      item["form"] = form;
                  }
  
                  string path = TXMLParser.GetAttributeRecursive(child, "Path", false);
  
                  if (path.Length == 0)
                  {
                      path = APath;
                  }
  
                  item.Add("path", path);
  
                  if (File.Exists(TAppSettingsManager.GetValue("Forms.Path") + "/" + path.Replace('_', '/') + "/" + child.Name + ".html"))
                  {
                      item["htmlexists"] = true;
                  }
  
                  items.Add(child.Name, item);
              }
  
              return items;
          }
  
  
          private Dictionary<string, object> AddFolder(XmlNode AFolderNode, TPetraPrincipal AUserInfo)
          {
              // enabled/disabled based on permissions
              bool enabled = true;
              if ((TYml2Xml.HasAttribute(AFolderNode, "Enabled"))
                  && (TYml2Xml.GetAttribute(AFolderNode, "Enabled").ToLower() == "false"))
              {
                  enabled = false;
              }
              else
              {
  
gt:                 enabled = HasAccessPermission(AFolderNode, AUserInfo);