Created
August 30, 2013 14:35
-
-
Save f1code/6390503 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using System.Text; | |
| using Sage.Platform.Application; | |
| using Sage.Platform.Application.UI; | |
| using Sage.Platform.Security; | |
| using Sage.SalesLogix.Web; | |
| using Sage.SalesLogix.Security; | |
| using System.Reflection; | |
| using Sage.Entity.Interfaces; | |
| using System.Security; | |
| using Sage.Platform.ComponentModel; | |
| using log4net; | |
| using Sage.SalesLogix.Client.GroupBuilder; | |
| using System.Xml; | |
| using SSSWorld.Common; | |
| using System.Diagnostics; | |
| namespace SSSWorld.Slx75.Web.Security | |
| { | |
| /// <summary> | |
| /// Decorate groups retrieved on the Customer Portal to apply the user's security. | |
| /// To use this module you actually need to load it via the CustomerPortalGroupSecurityModuleLoader. | |
| /// It does not need to be registered in the application's modules. | |
| /// | |
| /// In the properties for the module, add an app setting named "PortalSecurityCondition_TABLE" | |
| /// containing the condition to add (replace table with name of table, eg | |
| /// PortalSecurityCondition_RMA) | |
| /// :CUSACCID and :CUSCONID will be replaced with the customer's account and contact id. | |
| /// For example, use A1.ACCOUNTID=:CUSACCID on ticket. | |
| /// Joined table can be used only if they already exist in the group, and the proper alias (A1, A2 etc) must be used. | |
| /// </summary> | |
| /// <see cref="CustomerPortalGroupSecurityModuleLoader"/> | |
| public class CustomerPortalGroupSecurityModule : IModule, IModuleConfiguration | |
| { | |
| private static readonly ILog LOG = LogManager.GetLogger(typeof(CustomerPortalGroupSecurityModule)); | |
| #region Service Dependencies | |
| private WebPortalUserService _userService; | |
| private IGroupContextService _groupContextService; | |
| [ServiceDependency(Type = typeof(IUserService))] | |
| public WebPortalUserService UserService | |
| { | |
| get { return _userService; } | |
| set { _userService = value; } | |
| } | |
| [ServiceDependency(Type = typeof(IGroupContextService))] | |
| public IGroupContextService GroupContextService | |
| { | |
| get { return _groupContextService; } | |
| set { _groupContextService = value; } | |
| } | |
| #endregion | |
| #region IModule Members | |
| /// <summary> | |
| /// When the module loads, it will pull the current group's XML, and adjust it if needed. | |
| /// </summary> | |
| public void Load() | |
| { | |
| GroupContext ctx = GroupContextService.GetGroupContext(); | |
| /* | |
| ModuleConfiguration config = (ModuleConfiguration)_parentWorkItem.Modules.Get(typeof(CustomerPortalGroupSecurityModule)); | |
| if (config == null) | |
| { | |
| throw new Slx72Exception("Missing configuration for module CustomerPortalGroupSecurity"); | |
| } | |
| */ | |
| if (ctx == null || ctx.CurrentGroupInfo == null) | |
| { | |
| LOG.Debug("NULL group context"); | |
| } | |
| else | |
| { | |
| Debug.Assert(ctx != null, "ctx != null"); | |
| Debug.Assert(ctx.CurrentGroupInfo != null, "ctx.CurrentGroupInfo != null"); | |
| Debug.Assert(ctx.CurrentGroupInfo.CurrentGroup != null, "ctx.CurrentGroupInfo.CurrentGroup != null"); | |
| GroupInfo groupInfo = ctx.CurrentGroupInfo.CurrentGroup.GroupInformation; | |
| AddGroupSecurity(groupInfo); | |
| } | |
| } | |
| public WorkItem ModuleWorkItem | |
| { | |
| get { return null; } | |
| } | |
| #endregion | |
| #region IModuleConfiguration Members | |
| public void Configure(XmlElement xmlConfig) | |
| { | |
| LOG.Debug(xmlConfig.OuterXml); | |
| throw new Exception("Testing, testing."); | |
| } | |
| #endregion | |
| /// <summary> | |
| /// If the group's XML has not yet been decorated, add the parameter to restrict it by the user's account. | |
| /// This can also be called externally to decorate an arbitrary GroupInfo object. | |
| /// </summary> | |
| /// <param name="groupInfo"></param> | |
| public void AddGroupSecurity(GroupInfo groupInfo) | |
| { | |
| String xml = groupInfo.GroupXML; | |
| XmlDocument xmlDoc = new XmlDocument(); | |
| xmlDoc.LoadXml(xml); | |
| if (!WasGroupDecorated(xmlDoc)) | |
| { | |
| PortalUser user = this.UserService.GetPortalUser(); | |
| String condition = GetGroupCondition(user); | |
| if(condition != null) | |
| AddGroupWhere(xmlDoc, condition); | |
| SetGroupParameterValue(xmlDoc, "CUSACCID", (String)user.Contact.Account.Id); | |
| SetGroupParameterValue(xmlDoc, "CUSCONID", (String)user.Contact.Id); | |
| SetGroupDecorated(xmlDoc); | |
| groupInfo.GroupXML = xmlDoc.OuterXml; | |
| LOG.Debug("Group XML: " + xmlDoc.OuterXml); | |
| groupInfo.GroupXML = xmlDoc.OuterXml; | |
| } | |
| } | |
| /// <summary> | |
| /// Retrieve condition template from the configuration | |
| /// </summary> | |
| /// <returns></returns> | |
| protected virtual String GetGroupCondition(PortalUser user) | |
| { | |
| String c = MyConfiguration.Instance.GetAppSetting("PortalSecurityCondition_" + _groupContextService.GetGroupContext().CurrentTable); | |
| if (c == null) | |
| return null; | |
| return "(" + c + ")"; | |
| } | |
| /// <summary> | |
| /// Set the value of the specified parameter in the XML. | |
| /// If the parameter does not already exist under the parameters node, it will be created. | |
| /// </summary> | |
| /// <param name="xmlDoc"></param> | |
| /// <param name="paramName"></param> | |
| /// <param name="paramValue"></param> | |
| private void SetGroupParameterValue(XmlDocument xmlDoc, string paramName, string paramValue) | |
| { | |
| XmlElement groupNode = (XmlElement)xmlDoc.SelectSingleNode("SLXGroup"); | |
| if (groupNode == null) | |
| throw new InvalidOperationException("SLXGroup node not found in xml"); | |
| XmlElement paramsNode = (XmlElement) groupNode.SelectSingleNode("parameters"); | |
| XmlElement paramNode = null; | |
| if (paramsNode == null) | |
| { | |
| XmlElement selectNode = (XmlElement)groupNode.SelectSingleNode("selectsql"); | |
| if (selectNode == null) | |
| throw new InvalidOperationException("selectsql node not found in xml"); | |
| paramsNode = xmlDoc.CreateElement("parameters"); | |
| groupNode.InsertBefore(paramsNode, selectNode); | |
| } | |
| else | |
| { | |
| paramNode = (XmlElement)paramsNode.SelectSingleNode("parameter[name/text()='" + paramName + "']/value"); | |
| } | |
| if (paramNode != null) | |
| { | |
| XmlCDataSection data = (XmlCDataSection)paramNode.FirstChild; | |
| data.Data = paramValue; | |
| } | |
| else | |
| { | |
| paramNode = xmlDoc.CreateElement("parameter"); | |
| paramNode.InnerXml = "<name><![CDATA[" + paramName + "]]></name><datatype>string</datatype><value><![CDATA[" + | |
| paramValue + "]]></value>"; | |
| paramsNode.AppendChild(paramNode); | |
| } | |
| } | |
| /// <summary> | |
| /// Add a condition to the wheresql node in the group XML. | |
| /// Note: this does not add the condition to the conditions section (which is used to edit the group) | |
| /// </summary> | |
| /// <param name="xmlDoc">Root of group xml</param> | |
| /// <param name="condition">condition to add</param> | |
| private void AddGroupWhere(XmlDocument xmlDoc, String condition) | |
| { | |
| XmlElement whereNode = (XmlElement)xmlDoc.SelectSingleNode("SLXGroup/wheresql"); | |
| if (whereNode == null) | |
| { | |
| // add wheresql after selectsql | |
| XmlElement selectNode = (XmlElement)xmlDoc.SelectSingleNode("SLXGroup/selectsql"); | |
| if (selectNode == null) | |
| throw new SlxGobiException("Group error - Can't locate selectsql node in group"); | |
| whereNode = xmlDoc.CreateElement("wheresql"); | |
| XmlCDataSection whereData = xmlDoc.CreateCDataSection(condition); | |
| whereNode.AppendChild(whereData); | |
| xmlDoc.InsertAfter(whereNode, selectNode); | |
| } | |
| else | |
| { | |
| if (whereNode.ChildNodes.Count == 0) | |
| whereNode.AppendChild(xmlDoc.CreateCDataSection("")); | |
| else if (whereNode.FirstChild.NodeType != XmlNodeType.CDATA) | |
| throw new SlxGobiException("Group error - First child to a wheresql node should be CDATA"); | |
| XmlCDataSection whereData = (XmlCDataSection)whereNode.FirstChild; | |
| if(!whereData.Data.Contains(condition)) | |
| whereData.Data = AddSqlCondition(whereData.Data, condition); | |
| } | |
| } | |
| /// <summary> | |
| /// Add a condition to the given SQL and return the modified string. | |
| /// </summary> | |
| /// <param name="sql"></param> | |
| /// <param name="condition"></param> | |
| /// <returns></returns> | |
| String AddSqlCondition(String sql, String condition) | |
| { | |
| if (sql != "") | |
| sql = "(" + sql + ") AND "; | |
| return sql + condition; | |
| } | |
| /// <summary> | |
| /// Check whether the group was marked decorated for security. | |
| /// </summary> | |
| /// <param name="xml"></param> | |
| /// <returns></returns> | |
| private bool WasGroupDecorated(XmlDocument xmlDoc){ | |
| return xmlDoc.DocumentElement.HasAttribute("decorated"); | |
| } | |
| /// <summary> | |
| /// Mark group as decorated for security. | |
| /// </summary> | |
| /// <param name="xml"></param> | |
| private void SetGroupDecorated(XmlDocument xmlDoc){ | |
| XmlElement groupNode = xmlDoc.DocumentElement; | |
| XmlAttribute decAttr = xmlDoc.CreateAttribute("decorated"); | |
| decAttr.Value = "true"; | |
| groupNode.Attributes.Append(decAttr); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment