diff --git a/src/Umbraco.Core/DatabaseContext.cs b/src/Umbraco.Core/DatabaseContext.cs index ed9b7c5a9d..2f0efcbfc0 100644 --- a/src/Umbraco.Core/DatabaseContext.cs +++ b/src/Umbraco.Core/DatabaseContext.cs @@ -112,7 +112,7 @@ namespace Umbraco.Core public void ConfigureEmbeddedDatabaseConnection() { const string providerName = "System.Data.SqlServerCe.4.0"; - const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf"; + const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;File Access Retry Timeout=10"; SaveConnectionString(connectionString, providerName); diff --git a/src/Umbraco.Core/NetworkHelper.cs b/src/Umbraco.Core/NetworkHelper.cs new file mode 100644 index 0000000000..d69c4a963c --- /dev/null +++ b/src/Umbraco.Core/NetworkHelper.cs @@ -0,0 +1,50 @@ +using System; + +namespace Umbraco.Core +{ + /// + /// Currently just used to get the machine name in med trust and to format a machine name for use with file names + /// + internal class NetworkHelper + { + /// + /// Returns the machine name that is safe to use in file paths. + /// + /// + /// see: https://github.com/Shandem/ClientDependency/issues/4 + /// + public static string FileSafeMachineName + { + get { return MachineName.ReplaceNonAlphanumericChars('-'); } + } + + /// + /// Returns the current machine name + /// + /// + /// Tries to resolve the machine name, if it cannot it uses the config section. + /// + public static string MachineName + { + get + { + try + { + return Environment.MachineName; + } + catch + { + try + { + return System.Net.Dns.GetHostName(); + } + catch + { + //if we get here it means we cannot access the machine name + throw new ApplicationException("Cannot resolve the current machine name eithe by Environment.MachineName or by Dns.GetHostname()"); + } + } + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/PluginManager.cs b/src/Umbraco.Core/PluginManager.cs index 960b0df16a..840bb733f1 100644 --- a/src/Umbraco.Core/PluginManager.cs +++ b/src/Umbraco.Core/PluginManager.cs @@ -20,7 +20,6 @@ using File = System.IO.File; namespace Umbraco.Core { - /// /// Used to resolve all plugin types and cache them and is also used to instantiate plugin types /// @@ -37,6 +36,7 @@ namespace Umbraco.Core internal class PluginManager { private readonly ApplicationContext _appContext; + private const string CacheKey = "umbraco-plugins.list"; /// /// Creates a new PluginManager with an ApplicationContext instance which ensures that the plugin xml @@ -251,7 +251,7 @@ namespace Umbraco.Core XDocument xml; if (_appContext != null) { - xml = _appContext.ApplicationCache.GetCacheItem("umbraco-plugins.list", + xml = _appContext.ApplicationCache.GetCacheItem(CacheKey, new TimeSpan(0, 0, 5, 0), () => XDocument.Load(filePath)); } @@ -304,18 +304,18 @@ namespace Umbraco.Core if (_appContext != null) { - _appContext.ApplicationCache.ClearCacheItem("umbraco-plugins.list"); + _appContext.ApplicationCache.ClearCacheItem(CacheKey); } } - + private string GetPluginListFilePath() { - return Path.Combine(_tempFolder, "umbraco-plugins.list"); + return Path.Combine(_tempFolder, string.Format("umbraco-plugins.{0}.list", NetworkHelper.FileSafeMachineName)); } private string GetPluginHashFilePath() { - return Path.Combine(_tempFolder, "umbraco-plugins.hash"); + return Path.Combine(_tempFolder, string.Format("umbraco-plugins.{0}.hash", NetworkHelper.FileSafeMachineName)); } /// diff --git a/src/Umbraco.Core/Services/UserService.cs b/src/Umbraco.Core/Services/UserService.cs index 577365cd62..448a1f46e9 100644 --- a/src/Umbraco.Core/Services/UserService.cs +++ b/src/Umbraco.Core/Services/UserService.cs @@ -44,13 +44,13 @@ namespace Umbraco.Core.Services public IProfile GetProfileById(int id) { var user = GetUserById(id); - return new Profile(user.Id, user.Username); + return new Profile(user.Id, user.Name); } public IProfile GetProfileByUserName(string username) { var user = GetUserByUserName(username); - return new Profile(user.Id, user.Username); + return new Profile(user.Id, user.Name); } public IUser GetUserByUserName(string username) diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs index d8394e6fd3..b2fa0368ab 100644 --- a/src/Umbraco.Core/StringExtensions.cs +++ b/src/Umbraco.Core/StringExtensions.cs @@ -28,6 +28,17 @@ namespace Umbraco.Core [UmbracoWillObsolete("Do not use this constants. See IShortStringHelper.CleanStringForSafeAliasJavaScriptCode.")] public const string UmbracoInvalidFirstCharacters = "01234567890"; + internal static string ReplaceNonAlphanumericChars(this string input, char replacement) + { + //any character that is not alphanumeric, convert to a hyphen + var mName = input; + foreach (var c in mName.ToCharArray().Where(c => !char.IsLetterOrDigit(c))) + { + mName = mName.Replace(c, replacement); + } + return mName; + } + public static string ExceptChars(this string str, HashSet toExclude) { var sb = new StringBuilder(str.Length); diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index cabf7e59e4..c76ddcf5e4 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -264,6 +264,7 @@ + diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index 9fe4b63ca8..e4df374cd3 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -17,7 +17,7 @@ - + diff --git a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs index a9b80f9b17..9f8a3be793 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs @@ -57,7 +57,7 @@ namespace Umbraco.Tests.Migrations.Upgrades public override UmbracoDatabase GetConfiguredDatabase() { - return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf", "System.Data.SqlServerCe.4.0"); + return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10", "System.Data.SqlServerCe.4.0"); } public override DatabaseProviders GetDatabaseProvider() diff --git a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs index e8a3ef1939..3dfc059358 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs @@ -63,7 +63,7 @@ namespace Umbraco.Tests.Migrations.Upgrades public override UmbracoDatabase GetConfiguredDatabase() { - return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf", "System.Data.SqlServerCe.4.0"); + return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10", "System.Data.SqlServerCe.4.0"); } public override DatabaseProviders GetDatabaseProvider() diff --git a/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs index 3dcc1a5308..1abb496fe9 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs @@ -100,7 +100,7 @@ namespace Umbraco.Tests.Migrations.Upgrades public UmbracoDatabase GetConfiguredDatabase() { - return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf", "System.Data.SqlServerCe.4.0"); + return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10", "System.Data.SqlServerCe.4.0"); } public string GetDatabaseSpecificSqlScript() diff --git a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs index 011f2826fa..15104530b0 100644 --- a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs +++ b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs @@ -69,7 +69,7 @@ namespace Umbraco.Tests.Persistence //Get the connectionstring settings from config var settings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName]; - //by default the conn string is: Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf + //by default the conn string is: Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10 //we'll just replace the sdf file with our custom one: //Create the Sql CE database var engine = new SqlCeEngine(settings.ConnectionString.Replace("UmbracoPetaPocoTests", "DatabaseContextTests")); diff --git a/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs b/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs index d47b5cac75..7147dea975 100644 --- a/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs +++ b/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs @@ -35,12 +35,12 @@ namespace Umbraco.Tests.Persistence } //Create the Sql CE database - var engine = new SqlCeEngine("Datasource=|DataDirectory|test.sdf"); + var engine = new SqlCeEngine("Datasource=|DataDirectory|test.sdf;Flush Interval=1;File Access Retry Timeout=10"); engine.CreateDatabase(); SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; - _database = new Database("Datasource=|DataDirectory|test.sdf", + _database = new Database("Datasource=|DataDirectory|test.sdf;Flush Interval=1;File Access Retry Timeout=10", "System.Data.SqlServerCe.4.0"); } diff --git a/src/Umbraco.Tests/PluginManagerTests.cs b/src/Umbraco.Tests/PluginManagerTests.cs index c38f6ac37c..4610839fcf 100644 --- a/src/Umbraco.Tests/PluginManagerTests.cs +++ b/src/Umbraco.Tests/PluginManagerTests.cs @@ -160,14 +160,15 @@ namespace Umbraco.Tests { var tempFolder = IOHelper.MapPath("~/App_Data/TEMP/PluginCache"); var manager = new PluginManager(false); - var filePath = Path.Combine(tempFolder, "umbraco-plugins.list"); + var filePath= Path.Combine(tempFolder, string.Format("umbraco-plugins.{0}.list", NetworkHelper.FileSafeMachineName)); + File.WriteAllText(filePath, @" "); - + Assert.IsTrue(manager.DetectLegacyPluginListFile()); File.Delete(filePath); diff --git a/src/Umbraco.Tests/PublishedCache/PublishedMediaCacheTests.cs b/src/Umbraco.Tests/PublishedCache/PublishedMediaCacheTests.cs index d795ebe18d..a1d922e86d 100644 --- a/src/Umbraco.Tests/PublishedCache/PublishedMediaCacheTests.cs +++ b/src/Umbraco.Tests/PublishedCache/PublishedMediaCacheTests.cs @@ -61,7 +61,7 @@ namespace Umbraco.Tests.PublishedCache Assert.AreEqual(mRoot.Id, publishedMedia.Id); Assert.AreEqual(mRoot.CreateDateTime.ToString("dd/MM/yyyy HH:mm:ss"), publishedMedia.CreateDate.ToString("dd/MM/yyyy HH:mm:ss")); Assert.AreEqual(mRoot.User.Id, publishedMedia.CreatorId); - Assert.AreEqual(mRoot.User.LoginName, publishedMedia.CreatorName); + Assert.AreEqual(mRoot.User.Name, publishedMedia.CreatorName); Assert.AreEqual(mRoot.ContentType.Alias, publishedMedia.DocumentTypeAlias); Assert.AreEqual(mRoot.ContentType.Id, publishedMedia.DocumentTypeId); Assert.AreEqual(mRoot.Level, publishedMedia.Level); diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs index 91581858ac..be846f10ee 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs @@ -111,7 +111,7 @@ namespace Umbraco.Tests.TestHelpers /// protected virtual string GetDbConnectionString() { - return @"Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf"; + return @"Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10"; } /// diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index ed5408b692..4903953a65 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -47,7 +47,7 @@ namespace Umbraco.Tests.TestHelpers /// public static void InitializeDatabase() { - ConfigurationManager.AppSettings.Set(Core.Configuration.GlobalSettings.UmbracoConnectionName, @"datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\UmbracoPetaPocoTests.sdf"); + ConfigurationManager.AppSettings.Set(Core.Configuration.GlobalSettings.UmbracoConnectionName, @"datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10"); ClearDatabase(); diff --git a/src/Umbraco.Web/HtmlHelperRenderExtensions.cs b/src/Umbraco.Web/HtmlHelperRenderExtensions.cs index ecccd126a0..79d6ec3f7c 100644 --- a/src/Umbraco.Web/HtmlHelperRenderExtensions.cs +++ b/src/Umbraco.Web/HtmlHelperRenderExtensions.cs @@ -466,7 +466,7 @@ namespace Umbraco.Web Mandate.ParameterNotNullOrEmpty(action, "action"); Mandate.ParameterNotNullOrEmpty(controllerName, "controllerName"); - var formAction = UmbracoContext.Current.OriginalRequestUrl.ToString(); + var formAction = UmbracoContext.Current.OriginalRequestUrl.PathAndQuery; return html.RenderForm(formAction, FormMethod.Post, htmlAttributes, controllerName, action, area, additionalRouteVals); } diff --git a/src/Umbraco.Web/Mvc/UmbracoTemplatePage.cs b/src/Umbraco.Web/Mvc/UmbracoTemplatePage.cs index 9eba36e21a..231c6e12b2 100644 --- a/src/Umbraco.Web/Mvc/UmbracoTemplatePage.cs +++ b/src/Umbraco.Web/Mvc/UmbracoTemplatePage.cs @@ -71,46 +71,5 @@ namespace Umbraco.Web.Mvc : new UmbracoHelper(UmbracoContext, Model.Content)); } } - - /// - /// This will detect the end /body tag and insert the preview badge if in preview mode - /// - /// - public override void WriteLiteral(object value) - { - // filter / add preview banner - if (Response.ContentType.InvariantEquals("text/html")) // ASP.NET default value - { - - if (UmbracoContext.Current.IsDebug || UmbracoContext.Current.InPreviewMode) - { - var text = value.ToString().ToLowerInvariant(); - int pos = text.IndexOf(""); - if (pos > -1) - { - if (UmbracoContext.Current.InPreviewMode) - { - var htmlBadge = - String.Format(UmbracoSettings.PreviewBadge, - IOHelper.ResolveUrl(SystemDirectories.Umbraco), - IOHelper.ResolveUrl(SystemDirectories.UmbracoClient), - Server.UrlEncode(UmbracoContext.Current.HttpContext.Request.Path)); - - text = text.Substring(0, pos) + htmlBadge + text.Substring(pos, text.Length - pos); - } - else - { - var profilerMarkup = this.Html.RenderProfiler(); - text = text.Substring(0, pos) + profilerMarkup + text.Substring(pos, text.Length - pos); - } - base.WriteLiteral(text); - return; - } - } - } - - base.WriteLiteral(value); - } - } } \ No newline at end of file diff --git a/src/Umbraco.Web/Mvc/UmbracoViewPage.cs b/src/Umbraco.Web/Mvc/UmbracoViewPage.cs index ba936ee9ee..fa22cf419b 100644 --- a/src/Umbraco.Web/Mvc/UmbracoViewPage.cs +++ b/src/Umbraco.Web/Mvc/UmbracoViewPage.cs @@ -1,5 +1,9 @@ +using System; +using System.Text; using System.Web.Mvc; using Umbraco.Core; +using Umbraco.Core.Configuration; +using Umbraco.Core.IO; using Umbraco.Web.Routing; namespace Umbraco.Web.Mvc @@ -112,5 +116,49 @@ namespace Umbraco.Web.Mvc } + /// + /// This will detect the end /body tag and insert the preview badge if in preview mode + /// + /// + public override void WriteLiteral(object value) + { + // filter / add preview banner + if (Response.ContentType.InvariantEquals("text/html")) // ASP.NET default value + { + if (UmbracoContext.Current.IsDebug || UmbracoContext.Current.InPreviewMode) + { + var text = value.ToString().ToLowerInvariant(); + var pos = text.IndexOf("", StringComparison.InvariantCultureIgnoreCase); + + if (pos > -1) + { + string markupToInject; + + if (UmbracoContext.Current.InPreviewMode) + { + // creating previewBadge markup + markupToInject = + String.Format(UmbracoSettings.PreviewBadge, + IOHelper.ResolveUrl(SystemDirectories.Umbraco), + IOHelper.ResolveUrl(SystemDirectories.UmbracoClient), + Server.UrlEncode(UmbracoContext.Current.HttpContext.Request.Path)); + } + else + { + // creating mini-profiler markup + markupToInject = Html.RenderProfiler().ToHtmlString(); + } + + var sb = new StringBuilder(text); + sb.Insert(pos, markupToInject); + + base.WriteLiteral(sb.ToString()); + return; + } + } + } + + base.WriteLiteral(value); + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Routing/PublishedContentNotFoundHandler.cs b/src/Umbraco.Web/Routing/PublishedContentNotFoundHandler.cs index 83db913b44..df5584ce11 100644 --- a/src/Umbraco.Web/Routing/PublishedContentNotFoundHandler.cs +++ b/src/Umbraco.Web/Routing/PublishedContentNotFoundHandler.cs @@ -37,7 +37,7 @@ namespace Umbraco.Web.Routing response.Write("

Page not found

"); response.Write("

"); - response.Write(string.Format(reason, HttpUtility.HtmlEncode(UmbracoContext.Current.OriginalRequestUrl))); + response.Write(string.Format(reason, HttpUtility.HtmlEncode(UmbracoContext.Current.OriginalRequestUrl.PathAndQuery))); response.Write("

"); if (!string.IsNullOrWhiteSpace(_message)) response.Write("

" + _message + "

"); diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/moveOrCopy.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/moveOrCopy.aspx.cs index e27fd53785..ccd6c6481d 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/moveOrCopy.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/moveOrCopy.aspx.cs @@ -108,6 +108,7 @@ namespace umbraco.dialogs if (validAction == false) { + panel_buttons.Visible = false; ScriptManager.RegisterStartupScript(this, GetType(), "notvalid", "notValid();", true); } } @@ -121,21 +122,22 @@ namespace umbraco.dialogs return CheckPermissions(cmsNode, currentAction); } + /// + /// Checks if the current user has permissions to execute this action against this node + /// + /// + /// + /// + /// + /// This used to do a recursive check for all descendent nodes but this is not required and is a massive CPU hog. + /// See: http://issues.umbraco.org/issue/U4-2632, https://groups.google.com/forum/?fromgroups=#!topic/umbraco-dev/L1D4LwVSP2Y + /// private bool CheckPermissions(IContentBase node, IAction currentAction) { var currUserPermissions = new UserPermissions(CurrentUser); var lstCurrUserActions = currUserPermissions.GetExistingNodePermission(node.Id); - if (lstCurrUserActions.Contains(currentAction) == false) - return false; - - - if (Umbraco.Core.Models.ContentExtensions.HasChildren(node, Services)) - { - return Umbraco.Core.Models.ContentExtensions.Children(node, Services) - .All(child => CheckPermissions(child, currentAction)); - } - return true; + return lstCurrUserActions.Contains(currentAction); } private void HandleDocumentTypeCopy() diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs index 81b93b4a49..4dc72b7386 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs @@ -163,14 +163,15 @@ namespace umbraco.cms.presentation /// Maps active directory account to umbraco user account ///
/// Name of the login. + /// Email address of the user private void ActiveDirectoryMapping(string loginName, string email) { // Password is not copied over because it is stored in active directory for security! // The user is create with default access to content and as a writer user type if (BusinessLogic.User.getUserId(loginName) == -1) { - BusinessLogic.User.MakeNew(loginName, loginName, string.Empty, email, BusinessLogic.UserType.GetUserType(2)); - BusinessLogic.User u = new BusinessLogic.User(loginName); + BusinessLogic.User.MakeNew(loginName, loginName, string.Empty, email ?? "", UserType.GetUserType(2)); + var u = new User(loginName); u.addApplication(Constants.Applications.Content); } } diff --git a/src/umbraco.providers/members/MembersMembershipProvider.cs b/src/umbraco.providers/members/MembersMembershipProvider.cs index bab5a4b505..0572613d78 100644 --- a/src/umbraco.providers/members/MembersMembershipProvider.cs +++ b/src/umbraco.providers/members/MembersMembershipProvider.cs @@ -820,6 +820,7 @@ namespace umbraco.providers.members { UpdateMemberProperty(updateMemberDataObject, m_LockPropertyTypeAlias, true); } + updateMemberDataObject.Save(); } }