websitepanel/WebsitePanel/Sources/WebsitePanel.WebPortal/Code/PortalConfiguration.cs
robvde 089a62ce72 New attribute added to the 'ModulesData.config' 'selectedUserContext' through
this attribute the left menu (UserAccountMenu) can be managed based on the
selected user. The logged on user context (roles) finally determines if the
menu item shows up or not.

selectedUserContext attribute can contain "Administrator,Reseller,User"
2012-07-30 17:02:06 +04:00

394 lines
No EOL
17 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()));
if (xmlPage.Attributes["selectedUserContext"] != null)
page.Roles.AddRange(xmlPage.Attributes["selectedUserContext"].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);
}
}
}
}