diff --git a/src/Umbraco.Core/Cache/CacheKeys.cs b/src/Umbraco.Core/Cache/CacheKeys.cs index 57922d36af..0adab2b896 100644 --- a/src/Umbraco.Core/Cache/CacheKeys.cs +++ b/src/Umbraco.Core/Cache/CacheKeys.cs @@ -14,7 +14,8 @@ namespace Umbraco.Core.Cache public const string MacroHtmlDateAddedCacheKey = "macroHtml_DateAdded_"; public const string MacroControlDateAddedCacheKey = "macroControl_DateAdded_"; - public const string MemberCacheKey = "UL_GetMember"; + public const string MemberLibraryCacheKey = "UL_GetMember"; + public const string MemberBusinessLogicCacheKey = "MemberCacheItem_"; public const string TemplateFrontEndCacheKey = "template"; public const string TemplateBusinessLogicCacheKey = "UmbracoTemplateCache"; diff --git a/src/Umbraco.Core/CacheHelper.cs b/src/Umbraco.Core/CacheHelper.cs index 8943d27a22..4f032a278a 100644 --- a/src/Umbraco.Core/CacheHelper.cs +++ b/src/Umbraco.Core/CacheHelper.cs @@ -140,6 +140,16 @@ namespace Umbraco.Core } } + public IEnumerable GetCacheItemsByKeySearch(string keyStartsWith) + { + return (from DictionaryEntry c in _cache + where c.Key is string && ((string) c.Key).InvariantStartsWith(keyStartsWith) + select c.Value.TryConvertTo() + into attempt + where attempt.Success + select attempt.Result).ToList(); + } + /// /// Returns a cache item by key, does not update the cache if it isn't there. /// diff --git a/src/Umbraco.Web/Cache/MemberCacheRefresher.cs b/src/Umbraco.Web/Cache/MemberCacheRefresher.cs index 9bc6fe6418..efd795b8db 100644 --- a/src/Umbraco.Web/Cache/MemberCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/MemberCacheRefresher.cs @@ -45,7 +45,9 @@ namespace Umbraco.Web.Cache private void ClearCache(int id) { ApplicationContext.Current.ApplicationCache. - ClearCacheByKeySearch(string.Format("{0}_{1}", CacheKeys.MemberCacheKey, id)); + ClearCacheByKeySearch(string.Format("{0}_{1}", CacheKeys.MemberLibraryCacheKey, id)); + ApplicationContext.Current.ApplicationCache. + ClearCacheByKeySearch(string.Format("{0}{1}", CacheKeys.MemberBusinessLogicCacheKey, id)); } } } \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/library.cs b/src/Umbraco.Web/umbraco.presentation/library.cs index 05be52da1d..4e2a9a093e 100644 --- a/src/Umbraco.Web/umbraco.presentation/library.cs +++ b/src/Umbraco.Web/umbraco.presentation/library.cs @@ -516,7 +516,7 @@ namespace umbraco { var retVal = ApplicationContext.Current.ApplicationCache.GetCacheItem( string.Format( - "{0}_{1}", CacheKeys.MemberCacheKey, MemberId), + "{0}_{1}", CacheKeys.MemberLibraryCacheKey, MemberId), TimeSpan.FromSeconds(UmbracoSettings.UmbracoLibraryCacheDuration), () => getMemberDo(MemberId)); diff --git a/src/umbraco.cms/businesslogic/cache/Cache.cs b/src/umbraco.cms/businesslogic/cache/Cache.cs index dd424bad88..fb53436a40 100644 --- a/src/umbraco.cms/businesslogic/cache/Cache.cs +++ b/src/umbraco.cms/businesslogic/cache/Cache.cs @@ -67,6 +67,7 @@ namespace umbraco.cms.businesslogic.cache /// Retrieve all cached items /// /// A hastable containing all cacheitems + [Obsolete("This method should not be used, use other methods to return specific cached items")] public static System.Collections.Hashtable ReturnCacheItemsOrdred() { System.Collections.Hashtable ht = new System.Collections.Hashtable(); diff --git a/src/umbraco.cms/businesslogic/member/Member.cs b/src/umbraco.cms/businesslogic/member/Member.cs index 6a739382ff..fb65233c69 100644 --- a/src/umbraco.cms/businesslogic/member/Member.cs +++ b/src/umbraco.cms/businesslogic/member/Member.cs @@ -7,6 +7,7 @@ using System.Runtime.CompilerServices; using System.Web; using System.Xml; using Umbraco.Core; +using Umbraco.Core.Cache; using Umbraco.Core.Models.Rdbms; using umbraco.cms.businesslogic.cache; using umbraco.BusinessLogic; @@ -91,7 +92,6 @@ namespace umbraco.cms.businesslogic.member /// /// Note: is ressource intensive, use with care. /// - [Obsolete("Use System.Web.Security.Membership.GetAllUsers()")] public static Member[] GetAll { get @@ -146,13 +146,11 @@ namespace umbraco.cms.businesslogic.member /// /// The first letter /// - [Obsolete("Use System.Web.Security.Membership.FindUsersByName(string letter)")] public static Member[] getMemberFromFirstLetter(char letter) { return GetMemberByName(letter.ToString(), true); } - [Obsolete("Use System.Web.Security.Membership.FindUsersByName(string letter)")] public static Member[] GetMemberByName(string usernameToMatch, bool matchByNameInsteadOfLogin) { string field = matchByNameInsteadOfLogin ? "umbracoNode.text" : "cmsMember.loginName"; @@ -184,7 +182,6 @@ namespace umbraco.cms.businesslogic.member /// Member type /// The umbraco usercontext /// The new member - [Obsolete("Use System.Web.Security.Membership.CreateUser")] public static Member MakeNew(string Name, MemberType mbt, User u) { return MakeNew(Name, "", "", mbt, u); @@ -199,7 +196,6 @@ namespace umbraco.cms.businesslogic.member /// The umbraco usercontext /// The email of the user /// The new member - [Obsolete("Use System.Web.Security.Membership.CreateUser")] public static Member MakeNew(string Name, string Email, MemberType mbt, User u) { return MakeNew(Name, "", Email, mbt, u); @@ -213,7 +209,6 @@ namespace umbraco.cms.businesslogic.member /// The umbraco usercontext /// The email of the user /// The new member - [Obsolete("Use System.Web.Security.Membership.CreateUser")] public static Member MakeNew(string Name, string LoginName, string Email, MemberType mbt, User u) { var loginName = (!String.IsNullOrEmpty(LoginName)) ? LoginName : Name; @@ -265,7 +260,6 @@ namespace umbraco.cms.businesslogic.member /// /// The unique Loginname /// The member with the specified loginname - null if no Member with the login exists - [Obsolete("Use System.Web.Security.Membership.GetUser")] public static Member GetMemberFromLoginName(string loginName) { if (String.IsNullOrEmpty(loginName)) @@ -298,7 +292,6 @@ namespace umbraco.cms.businesslogic.member /// /// The email of the member /// The member with the specified email - null if no Member with the email exists - [Obsolete("Use System.Web.Security.Membership.GetUserNameByEmail")] public static Member GetMemberFromEmail(string email) { if (string.IsNullOrEmpty(email)) @@ -503,13 +496,12 @@ namespace umbraco.cms.businesslogic.member /// /// A list of groups the member are member of /// - [Obsolete("Use System.Web.Security.Roles.GetRolesForUser()")] public Hashtable Groups { get { if (m_Groups == null) - populateGroups(); + PopulateGroups(); return m_Groups; } } @@ -669,7 +661,6 @@ namespace umbraco.cms.businesslogic.member /// /// Deltes the current member /// - [Obsolete("Use System.Web.Security.Membership.DeleteUser")] public override void delete() { DeleteEventArgs e = new DeleteEventArgs(); @@ -677,9 +668,6 @@ namespace umbraco.cms.businesslogic.member if (!e.Cancel) { - // Remove from cache (if exists) - Cache.ClearCacheItem(GetCacheKey(Id)); - // delete all relations to groups foreach (int groupId in this.Groups.Keys) { @@ -713,7 +701,6 @@ namespace umbraco.cms.businesslogic.member /// /// The id of the group which the member is being added to [MethodImpl(MethodImplOptions.Synchronized)] - [Obsolete("Use System.Web.Security.Roles.AddUserToRole")] public void AddGroup(int GroupId) { AddGroupEventArgs e = new AddGroupEventArgs(); @@ -729,7 +716,7 @@ namespace umbraco.cms.businesslogic.member if (!exists) SqlHelper.ExecuteNonQuery("INSERT INTO cmsMember2MemberGroup (member, memberGroup) values (@id, @groupId)", parameters); - populateGroups(); + PopulateGroups(); FireAfterAddGroup(e); } @@ -739,7 +726,6 @@ namespace umbraco.cms.businesslogic.member /// Removes the member from the MemberGroup specified /// /// The MemberGroup from which the Member is removed - [Obsolete("Use System.Web.Security.Roles.RemoveUserFromRole")] public void RemoveGroup(int GroupId) { RemoveGroupEventArgs e = new RemoveGroupEventArgs(); @@ -751,7 +737,7 @@ namespace umbraco.cms.businesslogic.member SqlHelper.ExecuteNonQuery( "delete from cmsMember2MemberGroup where member = @id and Membergroup = @groupId", SqlHelper.CreateParameter("@id", Id), SqlHelper.CreateParameter("@groupId", GroupId)); - populateGroups(); + PopulateGroups(); FireAfterRemoveGroup(e); } } @@ -789,10 +775,10 @@ namespace umbraco.cms.businesslogic.member #region Private methods - private void populateGroups() + private void PopulateGroups() { - Hashtable temp = new Hashtable(); - using (IRecordsReader dr = SqlHelper.ExecuteReader( + var temp = new Hashtable(); + using (var dr = SqlHelper.ExecuteReader( "select memberGroup from cmsMember2MemberGroup where member = @id", SqlHelper.CreateParameter("@id", Id))) { @@ -805,7 +791,7 @@ namespace umbraco.cms.businesslogic.member private static string GetCacheKey(int id) { - return string.Format("MemberCacheItem_{0}", id); + return string.Format("{0}{1}", CacheKeys.MemberBusinessLogicCacheKey, id); } // zb-00035 #29931 : helper class to handle member state @@ -978,17 +964,18 @@ namespace umbraco.cms.businesslogic.member FormsAuthentication.SetAuthCookie(m.LoginName, true); //cache the member - var cachedMember = Cache.GetCacheItem(GetCacheKey(m.Id), m_Locker, + var cachedMember = ApplicationContext.Current.ApplicationCache.GetCacheItem( + GetCacheKey(m.Id), TimeSpan.FromMinutes(30), - delegate - { - // Debug information - HttpContext.Current.Trace.Write("member", - string.Format("Member added to cache: {0}/{1} ({2})", - m.Text, m.LoginName, m.Id)); + () => + { + // Debug information + HttpContext.Current.Trace.Write("member", + string.Format("Member added to cache: {0}/{1} ({2})", + m.Text, m.LoginName, m.Id)); - return m; - }); + return m; + }); m.FireAfterAddToCache(e); } @@ -1007,13 +994,14 @@ namespace umbraco.cms.businesslogic.member /// Can be used in the runtime /// /// The member to log in - /// Use sessionbased recognition - /// The live time of the cookie + /// create a persistent cookie + /// Has no effect + [Obsolete("Use the membership api and FormsAuthentication to log users in, this method is no longer used anymore")] public static void AddMemberToCache(Member m, bool UseSession, TimeSpan TimespanForCookie) { if (m != null) { - AddToCacheEventArgs e = new AddToCacheEventArgs(); + var e = new AddToCacheEventArgs(); m.FireBeforeAddToCache(e); if (!e.Cancel) @@ -1025,19 +1013,18 @@ namespace umbraco.cms.businesslogic.member FormsAuthentication.SetAuthCookie(m.LoginName, !UseSession); //cache the member - var cachedMember = Cache.GetCacheItem(GetCacheKey(m.Id), m_Locker, + var cachedMember = ApplicationContext.Current.ApplicationCache.GetCacheItem( + GetCacheKey(m.Id), TimeSpan.FromMinutes(30), - delegate - { - // Debug information - HttpContext.Current.Trace.Write("member", - string.Format("Member added to cache: {0}/{1} ({2})", - m.Text, m.LoginName, m.Id)); - - return m; - }); - + () => + { + // Debug information + HttpContext.Current.Trace.Write("member", + string.Format("Member added to cache: {0}/{1} ({2})", + m.Text, m.LoginName, m.Id)); + return m; + }); m.FireAfterAddToCache(e); } @@ -1063,9 +1050,10 @@ namespace umbraco.cms.businesslogic.member /// Can be used in the public website /// /// Node Id of the member to remove + [Obsolete("Member cache is automatically cleared when members are updated")] public static void RemoveMemberFromCache(int NodeId) { - Cache.ClearCacheItem(GetCacheKey(NodeId)); + ApplicationContext.Current.ApplicationCache.ClearCacheItem(GetCacheKey(NodeId)); } /// @@ -1096,6 +1084,7 @@ namespace umbraco.cms.businesslogic.member /// Can be used in the public website /// /// The Node id of the member to clear + [Obsolete("Use FormsAuthentication.SignOut instead")] public static void ClearMemberFromClient(int NodeId) { // zb-00035 #29931 : cleanup member state management @@ -1117,15 +1106,13 @@ namespace umbraco.cms.businesslogic.member public static Hashtable CachedMembers() { var h = new Hashtable(); - Cache.ReturnCacheItemsOrdred() - .Cast() - .Where(x => x.Key.ToString().StartsWith("MemberCacheItem_")) - .Select(x => (Member)x.Value) - .ToList() - .ForEach(x => - { - h.Add(x.Id, x); - }); + + var items = ApplicationContext.Current.ApplicationCache.GetCacheItemsByKeySearch( + CacheKeys.MemberBusinessLogicCacheKey); + foreach (var i in items) + { + h.Add(i.Id, i); + } return h; } diff --git a/src/umbraco.providers/members/MembersMembershipProvider.cs b/src/umbraco.providers/members/MembersMembershipProvider.cs index f7498fc6d1..61a9aa7c70 100644 --- a/src/umbraco.providers/members/MembersMembershipProvider.cs +++ b/src/umbraco.providers/members/MembersMembershipProvider.cs @@ -333,8 +333,8 @@ namespace umbraco.providers.members Member m = Member.GetMemberFromLoginName(username); if (m != null) { - updateMemberProperty(m, m_PasswordRetrievalQuestionPropertyTypeAlias, newPasswordQuestion); - updateMemberProperty(m, m_PasswordRetrievalAnswerPropertyTypeAlias, newPasswordAnswer); + UpdateMemberProperty(m, m_PasswordRetrievalQuestionPropertyTypeAlias, newPasswordQuestion); + UpdateMemberProperty(m, m_PasswordRetrievalAnswerPropertyTypeAlias, newPasswordAnswer); m.Save(); return true; } @@ -385,17 +385,17 @@ namespace umbraco.providers.members // custom fields if (!String.IsNullOrEmpty(m_PasswordRetrievalQuestionPropertyTypeAlias)) - updateMemberProperty(m, m_PasswordRetrievalQuestionPropertyTypeAlias, passwordQuestion); + UpdateMemberProperty(m, m_PasswordRetrievalQuestionPropertyTypeAlias, passwordQuestion); if (!String.IsNullOrEmpty(m_PasswordRetrievalAnswerPropertyTypeAlias)) - updateMemberProperty(m, m_PasswordRetrievalAnswerPropertyTypeAlias, passwordAnswer); + UpdateMemberProperty(m, m_PasswordRetrievalAnswerPropertyTypeAlias, passwordAnswer); if (!String.IsNullOrEmpty(m_ApprovedPropertyTypeAlias)) - updateMemberProperty(m, m_ApprovedPropertyTypeAlias, isApproved); + UpdateMemberProperty(m, m_ApprovedPropertyTypeAlias, isApproved); if (!String.IsNullOrEmpty(m_LastLoginPropertyTypeAlias)) { mUser.LastActivityDate = DateTime.Now; - updateMemberProperty(m, m_LastLoginPropertyTypeAlias, mUser.LastActivityDate); + UpdateMemberProperty(m, m_LastLoginPropertyTypeAlias, mUser.LastActivityDate); } // save @@ -539,7 +539,7 @@ namespace umbraco.providers.members if (!String.IsNullOrEmpty(m_LockPropertyTypeAlias)) { bool isLockedOut = false; - bool.TryParse(getMemberProperty(m, m_LockPropertyTypeAlias, true), out isLockedOut); + bool.TryParse(GetMemberProperty(m, m_LockPropertyTypeAlias, true), out isLockedOut); if (isLockedOut) { throw new MembershipPasswordException("The supplied user is locked out"); @@ -547,7 +547,7 @@ namespace umbraco.providers.members } // match password answer - if (getMemberProperty(m, m_PasswordRetrievalAnswerPropertyTypeAlias, false) != answer) + if (GetMemberProperty(m, m_PasswordRetrievalAnswerPropertyTypeAlias, false) != answer) { throw new MembershipPasswordException("Incorrect password answer"); } @@ -645,7 +645,7 @@ namespace umbraco.providers.members if (!String.IsNullOrEmpty(m_LockPropertyTypeAlias)) { bool isLockedOut = false; - bool.TryParse(getMemberProperty(m, m_LockPropertyTypeAlias, true), out isLockedOut); + bool.TryParse(GetMemberProperty(m, m_LockPropertyTypeAlias, true), out isLockedOut); if (isLockedOut) { throw new MembershipPasswordException("The supplied user is locked out"); @@ -653,7 +653,7 @@ namespace umbraco.providers.members } // match password answer - if (getMemberProperty(m, m_PasswordRetrievalAnswerPropertyTypeAlias, false) != answer) + if (GetMemberProperty(m, m_PasswordRetrievalAnswerPropertyTypeAlias, false) != answer) { throw new MembershipPasswordException("Incorrect password answer"); } @@ -683,7 +683,7 @@ namespace umbraco.providers.members Member m = Member.GetMemberFromLoginName(userName); if (m != null) { - updateMemberProperty(m, m_LockPropertyTypeAlias, false); + UpdateMemberProperty(m, m_LockPropertyTypeAlias, false); return true; } else @@ -709,18 +709,18 @@ namespace umbraco.providers.members m.Email = user.Email; // if supported, update approve status - updateMemberProperty(m, m_ApprovedPropertyTypeAlias, user.IsApproved); + UpdateMemberProperty(m, m_ApprovedPropertyTypeAlias, user.IsApproved); // if supported, update lock status - updateMemberProperty(m, m_LockPropertyTypeAlias, user.IsLockedOut); + UpdateMemberProperty(m, m_LockPropertyTypeAlias, user.IsLockedOut); // if supported, update comment - updateMemberProperty(m, m_CommentPropertyTypeAlias, user.Comment); + UpdateMemberProperty(m, m_CommentPropertyTypeAlias, user.Comment); m.Save(); } - private void updateMemberProperty(Member m, string propertyAlias, object propertyValue) + private static void UpdateMemberProperty(Member m, string propertyAlias, object propertyValue) { if (!String.IsNullOrEmpty(propertyAlias)) { @@ -732,7 +732,7 @@ namespace umbraco.providers.members } } - private string getMemberProperty(Member m, string propertyAlias, bool isBool) + private static string GetMemberProperty(Member m, string propertyAlias, bool isBool) { if (!String.IsNullOrEmpty(propertyAlias)) { @@ -768,7 +768,7 @@ namespace umbraco.providers.members // check for lock status. If locked, then set the member property to null if (!String.IsNullOrEmpty(m_LockPropertyTypeAlias)) { - string lockedStatus = getMemberProperty(m, m_LockPropertyTypeAlias, true); + string lockedStatus = GetMemberProperty(m, m_LockPropertyTypeAlias, true); if (!String.IsNullOrEmpty(lockedStatus)) { bool isLocked = false; @@ -783,20 +783,20 @@ namespace umbraco.providers.members } // check for approve status. If not approved, then set the member property to null - if (!checkApproveStatus(m)) { + if (!CheckApproveStatus(m)) { m = null; } // maybe update login date if (m != null && !String.IsNullOrEmpty(m_LastLoginPropertyTypeAlias)) { - updateMemberProperty(m, m_LastLoginPropertyTypeAlias, DateTime.Now); + UpdateMemberProperty(m, m_LastLoginPropertyTypeAlias, DateTime.Now); } // maybe reset password attempts if (m != null && !String.IsNullOrEmpty(m_FailedPasswordAttemptsPropertyTypeAlias)) { - updateMemberProperty(m, m_FailedPasswordAttemptsPropertyTypeAlias, 0); + UpdateMemberProperty(m, m_FailedPasswordAttemptsPropertyTypeAlias, 0); } // persist data @@ -808,17 +808,17 @@ namespace umbraco.providers.members { Member updateMemberDataObject = Member.GetMemberFromLoginName(username); // update fail rate if it's approved - if (updateMemberDataObject != null && checkApproveStatus(updateMemberDataObject)) + if (updateMemberDataObject != null && CheckApproveStatus(updateMemberDataObject)) { int failedAttempts = 0; - int.TryParse(getMemberProperty(updateMemberDataObject, m_FailedPasswordAttemptsPropertyTypeAlias, false), out failedAttempts); + int.TryParse(GetMemberProperty(updateMemberDataObject, m_FailedPasswordAttemptsPropertyTypeAlias, false), out failedAttempts); failedAttempts = failedAttempts+1; - updateMemberProperty(updateMemberDataObject, m_FailedPasswordAttemptsPropertyTypeAlias, failedAttempts); + UpdateMemberProperty(updateMemberDataObject, m_FailedPasswordAttemptsPropertyTypeAlias, failedAttempts); // lock user? if (failedAttempts >= MaxInvalidPasswordAttempts) { - updateMemberProperty(updateMemberDataObject, m_LockPropertyTypeAlias, true); + UpdateMemberProperty(updateMemberDataObject, m_LockPropertyTypeAlias, true); } } @@ -826,14 +826,14 @@ namespace umbraco.providers.members return (m != null); } - private bool checkApproveStatus(Member m) + private bool CheckApproveStatus(Member m) { bool isApproved = false; if (!String.IsNullOrEmpty(m_ApprovedPropertyTypeAlias)) { if (m != null) { - string approveStatus = getMemberProperty(m, m_ApprovedPropertyTypeAlias, true); + string approveStatus = GetMemberProperty(m, m_ApprovedPropertyTypeAlias, true); if (!String.IsNullOrEmpty(approveStatus)) { bool.TryParse(approveStatus, out isApproved); @@ -919,7 +919,7 @@ namespace umbraco.providers.members password = Encoding.Unicode.GetString(DecryptPassword(Convert.FromBase64String(password))); break; case MembershipPasswordFormat.Hashed: - throw new ProviderException("Cannot unencode a hashed password."); + throw new ProviderException("Cannot decrypt a hashed password."); default: throw new ProviderException("Unsupported password format."); } @@ -945,27 +945,27 @@ namespace umbraco.providers.members // last login if (!String.IsNullOrEmpty(m_LastLoginPropertyTypeAlias)) { - DateTime.TryParse(getMemberProperty(m, m_LastLoginPropertyTypeAlias, false), out lastLogin); + DateTime.TryParse(GetMemberProperty(m, m_LastLoginPropertyTypeAlias, false), out lastLogin); } // approved if (!String.IsNullOrEmpty(m_ApprovedPropertyTypeAlias)) { - bool.TryParse(getMemberProperty(m, m_ApprovedPropertyTypeAlias, true), out isApproved); + bool.TryParse(GetMemberProperty(m, m_ApprovedPropertyTypeAlias, true), out isApproved); } // locked if (!String.IsNullOrEmpty(m_LockPropertyTypeAlias)) { - bool.TryParse(getMemberProperty(m, m_LockPropertyTypeAlias, true), out isLocked); + bool.TryParse(GetMemberProperty(m, m_LockPropertyTypeAlias, true), out isLocked); } // comment if (!String.IsNullOrEmpty(m_CommentPropertyTypeAlias)) { - comment = getMemberProperty(m, m_CommentPropertyTypeAlias, false); + comment = GetMemberProperty(m, m_CommentPropertyTypeAlias, false); } // password question if (!String.IsNullOrEmpty(m_PasswordRetrievalQuestionPropertyTypeAlias)) { - passwordQuestion = getMemberProperty(m, m_PasswordRetrievalQuestionPropertyTypeAlias, false); + passwordQuestion = GetMemberProperty(m, m_PasswordRetrievalQuestionPropertyTypeAlias, false); } return new MembershipUser(m_providerName, m.LoginName, m.Id, m.Email, passwordQuestion, comment, isApproved, isLocked, m.CreateDateTime, lastLogin,