backports missing logic and tests from 7 that I overlooked.

This commit is contained in:
Shannon
2013-12-17 16:13:38 +11:00
parent 82b2821e27
commit 137d859532
8 changed files with 251 additions and 18 deletions

View File

@@ -236,8 +236,7 @@ namespace Umbraco.Core
},
{
PasswordQuestion,
new PropertyType(new Guid(PropertyEditors.Textbox), DataTypeDatabaseType
.Nvarchar)
new PropertyType(new Guid(PropertyEditors.Textbox), DataTypeDatabaseType.Nvarchar)
{
Alias = PasswordQuestion,
Name = PasswordQuestionLabel

View File

@@ -20,6 +20,17 @@ namespace Umbraco.Core.Models
private object _providerUserKey;
private Type _userTypeKey;
/// <summary>
/// Constructor for creating a Member object
/// </summary>
/// <param name="name">Name of the content</param>
/// <param name="contentType">ContentType for the current Content object</param>
public Member(string name, IMemberType contentType)
: base(name, -1, contentType, new PropertyCollection())
{
_contentType = contentType;
}
internal Member(string name, string email, string username, string password, int parentId, IMemberType contentType)
: base(name, parentId, contentType, new PropertyCollection())
{

View File

@@ -22,14 +22,17 @@ namespace Umbraco.Core.Persistence.Repositories
{
private readonly IMemberTypeRepository _memberTypeRepository;
public MemberRepository(IDatabaseUnitOfWork work, IMemberTypeRepository memberTypeRepository) : base(work)
public MemberRepository(IDatabaseUnitOfWork work, IMemberTypeRepository memberTypeRepository)
: base(work)
{
if (memberTypeRepository == null) throw new ArgumentNullException("memberTypeRepository");
_memberTypeRepository = memberTypeRepository;
}
public MemberRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IMemberTypeRepository memberTypeRepository)
: base(work, cache)
{
if (memberTypeRepository == null) throw new ArgumentNullException("memberTypeRepository");
_memberTypeRepository = memberTypeRepository;
}
@@ -104,11 +107,11 @@ namespace Umbraco.Core.Persistence.Repositories
sql.Select("umbracoNode.*", "cmsContent.contentType", "cmsContentType.alias AS ContentTypeAlias", "cmsContentVersion.VersionId",
"cmsContentVersion.VersionDate", "cmsContentVersion.LanguageLocale", "cmsMember.Email",
"cmsMember.LoginName", "cmsMember.Password", "cmsPropertyData.id AS PropertyDataId", "cmsPropertyData.propertytypeid",
"cmsMember.LoginName", "cmsMember.Password", "cmsPropertyData.id AS PropertyDataId", "cmsPropertyData.propertytypeid",
"cmsPropertyData.dataDate", "cmsPropertyData.dataInt", "cmsPropertyData.dataNtext", "cmsPropertyData.dataNvarchar",
"cmsPropertyType.id", "cmsPropertyType.Alias", "cmsPropertyType.Description",
"cmsPropertyType.Name", "cmsPropertyType.mandatory", "cmsPropertyType.validationRegExp",
"cmsPropertyType.helpText", "cmsPropertyType.sortOrder AS PropertyTypeSortOrder", "cmsPropertyType.propertyTypeGroupId",
"cmsPropertyType.helpText", "cmsPropertyType.sortOrder AS PropertyTypeSortOrder", "cmsPropertyType.propertyTypeGroupId",
"cmsPropertyType.dataTypeId", "cmsDataType.controlId", "cmsDataType.dbType")
.From<NodeDto>()
.InnerJoin<ContentDto>().On<ContentDto, NodeDto>(left => left.NodeId, right => right.NodeId)
@@ -247,7 +250,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
property.Id = keyDictionary[property.PropertyTypeId];
}
((Member)entity).ResetDirtyProperties();
}
@@ -256,8 +259,10 @@ namespace Umbraco.Core.Persistence.Repositories
//Updates Modified date
((Member)entity).UpdatingEntity();
var dirtyEntity = (ICanBeDirty)entity;
//Look up parent to get and set the correct Path and update SortOrder if ParentId has changed
if (((ICanBeDirty)entity).IsPropertyDirty("ParentId"))
if (dirtyEntity.IsPropertyDirty("ParentId"))
{
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = ((IUmbracoEntity)entity).ParentId });
((IUmbracoEntity)entity).Path = string.Concat(parent.Path, ",", entity.Id);
@@ -293,13 +298,32 @@ namespace Umbraco.Core.Persistence.Repositories
//Updates the current version - cmsContentVersion
//Assumes a Version guid exists and Version date (modified date) has been set/updated
Database.Update(dto.ContentVersionDto);
//Updates the cmsMember entry
Database.Update(dto);
//Updates the cmsMember entry if it has changed
var changedCols = new List<string>();
if (dirtyEntity.IsPropertyDirty("Email"))
{
changedCols.Add("Email");
}
if (dirtyEntity.IsPropertyDirty("Username"))
{
changedCols.Add("LoginName");
}
// DO NOT update the password if it is null or empty
if (dirtyEntity.IsPropertyDirty("Password") && entity.Password.IsNullOrWhiteSpace() == false)
{
changedCols.Add("Password");
}
//only update the changed cols
if (changedCols.Count > 0)
{
Database.Update(dto, changedCols);
}
//TODO ContentType for the Member entity
//Create the PropertyData for this version - cmsPropertyData
var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id);
var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id);
var keyDictionary = new Dictionary<int, int>();
//Add Properties
@@ -333,8 +357,8 @@ namespace Umbraco.Core.Persistence.Repositories
property.Id = keyDictionary[property.PropertyTypeId];
}
}
((ICanBeDirty)entity).ResetDirtyProperties();
dirtyEntity.ResetDirtyProperties();
}
protected override void PersistDeletedItem(IMember entity)
@@ -416,9 +440,10 @@ namespace Umbraco.Core.Persistence.Repositories
public bool Exists(string username)
{
var sql = new Sql();
var escapedUserName = Database.EscapeAtSymbols(username);
sql.Select("COUNT(*)")
.From<MemberDto>()
.Where<MemberDto>(x => x.LoginName == username);
.Where<MemberDto>(x => x.LoginName == escapedUserName);
return Database.ExecuteScalar<int>(sql) > 0;
}

