From b5329ace3bb22223249bf58bea2de716dd253e78 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 14 Mar 2014 18:38:57 +1100 Subject: [PATCH] Backports fixes for legacy encoding checks and to not do any db lookups for the new membership providers and also ensures the legacy membership provider doesn't do any db lookups on init. --- .../Configuration/GlobalSettings.cs | 29 +++--- .../Providers/MembersMembershipProvider.cs | 29 ++++-- .../Providers/UsersMembershipProvider.cs | 43 ++++++--- .../members/UmbracoMembershipProvider.cs | 36 ++++++-- .../members/UmbracoRoleProvider.cs | 91 ++++++++++++------- 5 files changed, 156 insertions(+), 72 deletions(-) diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs index 028d745a0e..8911f6c130 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs @@ -5,11 +5,13 @@ using System.Linq; using System.Web; using System.Web.Configuration; using System.Web.Routing; +using System.Web.Security; using System.Xml; using System.Xml.Linq; using System.Xml.XPath; using Umbraco.Core.IO; using Umbraco.Core.Logging; +using Umbraco.Core.Security; namespace Umbraco.Core.Configuration { @@ -265,7 +267,7 @@ namespace Umbraco.Core.Configuration { get { - return ConfiguredMembershipProvidersLegacyEncoding(Constants.Conventions.Member.UmbracoMemberProviderName); + return IsConfiguredMembershipProviderUsingLegacyEncoding(Constants.Conventions.Member.UmbracoMemberProviderName); } set { @@ -281,7 +283,7 @@ namespace Umbraco.Core.Configuration { get { - return ConfiguredMembershipProvidersLegacyEncoding(Constants.Conventions.User.UmbracoUsersProviderName); + return IsConfiguredMembershipProviderUsingLegacyEncoding(Constants.Conventions.Member.UmbracoMemberProviderName); } set { @@ -366,22 +368,17 @@ namespace Umbraco.Core.Configuration webConfigXml.Save(webConfigFilename, SaveOptions.DisableFormatting); } - - private static bool ConfiguredMembershipProvidersLegacyEncoding(string providerName) + + private static bool IsConfiguredMembershipProviderUsingLegacyEncoding(string providerName) { - var webConfigFilename = GetFullWebConfigFileName(); - var webConfigXml = XDocument.Load(webConfigFilename, LoadOptions.PreserveWhitespace); + //check if this can even be configured. + var membershipProvider = Membership.Providers[providerName] as MembershipProviderBase; + if (membershipProvider == null) + { + return false; + } - var membershipConfigs = webConfigXml.XPathSelectElements("configuration/system.web/membership/providers/add").ToList(); - - var provider = membershipConfigs.SingleOrDefault(c => c.Attribute("name") != null && c.Attribute("name").Value == providerName); - - var useLegacyEncodingAttribute = provider.Attribute("useLegacyEncoding"); - - bool useLegacyEncoding; - bool.TryParse(useLegacyEncodingAttribute.Value, out useLegacyEncoding); - - return useLegacyEncoding; + return membershipProvider.UseLegacyEncoding; } /// diff --git a/src/Umbraco.Web/Security/Providers/MembersMembershipProvider.cs b/src/Umbraco.Web/Security/Providers/MembersMembershipProvider.cs index 1dc88b4b51..4ad0836a12 100644 --- a/src/Umbraco.Web/Security/Providers/MembersMembershipProvider.cs +++ b/src/Umbraco.Web/Security/Providers/MembersMembershipProvider.cs @@ -40,6 +40,8 @@ namespace Umbraco.Web.Security.Providers } private string _defaultMemberTypeAlias = "Member"; + private volatile bool _hasDefaultMember = false; + private static readonly object Locker = new object(); public override string ProviderName { @@ -77,20 +79,35 @@ namespace Umbraco.Web.Security.Providers if (config["defaultMemberTypeAlias"] != null) { _defaultMemberTypeAlias = config["defaultMemberTypeAlias"]; - } - else - { - _defaultMemberTypeAlias = MemberService.GetDefaultMemberType(); if (_defaultMemberTypeAlias.IsNullOrWhiteSpace()) { - 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"); + 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 { - get { return _defaultMemberTypeAlias; } + get + { + if (_hasDefaultMember == false) + { + lock (Locker) + { + if (_hasDefaultMember == false) + { + _defaultMemberTypeAlias = MemberService.GetDefaultMemberType(); + 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; + } + } + } + return _defaultMemberTypeAlias; + } } } } diff --git a/src/Umbraco.Web/Security/Providers/UsersMembershipProvider.cs b/src/Umbraco.Web/Security/Providers/UsersMembershipProvider.cs index ba2c127877..d1ec03c97d 100644 --- a/src/Umbraco.Web/Security/Providers/UsersMembershipProvider.cs +++ b/src/Umbraco.Web/Security/Providers/UsersMembershipProvider.cs @@ -15,20 +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; } } @@ -44,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) @@ -55,20 +57,35 @@ namespace Umbraco.Web.Security.Providers if (config["defaultUserTypeAlias"] != null) { _defaultMemberTypeAlias = config["defaultUserTypeAlias"]; - } - else - { - var defaultFromService = MemberService.GetDefaultMemberType(); - if (defaultFromService.IsNullOrWhiteSpace()) + 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; + } + } public override string DefaultMemberTypeAlias { - get { return _defaultMemberTypeAlias; } + get + { + if (_hasDefaultMember == false) + { + lock (Locker) + { + if (_hasDefaultMember == false) + { + _defaultMemberTypeAlias = MemberService.GetDefaultMemberType(); + 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; + } + } + } + return _defaultMemberTypeAlias; + } } } } \ No newline at end of file diff --git a/src/umbraco.providers/members/UmbracoMembershipProvider.cs b/src/umbraco.providers/members/UmbracoMembershipProvider.cs index dc094fd15b..cd6a80d340 100644 --- a/src/umbraco.providers/members/UmbracoMembershipProvider.cs +++ b/src/umbraco.providers/members/UmbracoMembershipProvider.cs @@ -48,7 +48,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 @@ -118,11 +120,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) @@ -233,7 +238,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