From c2dc896fcee3c6587e90bf560355bafbab03444c Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 16 Jul 2015 15:29:46 +0200 Subject: [PATCH] working on: U4-6756 Don't ship or generate unnecessary folders --- build/Build.proj | 7 - build/NuSpecs/UmbracoCms.nuspec | 1 - .../FileResources/BlockingWeb.config} | 36 +-- .../FileResources/Files.Designer.cs | 86 ++++++ src/Umbraco.Core/FileResources/Files.resx | 124 ++++++++ src/Umbraco.Core/IO/IOHelper.cs | 39 ++- src/Umbraco.Core/Manifest/ManifestParser.cs | 10 +- src/Umbraco.Core/Umbraco.Core.csproj | 13 +- src/Umbraco.Web.UI/App_Start/Test.cs | 272 ++++++++++++++++++ src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 1 - .../developer/Macros/EditMacro.aspx.cs | 32 ++- .../Install/FilePermissionHelper.cs | 4 +- ...ureSystemPathsApplicationStartupHandler.cs | 24 +- .../umbraco/Trees/loadTemplates.cs | 41 +-- .../umbraco/create/XsltTasks.cs | 9 +- .../developer/Macros/editMacro.aspx.cs | 3 + .../webservices/codeEditorSave.asmx.cs | 9 +- .../webservices/legacyAjaxCalls.asmx.cs | 7 +- .../usercontrolPrevalueEditor.cs | 1 + 19 files changed, 620 insertions(+), 99 deletions(-) rename src/{Umbraco.Web.UI/xslt/Web.config => Umbraco.Core/FileResources/BlockingWeb.config} (96%) create mode 100644 src/Umbraco.Core/FileResources/Files.Designer.cs create mode 100644 src/Umbraco.Core/FileResources/Files.resx create mode 100644 src/Umbraco.Web.UI/App_Start/Test.cs diff --git a/build/Build.proj b/build/Build.proj index 051e02de5c..799e4dc82d 100644 --- a/build/Build.proj +++ b/build/Build.proj @@ -97,15 +97,8 @@ - - - - - - - diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec index 76d72935e9..6722257f77 100644 --- a/build/NuSpecs/UmbracoCms.nuspec +++ b/build/NuSpecs/UmbracoCms.nuspec @@ -26,7 +26,6 @@ - diff --git a/src/Umbraco.Web.UI/xslt/Web.config b/src/Umbraco.Core/FileResources/BlockingWeb.config similarity index 96% rename from src/Umbraco.Web.UI/xslt/Web.config rename to src/Umbraco.Core/FileResources/BlockingWeb.config index fd6e3a816a..80182af9a1 100644 --- a/src/Umbraco.Web.UI/xslt/Web.config +++ b/src/Umbraco.Core/FileResources/BlockingWeb.config @@ -1,18 +1,18 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/src/Umbraco.Core/FileResources/Files.Designer.cs b/src/Umbraco.Core/FileResources/Files.Designer.cs new file mode 100644 index 0000000000..456dae221f --- /dev/null +++ b/src/Umbraco.Core/FileResources/Files.Designer.cs @@ -0,0 +1,86 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.0 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Umbraco.Core.FileResources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Files { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Files() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Umbraco.Core.FileResources.Files", typeof(Files).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to <?xml version="1.0"?> + /// + ///<!-- Blocks public downloading of anything in this folder and sub folders --> + /// + ///<configuration> + /// <system.web> + /// <httpHandlers> + /// <add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/> + /// </httpHandlers> + /// </system.web> + /// <system.webServer> + /// <validation validateIntegratedModeConfiguration="false" /> + /// <handlers> + /// <remove name="BlockViewHandler"/> + /// <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.H [rest of string was truncated]";. + /// + internal static string BlockingWebConfig { + get { + return ResourceManager.GetString("BlockingWebConfig", resourceCulture); + } + } + } +} diff --git a/src/Umbraco.Core/FileResources/Files.resx b/src/Umbraco.Core/FileResources/Files.resx new file mode 100644 index 0000000000..823aacefb7 --- /dev/null +++ b/src/Umbraco.Core/FileResources/Files.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + blockingweb.config;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + \ No newline at end of file diff --git a/src/Umbraco.Core/IO/IOHelper.cs b/src/Umbraco.Core/IO/IOHelper.cs index dc5e278970..161296baff 100644 --- a/src/Umbraco.Core/IO/IOHelper.cs +++ b/src/Umbraco.Core/IO/IOHelper.cs @@ -6,6 +6,7 @@ using System.IO; using System.Configuration; using System.Web; using System.Text.RegularExpressions; +using System.Web.Hosting; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; @@ -67,7 +68,7 @@ namespace Umbraco.Core.IO if (tag.Groups[1].Success) url = tag.Groups[1].Value; - if (string.IsNullOrEmpty(url) == false) + if (String.IsNullOrEmpty(url) == false) { string resolvedUrl = (url.Substring(0, 1) == "/") ? ResolveUrl(url.Substring(1)) : ResolveUrl(url); text = text.Replace(url, resolvedUrl); @@ -92,10 +93,10 @@ namespace Umbraco.Core.IO if (useHttpContext && HttpContext.Current != null) { //string retval; - if (string.IsNullOrEmpty(path) == false && (path.StartsWith("~") || path.StartsWith(SystemDirectories.Root))) - return System.Web.Hosting.HostingEnvironment.MapPath(path); + if (String.IsNullOrEmpty(path) == false && (path.StartsWith("~") || path.StartsWith(SystemDirectories.Root))) + return HostingEnvironment.MapPath(path); else - return System.Web.Hosting.HostingEnvironment.MapPath("~/" + path.TrimStart('/')); + return HostingEnvironment.MapPath("~/" + path.TrimStart('/')); } var root = GetRootDirectorySafe(); @@ -115,7 +116,7 @@ namespace Umbraco.Core.IO { string retval = ConfigurationManager.AppSettings[settingsKey]; - if (string.IsNullOrEmpty(retval)) + if (String.IsNullOrEmpty(retval)) retval = standardPath; return retval.TrimEnd('/'); @@ -232,7 +233,7 @@ namespace Umbraco.Core.IO /// internal static string GetRootDirectorySafe() { - if (string.IsNullOrEmpty(_rootDir) == false) + if (String.IsNullOrEmpty(_rootDir) == false) { return _rootDir; } @@ -241,7 +242,7 @@ namespace Umbraco.Core.IO var uri = new Uri(codeBase); var path = uri.LocalPath; var baseDirectory = Path.GetDirectoryName(path); - if (string.IsNullOrEmpty(baseDirectory)) + if (String.IsNullOrEmpty(baseDirectory)) throw new Exception("No root directory could be resolved. Please ensure that your Umbraco solution is correctly configured."); _rootDir = baseDirectory.Contains("bin") @@ -253,8 +254,8 @@ namespace Umbraco.Core.IO internal static string GetRootDirectoryBinFolder() { - string binFolder = string.Empty; - if (string.IsNullOrEmpty(_rootDir)) + string binFolder = String.Empty; + if (String.IsNullOrEmpty(_rootDir)) { binFolder = Assembly.GetExecutingAssembly().GetAssemblyFile().Directory.FullName; return binFolder; @@ -298,5 +299,25 @@ namespace Umbraco.Core.IO // use string extensions return filePath.ToSafeFileName(); } + + public static void EnsurePathExists(string path) + { + var absolutePath = IOHelper.MapPath(path); + if (Directory.Exists(absolutePath) == false) + Directory.CreateDirectory(absolutePath); + } + + public static void EnsureFileExists(string path, string contents) + { + var absolutePath = IOHelper.MapPath(path); + if (File.Exists(absolutePath) == false) + { + using (var writer = File.CreateText(absolutePath)) + { + writer.Write(contents); + } + } + + } } } diff --git a/src/Umbraco.Core/Manifest/ManifestParser.cs b/src/Umbraco.Core/Manifest/ManifestParser.cs index aeb4da888c..571c916123 100644 --- a/src/Umbraco.Core/Manifest/ManifestParser.cs +++ b/src/Umbraco.Core/Manifest/ManifestParser.cs @@ -96,11 +96,15 @@ namespace Umbraco.Core.Manifest if (depth < 1) { - var dirs = currDir.GetDirectories(); var result = new List(); - foreach (var d in dirs) + if (currDir.Exists) { - result.AddRange(GetAllManifestFileContents(d)); + var dirs = currDir.GetDirectories(); + + foreach (var d in dirs) + { + result.AddRange(GetAllManifestFileContents(d)); + } } return result; } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 9256e00a2c..438ad349a5 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -328,6 +328,11 @@ + + True + True + Files.resx + @@ -1347,6 +1352,7 @@ + @@ -1358,7 +1364,12 @@ - + + + ResXFileCodeGenerator + Files.Designer.cs + + diff --git a/src/Umbraco.Web.UI/App_Start/Test.cs b/src/Umbraco.Web.UI/App_Start/Test.cs new file mode 100644 index 0000000000..d70f18eb9b --- /dev/null +++ b/src/Umbraco.Web.UI/App_Start/Test.cs @@ -0,0 +1,272 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading.Tasks; +using System.Web; +using Microsoft.Owin; +using Microsoft.Owin.Security.Google; +using Microsoft.Owin.Security.OpenIdConnect; +using Owin; +using Umbraco.Core; +using Umbraco.Core.Security; +using Umbraco.Web.Security.Identity; +using Umbraco.Web.UI.App_Start; + +[assembly: OwinStartup("UmbracoStandardOwinStartup2", typeof(UmbracoStandardOwinStartup2))] + +namespace Umbraco.Web.UI.App_Start +{ + /// + /// A custom way to configure OWIN for Umbraco + /// + /// + /// The startup type is specified in appSettings under owin:appStartup - change it to "CustomUmbracoStartup" to use this class + /// + /// This startup class would allow you to customize the Identity IUserStore and/or IUserManager for the Umbraco Backoffice + /// + public class UmbracoCustomOwinStartup + { + public void Configuration(IAppBuilder app) + { + //Configure the Identity user manager and user store for use with Umbraco Back office + + // *** EXPERT: overloads of this method allow you to specify a custom UserStore or even a custom UserManager! + // *** If you plan to implement your own custom 2 factor auth, you will need a custom implementation of: + // *** BackOfficeUserManager & BackOfficeUserStore. Your custom BackOfficeUserManager will need to override/implement: + // *** - SupportsUserTwoFactor to return true + // *** - Umbraco.Web.Security.Identity.IUmbracoBackOfficeTwoFactorOptions + // *** The result view returned from IUmbracoBackOfficeTwoFactorOptions.GetTwoFactorView will be the angular + // *** view displayed to the user to enter the 2 factor authentication code. You will need to create/implement + // *** the custom angular view and all logic to handle the REST call to verify the code and log the user in + // *** based on the username provided on the $scope of your view. + // *** Your custom BackOfficeUserStore will need to override/implement: + // *** - Microsoft.AspNet.Identity.IUserTwoFactorStore + + app.ConfigureUserManagerForUmbracoBackOffice( + ApplicationContext.Current, + global::Umbraco.Core.Security.MembershipProviderExtensions.GetUsersMembershipProvider().AsUmbracoMembershipProvider()); + + //Ensure owin is configured for Umbraco back office authentication + app + .UseUmbracoBackOfficeCookieAuthentication(ApplicationContext.Current) + .UseUmbracoBackOfficeExternalCookieAuthentication(ApplicationContext.Current); + /* + * Configure external logins for the back office: + * + * Depending on the authentication sources you would like to enable, you will need to install + * certain Nuget packages. + * + * For Google auth: Install-Package UmbracoCms.IdentityExtensions.Google + * For Facebook auth: Install-Package UmbracoCms.IdentityExtensions.Facebook + * For Microsoft auth: Install-Package UmbracoCms.IdentityExtensions.Microsoft + * For Azure ActiveDirectory auth: Install-Package UmbracoCms.IdentityExtensions.AzureActiveDirectory + * + * There are many more providers such as Twitter, Yahoo, ActiveDirectory, etc... most information can + * be found here: http://www.asp.net/web-api/overview/security/external-authentication-services + * + * For sample code on using external providers with the Umbraco back office, install one of the + * packages listed above to review it's code samples + * + */ + /* + * To configure a simple auth token server for the back office: + * + * By default the CORS policy is to allow all requests + * + * app.UseUmbracoBackOfficeTokenAuth(new BackOfficeAuthServerProviderOptions()); + * + * If you want to have a custom CORS policy for the token server you can provide + * a custom CORS policy, example: + * + * app.UseUmbracoBackOfficeTokenAuth( + * new BackOfficeAuthServerProviderOptions() + * { + * //Modify the CorsPolicy as required + * CorsPolicy = new CorsPolicy() + * { + * AllowAnyHeader = true, + * AllowAnyMethod = true, + * Origins = { "http://mywebsite.com" } + * } + * }); + */ + } + } + + /// + /// The standard way to configure OWIN for Umbraco + /// + /// + /// The startup type is specified in appSettings under owin:appStartup - change it to "StandardUmbracoStartup" to use this class + /// + public class UmbracoStandardOwinStartup2 : UmbracoDefaultOwinStartup + { + public override void Configuration(IAppBuilder app) + { + //ensure the default options are configured + base.Configuration(app); + + // + app.ConfigureBackOfficeGoogleAuth( + "1072120697051-p41pro11srud3o3n90j7m00geq426jqt.apps.googleusercontent.com", + "cs_LJTXh2rtI01C5OIt9WFkt"); + + /* + * Configure external logins for the back office: + * + * Depending on the authentication sources you would like to enable, you will need to install + * certain Nuget packages. + * + * For Google auth: Install-Package UmbracoCms.IdentityExtensions.Google + * For Facebook auth: Install-Package UmbracoCms.IdentityExtensions.Facebook + * For Microsoft auth: Install-Package UmbracoCms.IdentityExtensions.Microsoft + * For Azure ActiveDirectory auth: Install-Package UmbracoCms.IdentityExtensions.AzureActiveDirectory + * + * There are many more providers such as Twitter, Yahoo, ActiveDirectory, etc... most information can + * be found here: http://www.asp.net/web-api/overview/security/external-authentication-services + * + * For sample code on using external providers with the Umbraco back office, install one of the + * packages listed above to review it's code samples + * + */ + + /* + * To configure a simple auth token server for the back office: + * + * By default the CORS policy is to allow all requests + * + * app.UseUmbracoBackOfficeTokenAuth(new BackOfficeAuthServerProviderOptions()); + * + * If you want to have a custom CORS policy for the token server you can provide + * a custom CORS policy, example: + * + * app.UseUmbracoBackOfficeTokenAuth( + * new BackOfficeAuthServerProviderOptions() + * { + * //Modify the CorsPolicy as required + * CorsPolicy = new CorsPolicy() + * { + * AllowAnyHeader = true, + * AllowAnyMethod = true, + * Origins = { "http://mywebsite.com" } + * } + * }); + */ + + } + } + + public static class UmbracoGoogleAuthExtensions + { + /// + /// Configure google sign-in + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Nuget installation: + /// Microsoft.Owin.Security.Google + /// + /// Google account documentation for ASP.Net Identity can be found: + /// + /// http://www.asp.net/web-api/overview/security/external-authentication-services#GOOGLE + /// + /// Google apps can be created here: + /// + /// https://developers.google.com/accounts/docs/OpenIDConnect#getcredentials + /// + /// + public static void ConfigureBackOfficeGoogleAuth(this IAppBuilder app, string clientId, string clientSecret, + string caption = "Google", string style = "btn-google-plus", string icon = "fa-google-plus") + { + var googleOptions = new GoogleOAuth2AuthenticationOptions() + { + ClientId = clientId, + ClientSecret = clientSecret, + //In order to allow using different google providers on the front-end vs the back office, + // these settings are very important to make them distinguished from one another. + SignInAsAuthenticationType = global::Umbraco.Core.Constants.Security.BackOfficeExternalAuthenticationType, + // By default this is '/signin-google', you will need to change that default value in your + // Google developer settings for your web-app in the "REDIRECT URIS" setting + CallbackPath = new PathString("/umbraco-google-signin") + }; + + googleOptions.SetExternalSignInAutoLinkOptions( + new ExternalSignInAutoLinkOptions( + autoLinkExternalAccount: true)); + + googleOptions.ForUmbracoBackOffice(style, icon); + googleOptions.Caption = caption; + app.UseGoogleAuthentication(googleOptions); + } + + /// + /// Configure ActiveDirectory sign-in + /// + /// + /// + /// + /// + /// The URL that will be redirected to after login is successful, example: http://mydomain.com/umbraco/; + /// + /// + /// + /// This is the "Issuer Id" for you Azure AD application. This a GUID value and can be found + /// in the Azure portal when viewing your configured application and clicking on 'View endpoints' + /// which will list all of the API endpoints. Each endpoint will contain a GUID value, this is + /// the Issuer Id which must be used for this value. + /// + /// If this value is not set correctly then accounts won't be able to be detected + /// for un-linking in the back office. + /// + /// + /// + /// + /// + /// + /// ActiveDirectory account documentation for ASP.Net Identity can be found: + /// https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet + /// + public static void ConfigureBackOfficeAzureActiveDirectoryAuth(this IAppBuilder app, + string tenant, string clientId, string postLoginRedirectUri, Guid issuerId, + string caption = "Active Directory", string style = "btn-microsoft", string icon = "fa-windows") + { + var authority = string.Format( + CultureInfo.InvariantCulture, + "https://login.windows.net/{0}", + tenant); + + var adOptions = new OpenIdConnectAuthenticationOptions + { + SignInAsAuthenticationType = global::Umbraco.Core.Constants.Security.BackOfficeExternalAuthenticationType, + ClientId = clientId, + Authority = authority, + Notifications = new OpenIdConnectAuthenticationNotifications + { + RedirectToIdentityProvider = notification => + { + return Task.FromResult(0); + } + } + }; + + adOptions.SetExternalSignInAutoLinkOptions(new ExternalSignInAutoLinkOptions()); + + adOptions.ForUmbracoBackOffice(style, icon); + adOptions.Caption = caption; + //Need to set the auth tyep as the issuer path + adOptions.AuthenticationType = string.Format( + CultureInfo.InvariantCulture, + "https://sts.windows.net/{0}/", + issuerId); + app.UseOpenIdConnectAuthentication(adOptions); + } + + } +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index f15f60e9d8..eb182080e6 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -2386,7 +2386,6 @@ - diff --git a/src/Umbraco.Web.UI/umbraco/developer/Macros/EditMacro.aspx.cs b/src/Umbraco.Web.UI/umbraco/developer/Macros/EditMacro.aspx.cs index 033e8389e6..92a071d858 100644 --- a/src/Umbraco.Web.UI/umbraco/developer/Macros/EditMacro.aspx.cs +++ b/src/Umbraco.Web.UI/umbraco/developer/Macros/EditMacro.aspx.cs @@ -68,21 +68,23 @@ namespace Umbraco.Web.UI.Umbraco.Developer.Macros //get all the partials in the normal /MacroPartials folder var foundMacroPartials = GetPartialViewFiles(partialsDir, partialsDir, SystemDirectories.MvcViews + "/MacroPartials"); //now try to find all of them int he App_Plugins/[PackageName]/Views/MacroPartials folder - var partialPluginsDir = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.AppPlugins)); - foreach(var d in partialPluginsDir.GetDirectories()) - { - var viewsFolder = d.GetDirectories("Views"); - if (viewsFolder.Any()) - { - var macroPartials = viewsFolder.First().GetDirectories("MacroPartials"); - if (macroPartials.Any()) - { - foundMacroPartials = foundMacroPartials.Concat( - GetPartialViewFiles(macroPartials.First().FullName, macroPartials.First().FullName, SystemDirectories.AppPlugins + "/" + d.Name + "/Views/MacroPartials")); - } - } - } - + var appPluginsFolder = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.AppPlugins)); + if (appPluginsFolder.Exists) + { + foreach (var d in appPluginsFolder.GetDirectories()) + { + var viewsFolder = d.GetDirectories("Views"); + if (viewsFolder.Any()) + { + var macroPartials = viewsFolder.First().GetDirectories("MacroPartials"); + if (macroPartials.Any()) + { + foundMacroPartials = foundMacroPartials.Concat( + GetPartialViewFiles(macroPartials.First().FullName, macroPartials.First().FullName, SystemDirectories.AppPlugins + "/" + d.Name + "/Views/MacroPartials")); + } + } + } + } PartialViewList.DataSource = foundMacroPartials; diff --git a/src/Umbraco.Web/Install/FilePermissionHelper.cs b/src/Umbraco.Web/Install/FilePermissionHelper.cs index b5bc908fde..e9835e0f32 100644 --- a/src/Umbraco.Web/Install/FilePermissionHelper.cs +++ b/src/Umbraco.Web/Install/FilePermissionHelper.cs @@ -42,8 +42,10 @@ namespace Umbraco.Web.Install { errorReport = new List(); bool succes = true; - foreach (string dir in PermissionDirs) + foreach (string dir in directories) { + if (Directory.Exists(dir) == false) continue; + bool result = SaveAndDeleteFile(IOHelper.MapPath(dir + "/configWizardPermissionTest.txt")); if (result == false) diff --git a/src/Umbraco.Web/umbraco.presentation/EnsureSystemPathsApplicationStartupHandler.cs b/src/Umbraco.Web/umbraco.presentation/EnsureSystemPathsApplicationStartupHandler.cs index dc354be71d..00ec43229a 100644 --- a/src/Umbraco.Web/umbraco.presentation/EnsureSystemPathsApplicationStartupHandler.cs +++ b/src/Umbraco.Web/umbraco.presentation/EnsureSystemPathsApplicationStartupHandler.cs @@ -16,25 +16,11 @@ namespace umbraco.presentation { base.ApplicationInitialized(umbracoApplication, applicationContext); - EnsurePathExists("~/App_Code"); - EnsurePathExists("~/App_Data"); - EnsurePathExists(SystemDirectories.AppPlugins); - EnsurePathExists(SystemDirectories.Css); - EnsurePathExists(SystemDirectories.Masterpages); - EnsurePathExists(SystemDirectories.Media); - EnsurePathExists(SystemDirectories.Scripts); - EnsurePathExists(SystemDirectories.UserControls); - EnsurePathExists(SystemDirectories.Xslt); - EnsurePathExists(SystemDirectories.MvcViews); - EnsurePathExists(SystemDirectories.MvcViews + "/Partials"); - EnsurePathExists(SystemDirectories.MvcViews + "/MacroPartials"); - } - - public void EnsurePathExists(string path) - { - var absolutePath = IOHelper.MapPath(path); - if (!Directory.Exists(absolutePath)) - Directory.CreateDirectory(absolutePath); + IOHelper.EnsurePathExists("~/App_Data"); + IOHelper.EnsurePathExists(SystemDirectories.Media); + IOHelper.EnsurePathExists(SystemDirectories.MvcViews); + IOHelper.EnsurePathExists(SystemDirectories.MvcViews + "/Partials"); + IOHelper.EnsurePathExists(SystemDirectories.MvcViews + "/MacroPartials"); } } } \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadTemplates.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadTemplates.cs index 0b8644aa43..bf7c04bb27 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadTemplates.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadTemplates.cs @@ -87,7 +87,7 @@ namespace umbraco private void RenderTemplateFolderItems(string folder, string folderPath, ref XmlTree tree) { string relPath = SystemDirectories.Masterpages + "/" + folder; - if (!string.IsNullOrEmpty(folderPath)) + if (string.IsNullOrEmpty(folderPath) == false) relPath += folderPath; string fullPath = IOHelper.MapPath(relPath); @@ -160,26 +160,31 @@ namespace umbraco { if (base.m_id == -1) { - foreach (string s in Directory.GetDirectories(IOHelper.MapPath(SystemDirectories.Masterpages))) + var dir = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.Masterpages)); + if (dir.Exists) { - var _s = Path.GetFileNameWithoutExtension(s); - - XmlTreeNode xNode = XmlTreeNode.Create(this); - xNode.NodeID = _s; - xNode.Text = _s; - xNode.Icon = "icon-folder"; - xNode.OpenIcon = "icon-folder"; - xNode.Source = GetTreeServiceUrl(_s) + "&folder=" + _s; - xNode.HasChildren = true; - xNode.Menu.Clear(); - xNode.Menu.Add(ActionRefresh.Instance); - - OnBeforeNodeRender(ref tree, ref xNode, EventArgs.Empty); - if (xNode != null) + foreach (var s in dir.GetDirectories()) { - tree.Add(xNode); - OnAfterNodeRender(ref tree, ref xNode, EventArgs.Empty); + var _s = Path.GetFileNameWithoutExtension(s.FullName); + + XmlTreeNode xNode = XmlTreeNode.Create(this); + xNode.NodeID = _s; + xNode.Text = _s; + xNode.Icon = "icon-folder"; + xNode.OpenIcon = "icon-folder"; + xNode.Source = GetTreeServiceUrl(_s) + "&folder=" + _s; + xNode.HasChildren = true; + xNode.Menu.Clear(); + xNode.Menu.Add(ActionRefresh.Instance); + + OnBeforeNodeRender(ref tree, ref xNode, EventArgs.Empty); + if (xNode != null) + { + tree.Add(xNode); + OnAfterNodeRender(ref tree, ref xNode, EventArgs.Empty); + } } + } } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/create/XsltTasks.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/create/XsltTasks.cs index 7a9b777c83..6c6174c0bb 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/create/XsltTasks.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/create/XsltTasks.cs @@ -1,5 +1,6 @@ using System; using System.Data; +using System.IO; using System.Web.Security; using Umbraco.Core; using Umbraco.Core.IO; @@ -9,6 +10,7 @@ using umbraco.BusinessLogic; using umbraco.DataLayer; using umbraco.BasePages; using umbraco.cms.businesslogic.member; +using Umbraco.Core.FileResources; namespace umbraco { @@ -22,14 +24,17 @@ namespace umbraco public override bool PerformSave() { + IOHelper.EnsurePathExists(SystemDirectories.Xslt); + IOHelper.EnsureFileExists(Path.Combine(IOHelper.MapPath(SystemDirectories.Xslt), "web.config"), Files.BlockingWebConfig); + var template = Alias.Substring(0, Alias.IndexOf("|||")); var fileName = Alias.Substring(Alias.IndexOf("|||") + 3, Alias.Length - Alias.IndexOf("|||") - 3).Replace(" ", ""); - if (!fileName.ToLowerInvariant().EndsWith(".xslt")) + if (fileName.ToLowerInvariant().EndsWith(".xslt") == false) fileName += ".xslt"; var xsltTemplateSource = IOHelper.MapPath(SystemDirectories.Umbraco + "/xslt/templates/" + template); var xsltNewFilename = IOHelper.MapPath(SystemDirectories.Xslt + "/" + fileName); - if (!System.IO.File.Exists(xsltNewFilename)) + if (File.Exists(xsltNewFilename) == false) { if (fileName.Contains("/")) //if there's a / create the folder structure for it { diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs index 9dde8ec59f..f8d15004da 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs @@ -130,6 +130,8 @@ namespace umbraco.cms.presentation.developer { var dirInfo = new DirectoryInfo(path); + if (dirInfo.Exists == false) return; + // Populate subdirectories var dirInfos = dirInfo.GetDirectories(); foreach (var dir in dirInfos) @@ -269,6 +271,7 @@ namespace umbraco.cms.presentation.developer private void PopulateUserControls(string path) { var directoryInfo = new DirectoryInfo(path); + if (directoryInfo.Exists == false) return; var rootDir = IOHelper.MapPath(SystemDirectories.UserControls); diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/codeEditorSave.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/codeEditorSave.asmx.cs index 08217ad106..65fbf2537b 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/codeEditorSave.asmx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/codeEditorSave.asmx.cs @@ -62,6 +62,7 @@ namespace umbraco.presentation.webservices { if (AuthorizeRequest(DefaultApps.developer.ToString())) { + IOHelper.EnsurePathExists(SystemDirectories.Xslt); // validate file IOHelper.ValidateEditPath(IOHelper.MapPath(SystemDirectories.Xslt + "/" + fileName), @@ -69,8 +70,7 @@ namespace umbraco.presentation.webservices // validate extension IOHelper.ValidateFileExtension(IOHelper.MapPath(SystemDirectories.Xslt + "/" + fileName), new List() { "xsl", "xslt" }); - - + StreamWriter SW; string tempFileName = IOHelper.MapPath(SystemDirectories.Xslt + "/" + DateTime.Now.Ticks + "_temp.xslt"); SW = File.CreateText(tempFileName); @@ -392,7 +392,10 @@ namespace umbraco.presentation.webservices if (File.Exists(saveOldPath)) File.Delete(saveOldPath); } - + + //ensure the folder exists before saving + Directory.CreateDirectory(Path.GetDirectoryName(savePath)); + using (var sw = File.CreateText(savePath)) { sw.Write(val); 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 3ec59bd378..c3382138fa 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx.cs @@ -276,7 +276,9 @@ namespace umbraco.presentation.webservices } private string SaveXslt(string fileName, string fileContents, bool ignoreDebugging) - { + { + IOHelper.EnsurePathExists(SystemDirectories.Xslt); + var tempFileName = IOHelper.MapPath(SystemDirectories.Xslt + "/" + System.DateTime.Now.Ticks + "_temp.xslt"); using (var sw = File.CreateText(tempFileName)) { @@ -412,6 +414,9 @@ namespace umbraco.presentation.webservices //Directory check.. only allow files in script dir and below to be edited if (savePath.StartsWith(IOHelper.MapPath(SystemDirectories.Scripts + "/"))) { + //ensure the folder exists before saving + Directory.CreateDirectory(Path.GetDirectoryName(savePath)); + using (var sw = File.CreateText(IOHelper.MapPath(SystemDirectories.Scripts + "/" + filename))) { sw.Write(val); diff --git a/src/umbraco.editorControls/userControlWrapper/usercontrolPrevalueEditor.cs b/src/umbraco.editorControls/userControlWrapper/usercontrolPrevalueEditor.cs index 5760168776..555407b875 100644 --- a/src/umbraco.editorControls/userControlWrapper/usercontrolPrevalueEditor.cs +++ b/src/umbraco.editorControls/userControlWrapper/usercontrolPrevalueEditor.cs @@ -77,6 +77,7 @@ namespace umbraco.editorControls.userControlGrapper private void populateUserControls(string path) { DirectoryInfo di = new DirectoryInfo(path); + if (di.Exists == false) return; foreach (FileInfo uc in di.GetFiles("*.ascx")) {