View File

@@ -23,6 +23,8 @@ namespace Umbraco.Core.Services
IEnumerable<IMember> GetMembersByGroup(string memberGroupName);
IEnumerable<IMember> GetAllMembers(params int[] ids);
//TODO: Need to get all members that start with a certain letter
void DeleteMembersOfType(int memberTypeId);
}
@@ -51,7 +53,7 @@ namespace Umbraco.Core.Services
void Delete(IMember membershipUser);
void Save(IMember membershipUser);
void Save(IMember membershipUser, bool raiseEvents = true);
IEnumerable<IMember> FindMembersByEmail(string emailStringToMatch);
}

View File

@@ -393,8 +393,15 @@ namespace Umbraco.Core.Services
/// Saves an updated Member
/// </summary>
/// <param name="member"></param>
public void Save(IMember member)
/// <param name="raiseEvents"></param>
public void Save(IMember member, bool raiseEvents = true)
{
if (raiseEvents)
{
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMember>(member), this))
return;
}
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
{
@@ -404,6 +411,9 @@ namespace Umbraco.Core.Services
var xml = member.ToXml();
CreateAndSaveMemberXml(xml, member.Id, uow.Database);
}
if (raiseEvents)
Saved.RaiseEvent(new SaveEventArgs<IMember>(member, false), this);
}
#endregion
@@ -483,14 +493,91 @@ namespace Umbraco.Core.Services
int result = exists ? db.Update(poco) : Convert.ToInt32(db.Insert(poco));
}
#region Event Handlers
/// <summary>
/// Occurs before Delete
/// </summary>
/// </summary>
public static event TypedEventHandler<IMemberService, DeleteEventArgs<IMember>> Deleting;
/// <summary>
/// Occurs after Delete
/// </summary>
public static event TypedEventHandler<IMemberService, DeleteEventArgs<IMember>> Deleted;
/// <summary>
/// Occurs before Save
/// </summary>
public static event TypedEventHandler<IMemberService, SaveEventArgs<IMember>> Saving;
/// <summary>
/// Occurs after Save
/// </summary>
public static event TypedEventHandler<IMemberService, SaveEventArgs<IMember>> Saved;
#endregion
///// <summary>
///// A helper method that will create a basic/generic member for use with a generic membership provider
///// </summary>
///// <returns></returns>
//internal static IMember CreateGenericMembershipProviderMember(string name, string email, string username, string password)
//{
// var identity = int.MaxValue;
// var memType = new MemberType(-1);
// var propGroup = new PropertyGroup
// {
// Name = "Membership",
// Id = --identity
// };
// propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext)
// {
// Alias = Constants.Conventions.Member.Comments,
// Name = Constants.Conventions.Member.CommentsLabel,
// SortOrder = 0,
// Id = --identity
// });
// propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer)
// {
// Alias = Constants.Conventions.Member.IsApproved,
// Name = Constants.Conventions.Member.IsApprovedLabel,
// SortOrder = 3,
// Id = --identity
// });
// propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer)
// {
// Alias = Constants.Conventions.Member.IsLockedOut,
// Name = Constants.Conventions.Member.IsLockedOutLabel,
// SortOrder = 4,
// Id = --identity
// });
// propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date)
// {
// Alias = Constants.Conventions.Member.LastLockoutDate,
// Name = Constants.Conventions.Member.LastLockoutDateLabel,
// SortOrder = 5,
// Id = --identity
// });
// propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date)
// {
// Alias = Constants.Conventions.Member.LastLoginDate,
// Name = Constants.Conventions.Member.LastLoginDateLabel,
// SortOrder = 6,
// Id = --identity
// });
// propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date)
// {
// Alias = Constants.Conventions.Member.LastPasswordChangeDate,
// Name = Constants.Conventions.Member.LastPasswordChangeDateLabel,
// SortOrder = 7,
// Id = --identity
// });
// memType.PropertyGroups.Add(propGroup);
// return new Member(name, email, username, password, -1, memType);
//}
}
}

