diff --git a/src/Umbraco.Web/Security/LegacyDefaultAppMapping.cs b/src/Umbraco.Web/Security/LegacyDefaultAppMapping.cs new file mode 100644 index 0000000000..99d0b71f5b --- /dev/null +++ b/src/Umbraco.Web/Security/LegacyDefaultAppMapping.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Umbraco.Web.Security +{ + /// + /// This is used specifically to assign a default 'app' to a particular section in order to validate the + /// currently logged in user's allowed applications + /// + /// + /// This relates to these issues: + /// http://issues.umbraco.org/issue/U4-2021 + /// http://issues.umbraco.org/issue/U4-529 + /// + /// In order to fix these issues we need to pass in an 'app' parameter but since we don't want to break compatibility + /// we will create this mapping to map a 'default application' to a section action (like creating or deleting) + /// + public static class LegacyDefaultAppMapping + { + /// + /// Constructor that assigns all initial known mappings + /// + static LegacyDefaultAppMapping() + { + } + + private static readonly ConcurrentDictionary NodeTypeAliasMapping = new ConcurrentDictionary(); + + /// + /// Adds the default app mapping to the node type + /// + /// The nodeType is the same nodeType found in the UI.xml + /// The default app associated with this nodeType if the 'app' parameter was not detected + public static void AddNodeTypeMappingForCreateDialog(string nodeType, string defaultApp) + { + NodeTypeAliasMapping.AddOrUpdate(nodeType, s => defaultApp, (s, s1) => defaultApp); + } + + internal static string GetDefaultAppForCreateDialog(string nodeTypeAlias) + { + string app; + return NodeTypeAliasMapping.TryGetValue(nodeTypeAlias, out app) ? app : null; + } + + } +} diff --git a/src/Umbraco.Web/UI/LegacyDialogHandler.cs b/src/Umbraco.Web/UI/LegacyDialogHandler.cs new file mode 100644 index 0000000000..0e6d3aeca8 --- /dev/null +++ b/src/Umbraco.Web/UI/LegacyDialogHandler.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Xml; +using Umbraco.Core.IO; +using umbraco.BasePages; +using umbraco.interfaces; + +namespace Umbraco.Web.UI +{ + /// + /// This is used to replace the old umbraco.presentation.create.dialogHandler_temp class which is used + /// to handle sections create/delete actions. + /// + /// + /// We need to overhaul how all of this is handled which is why this is a legacy class + /// http://issues.umbraco.org/issue/U4-1373 + /// + public static class LegacyDialogHandler + { + public static void Delete(string nodeType, int nodeId, string text) + { + // Load task settings + var createDef = GetXmlDoc(); + + // Create an instance of the type by loading it from the assembly + var def = createDef.SelectSingleNode("//nodeType [@alias = '" + nodeType + "']"); + var taskAssembly = def.SelectSingleNode("./tasks/delete").Attributes.GetNamedItem("assembly").Value; + var taskType = def.SelectSingleNode("./tasks/delete").Attributes.GetNamedItem("type").Value; + var assembly = Assembly.LoadFrom(IOHelper.MapPath(SystemDirectories.Bin + "/" + taskAssembly + ".dll")); + var type = assembly.GetType(taskAssembly + "." + taskType); + var typeInstance = Activator.CreateInstance(type) as ITask; + if (typeInstance == null) return; + typeInstance.ParentID = nodeId; + typeInstance.Alias = text; + typeInstance.Delete(); + } + + public static string Create(string nodeType, int nodeId, string text, int typeId = 0) + { + // Load task settings + var createDef = GetXmlDoc(); + + // Create an instance of the type by loading it from the assembly + var def = createDef.SelectSingleNode("//nodeType [@alias = '" + nodeType + "']"); + var taskAssembly = def.SelectSingleNode("./tasks/create").Attributes.GetNamedItem("assembly").Value; + var taskType = def.SelectSingleNode("./tasks/create").Attributes.GetNamedItem("type").Value; + + var assembly = Assembly.LoadFrom(IOHelper.MapPath(SystemDirectories.Bin + "/" + taskAssembly + ".dll")); + var type = assembly.GetType(taskAssembly + "." + taskType); + var typeInstance = Activator.CreateInstance(type) as ITask; + if (typeInstance != null) + { + typeInstance.TypeID = typeId; + typeInstance.ParentID = nodeId; + typeInstance.Alias = text; + typeInstance.UserId = BasePage.GetUserId(BasePage.umbracoUserContextID); + typeInstance.Save(); + + // check for returning url + var returnUrlTask = typeInstance as ITaskReturnUrl; + return returnUrlTask != null + ? returnUrlTask.ReturnUrl + : ""; + } + + return ""; + } + + private static XmlDocument GetXmlDoc() + { + // Load task settings + var createDef = new XmlDocument(); + using (var defReader = new XmlTextReader(IOHelper.MapPath(SystemFiles.CreateUiXml))) + { + createDef.Load(defReader); + defReader.Close(); + return createDef; + } + } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index f107977a6a..a400ea3dc3 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -325,6 +325,7 @@ + ASPXCodeBehind diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/create/dialogHandler_temp.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/create/dialogHandler_temp.cs index 4a5900d1cf..90004061e6 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/create/dialogHandler_temp.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/create/dialogHandler_temp.cs @@ -3,6 +3,7 @@ using System; using System.Xml; using System.Xml.XPath; using System.Reflection; +using Umbraco.Web.UI; using umbraco.BusinessLogic; using umbraco.BasePages; using umbraco.IO; @@ -12,35 +13,16 @@ namespace umbraco.presentation.create /// /// Summary description for dialogHandler_temp. /// + [Obsolete("This class is no longer used, it has been replaced by Umbraco.Web.UI.LegacyDialogHandler which will also eventually be deprecated")] public class dialogHandler_temp { - public dialogHandler_temp() - { - } - public static void Delete(string NodeType, int NodeId) { Delete(NodeType, NodeId, ""); } public static void Delete(string NodeType, int NodeId, string Text) { - // Load task settings - XmlDocument createDef = GetXmlDoc(); - - // Create an instance of the type by loading it from the assembly - XmlNode def = createDef.SelectSingleNode("//nodeType [@alias = '" + NodeType + "']"); - string taskAssembly = def.SelectSingleNode("./tasks/delete").Attributes.GetNamedItem("assembly").Value; - string taskType = def.SelectSingleNode("./tasks/delete").Attributes.GetNamedItem("type").Value; - - Assembly assembly = Assembly.LoadFrom( IOHelper.MapPath(SystemDirectories.Bin + "/" + taskAssembly + ".dll")); - Type type = assembly.GetType(taskAssembly + "." + taskType); - interfaces.ITask typeInstance = Activator.CreateInstance(type) as interfaces.ITask; - if (typeInstance != null) - { - typeInstance.ParentID = NodeId; - typeInstance.Alias = Text; - typeInstance.Delete(); - } + LegacyDialogHandler.Delete(NodeType, NodeId, Text); } public static string Create(string NodeType, int NodeId, string Text) @@ -50,60 +32,7 @@ namespace umbraco.presentation.create public static string Create(string NodeType, int TypeId, int NodeId, string Text) { - - // Load task settings - XmlDocument createDef = GetXmlDoc(); - - // Create an instance of the type by loading it from the assembly - XmlNode def = createDef.SelectSingleNode("//nodeType [@alias = '" + NodeType + "']"); - string taskAssembly = def.SelectSingleNode("./tasks/create").Attributes.GetNamedItem("assembly").Value; - string taskType = def.SelectSingleNode("./tasks/create").Attributes.GetNamedItem("type").Value; - - Assembly assembly = Assembly.LoadFrom( IOHelper.MapPath(SystemDirectories.Bin + "/" + taskAssembly + ".dll")); - Type type = assembly.GetType(taskAssembly + "." + taskType); - interfaces.ITask typeInstance = Activator.CreateInstance(type) as interfaces.ITask; - if (typeInstance != null) - { - typeInstance.TypeID = TypeId; - typeInstance.ParentID = NodeId; - typeInstance.Alias = Text; - typeInstance.UserId = BasePages.UmbracoEnsuredPage.GetUserId(BasePages.UmbracoEnsuredPage.umbracoUserContextID); - typeInstance.Save(); - - // check for returning url - try - { - return ((interfaces.ITaskReturnUrl)typeInstance).ReturnUrl; - } - catch - { - return ""; - } - } - - - //try - //{ - - //} - //catch (Exception ex) - //{ - // Log.Add(LogTypes.Error, UmbracoEnsuredPage.CurrentUser, -1, string.Format("Could not create node ({0},{1},{2},{3} ERROR: {4}", NodeType, TypeId, NodeId, Text, ex.Message)); - // return ""; - //} - - return ""; + return LegacyDialogHandler.Create(NodeType, NodeId, Text, TypeId); } - - private static XmlDocument GetXmlDoc() - { - // Load task settings - XmlDocument createDef = new XmlDocument(); - XmlTextReader defReader = new XmlTextReader(IOHelper.MapPath(SystemFiles.CreateUiXml)); - createDef.Load(defReader); - defReader.Close(); - return createDef; - } - } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx.cs index f9e9127325..8e330009ff 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx.cs @@ -1,23 +1,17 @@ using System; -using System.Data; using System.Web; -using System.Collections; using System.Web.Services; -using System.Web.Services.Protocols; using System.ComponentModel; - using System.Web.Script.Services; using System.Xml; -using System.Xml.XPath; using System.Xml.Xsl; using System.IO; -using System.Text; using System.Text.RegularExpressions; -using System.Diagnostics; using System.Net; using System.Web.UI; +using Umbraco.Core.IO; +using Umbraco.Web.UI; using umbraco.businesslogic.Exceptions; -using umbraco.IO; using umbraco.cms.businesslogic.web; using umbraco.cms.businesslogic.media; using umbraco.BasePages; @@ -32,26 +26,21 @@ namespace umbraco.presentation.webservices [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ToolboxItem(false)] [ScriptService] - public class legacyAjaxCalls : System.Web.Services.WebService + public class legacyAjaxCalls : WebService { [WebMethod] public bool ValidateUser(string username, string password) { - if (System.Web.Security.Membership.Providers[UmbracoSettings.DefaultBackofficeProvider].ValidateUser( username, password)) { - BusinessLogic.User u = new BusinessLogic.User(username); + var u = new BusinessLogic.User(username); BasePage.doLogin(u); - return true; } - else - { - return false; - } - + return false; } + /// /// method to accept a string value for the node id. Used for tree's such as python /// and xslt since the file names are the node IDs @@ -63,43 +52,48 @@ namespace umbraco.presentation.webservices [ScriptMethod] public void Delete(string nodeId, string alias, string nodeType) { - Authorize(); //check which parameters to pass depending on the types passed in - int intNodeID; - if (int.TryParse(nodeId, out intNodeID) && nodeType != "member") // Fix for #26965 - numeric member login gets parsed as nodeId - presentation.create.dialogHandler_temp.Delete(nodeType, intNodeID, alias); + int intNodeId; + // Fix for #26965 - numeric member login gets parsed as nodeId + if (int.TryParse(nodeId, out intNodeId) && nodeType != "member") + { + LegacyDialogHandler.Delete(nodeType, intNodeId, alias); + } else - presentation.create.dialogHandler_temp.Delete(nodeType, 0, nodeId); + { + LegacyDialogHandler.Delete(nodeType, 0, nodeId); + } } - + /// /// Permanently deletes a document/media object. /// Used to remove an item from the recycle bin. /// /// + /// [WebMethod] [ScriptMethod] public void DeleteContentPermanently(string nodeId, string nodeType) { Authorize(); - int intNodeID; - if (int.TryParse(nodeId, out intNodeID)) + int intNodeId; + if (int.TryParse(nodeId, out intNodeId)) { switch (nodeType) { case "media": case "mediaRecycleBin": - new Media(intNodeID).delete(true); + new Media(intNodeId).delete(true); break; case "content": case "contentRecycleBin": - new Document(intNodeID).delete(true); + new Document(intNodeId).delete(true); break; default: - new Document(intNodeID).delete(true); + new Document(intNodeId).delete(true); break; } } @@ -179,9 +173,9 @@ namespace umbraco.presentation.webservices public int GetSecondsBeforeUserLogout() { Authorize(); - long timeout = BasePage.GetTimeout(true); - DateTime timeoutDate = new DateTime(timeout); - DateTime currentDate = DateTime.Now; + var timeout = BasePage.GetTimeout(true); + var timeoutDate = new DateTime(timeout); + var currentDate = DateTime.Now; return (int) timeoutDate.Subtract(currentDate).TotalSeconds; @@ -199,21 +193,20 @@ namespace umbraco.presentation.webservices [ScriptMethod] public string SaveFile(string fileName, string fileAlias, string fileContents, string fileType, int fileID, int masterID, bool ignoreDebug) { - Authorize(); switch (fileType) { case "xslt": - return saveXslt(fileName, fileContents, ignoreDebug); + return SaveXslt(fileName, fileContents, ignoreDebug); case "python": return "true"; case "css": - return saveCss(fileName, fileContents, fileID); + return SaveCss(fileName, fileContents, fileID); case "script": - return saveScript(fileName, fileContents); + return SaveScript(fileName, fileContents); case "template": - return saveTemplate(fileName, fileAlias, fileContents, fileID, masterID); + return SaveTemplate(fileName, fileAlias, fileContents, fileID, masterID); default: throw new ArgumentException(String.Format("Invalid fileType passed: '{0}'", fileType)); } @@ -222,46 +215,43 @@ namespace umbraco.presentation.webservices public string Tidy(string textToTidy) { - Authorize(); return library.Tidy(helper.Request("StringToTidy"), true); - } - private string saveCss(string fileName, string fileContents, int fileID) + private static string SaveCss(string fileName, string fileContents, int fileId) { - string returnValue = "false"; - cms.businesslogic.web.StyleSheet stylesheet = new cms.businesslogic.web.StyleSheet(fileID); + string returnValue; + var stylesheet = new StyleSheet(fileId) + { + Content = fileContents, + Text = fileName + }; - if (stylesheet != null) + try { - stylesheet.Content = fileContents; - stylesheet.Text = fileName; - try - { - stylesheet.saveCssToFile(); - returnValue = "true"; - } - catch (Exception ee) - { - throw new Exception("Couldn't save file", ee); - } - - //this.speechBubble(speechBubbleIcon.save, ui.Text("speechBubbles", "editStylesheetSaved", base.getUser()), ""); + stylesheet.saveCssToFile(); + returnValue = "true"; } + catch (Exception ee) + { + throw new Exception("Couldn't save file", ee); + } + return returnValue; } - private string saveXslt(string fileName, string fileContents, bool ignoreDebugging) + private string SaveXslt(string fileName, string fileContents, bool ignoreDebugging) { - StreamWriter SW; - string tempFileName = IOHelper.MapPath(SystemDirectories.Xslt + "/" + System.DateTime.Now.Ticks + "_temp.xslt"); - SW = File.CreateText(tempFileName); - SW.Write(fileContents); - SW.Close(); + var tempFileName = IOHelper.MapPath(SystemDirectories.Xslt + "/" + DateTime.Now.Ticks + "_temp.xslt"); + using (var sw = File.CreateText(tempFileName)) + { + sw.Write(fileContents); + sw.Close(); + } // Test the xslt - string errorMessage = ""; + var errorMessage = ""; if (!ignoreDebugging) { try @@ -270,15 +260,14 @@ namespace umbraco.presentation.webservices // Check if there's any documents yet if (content.Instance.XmlContent.SelectNodes("/root/node").Count > 0) { - XmlDocument macroXML = new XmlDocument(); - macroXML.LoadXml(""); + var macroXml = new XmlDocument(); + macroXml.LoadXml(""); - XslCompiledTransform macroXSLT = new XslCompiledTransform(); - page umbPage = new page(content.Instance.XmlContent.SelectSingleNode("//node [@parentID = -1]")); + var macroXslt = new XslCompiledTransform(); + var umbPage = new page(content.Instance.XmlContent.SelectSingleNode("//node [@parentID = -1]")); - XsltArgumentList xslArgs; - xslArgs = macro.AddMacroXsltExtensions(); - library lib = new library(umbPage); + var xslArgs = macro.AddMacroXsltExtensions(); + var lib = new library(umbPage); xslArgs.AddExtensionObject("urn:umbraco.library", lib); HttpContext.Current.Trace.Write("umbracoMacro", "After adding extensions"); @@ -288,58 +277,51 @@ namespace umbraco.presentation.webservices // Create reader and load XSL file // We need to allow custom DTD's, useful for defining an ENTITY - XmlReaderSettings readerSettings = new XmlReaderSettings(); + var readerSettings = new XmlReaderSettings(); readerSettings.ProhibitDtd = false; - using (XmlReader xmlReader = XmlReader.Create(tempFileName, readerSettings)) + using (var xmlReader = XmlReader.Create(tempFileName, readerSettings)) { - XmlUrlResolver xslResolver = new XmlUrlResolver(); - xslResolver.Credentials = CredentialCache.DefaultCredentials; - macroXSLT.Load(xmlReader, XsltSettings.TrustedXslt, xslResolver); + var xslResolver = new XmlUrlResolver + { + Credentials = CredentialCache.DefaultCredentials + }; + macroXslt.Load(xmlReader, XsltSettings.TrustedXslt, xslResolver); xmlReader.Close(); // Try to execute the transformation - HtmlTextWriter macroResult = new HtmlTextWriter(new StringWriter()); - macroXSLT.Transform(macroXML, xslArgs, macroResult); + var macroResult = new HtmlTextWriter(new StringWriter()); + macroXslt.Transform(macroXml, xslArgs, macroResult); macroResult.Close(); } } else { errorMessage = "stub"; - //base.speechBubble(speechBubbleIcon.info, ui.Text("errors", "xsltErrorHeader", base.getUser()), "Unable to validate xslt as no published content nodes exist."); } } catch (Exception errorXslt) { - //base.speechBubble(speechBubbleIcon.error, ui.Text("errors", "xsltErrorHeader", base.getUser()), ui.Text("errors", "xsltErrorText", base.getUser())); - - //errorHolder.Visible = true; - //closeErrorMessage.Visible = true; - //errorHolder.Attributes.Add("style", "height: 250px; overflow: auto; border: 1px solid CCC; padding: 5px;"); - errorMessage = (errorXslt.InnerException ?? errorXslt).ToString(); // Full error message errorMessage = errorMessage.Replace("\n", "
\n"); - //closeErrorMessage.Visible = true; - string[] errorLine; // Find error - MatchCollection m = Regex.Matches(errorMessage, @"\d*[^,],\d[^\)]", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); + var m = Regex.Matches(errorMessage, @"\d*[^,],\d[^\)]", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); foreach (Match mm in m) { - errorLine = mm.Value.Split(','); + var errorLine = mm.Value.Split(','); if (errorLine.Length > 0) { - int theErrorLine = int.Parse(errorLine[0]); - int theErrorChar = int.Parse(errorLine[1]); + var theErrorLine = int.Parse(errorLine[0]); + var theErrorChar = int.Parse(errorLine[1]); errorMessage = "Error in XSLT at line " + errorLine[0] + ", char " + errorLine[1] + "
"; errorMessage += ""; - string[] xsltText = fileContents.Split("\n".ToCharArray()); - for (int i = 0; i < xsltText.Length; i++) + var xsltText = fileContents.Split("\n".ToCharArray()); + for (var i = 0; i < xsltText.Length; i++) { if (i >= theErrorLine - 3 && i <= theErrorLine + 1) if (i + 1 == theErrorLine) @@ -363,13 +345,15 @@ namespace umbraco.presentation.webservices if (errorMessage == "" && fileName.ToLower().EndsWith(".xslt")) { //Hardcoded security-check... only allow saving files in xslt directory... - string savePath = IOHelper.MapPath(SystemDirectories.Xslt + "/" + fileName); + var savePath = IOHelper.MapPath(SystemDirectories.Xslt + "/" + fileName); if (savePath.StartsWith(IOHelper.MapPath(SystemDirectories.Xslt))) { - SW = File.CreateText(savePath); - SW.Write(fileContents); - SW.Close(); + using (var sw = File.CreateText(savePath)) + { + sw.Write(fileContents); + sw.Close(); + } errorMessage = "true"; } else @@ -378,23 +362,15 @@ namespace umbraco.presentation.webservices } } - System.IO.File.Delete(tempFileName); - + File.Delete(tempFileName); return errorMessage; } - private string savePython(string filename, string contents) - { - - - return "true"; - } - - private string saveScript(string filename, string contents) + private static string SaveScript(string filename, string contents) { string val = contents; - string returnValue = "false"; + string returnValue; try { string savePath = IOHelper.MapPath(SystemDirectories.Scripts + "/" + filename); @@ -402,11 +378,13 @@ namespace umbraco.presentation.webservices //Directory check.. only allow files in script dir and below to be edited if (savePath.StartsWith(IOHelper.MapPath(SystemDirectories.Scripts + "/"))) { - StreamWriter SW; - SW = File.CreateText(IOHelper.MapPath(SystemDirectories.Scripts + "/" + filename)); - SW.Write(val); - SW.Close(); - returnValue = "true"; + using (var sw = File.CreateText(IOHelper.MapPath(SystemDirectories.Scripts + "/" + filename))) + { + sw.Write(val); + sw.Close(); + returnValue = "true"; + } + } else { @@ -422,34 +400,25 @@ namespace umbraco.presentation.webservices return returnValue; } - private string saveTemplate(string templateName, string templateAlias, string templateContents, int templateID, int masterTemplateID) + private static string SaveTemplate(string templateName, string templateAlias, string templateContents, int templateId, int masterTemplateId) { + var templt = new cms.businesslogic.template.Template(templateId) + { + Text = templateName, + Alias = templateAlias, + MasterTemplate = masterTemplateId, + Design = templateContents + }; - cms.businesslogic.template.Template _template = new global::umbraco.cms.businesslogic.template.Template(templateID); - string retVal = "false"; - - if (_template != null) - { - _template.Text = templateName; - _template.Alias = templateAlias; - _template.MasterTemplate = masterTemplateID; - _template.Design = templateContents; - - retVal = "true"; - - // Clear cache in rutime - if (UmbracoSettings.UseDistributedCalls) - cache.dispatcher.Refresh( - new Guid("dd12b6a0-14b9-46e8-8800-c154f74047c8"), - _template.Id); - else - template.ClearCachedTemplate(_template.Id); - } + // Clear cache in rutime + if (UmbracoSettings.UseDistributedCalls) + cache.dispatcher.Refresh( + new Guid("dd12b6a0-14b9-46e8-8800-c154f74047c8"), + templt.Id); else - return "false"; + template.ClearCachedTemplate(templt.Id); - - return retVal; + return "true"; } @@ -460,7 +429,7 @@ namespace umbraco.presentation.webservices if (GlobalSettings.UseSSL && !HttpContext.Current.Request.IsSecureConnection) throw new UserAuthorizationException("This installation requires a secure connection (via SSL). Please update the URL to include https://"); - if (!BasePages.BasePage.ValidateUserContextID(BasePages.BasePage.umbracoUserContextID)) + if (!BasePage.ValidateUserContextID(BasePages.BasePage.umbracoUserContextID)) throw new Exception("Client authorization failed. User is not logged in"); }