decouple user repo from the membershi providers, lets see what happens with unit tests on the server
This commit is contained in:
@@ -26,12 +26,23 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// </summary>
|
||||
internal class UserRepository : PetaPocoRepositoryBase<int, IUser>, IUserRepository
|
||||
{
|
||||
//private readonly CacheHelper _cacheHelper;
|
||||
|
||||
public UserRepository(IScopeUnitOfWork work, CacheHelper cacheHelper, ILogger logger, ISqlSyntaxProvider sqlSyntax)
|
||||
private readonly IDictionary<string, string> _passwordConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="work"></param>
|
||||
/// <param name="cacheHelper"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="sqlSyntax"></param>
|
||||
/// <param name="passwordConfiguration">
|
||||
/// A dictionary specifying the configuration for user passwords. If this is null then no password configuration will be persisted or read.
|
||||
/// </param>
|
||||
public UserRepository(IScopeUnitOfWork work, CacheHelper cacheHelper, ILogger logger, ISqlSyntaxProvider sqlSyntax,
|
||||
IDictionary<string, string> passwordConfiguration = null)
|
||||
: base(work, cacheHelper, logger, sqlSyntax)
|
||||
{
|
||||
//_cacheHelper = cacheHelper;
|
||||
_passwordConfiguration = passwordConfiguration;
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<int,IUser>
|
||||
@@ -46,8 +57,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
.OrderBy<UserStartNodeDto>(d => d.Id, SqlSyntax);
|
||||
|
||||
var dto = Database.Fetch<UserDto, UserGroupDto, UserGroup2AppDto, UserStartNodeDto, UserDto>(new UserGroupRelator().Map, sql)
|
||||
.FirstOrDefault();
|
||||
|
||||
.FirstOrDefault();
|
||||
|
||||
if (dto == null)
|
||||
return null;
|
||||
|
||||
@@ -127,7 +138,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
var sql = GetBaseQuery("umbracoUser.*");
|
||||
sql.Where(GetBaseWhereClause(), new { Id = id });
|
||||
dto = Database.FirstOrDefault<UserDto>(sql);
|
||||
dto = Database.FirstOrDefault<UserDto>(sql);
|
||||
}
|
||||
|
||||
if (dto == null)
|
||||
@@ -139,14 +150,14 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
public IProfile GetProfile(string username)
|
||||
{
|
||||
var sql = GetBaseQuery(false).Where<UserDto>(userDto => userDto.UserName == username, SqlSyntax);
|
||||
|
||||
var sql = GetBaseQuery(false).Where<UserDto>(userDto => userDto.UserName == username, SqlSyntax);
|
||||
|
||||
var dto = Database.Fetch<UserDto>(sql)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (dto == null)
|
||||
return null;
|
||||
|
||||
return null;
|
||||
|
||||
return new UserProfile(dto.Id, dto.UserName);
|
||||
}
|
||||
|
||||
@@ -176,8 +187,8 @@ UNION
|
||||
SELECT '5CountOfInvited' AS colName, COUNT(id) AS num FROM umbracoUser WHERE lastLoginDate IS NULL AND userDisabled = 1 AND invitedDate IS NOT NULL
|
||||
ORDER BY colName";
|
||||
|
||||
var result = Database.Fetch<dynamic>(sql);
|
||||
|
||||
var result = Database.Fetch<dynamic>(sql);
|
||||
|
||||
return new Dictionary<UserState, int>
|
||||
{
|
||||
{UserState.All, result[0].num},
|
||||
@@ -193,7 +204,7 @@ ORDER BY colName";
|
||||
var sql = GetQueryWithGroups();
|
||||
if (ids.Any())
|
||||
{
|
||||
sql.Where("umbracoUser.id in (@ids)", new {ids = ids});
|
||||
sql.Where("umbracoUser.id in (@ids)", new { ids = ids });
|
||||
}
|
||||
sql //must be included for relator to work
|
||||
.OrderBy<UserDto>(d => d.Id, SqlSyntax)
|
||||
@@ -201,11 +212,11 @@ ORDER BY colName";
|
||||
.OrderBy<UserStartNodeDto>(d => d.Id, SqlSyntax);
|
||||
|
||||
var users = ConvertFromDtos(Database.Fetch<UserDto, UserGroupDto, UserGroup2AppDto, UserStartNodeDto, UserDto>(new UserGroupRelator().Map, sql))
|
||||
.ToArray(); // important so we don't iterate twice, if we don't do this we can end up with null values in cache if we were caching.
|
||||
|
||||
.ToArray(); // important so we don't iterate twice, if we don't do this we can end up with null values in cache if we were caching.
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override IEnumerable<IUser> PerformGetByQuery(IQuery<IUser> query)
|
||||
{
|
||||
var sqlClause = GetQueryWithGroups();
|
||||
@@ -220,15 +231,15 @@ ORDER BY colName";
|
||||
.DistinctBy(x => x.Id);
|
||||
|
||||
var users = ConvertFromDtos(dtos)
|
||||
.ToArray(); // important so we don't iterate twice, if we don't do this we can end up with null values in cache if we were caching.
|
||||
|
||||
.ToArray(); // important so we don't iterate twice, if we don't do this we can end up with null values in cache if we were caching.
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Overrides of PetaPocoRepositoryBase<int,IUser>
|
||||
|
||||
|
||||
protected override Sql GetBaseQuery(bool isCount)
|
||||
{
|
||||
var sql = new Sql();
|
||||
@@ -298,26 +309,25 @@ ORDER BY colName";
|
||||
protected override Guid NodeObjectTypeId
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override void PersistNewItem(IUser entity)
|
||||
{
|
||||
((User)entity).AddingEntity();
|
||||
|
||||
//ensure security stamp if non
|
||||
|
||||
//ensure security stamp if non
|
||||
if (entity.SecurityStamp.IsNullOrWhiteSpace())
|
||||
{
|
||||
entity.SecurityStamp = Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var userDto = UserFactory.BuildDto(entity);
|
||||
|
||||
//Check if we have a known config, we only want to store config for hashing
|
||||
//TODO: This logic will need to be updated when we do http://issues.umbraco.org/issue/U4-10089
|
||||
var membershipProvider = MembershipProviderExtensions.GetUsersMembershipProvider();
|
||||
if (membershipProvider.PasswordFormat == MembershipPasswordFormat.Hashed)
|
||||
//TODO: This logic will need to be updated when we do http://issues.umbraco.org/issue/U4-10089
|
||||
if (_passwordConfiguration != null && _passwordConfiguration.Count > 0)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(new { hashAlgorithm = Membership.HashAlgorithmType });
|
||||
var json = JsonConvert.SerializeObject(_passwordConfiguration);
|
||||
userDto.PasswordConfig = json;
|
||||
}
|
||||
|
||||
@@ -341,8 +351,8 @@ ORDER BY colName";
|
||||
//lookup all assigned
|
||||
var assigned = entity.Groups == null || entity.Groups.Any() == false
|
||||
? new List<UserGroupDto>()
|
||||
: Database.Fetch<UserGroupDto>("SELECT * FROM umbracoUserGroup WHERE userGroupAlias IN (@aliases)", new { aliases = entity.Groups.Select(x => x.Alias) });
|
||||
|
||||
: Database.Fetch<UserGroupDto>("SELECT * FROM umbracoUserGroup WHERE userGroupAlias IN (@aliases)", new { aliases = entity.Groups.Select(x => x.Alias) });
|
||||
|
||||
foreach (var groupDto in assigned)
|
||||
{
|
||||
var dto = new User2UserGroupDto
|
||||
@@ -360,18 +370,18 @@ ORDER BY colName";
|
||||
protected override void PersistUpdatedItem(IUser entity)
|
||||
{
|
||||
//Updates Modified date
|
||||
((User)entity).UpdatingEntity();
|
||||
|
||||
//ensure security stamp if non
|
||||
((User)entity).UpdatingEntity();
|
||||
|
||||
//ensure security stamp if non
|
||||
if (entity.SecurityStamp.IsNullOrWhiteSpace())
|
||||
{
|
||||
entity.SecurityStamp = Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
var userDto = UserFactory.BuildDto(entity);
|
||||
|
||||
//build list of columns to check for saving - we don't want to save the password if it hasn't changed!
|
||||
//List the columns to save, NOTE: would be nice to not have hard coded strings here but no real good way around that
|
||||
var userDto = UserFactory.BuildDto(entity);
|
||||
|
||||
//build list of columns to check for saving - we don't want to save the password if it hasn't changed!
|
||||
//List the columns to save, NOTE: would be nice to not have hard coded strings here but no real good way around that
|
||||
var colsToSave = new Dictionary<string, string>()
|
||||
{
|
||||
{"userDisabled", "IsApproved"},
|
||||
@@ -379,8 +389,8 @@ ORDER BY colName";
|
||||
{"startStructureID", "StartContentId"},
|
||||
{"startMediaID", "StartMediaId"},
|
||||
{"userName", "Name"},
|
||||
{"userLogin", "Username"},
|
||||
{"userEmail", "Email"},
|
||||
{"userLogin", "Username"},
|
||||
{"userEmail", "Email"},
|
||||
{"userLanguage", "Language"},
|
||||
{"securityStampToken", "SecurityStamp"},
|
||||
{"lastLockoutDate", "LastLockoutDate"},
|
||||
@@ -416,11 +426,12 @@ ORDER BY colName";
|
||||
|
||||
//Check if we have a known config, we only want to store config for hashing
|
||||
//TODO: This logic will need to be updated when we do http://issues.umbraco.org/issue/U4-10089
|
||||
var membershipProvider = MembershipProviderExtensions.GetUsersMembershipProvider();
|
||||
if (membershipProvider.PasswordFormat == MembershipPasswordFormat.Hashed)
|
||||
if (_passwordConfiguration != null && _passwordConfiguration.Count > 0)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(new { hashAlgorithm = Membership.HashAlgorithmType });
|
||||
var json = JsonConvert.SerializeObject(_passwordConfiguration);
|
||||
userDto.PasswordConfig = json;
|
||||
|
||||
changedCols.Add("passwordConfig");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,7 +486,7 @@ ORDER BY colName";
|
||||
//remove the ones not assigned to the entity
|
||||
var toDelete = assignedIds.Except(entityStartIds).ToArray();
|
||||
if (toDelete.Length > 0)
|
||||
Database.Delete<UserStartNodeDto>("WHERE UserId = @UserId AND startNode IN (@startNodes)", new {UserId = entity.Id, startNodes = toDelete});
|
||||
Database.Delete<UserStartNodeDto>("WHERE UserId = @UserId AND startNode IN (@startNodes)", new { UserId = entity.Id, startNodes = toDelete });
|
||||
//add the ones not currently in the db
|
||||
var toAdd = entityStartIds.Except(assignedIds).ToArray();
|
||||
foreach (var i in toAdd)
|
||||
@@ -515,8 +526,8 @@ ORDER BY colName";
|
||||
.Where<UserDto>(x => x.UserName == username);
|
||||
|
||||
return Database.ExecuteScalar<int>(sql) > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of <see cref="IUser"/> objects associated with a given group
|
||||
/// </summary>
|
||||
@@ -566,8 +577,8 @@ ORDER BY colName";
|
||||
var mappedField = mapper.Map(expressionMember.Name);
|
||||
|
||||
if (mappedField.IsNullOrWhiteSpace())
|
||||
throw new ArgumentException("Could not find a mapping for the column specified in the orderBy clause");
|
||||
|
||||
throw new ArgumentException("Could not find a mapping for the column specified in the orderBy clause");
|
||||
|
||||
long tr;
|
||||
var results = GetPagedResultsByQuery(query, Convert.ToInt64(pageIndex), pageSize, out tr, mappedField, Direction.Ascending);
|
||||
totalRecords = Convert.ToInt32(tr);
|
||||
@@ -603,13 +614,13 @@ ORDER BY colName";
|
||||
throw new ArgumentException("Could not find a mapping for the column specified in the orderBy clause");
|
||||
|
||||
return GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, mappedField, orderDirection, userGroups, userState, filter);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private IEnumerable<IUser> GetPagedResultsByQuery(IQuery<IUser> query, long pageIndex, int pageSize, out long totalRecords, string orderBy, Direction orderDirection,
|
||||
string[] userGroups = null,
|
||||
UserState[] userState = null,
|
||||
}
|
||||
|
||||
|
||||
|
||||
private IEnumerable<IUser> GetPagedResultsByQuery(IQuery<IUser> query, long pageIndex, int pageSize, out long totalRecords, string orderBy, Direction orderDirection,
|
||||
string[] userGroups = null,
|
||||
UserState[] userState = null,
|
||||
IQuery<IUser> filter = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(orderBy)) throw new ArgumentException("Value cannot be null or whitespace.", "orderBy");
|
||||
@@ -633,7 +644,7 @@ ORDER BY colName";
|
||||
INNER JOIN umbracoUser2UserGroup ON umbracoUser2UserGroup.userId = umbracoUser.id
|
||||
INNER JOIN umbracoUserGroup ON umbracoUserGroup.id = umbracoUser2UserGroup.userGroupId
|
||||
WHERE umbracoUserGroup.userGroupAlias IN (@userGroups)))";
|
||||
filterSql.Append(subQuery, new {userGroups= userGroups});
|
||||
filterSql.Append(subQuery, new { userGroups = userGroups });
|
||||
}
|
||||
if (userState != null && userState.Length > 0)
|
||||
{
|
||||
@@ -671,12 +682,12 @@ ORDER BY colName";
|
||||
}
|
||||
|
||||
// Get base query for returning IDs
|
||||
var sqlBaseIds = GetBaseQuery("id");
|
||||
|
||||
var sqlBaseIds = GetBaseQuery("id");
|
||||
|
||||
if (query == null) query = new Query<IUser>();
|
||||
var translatorIds = new SqlTranslator<IUser>(sqlBaseIds, query);
|
||||
var sqlQueryIds = translatorIds.Translate();
|
||||
|
||||
|
||||
//get sorted and filtered sql
|
||||
var sqlNodeIdsWithSort = GetSortedSqlForPagedResults(
|
||||
GetFilteredSqlForPagedResults(sqlQueryIds, filterSql),
|
||||
@@ -696,11 +707,11 @@ ORDER BY colName";
|
||||
string sqlStringCount, sqlStringPage;
|
||||
Database.BuildPageQueries<UserDto>(pageIndex * pageSize, pageSize, sqlNodeIdsWithSort.SQL, ref args, out sqlStringCount, out sqlStringPage);
|
||||
|
||||
var sqlQueryFull = GetBaseQuery("umbracoUser.*, umbracoUserGroup.*, umbracoUserGroup2App.*, umbracoUserStartNode.*");
|
||||
|
||||
var sqlQueryFull = GetBaseQuery("umbracoUser.*, umbracoUserGroup.*, umbracoUserGroup2App.*, umbracoUserStartNode.*");
|
||||
|
||||
var fullQueryWithPagedInnerJoin = sqlQueryFull
|
||||
.Append("INNER JOIN (")
|
||||
//join the paged query with the paged query arguments
|
||||
.Append("INNER JOIN (")
|
||||
//join the paged query with the paged query arguments
|
||||
.Append(sqlStringPage, args)
|
||||
.Append(") temp ")
|
||||
.Append("ON umbracoUser.id = temp.id");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Web.Security;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.IO;
|
||||
@@ -9,6 +10,7 @@ using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Security;
|
||||
|
||||
namespace Umbraco.Core.Persistence
|
||||
{
|
||||
@@ -314,11 +316,18 @@ namespace Umbraco.Core.Persistence
|
||||
|
||||
public virtual IUserRepository CreateUserRepository(IScopeUnitOfWork uow)
|
||||
{
|
||||
var userMembershipProvider = MembershipProviderExtensions.GetUsersMembershipProvider();
|
||||
var passwordConfig = userMembershipProvider == null || userMembershipProvider.PasswordFormat != MembershipPasswordFormat.Hashed
|
||||
? null
|
||||
: new System.Collections.Generic.Dictionary<string, string> {{"hashAlgorithm", Membership.HashAlgorithmType}};
|
||||
|
||||
return new UserRepository(
|
||||
uow,
|
||||
//Need to cache users - we look up user information more than anything in the back office!
|
||||
_cacheHelper,
|
||||
_logger, _sqlSyntax);
|
||||
_logger,
|
||||
_sqlSyntax,
|
||||
passwordConfig);
|
||||
}
|
||||
|
||||
internal virtual IMacroRepository CreateMacroRepository(IScopeUnitOfWork uow)
|
||||
|
||||
Reference in New Issue
Block a user