Merge remote-tracking branch 'origin/6.2.0' into 7.1.0

Conflicts:
	src/Umbraco.Core/Models/Membership/EntityPermission.cs
	src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
	src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs
	src/Umbraco.Core/PluginManager.cs
	src/Umbraco.Web.UI/config/trees.config
	src/Umbraco.Web/Search/ExamineEvents.cs
	src/Umbraco.Web/umbraco.presentation/umbraco/Trees/TreeDefinitionCollection.cs
This commit is contained in:
Shannon
2014-02-17 15:56:48 +11:00
14 changed files with 104 additions and 40 deletions

View File

@@ -5,14 +5,14 @@
/// </summary>
public class EntityPermission
{
public EntityPermission(object userId, int entityId, string[] assignedPermissions)
public EntityPermission(int userId, int entityId, string[] assignedPermissions)
{
UserId = userId;
EntityId = entityId;
AssignedPermissions = assignedPermissions;
}
public object UserId { get; private set; }
public int UserId { get; private set; }
public int EntityId { get; private set; }
/// <summary>

View File

@@ -243,6 +243,10 @@ namespace Umbraco.Core.Persistence.Querying
args.RemoveAt(0);
}
//TODO: We should probably add the same logic we've done for ModelToSqlExpressionHelper with checking for:
// InvariantStartsWith, InvariantEndsWith, SqlWildcard, etc...
// since we should be able to easily handle that with the Poco objects too.
switch (m.Method.Name)
{
case "ToUpper":

View File

@@ -286,7 +286,7 @@ namespace Umbraco.Core.Persistence.Repositories
var userPermissions = (
from perm in parentPermissions
from p in perm.AssignedPermissions
select new Tuple<object, string>(perm.UserId, p)).ToList();
select new Tuple<int, string>(perm.UserId, p)).ToList();
permissionsRepo.AssignEntityPermissions(entity, userPermissions);
//flag the entity's permissions changed flag so we can track those changes.
@@ -558,7 +558,7 @@ namespace Umbraco.Core.Persistence.Repositories
return GetByVersion(dto.ContentVersionDto.VersionId);
}
public void AssignEntityPermissions(IContent entity, char permission, IEnumerable<object> userIds)
public void AssignEntityPermissions(IContent entity, char permission, IEnumerable<int> userIds)
{
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper);
repo.AssignEntityPermissions(entity, permission, userIds);

View File

@@ -23,8 +23,13 @@ namespace Umbraco.Core.Persistence.Repositories
/// <returns>An enumerable list of <see cref="IContent"/></returns>
IEnumerable<IContent> GetByPublishedVersion(IQuery<IContent> query);
void AssignEntityPermissions(IContent entity, char permission, IEnumerable<object> userIds);
void AssignEntityPermissions(IContent entity, char permission, IEnumerable<int> userIds);
/// <summary>
/// Gets the list of permissions for the content item
/// </summary>
/// <param name="entityId"></param>
/// <returns></returns>
IEnumerable<EntityPermission> GetPermissionsForEntity(int entityId);
}
}

View File

