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"))
{