View File

@@ -221,6 +221,63 @@ namespace Umbraco.Tests.Persistence.Repositories
}
}
[Test]
public void MemberRepository_Does_Not_Replace_Password_When_Null()
{
IMember sut;
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
MemberTypeRepository memberTypeRepository;
using (var repository = CreateRepository(unitOfWork, out memberTypeRepository))
{
var memberType = MockedContentTypes.CreateSimpleMemberType();
memberTypeRepository.AddOrUpdate(memberType);
unitOfWork.Commit();
var member = MockedMember.CreateSimpleMember(memberType, "Johnny Hefty", "johnny@example.com", "123", "hefty");
repository.AddOrUpdate(member);
unitOfWork.Commit();
sut = repository.Get(member.Id);
//when the password is null it will not overwrite what is already there.
sut.Password = null;
repository.AddOrUpdate(sut);
unitOfWork.Commit();
sut = repository.Get(member.Id);
Assert.That(sut.Password, Is.EqualTo("123"));
}
}
[Test]
public void MemberRepository_Can_Update_Email_And_Login_When_Changed()
{
IMember sut;
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
MemberTypeRepository memberTypeRepository;
using (var repository = CreateRepository(unitOfWork, out memberTypeRepository))
{
var memberType = MockedContentTypes.CreateSimpleMemberType();
memberTypeRepository.AddOrUpdate(memberType);
unitOfWork.Commit();
var member = MockedMember.CreateSimpleMember(memberType, "Johnny Hefty", "johnny@example.com", "123", "hefty");
repository.AddOrUpdate(member);
unitOfWork.Commit();
sut = repository.Get(member.Id);
sut.Username = "This is new";
sut.Email = "thisisnew@hello.com";
repository.AddOrUpdate(sut);
unitOfWork.Commit();
sut = repository.Get(member.Id);
Assert.That(sut.Email, Is.EqualTo("thisisnew@hello.com"));
Assert.That(sut.Username, Is.EqualTo("This is new"));
}
}
[Test]
public void Can_Create_Correct_Subquery()
{

View File

@@ -0,0 +1,52 @@
using System;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Services;
using umbraco.interfaces;
namespace Umbraco.Web.Strategies.Migrations
{
/// <summary>
/// This will execute after upgrading to remove any xml cache for media that are currently in the bin
/// </summary>
/// <remarks>
/// This will execute for specific versions -
///
/// * If current is less than or equal to 7.0.0
/// </remarks>
public class ClearMediaXmlCacheForDeletedItemsAfterUpgrade : IApplicationStartupHandler
{
public ClearMediaXmlCacheForDeletedItemsAfterUpgrade()
{
MigrationRunner.Migrated += MigrationRunner_Migrated;
}
void MigrationRunner_Migrated(MigrationRunner sender, Core.Events.MigrationEventArgs e)
{
var target70 = new Version(7, 0, 0);
if (e.ConfiguredVersion <= target70)
{
var sql = @"DELETE a
FROM cmsContentXml a
INNER JOIN umbracoNode b
ON a.nodeId = b.id
WHERE nodeObjectType = 'B796F64C-1F99-4FFB-B886-4BF4BC011A9C' AND " + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("path") + " like '%-21%'";
// var sql = @"DELETE FROM cmsContentXml WHERE nodeId IN
// (SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
// INNER JOIN umbracoNode ON cmsContentXml.nodeId = umbracoNode.id
// WHERE nodeObjectType = 'B796F64C-1F99-4FFB-B886-4BF4BC011A9C' AND " + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("path") + " like '%-21%')";
var count = e.MigrationContext.Database.Execute(sql);
LogHelper.Info<ClearMediaXmlCacheForDeletedItemsAfterUpgrade>("Cleared " + count + " items from the media xml cache that were trashed and not meant to be there");
}
}
}
}

View File

@@ -391,6 +391,7 @@
<Compile Include="Search\LuceneIndexerExtensions.cs" />
<Compile Include="Security\ValidateRequestAttempt.cs" />
<Compile Include="Security\WebSecurity.cs" />
<Compile Include="Strategies\Migrations\ClearMediaXmlCacheForDeletedItemsAfterUpgrade.cs" />
<Compile Include="Strategies\Migrations\RebuildMediaXmlCacheAfterUpgrade.cs" />
<Compile Include="UI\CdfLogger.cs" />
<Compile Include="umbraco.presentation\CompatibilityHelper.cs" />
@@ -421,10 +422,9 @@
<Compile Include="umbraco.presentation\umbraco\dialogs\AssignDomain2.aspx.designer.cs">
<DependentUpon>AssignDomain2.aspx</DependentUpon>
</Compile>
<Compile Include="umbraco.presentation\umbraco\members\EditMember.aspx.cs">
<Compile Include="umbraco.presentation\umbraco\members\EditMember.aspx.cs">
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="umbraco.presentation\umbraco\users\EditUser.aspx.cs">
<SubType>ASPXCodeBehind</SubType>
</Compile>