Available roles now in the platform: Administrator, Reseller, User, PlatformCSR, PlatformHelpdesk, ResellerCSR, ResellerHelpdesk. The platform CSR and Helpdesk are peer accounts on platform root level. The names can be used within the websitepanel_pages.config on Page and Module level. On module level the roles can be specified on the viewRoles attribute and readOnlyRoles attribute. When specifying the later all controls will be disabled within the Modile, the viewRoles just show the page or not. When nothing specified the page is just shown
391 lines
No EOL
16 KiB
C#
391 lines
No EOL
16 KiB
C#
// Copyright (c) 2012, Outercurve Foundation.
|
|
// All rights reserved.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without modification,
|
|
// are permitted provided that the following conditions are met:
|
|
//
|
|
// - Redistributions of source code must retain the above copyright notice, this
|
|
// list of conditions and the following disclaimer.
|
|
//
|
|
// - Redistributions in binary form must reproduce the above copyright notice,
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
// and/or other materials provided with the distribution.
|
|
//
|
|
// - Neither the name of the Outercurve Foundation nor the names of its
|
|
// contributors may be used to endorse or promote products derived from this
|
|
// software without specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Configuration;
|
|
using System.Globalization;
|
|
using System.Web;
|
|
using System.Web.Caching;
|
|
using System.Web.Security;
|
|
using System.Web.UI;
|
|
using System.Web.UI.WebControls;
|
|
using System.Web.UI.WebControls.WebParts;
|
|
using System.Web.UI.HtmlControls;
|
|
using System.Xml;
|
|
|
|
namespace WebsitePanel.WebPortal
|
|
{
|
|
/// <summary>
|
|
/// Summary description for ModuleDefinitions
|
|
/// </summary>
|
|
public class PortalConfiguration
|
|
{
|
|
private const string ROLES_DELIMITERS = ";,";
|
|
private const string APP_DATA_FOLDER = "~/App_Data";
|
|
private const string THEMES_FOLDER = "~/App_Themes";
|
|
private const string MODULES_PATTERN = "*_Modules.config";
|
|
private const string PAGES_PATTERN = "*_Pages.config";
|
|
private const string SITE_SETTINGS_FILE = "SiteSettings.config";
|
|
private const string MODULE_DEFINITIONS_KEY = "PortalModuleDefinitionsCacheKey";
|
|
private const string SITE_STRUCTURE_KEY = "SiteStructureCacheKey";
|
|
private const string SITE_SETTINGS_KEY = "SiteSettingsCacheKey";
|
|
|
|
public static Dictionary<string, ModuleDefinition> ModuleDefinitions
|
|
{
|
|
get
|
|
{
|
|
Dictionary<string, ModuleDefinition> modules =
|
|
(Dictionary<string, ModuleDefinition>)HttpContext.Current.Cache[MODULE_DEFINITIONS_KEY];
|
|
if (modules == null)
|
|
{
|
|
// create list
|
|
modules = new Dictionary<string, ModuleDefinition>();
|
|
|
|
// load modules
|
|
string appData = HttpContext.Current.Server.MapPath(APP_DATA_FOLDER);
|
|
FileInfo[] files = new DirectoryInfo(appData).GetFiles(MODULES_PATTERN);
|
|
|
|
foreach (FileInfo file in files)
|
|
LoadModulesFromXml(modules, file.FullName);
|
|
|
|
// place to cache
|
|
HttpContext.Current.Cache.Insert(MODULE_DEFINITIONS_KEY, modules,
|
|
new System.Web.Caching.CacheDependency(appData));
|
|
|
|
}
|
|
return modules;
|
|
}
|
|
}
|
|
|
|
public static SiteStructure Site
|
|
{
|
|
get
|
|
{
|
|
SiteStructure site =
|
|
(SiteStructure)HttpContext.Current.Cache[SITE_STRUCTURE_KEY];
|
|
if (site == null)
|
|
{
|
|
// create list
|
|
site = new SiteStructure();
|
|
|
|
// load pages
|
|
string appData = HttpContext.Current.Server.MapPath(APP_DATA_FOLDER);
|
|
FileInfo[] files = new DirectoryInfo(appData).GetFiles(PAGES_PATTERN);
|
|
|
|
foreach (FileInfo file in files)
|
|
LoadPagesFromXml(site, file.FullName);
|
|
|
|
// place to cache
|
|
HttpContext.Current.Cache.Insert(SITE_STRUCTURE_KEY, site,
|
|
new System.Web.Caching.CacheDependency(appData));
|
|
|
|
}
|
|
return site;
|
|
}
|
|
}
|
|
|
|
public static SiteSettings SiteSettings
|
|
{
|
|
get
|
|
{
|
|
SiteSettings settings =
|
|
(SiteSettings)HttpContext.Current.Cache[SITE_SETTINGS_KEY];
|
|
if (settings == null)
|
|
{
|
|
// create list
|
|
settings = new SiteSettings();
|
|
|
|
// load pages
|
|
string appData = HttpContext.Current.Server.MapPath(APP_DATA_FOLDER);
|
|
string path = Path.Combine(appData, SITE_SETTINGS_FILE);
|
|
|
|
// load site settings
|
|
XmlDocument xml = new XmlDocument();
|
|
xml.Load(path);
|
|
|
|
XmlNodeList nodes = xml.SelectNodes("SiteSettings/*");
|
|
|
|
foreach(XmlNode node in nodes)
|
|
{
|
|
settings[node.LocalName] = node.InnerText;
|
|
}
|
|
|
|
// place to cache
|
|
HttpContext.Current.Cache.Insert(SITE_SETTINGS_KEY, settings,
|
|
new System.Web.Caching.CacheDependency(path));
|
|
|
|
}
|
|
return settings;
|
|
}
|
|
}
|
|
|
|
public static bool SaveSiteSettings()
|
|
{
|
|
// load pages
|
|
string appData = HttpContext.Current.Server.MapPath(APP_DATA_FOLDER);
|
|
string path = Path.Combine(appData, SITE_SETTINGS_FILE);
|
|
|
|
try
|
|
{
|
|
// build and save site settings
|
|
XmlDocument xml = new XmlDocument();
|
|
|
|
XmlElement root = xml.CreateElement("SiteSettings");
|
|
xml.AppendChild(root);
|
|
|
|
foreach (string keyName in SiteSettings.AllKeys)
|
|
{
|
|
XmlElement elem = xml.CreateElement(keyName);
|
|
elem.InnerText = SiteSettings[keyName];
|
|
|
|
root.AppendChild(elem);
|
|
}
|
|
|
|
xml.Save(path);
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private static void LoadModulesFromXml(Dictionary<string, ModuleDefinition> modules, string path)
|
|
{
|
|
// open xml document
|
|
XmlDocument xml = new XmlDocument();
|
|
xml.Load(path);
|
|
|
|
// select nodes
|
|
XmlNodeList xmlModules = xml.SelectNodes("ModuleDefinitions/ModuleDefinition");
|
|
foreach (XmlNode xmlModule in xmlModules)
|
|
{
|
|
ModuleDefinition module = new ModuleDefinition();
|
|
if (xmlModule.Attributes["id"] == null)
|
|
throw new Exception(String.Format("Module ID is not specified. File: {0}, Node: {1}",
|
|
path, xmlModule.OuterXml));
|
|
|
|
module.Id = xmlModule.Attributes["id"].Value.ToLower(CultureInfo.InvariantCulture);
|
|
modules.Add(module.Id, module);
|
|
|
|
// controls
|
|
XmlNodeList xmlControls = xmlModule.SelectNodes("Controls/Control");
|
|
foreach (XmlNode xmlControl in xmlControls)
|
|
{
|
|
ModuleControl control = new ModuleControl();
|
|
if (xmlControl.Attributes["icon"] != null)
|
|
control.IconFile = xmlControl.Attributes["icon"].Value;
|
|
|
|
if(xmlControl.Attributes["key"] != null)
|
|
control.Key = xmlControl.Attributes["key"].Value.ToLower(CultureInfo.InvariantCulture);
|
|
|
|
if (xmlControl.Attributes["src"] == null)
|
|
throw new Exception(String.Format("Control 'src' is not specified. File: {0}, Node: {1}",
|
|
path, xmlControl.ParentNode.OuterXml));
|
|
control.Src = xmlControl.Attributes["src"].Value;
|
|
|
|
if (xmlControl.Attributes["title"] == null)
|
|
throw new Exception(String.Format("Control 'title' is not specified. File: {0}, Node: {1}",
|
|
path, xmlControl.ParentNode.OuterXml));
|
|
control.Title = xmlControl.Attributes["title"].Value;
|
|
|
|
if (xmlControl.Attributes["type"] != null)
|
|
control.ControlType = (ModuleControlType)Enum.Parse(typeof(ModuleControlType), xmlControl.Attributes["type"].Value, true);
|
|
else
|
|
control.ControlType = ModuleControlType.View;
|
|
|
|
if (String.IsNullOrEmpty(control.Key))
|
|
module.DefaultControl = control;
|
|
|
|
module.Controls.Add(control.Key, control);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void LoadPagesFromXml(SiteStructure site, string path)
|
|
{
|
|
// open xml document
|
|
XmlDocument xml = new XmlDocument();
|
|
xml.Load(path);
|
|
|
|
// select nodes
|
|
XmlNodeList xmlPages = xml.SelectNodes("Pages/Page");
|
|
|
|
// process includes
|
|
ProcessXmlIncludes(xml, path);
|
|
|
|
// parse root nodes
|
|
ParsePagesRecursively(path, site, xmlPages, null);
|
|
}
|
|
|
|
private static void ProcessXmlIncludes(XmlDocument xml, string parentPath)
|
|
{
|
|
// working dir
|
|
string path = Path.GetDirectoryName(parentPath);
|
|
|
|
// get all <includes>
|
|
XmlNodeList nodes = xml.SelectNodes("//include");
|
|
foreach (XmlNode node in nodes)
|
|
{
|
|
if (node.Attributes["file"] == null)
|
|
continue;
|
|
|
|
string incPath = Path.Combine(path, node.Attributes["file"].Value);
|
|
XmlDocument inc = new XmlDocument();
|
|
inc.Load(incPath);
|
|
|
|
XmlElement incNode = xml.CreateElement(inc.DocumentElement.Name);
|
|
incNode.InnerXml = inc.DocumentElement.InnerXml;
|
|
|
|
// replace original node
|
|
node.ParentNode.ReplaceChild(incNode, node);
|
|
}
|
|
}
|
|
|
|
private static void ParsePagesRecursively(string path, SiteStructure site, XmlNodeList xmlPages, PortalPage parentPage)
|
|
{
|
|
foreach (XmlNode xmlPage in xmlPages)
|
|
{
|
|
PortalPage page = new PortalPage();
|
|
page.ParentPage = parentPage;
|
|
|
|
// page properties
|
|
if (xmlPage.Attributes["name"] == null)
|
|
throw new Exception(String.Format("Page name is not specified. File: {0}, Node: {1}",
|
|
path, xmlPage.OuterXml));
|
|
page.Name = xmlPage.Attributes["name"].Value;
|
|
|
|
if (xmlPage.Attributes["roles"] == null)
|
|
page.Roles.Add("*");
|
|
else
|
|
page.Roles.AddRange(xmlPage.Attributes["roles"].Value.Split(ROLES_DELIMITERS.ToCharArray()));
|
|
|
|
page.Enabled = (xmlPage.Attributes["enabled"] != null) ? Boolean.Parse(xmlPage.Attributes["enabled"].Value) : true;
|
|
page.Hidden = (xmlPage.Attributes["hidden"] != null) ? Boolean.Parse(xmlPage.Attributes["hidden"].Value) : false;
|
|
page.SkinSrc = (xmlPage.Attributes["skin"] != null) ? xmlPage.Attributes["skin"].Value : null;
|
|
page.AdminSkinSrc = (xmlPage.Attributes["adminskin"] != null) ? xmlPage.Attributes["adminskin"].Value : null;
|
|
|
|
if (xmlPage.Attributes["url"] != null)
|
|
page.Url = xmlPage.Attributes["url"].Value;
|
|
|
|
if (xmlPage.Attributes["target"] != null)
|
|
page.Target = xmlPage.Attributes["target"].Value;
|
|
|
|
// content panes
|
|
XmlNodeList xmlContentPanes = xmlPage.SelectNodes("Content");
|
|
foreach (XmlNode xmlContentPane in xmlContentPanes)
|
|
{
|
|
ContentPane pane = new ContentPane();
|
|
if (xmlContentPane.Attributes["id"] == null)
|
|
throw new Exception(String.Format("ContentPane ID is not specified. File: {0}, Node: {1}",
|
|
path, xmlContentPane.ParentNode.OuterXml));
|
|
pane.Id = xmlContentPane.Attributes["id"].Value;
|
|
page.ContentPanes.Add(pane.Id, pane);
|
|
|
|
// page modules
|
|
XmlNodeList xmlModules = xmlContentPane.SelectNodes("Module");
|
|
foreach (XmlNode xmlModule in xmlModules)
|
|
{
|
|
PageModule module = new PageModule();
|
|
module.ModuleId = site.Modules.Count + 1;
|
|
module.Page = page;
|
|
site.Modules.Add(module.ModuleId, module);
|
|
|
|
if (xmlModule.Attributes["moduleDefinitionID"] == null)
|
|
throw new Exception(String.Format("ModuleDefinition ID is not specified. File: {0}, Node: {1}",
|
|
path, xmlModule.ParentNode.OuterXml));
|
|
module.ModuleDefinitionID = xmlModule.Attributes["moduleDefinitionID"].Value.ToLower(CultureInfo.InvariantCulture);
|
|
|
|
if (xmlModule.Attributes["title"] != null)
|
|
module.Title = xmlModule.Attributes["title"].Value;
|
|
|
|
if (xmlModule.Attributes["icon"] != null)
|
|
module.IconFile = xmlModule.Attributes["icon"].Value;
|
|
|
|
if (xmlModule.Attributes["container"] != null)
|
|
module.ContainerSrc = xmlModule.Attributes["container"].Value;
|
|
|
|
if (xmlModule.Attributes["admincontainer"] != null)
|
|
module.AdminContainerSrc = xmlModule.Attributes["admincontainer"].Value;
|
|
|
|
if (xmlModule.Attributes["viewRoles"] == null)
|
|
module.ViewRoles.Add("*");
|
|
else
|
|
module.ViewRoles.AddRange(xmlModule.Attributes["viewRoles"].Value.Split(ROLES_DELIMITERS.ToCharArray()));
|
|
|
|
if (xmlModule.Attributes["readOnlyRoles"] != null)
|
|
module.ReadOnlyRoles.AddRange(xmlModule.Attributes["readOnlyRoles"].Value.Split(ROLES_DELIMITERS.ToCharArray()));
|
|
|
|
|
|
if (xmlModule.Attributes["editRoles"] == null)
|
|
module.EditRoles.Add("*");
|
|
else
|
|
module.EditRoles.AddRange(xmlModule.Attributes["editRoles"].Value.Split(ROLES_DELIMITERS.ToCharArray()));
|
|
|
|
// settings
|
|
XmlNodeList xmlSettings = xmlModule.SelectNodes("Settings/Add");
|
|
foreach (XmlNode xmlSetting in xmlSettings)
|
|
{
|
|
module.Settings[xmlSetting.Attributes["name"].Value] = xmlSetting.Attributes["value"].Value;
|
|
}
|
|
|
|
XmlNode xmlModuleData = xmlModule.SelectSingleNode("ModuleData");
|
|
if (xmlModuleData != null)
|
|
{
|
|
// check reference
|
|
if (xmlModuleData.Attributes["ref"] != null)
|
|
{
|
|
// load referenced module data
|
|
xmlModuleData = xmlModule.OwnerDocument.SelectSingleNode(
|
|
"Pages/ModulesData/ModuleData[@id='" + xmlModuleData.Attributes["ref"].Value + "']");
|
|
}
|
|
module.LoadXmlModuleData(xmlModuleData.OuterXml);
|
|
}
|
|
|
|
pane.Modules.Add(module);
|
|
}
|
|
}
|
|
|
|
// add page to te array
|
|
if (parentPage != null)
|
|
parentPage.Pages.Add(page);
|
|
|
|
site.Pages.Add(page);
|
|
|
|
// process children
|
|
XmlNodeList xmlChildPages = xmlPage.SelectNodes("Pages/Page");
|
|
ParsePagesRecursively(path, site, xmlChildPages, page);
|
|
}
|
|
}
|
|
}
|
|
} |