@@ -131,7 +131,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// <param name="entity"></param>
/// <param name="permission"></param>
/// <param name="userIds"></param>
internal void AssignEntityPermissions(TEntity entity, char permission, IEnumerable<object> userIds)
internal void AssignEntityPermissions(TEntity entity, char permission, IEnumerable<int> userIds)
{
var actions = userIds.Select(id => new User2NodePermissionDto
{
@@ -150,13 +150,13 @@ namespace Umbraco.Core.Persistence.Repositories
/// <param name="userPermissions">
/// A key/value pair list containing a userId and a permission to assign
/// </param>
internal void AssignEntityPermissions(TEntity entity, IEnumerable<Tuple<object, string>> userPermissions)
internal void AssignEntityPermissions(TEntity entity, IEnumerable<Tuple<int, string>> userPermissions)
{
var actions = userPermissions.Select(p => new User2NodePermissionDto
{
NodeId = entity.Id,
Permission = p.Item2,
UserId = (int)p.Item1
UserId = p.Item1
});
_unitOfWork.Database.BulkInsertRecords(actions);
@@ -168,7 +168,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// <param name="entity"></param>
/// <param name="permissions"></param>
/// <param name="userIds"></param>
internal void ReplaceEntityPermissions(TEntity entity, string permissions, IEnumerable<object> userIds)
internal void ReplaceEntityPermissions(TEntity entity, string permissions, IEnumerable<int> userIds)
{
_unitOfWork.Database.Update<User2NodePermissionDto>(
GenerateReplaceEntityPermissionsSql(entity.Id, permissions, userIds.ToArray()));
@@ -183,7 +183,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// A callback to get the descendant Ids of the current entity
/// </param>
/// <param name="userIds"></param>
internal void ReplaceEntityPermissions(TEntity entity, string permissions, Func<IEntity, IEnumerable<int>> getDescendantIds, IEnumerable<object> userIds)
internal void ReplaceEntityPermissions(TEntity entity, string permissions, Func<IEntity, IEnumerable<int>> getDescendantIds, IEnumerable<int> userIds)
{
_unitOfWork.Database.Update<User2NodePermissionDto>(
GenerateReplaceEntityPermissionsSql(
@@ -192,12 +192,12 @@ namespace Umbraco.Core.Persistence.Repositories
userIds.ToArray()));
}
internal static string GenerateReplaceEntityPermissionsSql(int entityId, string permissions, object[] userIds)
internal static string GenerateReplaceEntityPermissionsSql(int entityId, string permissions, int[] userIds)
{
return GenerateReplaceEntityPermissionsSql(new[] { entityId }, permissions, userIds);
}
internal static string GenerateReplaceEntityPermissionsSql(int[] entityIds, string permissions, object[] userIds)
internal static string GenerateReplaceEntityPermissionsSql(int[] entityIds, string permissions, int[] userIds)
{
//create the "SET" clause of the update statement
var sqlSet = string.Format("SET {0}={1}",

View File

@@ -157,7 +157,10 @@ namespace Umbraco.Core.Persistence.Repositories
}
}
var entityCollection = PerformGetAll(ids).ToArray();
var entityCollection = PerformGetAll(ids)
//ensure we don't include any null refs in the returned collection!
.WhereNotNull()
.ToArray();
foreach (var entity in entityCollection)
{
@@ -178,7 +181,9 @@ namespace Umbraco.Core.Persistence.Repositories
/// <returns></returns>
public IEnumerable<TEntity> GetByQuery(IQuery<TEntity> query)
{
return PerformGetByQuery(query);
return PerformGetByQuery(query)
//ensure we don't include any null refs in the returned collection!
.WhereNotNull();
}
protected abstract bool PerformExists(TId id);

View File

@@ -34,7 +34,7 @@ namespace Umbraco.Core
/// it will use the cached resolved plugins that it has already found which means that no assembly scanning is necessary. This leads
/// to much faster startup times.
/// </remarks>
internal class PluginManager
public class PluginManager
{
private readonly ApplicationContext _appContext;
private const string CacheKey = "umbraco-plugins.list";
@@ -107,7 +107,7 @@ namespace Umbraco.Core
/// <remarks>
/// The setter is generally only used for unit tests
/// </remarks>
internal static PluginManager Current
public static PluginManager Current
{
get
{
@@ -783,6 +783,7 @@ namespace Umbraco.Core
UpdateCachedPluginsFile<T>(typeList.GetTypes(), resolutionKind);
}
#region Public Methods
/// <summary>
/// Generic method to find the specified type and cache the result
/// </summary>
@@ -802,7 +803,7 @@ namespace Umbraco.Core
/// <typeparam name="T"></typeparam>
/// <typeparam name="TAttribute"></typeparam>
/// <returns></returns>
internal IEnumerable<Type> ResolveTypesWithAttribute<T, TAttribute>(bool cacheResult = true)
public IEnumerable<Type> ResolveTypesWithAttribute<T, TAttribute>(bool cacheResult = true)
where TAttribute : Attribute
{
return ResolveTypes<T>(
@@ -816,14 +817,15 @@ namespace Umbraco.Core
/// </summary>
/// <typeparam name="TAttribute"></typeparam>
/// <returns></returns>
internal IEnumerable<Type> ResolveAttributedTypes<TAttribute>(bool cacheResult = true)
public IEnumerable<Type> ResolveAttributedTypes<TAttribute>(bool cacheResult = true)
where TAttribute : Attribute
{
return ResolveTypes<TAttribute>(
() => TypeFinder.FindClassesWithAttribute<TAttribute>(AssembliesToScan),
TypeResolutionKind.FindAttributedTypes,
cacheResult);
}
}
#endregion
/// <summary>
/// Used for unit tests

View File

@@ -59,9 +59,13 @@ namespace Umbraco.Core.Services
_repositoryFactory = repositoryFactory;
}
//TODO: There are various ways to expose permission setting on this service, we just need to list out the different ways we'll need to
// be able to acheive this for the core, for now this is here so I can run a unit test.
internal void AssignContentPermissions(IContent entity, char permission, IEnumerable<object> userIds)
/// <summary>
/// Assigns a single permission to the current content item for the specified user ids
/// </summary>
/// <param name="entity"></param>
/// <param name="permission"></param>
/// <param name="userIds"></param>
public void AssignContentPermissions(IContent entity, char permission, IEnumerable<int> userIds)
{
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateContentRepository(uow))
@@ -70,6 +74,20 @@ namespace Umbraco.Core.Services
}
}
/// <summary>
/// Gets the list of permissions for the content item
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
public IEnumerable<EntityPermission> GetPermissionsForEntity(IContent content)
{
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateContentRepository(uow))
{
return repository.GetPermissionsForEntity(content.Id);
}
}
/// <summary>
/// Creates an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
/// that this Content should based on.
@@ -1220,6 +1238,7 @@ namespace Umbraco.Core.Services
}
}
/// <summary>
/// Sends an <see cref="IContent"/> to Publication, which executes handlers and events for the 'Send to Publication' action.
/// </summary>

View File

@@ -11,6 +11,20 @@ namespace Umbraco.Core.Services
/// </summary>
public interface IContentService : IService
{
/// <summary>
/// Assigns a single permission to the current content item for the specified user ids
/// </summary>
/// <param name="entity"></param>
/// <param name="permission"></param>
/// <param name="userIds"></param>
void AssignContentPermissions(IContent entity, char permission, IEnumerable<int> userIds);
/// <summary>
/// Gets the list of permissions for the content item
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
IEnumerable<EntityPermission> GetPermissionsForEntity(IContent content);
bool SendToPublication(IContent content, int userId = 0);

View File

@@ -16,7 +16,7 @@ namespace Umbraco.Tests.Persistence.Querying
public void Generate_Replace_Entity_Permissions_Test()
{
// Act
var sql = PermissionRepository<IContent>.GenerateReplaceEntityPermissionsSql(123, "A", new object[] {10, 11, 12});
var sql = PermissionRepository<IContent>.GenerateReplaceEntityPermissionsSql(123, "A", new int[] {10, 11, 12});
// Assert
Assert.AreEqual(@"SET [permission]='A' WHERE (([nodeId]=123) AND ([userId]=10 OR [userId]=11 OR [userId]=12))", sql);
@@ -26,7 +26,7 @@ namespace Umbraco.Tests.Persistence.Querying
public void Generate_Replace_Entity_Permissions_With_Descendants_Test()
{
// Act
var sql = PermissionRepository<IContent>.GenerateReplaceEntityPermissionsSql(new[] { 123, 456 },"A", new object[] { 10, 11, 12 });
var sql = PermissionRepository<IContent>.GenerateReplaceEntityPermissionsSql(new[] { 123, 456 }, "A", new int[] { 10, 11, 12 });
// Assert
Assert.AreEqual(@"SET [permission]='A' WHERE (([nodeId]=123 OR [nodeId]=456) AND ([userId]=10 OR [userId]=11 OR [userId]=12))", sql);

View File

@@ -70,7 +70,7 @@ namespace Umbraco.Tests.Persistence.Repositories
unitOfWork.Commit();
// Act
repository.AssignEntityPermissions(parentPage, 'A', new object[] { 0 });
repository.AssignEntityPermissions(parentPage, 'A', new int[] { 0 });
var childPage = MockedContent.CreateSimpleContent(contentType, "child", parentPage);
repository.AddOrUpdate(childPage);
unitOfWork.Commit();

View File

@@ -76,14 +76,14 @@ namespace Umbraco.Tests.Services
MockedContent.CreateSimpleContent(contentType)
};
ServiceContext.ContentService.Save(content);
((ContentService)ServiceContext.ContentService).AssignContentPermissions(content.ElementAt(0), ActionBrowse.Instance.Letter, new object[] { user.Id });
((ContentService)ServiceContext.ContentService).AssignContentPermissions(content.ElementAt(0), ActionDelete.Instance.Letter, new object[] { user.Id });
((ContentService)ServiceContext.ContentService).AssignContentPermissions(content.ElementAt(0), ActionMove.Instance.Letter, new object[] { user.Id });
ServiceContext.ContentService.AssignContentPermissions(content.ElementAt(0), ActionBrowse.Instance.Letter, new int[] { user.Id });
ServiceContext.ContentService.AssignContentPermissions(content.ElementAt(0), ActionDelete.Instance.Letter, new int[] { user.Id });
ServiceContext.ContentService.AssignContentPermissions(content.ElementAt(0), ActionMove.Instance.Letter, new int[] { user.Id });
((ContentService)ServiceContext.ContentService).AssignContentPermissions(content.ElementAt(1), ActionBrowse.Instance.Letter, new object[] { user.Id });
((ContentService)ServiceContext.ContentService).AssignContentPermissions(content.ElementAt(1), ActionDelete.Instance.Letter, new object[] { user.Id });
ServiceContext.ContentService.AssignContentPermissions(content.ElementAt(1), ActionBrowse.Instance.Letter, new int[] { user.Id });
ServiceContext.ContentService.AssignContentPermissions(content.ElementAt(1), ActionDelete.Instance.Letter, new int[] { user.Id });
((ContentService)ServiceContext.ContentService).AssignContentPermissions(content.ElementAt(2), ActionBrowse.Instance.Letter, new object[] { user.Id });
ServiceContext.ContentService.AssignContentPermissions(content.ElementAt(2), ActionBrowse.Instance.Letter, new int[] { user.Id });
// Act
var permissions = userService.GetPermissions(user, content.ElementAt(0).Id, content.ElementAt(1).Id, content.ElementAt(2).Id);
@@ -156,6 +156,17 @@ namespace Umbraco.Tests.Services
Assert.IsNull(ServiceContext.UserService.GetByUsername("notFound"));
}
[Test]
public void Get_By_Username_With_Backslash()
{
var userType = MockedUserType.CreateUserType();
ServiceContext.UserService.SaveUserType(userType);
var user = ServiceContext.UserService.CreateMemberWithIdentity("mydomain\\JohnDoe", "john@umbraco.io", "12345", userType);
Assert.IsNotNull(ServiceContext.UserService.GetByUsername(user.Username));
Assert.IsNull(ServiceContext.UserService.GetByUsername("notFound"));
}
[Test]
public void Get_By_Object_Id()
{

View File

@@ -178,15 +178,8 @@ namespace umbraco.cms.presentation.Trees
// tree type contains a comma (meaning it is assembly qualified)
if (tree.AssemblyName.IsNullOrWhiteSpace() || tree.Type.Contains(","))
{
var clrType = Type.GetType(tree.Type);
if (clrType == null)
{
LogHelper.Warn<TreeDefinitionCollection>("The tree definition: " + tree.Type + " could not be resolved to a .Net object type");
return false;
}
return clrType == type;
}
return tree.GetRuntimeType() == type;
}
//otherwise match using legacy match rules
return (string.Format("{0}.{1}", tree.AssemblyName, tree.Type).InvariantEquals(type.FullName));

View File

@@ -84,6 +84,17 @@ namespace umbraco.BusinessLogic
/// <value>The type.</value>
public string Type { get; set; }
private Type _runtimeType;
/// <summary>
/// Returns the CLR type based on it's assembly name stored in the config
/// </summary>
/// <returns></returns>
internal Type GetRuntimeType()
{
return _runtimeType ?? (_runtimeType = System.Type.GetType(Type));
}
/// <summary>
/// Gets or sets the default tree action.
/// </summary>