diff --git a/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs b/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs index f0f3ebffd0..d981855f24 100644 --- a/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs @@ -10,7 +10,7 @@ namespace Umbraco.Core.Models.Rdbms internal class PreviewXmlDto { [Column("nodeId")] - [PrimaryKeyColumn(AutoIncrement = false, Name = "", OnColumns = "nodeId, versionId")] + [PrimaryKeyColumn(AutoIncrement = false, Name = "PK_cmsContentPreviewXml", OnColumns = "nodeId, versionId")] [ForeignKey(typeof(ContentDto), Column = "nodeId")] public int NodeId { get; set; } diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs index b4117003fb..bb14bb67f3 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs @@ -69,7 +69,7 @@ namespace Umbraco.Core.Persistence.Migrations { ExecuteMigrations(schemaMigrationContext, database); } - catch (Exception) + catch (Exception ex) { //if this fails then the transaction will be rolled back, BUT if we are using MySql this is not the case, //since it does not support schema changes in a transaction, see: http://dev.mysql.com/doc/refman/5.0/en/implicit-commit.html @@ -77,11 +77,21 @@ namespace Umbraco.Core.Persistence.Migrations if (databaseProvider == DatabaseProviders.MySql) { - var downgrades = OrderedDowngradeMigrations(foundMigrations.Where(x => (x is SchemaMigration))).ToList(); - var downgradeMigrationContext = InitializeMigrations(downgrades, database, databaseProvider, false); - //lets hope that works! - if something cannot be rolled back then a CatastrophicDataLossException should - // be thrown. - ExecuteMigrations(downgradeMigrationContext, database); + try + { + var downgrades = OrderedDowngradeMigrations(foundMigrations.Where(x => (x is SchemaMigration))).ToList(); + var downgradeMigrationContext = InitializeMigrations(downgrades, database, databaseProvider, false); + //lets hope that works! - if something cannot be rolled back then a CatastrophicDataLossException should + // be thrown. + ExecuteMigrations(downgradeMigrationContext, database); + } + catch (Exception e) + { + throw new CatastrophicDataLossException( + "An error occurred running a schema migration but the changes could not be rolled back. Error: " + ex.Message + ". In some cases, it may be required that the database be restored to it's original state before running this upgrade process again.", + ex); + + } } //continue throwing the exception diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AssignMissingPrimaryForMySqlKeys.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AssignMissingPrimaryForMySqlKeys.cs new file mode 100644 index 0000000000..27c0dc91ba --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AssignMissingPrimaryForMySqlKeys.cs @@ -0,0 +1,97 @@ +using System.Linq; +using System.Web.UI; +using Umbraco.Core.Configuration; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero +{ + //see: http://issues.umbraco.org/issue/U4-4430 + [Migration("6.2.0", 3, GlobalSettings.UmbracoMigrationName)] + public class AssignMissingPrimaryForMySqlKeys : SchemaMigration + { + public override void Up() + { + if (Context.CurrentDatabaseProvider == DatabaseProviders.MySql) + { + var constraints = SqlSyntaxContext.SqlSyntaxProvider.GetConstraintsPerColumn(Context.Database).Distinct().ToArray(); + + //This should be 2 because this table has 2 keys + if (constraints.Count(x => x.Item1.InvariantEquals("cmsContentType2ContentType") && x.Item3.InvariantEquals("PRIMARY")) == 0) + { + Create.PrimaryKey("PK_cmsContentType2ContentType") + .OnTable("cmsContentType2ContentType") + .Columns(new[] {"parentContentTypeId", "childContentTypeId"}); + } + + //This should be 2 because this table has 2 keys + if (constraints.Count(x => x.Item1.InvariantEquals("cmsContentTypeAllowedContentType") && x.Item3.InvariantEquals("PRIMARY")) == 0) + { + Create.PrimaryKey("PK_cmsContentTypeAllowedContentType") + .OnTable("cmsContentTypeAllowedContentType") + .Columns(new[] { "Id", "AllowedId" }); + } + + //This should be 2 because this table has 2 keys + if (constraints.Count(x => x.Item1.InvariantEquals("cmsDocumentType") && x.Item3.InvariantEquals("PRIMARY")) == 0) + { + Create.PrimaryKey("PK_cmsDocumentType") + .OnTable("cmsDocumentType") + .Columns(new[] { "contentTypeNodeId", "templateNodeId" }); + } + + //This should be 2 because this table has 2 keys + if (constraints.Count(x => x.Item1.InvariantEquals("cmsMember2MemberGroup") && x.Item3.InvariantEquals("PRIMARY")) == 0) + { + Create.PrimaryKey("PK_cmsMember2MemberGroup") + .OnTable("cmsMember2MemberGroup") + .Columns(new[] { "Member", "MemberGroup" }); + } + + //This should be 2 because this table has 2 keys + if (constraints.Count(x => x.Item1.InvariantEquals("cmsPreviewXml") && x.Item3.InvariantEquals("PRIMARY")) == 0) + { + Create.PrimaryKey("PK_cmsContentPreviewXml") + .OnTable("cmsPreviewXml") + .Columns(new[] { "nodeId", "versionId" }); + } + + //This should be 2 because this table has 2 keys + if (constraints.Count(x => x.Item1.InvariantEquals("cmsTagRelationship") && x.Item3.InvariantEquals("PRIMARY")) == 0) + { + Create.PrimaryKey("PK_cmsTagRelationship") + .OnTable("cmsTagRelationship") + .Columns(new[] { "nodeId", "tagId" }); + } + + //This should be 2 because this table has 2 keys + if (constraints.Count(x => x.Item1.InvariantEquals("umbracoUser2app") && x.Item3.InvariantEquals("PRIMARY")) == 0) + { + Create.PrimaryKey("PK_user2app") + .OnTable("umbracoUser2app") + .Columns(new[] { "user", "app" }); + } + + //This should be 2 because this table has 3 keys + if (constraints.Count(x => x.Item1.InvariantEquals("umbracoUser2NodeNotify") && x.Item3.InvariantEquals("PRIMARY")) == 0) + { + Create.PrimaryKey("PK_umbracoUser2NodeNotify") + .OnTable("umbracoUser2NodeNotify") + .Columns(new[] { "userId", "nodeId", "action" }); + } + + //This should be 2 because this table has 3 keys + if (constraints.Count(x => x.Item1.InvariantEquals("umbracoUser2NodePermission") && x.Item3.InvariantEquals("PRIMARY")) == 0) + { + Create.PrimaryKey("PK_umbracoUser2NodePermission") + .OnTable("umbracoUser2NodePermission") + .Columns(new[] { "userId", "nodeId", "permission" }); + } + } + } + + public override void Down() + { + //don't do anything, these keys should have always existed! + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs index 7e8d7b7566..ba6f4dcc7e 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs @@ -218,7 +218,7 @@ ORDER BY TABLE_NAME, INDEX_NAME", { string primaryKey = string.Empty; var columnDefinition = table.Columns.FirstOrDefault(x => x.IsPrimaryKey); - if (columnDefinition != null && columnDefinition.PrimaryKeyColumns.Contains(",") == false) + if (columnDefinition != null) { string columns = string.IsNullOrEmpty(columnDefinition.PrimaryKeyColumns) ? GetQuotedColumnName(columnDefinition.Name) diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 4b17dd8e1d..c36feda1c9 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -359,6 +359,7 @@ + diff --git a/src/Umbraco.Tests/Persistence/SyntaxProvider/MySqlSyntaxProviderTests.cs b/src/Umbraco.Tests/Persistence/SyntaxProvider/MySqlSyntaxProviderTests.cs new file mode 100644 index 0000000000..00319c2ccc --- /dev/null +++ b/src/Umbraco.Tests/Persistence/SyntaxProvider/MySqlSyntaxProviderTests.cs @@ -0,0 +1,49 @@ +using System; +using NUnit.Framework; +using Umbraco.Core.Models.Rdbms; +using Umbraco.Core.Persistence.DatabaseModelDefinitions; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Tests.Persistence.SyntaxProvider +{ + [NUnit.Framework.Ignore("This doesn't actually test anything")] + [TestFixture] + public class MySqlSyntaxProviderTests + { + [SetUp] + public void SetUp() + { + SqlSyntaxContext.SqlSyntaxProvider = MySqlSyntax.Provider; + } + + [Test] + public void Can_Generate_Create_Table_Statement() + { + var type = typeof(TagRelationshipDto); + var definition = DefinitionFactory.GetTableDefinition(type); + + string create = SqlSyntaxContext.SqlSyntaxProvider.Format(definition); + string primaryKey = SqlSyntaxContext.SqlSyntaxProvider.FormatPrimaryKey(definition); + var indexes = SqlSyntaxContext.SqlSyntaxProvider.Format(definition.Indexes); + var keys = SqlSyntaxContext.SqlSyntaxProvider.Format(definition.ForeignKeys); + + Console.WriteLine(create); + Console.WriteLine(primaryKey); + foreach (var sql in keys) + { + Console.WriteLine(sql); + } + + foreach (var sql in indexes) + { + Console.WriteLine(sql); + } + } + + [TearDown] + public void TearDown() + { + SqlSyntaxContext.SqlSyntaxProvider = null; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlSyntaxProviderTests.cs b/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs similarity index 97% rename from src/Umbraco.Tests/Persistence/SyntaxProvider/SqlSyntaxProviderTests.cs rename to src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs index 7802ea6d58..4862333b07 100644 --- a/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlSyntaxProviderTests.cs +++ b/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs @@ -1,139 +1,140 @@ -using System; -using System.Collections.Generic; -using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Models.Rdbms; -using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.DatabaseAnnotations; -using Umbraco.Core.Persistence.DatabaseModelDefinitions; -using Umbraco.Core.Persistence.Migrations.Syntax.Create.Index; -using Umbraco.Core.Persistence.Migrations.Syntax.Expressions; -using Umbraco.Core.Persistence.SqlSyntax; - -namespace Umbraco.Tests.Persistence.SyntaxProvider -{ - [TestFixture] - public class SqlSyntaxProviderTests - { - [SetUp] - public void SetUp() - { - SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; - } - - [Test] - public void Can_Generate_Delete_SubQuery_Statement() - { - var mediaObjectType = Guid.Parse(Constants.ObjectTypes.Media); - var subQuery = new Sql() - .Select("DISTINCT cmsContentXml.nodeId") - .From() - .InnerJoin() - .On(left => left.NodeId, right => right.NodeId) - .Where(dto => dto.NodeObjectType == mediaObjectType); - - var sql = SqlSyntaxContext.SqlSyntaxProvider.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); - - Assert.AreEqual(@"DELETE FROM [cmsContentXml] WHERE [nodeId] IN (SELECT [nodeId] FROM (SELECT DISTINCT cmsContentXml.nodeId -FROM [cmsContentXml] -INNER JOIN [umbracoNode] -ON [cmsContentXml].[nodeId] = [umbracoNode].[id] -WHERE ([umbracoNode].[nodeObjectType] = 'b796f64c-1f99-4ffb-b886-4bf4bc011a9c')) x)".Replace(Environment.NewLine, " ").Replace("\n", " ").Replace("\r", " "), sql.Replace(Environment.NewLine, " ").Replace("\n", " ").Replace("\r", " ")); - } - - [Test] - public void Can_Generate_Create_Table_Statement() - { - var type = typeof (NodeDto); - var definition = DefinitionFactory.GetTableDefinition(type); - - string create = SqlSyntaxContext.SqlSyntaxProvider.Format(definition); - string primaryKey = SqlSyntaxContext.SqlSyntaxProvider.FormatPrimaryKey(definition); - var indexes = SqlSyntaxContext.SqlSyntaxProvider.Format(definition.Indexes); - var keys = SqlSyntaxContext.SqlSyntaxProvider.Format(definition.ForeignKeys); - - Console.WriteLine(create); - Console.WriteLine(primaryKey); - foreach (var sql in keys) - { - Console.WriteLine(sql); - } - - foreach (var sql in indexes) - { - Console.WriteLine(sql); - } - } - - [Test] - public void Format_SqlServer_NonClusteredIndexDefinition_AddsNonClusteredDirective() - { - SqlSyntaxContext.SqlSyntaxProvider = SqlServerSyntax.Provider; - - var indexDefinition = CreateIndexDefinition(); - indexDefinition.IndexType = IndexTypes.NonClustered; - - var actual = SqlSyntaxContext.SqlSyntaxProvider.Format(indexDefinition); - Assert.AreEqual("CREATE NONCLUSTERED INDEX [IX_A] ON [TheTable] ([A])", actual); - } - - [Test] - public void Format_SqlServer_NonClusteredIndexDefinition_UsingIsClusteredFalse_AddsClusteredDirective() - { - SqlSyntaxContext.SqlSyntaxProvider = SqlServerSyntax.Provider; - - var indexDefinition = CreateIndexDefinition(); - indexDefinition.IsClustered = false; - - var actual = SqlSyntaxContext.SqlSyntaxProvider.Format(indexDefinition); - Assert.AreEqual("CREATE CLUSTERED INDEX [IX_A] ON [TheTable] ([A])", actual); - } - - [Test] - public void CreateIndexBuilder_SqlServer_NonClustered_CreatesNonClusteredIndex() - { - SqlSyntaxContext.SqlSyntaxProvider = SqlServerSyntax.Provider; - var createExpression = new CreateIndexExpression { Index = { Name = "IX_A" } }; - var builder = new CreateIndexBuilder(createExpression); - builder.OnTable("TheTable").OnColumn("A").Ascending().WithOptions().NonClustered(); - Assert.AreEqual("CREATE NONCLUSTERED INDEX [IX_A] ON [TheTable] ([A])", createExpression.ToString()); - } - - [Test] - public void CreateIndexBuilder_SqlServer_Unique_CreatesUniqueNonClusteredIndex() - { - SqlSyntaxContext.SqlSyntaxProvider = SqlServerSyntax.Provider; - var createExpression = new CreateIndexExpression { Index = { Name = "IX_A" } }; - var builder = new CreateIndexBuilder(createExpression); - builder.OnTable("TheTable").OnColumn("A").Ascending().WithOptions().Unique(); - Assert.AreEqual("CREATE UNIQUE NONCLUSTERED INDEX [IX_A] ON [TheTable] ([A])", createExpression.ToString()); - } - - [Test] - public void CreateIndexBuilder_SqlServer_Clustered_CreatesClusteredIndex() - { - SqlSyntaxContext.SqlSyntaxProvider = SqlServerSyntax.Provider; - var createExpression = new CreateIndexExpression { Index = { Name = "IX_A" } }; - var builder = new CreateIndexBuilder(createExpression); - builder.OnTable("TheTable").OnColumn("A").Ascending().WithOptions().Clustered(); - Assert.AreEqual("CREATE CLUSTERED INDEX [IX_A] ON [TheTable] ([A])", createExpression.ToString()); - } - - private static IndexDefinition CreateIndexDefinition() - { - return new IndexDefinition - { - ColumnName = "A", - Name = "IX_A", - TableName = "TheTable", - SchemaName = "dbo" - }; - } - - [TearDown] - public void TearDown() - { - SqlSyntaxContext.SqlSyntaxProvider = null; - } - } +using System; +using System.Collections.Generic; +using NUnit.Framework; +using Umbraco.Core; +using Umbraco.Core.Models.Rdbms; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.DatabaseAnnotations; +using Umbraco.Core.Persistence.DatabaseModelDefinitions; +using Umbraco.Core.Persistence.Migrations.Syntax.Create.Index; +using Umbraco.Core.Persistence.Migrations.Syntax.Expressions; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Tests.Persistence.SyntaxProvider +{ + [TestFixture] + public class SqlCeSyntaxProviderTests + { + [SetUp] + public void SetUp() + { + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; + } + + [Test] + public void Can_Generate_Delete_SubQuery_Statement() + { + var mediaObjectType = Guid.Parse(Constants.ObjectTypes.Media); + var subQuery = new Sql() + .Select("DISTINCT cmsContentXml.nodeId") + .From() + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(dto => dto.NodeObjectType == mediaObjectType); + + var sql = SqlSyntaxContext.SqlSyntaxProvider.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); + + Assert.AreEqual(@"DELETE FROM [cmsContentXml] WHERE [nodeId] IN (SELECT [nodeId] FROM (SELECT DISTINCT cmsContentXml.nodeId +FROM [cmsContentXml] +INNER JOIN [umbracoNode] +ON [cmsContentXml].[nodeId] = [umbracoNode].[id] +WHERE ([umbracoNode].[nodeObjectType] = 'b796f64c-1f99-4ffb-b886-4bf4bc011a9c')) x)".Replace(Environment.NewLine, " ").Replace("\n", " ").Replace("\r", " "), sql.Replace(Environment.NewLine, " ").Replace("\n", " ").Replace("\r", " ")); + } + + [NUnit.Framework.Ignore("This doesn't actually test anything")] + [Test] + public void Can_Generate_Create_Table_Statement() + { + var type = typeof (NodeDto); + var definition = DefinitionFactory.GetTableDefinition(type); + + string create = SqlSyntaxContext.SqlSyntaxProvider.Format(definition); + string primaryKey = SqlSyntaxContext.SqlSyntaxProvider.FormatPrimaryKey(definition); + var indexes = SqlSyntaxContext.SqlSyntaxProvider.Format(definition.Indexes); + var keys = SqlSyntaxContext.SqlSyntaxProvider.Format(definition.ForeignKeys); + + Console.WriteLine(create); + Console.WriteLine(primaryKey); + foreach (var sql in keys) + { + Console.WriteLine(sql); + } + + foreach (var sql in indexes) + { + Console.WriteLine(sql); + } + } + + [Test] + public void Format_SqlServer_NonClusteredIndexDefinition_AddsNonClusteredDirective() + { + SqlSyntaxContext.SqlSyntaxProvider = SqlServerSyntax.Provider; + + var indexDefinition = CreateIndexDefinition(); + indexDefinition.IndexType = IndexTypes.NonClustered; + + var actual = SqlSyntaxContext.SqlSyntaxProvider.Format(indexDefinition); + Assert.AreEqual("CREATE NONCLUSTERED INDEX [IX_A] ON [TheTable] ([A])", actual); + } + + [Test] + public void Format_SqlServer_NonClusteredIndexDefinition_UsingIsClusteredFalse_AddsClusteredDirective() + { + SqlSyntaxContext.SqlSyntaxProvider = SqlServerSyntax.Provider; + + var indexDefinition = CreateIndexDefinition(); + indexDefinition.IsClustered = false; + + var actual = SqlSyntaxContext.SqlSyntaxProvider.Format(indexDefinition); + Assert.AreEqual("CREATE CLUSTERED INDEX [IX_A] ON [TheTable] ([A])", actual); + } + + [Test] + public void CreateIndexBuilder_SqlServer_NonClustered_CreatesNonClusteredIndex() + { + SqlSyntaxContext.SqlSyntaxProvider = SqlServerSyntax.Provider; + var createExpression = new CreateIndexExpression { Index = { Name = "IX_A" } }; + var builder = new CreateIndexBuilder(createExpression); + builder.OnTable("TheTable").OnColumn("A").Ascending().WithOptions().NonClustered(); + Assert.AreEqual("CREATE NONCLUSTERED INDEX [IX_A] ON [TheTable] ([A])", createExpression.ToString()); + } + + [Test] + public void CreateIndexBuilder_SqlServer_Unique_CreatesUniqueNonClusteredIndex() + { + SqlSyntaxContext.SqlSyntaxProvider = SqlServerSyntax.Provider; + var createExpression = new CreateIndexExpression { Index = { Name = "IX_A" } }; + var builder = new CreateIndexBuilder(createExpression); + builder.OnTable("TheTable").OnColumn("A").Ascending().WithOptions().Unique(); + Assert.AreEqual("CREATE UNIQUE NONCLUSTERED INDEX [IX_A] ON [TheTable] ([A])", createExpression.ToString()); + } + + [Test] + public void CreateIndexBuilder_SqlServer_Clustered_CreatesClusteredIndex() + { + SqlSyntaxContext.SqlSyntaxProvider = SqlServerSyntax.Provider; + var createExpression = new CreateIndexExpression { Index = { Name = "IX_A" } }; + var builder = new CreateIndexBuilder(createExpression); + builder.OnTable("TheTable").OnColumn("A").Ascending().WithOptions().Clustered(); + Assert.AreEqual("CREATE CLUSTERED INDEX [IX_A] ON [TheTable] ([A])", createExpression.ToString()); + } + + private static IndexDefinition CreateIndexDefinition() + { + return new IndexDefinition + { + ColumnName = "A", + Name = "IX_A", + TableName = "TheTable", + SchemaName = "dbo" + }; + } + + [TearDown] + public void TearDown() + { + SqlSyntaxContext.SqlSyntaxProvider = null; + } + } } \ No newline at end of file diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 427b83d740..b837fec9d7 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -279,6 +279,7 @@ + @@ -342,7 +343,7 @@ - + diff --git a/src/Umbraco.Web/Security/Providers/UsersMembershipProvider.cs b/src/Umbraco.Web/Security/Providers/UsersMembershipProvider.cs index b61272bc8c..d1ec03c97d 100644 --- a/src/Umbraco.Web/Security/Providers/UsersMembershipProvider.cs +++ b/src/Umbraco.Web/Security/Providers/UsersMembershipProvider.cs @@ -15,22 +15,22 @@ namespace Umbraco.Web.Security.Providers /// public class UsersMembershipProvider : UmbracoMembershipProvider, IUsersMembershipProvider { - + public UsersMembershipProvider() : this(ApplicationContext.Current.Services.UserService) - { + { } public UsersMembershipProvider(IMembershipMemberService memberService) : base(memberService) - { + { } private string _defaultMemberTypeAlias = "writer"; private volatile bool _hasDefaultMember = false; private static readonly object Locker = new object(); - public override string ProviderName + public override string ProviderName { get { return Constants.Conventions.User.UmbracoUsersProviderName; } } @@ -46,7 +46,7 @@ namespace Umbraco.Web.Security.Providers protected override MembershipUser ConvertToMembershipUser(IUser entity) { //the provider user key is always the int id - return entity.AsConcreteMembershipUser(Name); + return entity.AsConcreteMembershipUser(Name); } public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config) @@ -62,8 +62,8 @@ namespace Umbraco.Web.Security.Providers throw new ProviderException("No default user type alias is specified in the web.config string. Please add a 'defaultUserTypeAlias' to the add element in the provider declaration in web.config"); } _hasDefaultMember = true; - } - } + } + } public override string DefaultMemberTypeAlias { @@ -81,9 +81,9 @@ namespace Umbraco.Web.Security.Providers throw new ProviderException("No default user type alias is specified in the web.config string. Please add a 'defaultUserTypeAlias' to the add element in the provider declaration in web.config"); } _hasDefaultMember = true; - } + } } - } + } return _defaultMemberTypeAlias; } } diff --git a/src/umbraco.providers/members/UmbracoMembershipProvider.cs b/src/umbraco.providers/members/UmbracoMembershipProvider.cs index 039610d495..855af0a32f 100644 --- a/src/umbraco.providers/members/UmbracoMembershipProvider.cs +++ b/src/umbraco.providers/members/UmbracoMembershipProvider.cs @@ -49,7 +49,9 @@ namespace umbraco.providers.members #region Fields private string _defaultMemberTypeAlias = "Member"; - private string _providerName = Member.UmbracoMemberProviderName; + private string _providerName = Member.UmbracoMemberProviderName; + private volatile bool _hasDefaultMember = false; + private static readonly object Locker = new object(); #endregion @@ -119,11 +121,14 @@ namespace umbraco.providers.members // test for membertype (if not specified, choose the first member type available) if (config["defaultMemberTypeAlias"] != null) + { _defaultMemberTypeAlias = config["defaultMemberTypeAlias"]; - else if (MemberType.GetAll.Length == 1) - _defaultMemberTypeAlias = MemberType.GetAll[0].Alias; - else - throw new ProviderException("No default MemberType alias is specified in the web.config string. Please add a 'defaultMemberTypeAlias' to the add element in the provider declaration in web.config"); + if (_defaultMemberTypeAlias.IsNullOrWhiteSpace()) + { + throw new ProviderException("No default user type alias is specified in the web.config string. Please add a 'defaultUserTypeAlias' to the add element in the provider declaration in web.config"); + } + _hasDefaultMember = true; + } // test for approve status if (config["umbracoApprovePropertyTypeAlias"] != null) @@ -234,7 +239,26 @@ namespace umbraco.providers.members public override string DefaultMemberTypeAlias { - get { return _defaultMemberTypeAlias; } + get + { + if (_hasDefaultMember == false) + { + lock (Locker) + { + if (_hasDefaultMember == false) + { + var types = MemberType.GetAll; + if (types.Length == 1) + _defaultMemberTypeAlias = types[0].Alias; + else + throw new ProviderException("No default MemberType alias is specified in the web.config string. Please add a 'defaultMemberTypeAlias' to the add element in the provider declaration in web.config"); + + _hasDefaultMember = true; + } + } + } + return _defaultMemberTypeAlias; + } } /// diff --git a/src/umbraco.providers/members/UmbracoRoleProvider.cs b/src/umbraco.providers/members/UmbracoRoleProvider.cs index bfb8863ed0..f87f960a79 100644 --- a/src/umbraco.providers/members/UmbracoRoleProvider.cs +++ b/src/umbraco.providers/members/UmbracoRoleProvider.cs @@ -14,13 +14,13 @@ using umbraco.cms.businesslogic.member; using System.Collections; #endregion -namespace umbraco.providers.members +namespace umbraco.providers.members { /// /// A role provider for members /// [Obsolete("This has been superceded by Umbraco.Web.Security.Providers.MembersRoleProvider")] - public class UmbracoRoleProvider : RoleProvider + public class UmbracoRoleProvider : RoleProvider { #region @@ -33,11 +33,14 @@ namespace umbraco.providers.members /// /// /// The name of the application to store and retrieve role information for. - public override string ApplicationName { - get { + public override string ApplicationName + { + get + { return _applicationName; } - set { + set + { if (string.IsNullOrEmpty(value)) throw new ProviderException("ApplicationName cannot be empty."); @@ -60,13 +63,15 @@ namespace umbraco.providers.members /// on a provider /// after the provider has already been initialized. /// The name of the provider has a length of zero. - public override void Initialize(string name, NameValueCollection config) { + public override void Initialize(string name, NameValueCollection config) + { // Initialize values from web.config if (config == null) throw new ArgumentNullException("config"); if (name == null || name.Length == 0) name = "UmbracoMemberRoleProvider"; - if (String.IsNullOrEmpty(config["description"])) { + if (String.IsNullOrEmpty(config["description"])) + { config.Remove("description"); config.Add("description", "Umbraco Member Role provider"); } @@ -86,15 +91,20 @@ namespace umbraco.providers.members /// /// A string array of user names to be added to the specified roles. /// A string array of the role names to add the specified user names to. - public override void AddUsersToRoles(string[] usernames, string[] roleNames) { + public override void AddUsersToRoles(string[] usernames, string[] roleNames) + { ArrayList roles = new ArrayList(); foreach (string role in roleNames) - try { + try + { roles.Add(MemberGroup.GetByName(role).Id); - } catch { + } + catch + { throw new ProviderException(String.Format("No role with name '{0}' exists", role)); } - foreach (string username in usernames) { + foreach (string username in usernames) + { Member m = Member.GetMemberFromLoginName(username); foreach (int roleId in roles) m.AddGroup(roleId); @@ -105,7 +115,8 @@ namespace umbraco.providers.members /// Adds a new role to the data source for the configured applicationName. /// /// The name of the role to create. - public override void CreateRole(string roleName) { + public override void CreateRole(string roleName) + { MemberGroup.MakeNew(roleName, User.GetUser(0)); } @@ -117,13 +128,15 @@ namespace umbraco.providers.members /// /// true if the role was successfully deleted; otherwise, false. /// - public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) { + public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) + { MemberGroup group = MemberGroup.GetByName(roleName); if (group == null) throw new ProviderException(String.Format("No role with name '{0}' exists", roleName)); else if (throwOnPopulatedRole && group.GetMembersAsIds().Length > 0) throw new ProviderException(String.Format("Can't delete role '{0}', there are members assigned to the role", roleName)); - else { + else + { foreach (Member m in group.GetMembers()) m.RemoveGroup(group.Id); group.delete(); @@ -139,12 +152,14 @@ namespace umbraco.providers.members /// /// A string array containing the names of all the users where the user name matches usernameToMatch and the user is a member of the specified role. /// - public override string[] FindUsersInRole(string roleName, string usernameToMatch) { + public override string[] FindUsersInRole(string roleName, string usernameToMatch) + { ArrayList members = new ArrayList(); MemberGroup group = MemberGroup.GetByName(roleName); if (group == null) throw new ProviderException(String.Format("No role with name '{0}' exists", roleName)); - else { + else + { foreach (Member m in group.GetMembers(usernameToMatch)) members.Add(m.LoginName); return (string[])members.ToArray(typeof(string)); @@ -157,7 +172,8 @@ namespace umbraco.providers.members /// /// A string array containing the names of all the roles stored in the data source for the configured applicationName. /// - public override string[] GetAllRoles() { + public override string[] GetAllRoles() + { ArrayList roles = new ArrayList(); foreach (MemberGroup mg in MemberGroup.GetAll) roles.Add(mg.Text); @@ -171,15 +187,18 @@ namespace umbraco.providers.members /// /// A string array containing the names of all the roles that the specified user is in for the configured applicationName. /// - public override string[] GetRolesForUser(string username) { + public override string[] GetRolesForUser(string username) + { ArrayList roles = new ArrayList(); Member m = Member.GetMemberFromLoginName(username); - if (m != null) { + if (m != null) + { IDictionaryEnumerator ide = m.Groups.GetEnumerator(); while (ide.MoveNext()) roles.Add(((MemberGroup)ide.Value).Text); return (string[])roles.ToArray(typeof(string)); - } else + } + else throw new ProviderException(String.Format("No member with username '{0}' exists", username)); } @@ -190,12 +209,14 @@ namespace umbraco.providers.members /// /// A string array containing the names of all the users who are members of the specified role for the configured applicationName. /// - public override string[] GetUsersInRole(string roleName) { + public override string[] GetUsersInRole(string roleName) + { ArrayList members = new ArrayList(); MemberGroup group = MemberGroup.GetByName(roleName); if (group == null) throw new ProviderException(String.Format("No role with name '{0}' exists", roleName)); - else { + else + { foreach (Member m in group.GetMembers()) members.Add(m.LoginName); return (string[])members.ToArray(typeof(string)); @@ -210,11 +231,13 @@ namespace umbraco.providers.members /// /// true if the specified user is in the specified role for the configured applicationName; otherwise, false. /// - public override bool IsUserInRole(string username, string roleName) { + public override bool IsUserInRole(string username, string roleName) + { Member m = Member.GetMemberFromLoginName(username); if (m == null) throw new ProviderException(String.Format("No user with name '{0}' exists", username)); - else { + else + { MemberGroup mg = MemberGroup.GetByName(roleName); if (mg == null) throw new ProviderException(String.Format("No Membergroup with name '{0}' exists", roleName)); @@ -228,15 +251,20 @@ namespace umbraco.providers.members /// /// A string array of user names to be removed from the specified roles. /// A string array of role names to remove the specified user names from. - public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) { + public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) + { ArrayList roles = new ArrayList(); foreach (string role in roleNames) - try { + try + { roles.Add(MemberGroup.GetByName(role).Id); - } catch { + } + catch + { throw new ProviderException(String.Format("No role with name '{0}' exists", role)); } - foreach (string username in usernames) { + foreach (string username in usernames) + { Member m = Member.GetMemberFromLoginName(username); foreach (int roleId in roles) m.RemoveGroup(roleId); @@ -250,9 +278,10 @@ namespace umbraco.providers.members /// /// true if the role name already exists in the data source for the configured applicationName; otherwise, false. /// - public override bool RoleExists(string roleName) { - MemberGroup mg = MemberGroup.GetByName(roleName); - return mg != null; + public override bool RoleExists(string roleName) + { + MemberGroup mg = MemberGroup.GetByName(roleName); + return mg != null; } #endregion