Merge branch 'user-group-permissions' into temp-U4-10075

This commit is contained in:
Stephan
2017-07-14 20:15:51 +02:00
23 changed files with 382 additions and 78 deletions

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace Umbraco.Core.Persistence.Querying
@@ -16,6 +17,11 @@ namespace Umbraco.Core.Persistence.Querying
/// <returns>This instance so calls to this method are chainable</returns>
IQuery<T> Where(Expression<Func<T, bool>> predicate);
/// <summary>
/// Adds a set of OR-ed where clauses to the query.
/// </summary>
/// <param name="predicates"></param>
/// <returns>This instance so calls to this method are chainable.</returns>
IQuery<T> WhereAny(IEnumerable<Expression<Func<T, bool>>> predicates);
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
namespace Umbraco.Core.Persistence.Querying
{
@@ -39,6 +40,50 @@ namespace Umbraco.Core.Persistence.Querying
return this;
}
/// <summary>
/// Adds a set of OR-ed where clauses to the query.
/// </summary>
/// <param name="predicates"></param>
/// <returns>This instance so calls to this method are chainable.</returns>
public virtual IQuery<T> WhereAny(IEnumerable<Expression<Func<T, bool>>> predicates)
{
if (predicates == null) return this;
StringBuilder sb = null;
List<object> parameters = null;
Sql sql = null;
foreach (var predicate in predicates)
{
// see notes in Where()
var expressionHelper = new ModelToSqlExpressionVisitor<T>();
var whereExpression = expressionHelper.Visit(predicate);
if (sb == null)
{
sb = new StringBuilder("(");
parameters = new List<object>();
sql = new Sql();
}
else
{
sb.Append(" OR ");
sql.Append(" OR ");
}
sb.Append(whereExpression);
parameters.AddRange(expressionHelper.GetSqlParameters());
sql.Append(whereExpression, expressionHelper.GetSqlParameters());
}
if (sb == null) return this;
sb.Append(")");
//_wheres.Add(Tuple.Create(sb.ToString(), parameters.ToArray()));
_wheres.Add(Tuple.Create("(" + sql.SQL + ")", sql.Arguments));
return this;
}
/// <summary>
/// Returns all translated where clauses and their sql parameters
/// </summary>

View File

@@ -167,7 +167,7 @@ namespace Umbraco.Core.Persistence.Repositories
_permissionRepository.AssignPermission(groupId, permission, entityIds);
}
#region Overrides of RepositoryBase<int,IUserType>
#region Overrides of RepositoryBase<int,IUserGroup>
protected override IUserGroup PerformGet(int id)
{

View File

@@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Umbraco.Core.Cache;
using Umbraco.Core.CodeAnnotations;
using Umbraco.Core.Events;
@@ -361,6 +364,40 @@ namespace Umbraco.Core.Services
return contents;
}
}
/// <summary>
/// Returns a paged collection of descendants.
/// </summary>
public IEnumerable<IUmbracoEntity> GetPagedDescendants(IEnumerable<int> ids, UmbracoObjectTypes umbracoObjectType, long pageIndex, int pageSize, out long totalRecords,
string orderBy = "path", Direction orderDirection = Direction.Ascending, string filter = "")
{
var objectTypeId = umbracoObjectType.GetGuid();
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var query = Query<IUmbracoEntity>.Builder;
var idsA = ids.ToArray();
if (idsA.All(x => x != Constants.System.Root))
{
var clauses = new List<Expression<Func<IUmbracoEntity, bool>>>();
foreach (var id in idsA)
{
var qid = id;
clauses.Add(x => x.Path.SqlContains(string.Format(",{0},", qid), TextColumnType.NVarchar) || x.Path.SqlEndsWith(string.Format(",{0}", qid), TextColumnType.NVarchar));
}
query.WhereAny(clauses);
}
IQuery<IUmbracoEntity> filterQuery = null;
if (filter.IsNullOrWhiteSpace() == false)
{
filterQuery = Query<IUmbracoEntity>.Builder.Where(x => x.Name.Contains(filter));
}
var contents = repository.GetPagedResultsByQuery(query, objectTypeId, pageIndex, pageSize, out totalRecords, orderBy, orderDirection, filterQuery);
return contents;
}
}
/// <summary>
/// Returns a paged collection of descendants from the root

View File

@@ -175,6 +175,12 @@ namespace Umbraco.Core.Services
IEnumerable<IUmbracoEntity> GetPagedDescendants(int id, UmbracoObjectTypes umbracoObjectType, long pageIndex, int pageSize, out long totalRecords,
string orderBy = "path", Direction orderDirection = Direction.Ascending, string filter = "");
/// <summary>
/// Returns a paged collection of descendants
/// </summary>
IEnumerable<IUmbracoEntity> GetPagedDescendants(IEnumerable<int> ids, UmbracoObjectTypes umbracoObjectType, long pageIndex, int pageSize, out long totalRecords,
string orderBy = "path", Direction orderDirection = Direction.Ascending, string filter = "");
/// <summary>
/// Returns a paged collection of descendants from the root
/// </summary>

View File

@@ -118,6 +118,7 @@
</Reference>
<Reference Include="System.DirectoryServices.AccountManagement" />
<Reference Include="System.Drawing" />
<Reference Include="System.Linq.Expressions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Runtime.Caching" />

View File

@@ -64,18 +64,18 @@ namespace Umbraco.Tests.Persistence.Repositories
using (var repository = CreateRepository(unitOfWork))
{
var userType1 = MockedUserGroup.CreateUserGroup("1");
var userType2 = MockedUserGroup.CreateUserGroup("2");
var userGroup1 = MockedUserGroup.CreateUserGroup("1");
var userGroup2 = MockedUserGroup.CreateUserGroup("2");
// Act
repository.AddOrUpdate(userType1);
repository.AddOrUpdate(userGroup1);
unitOfWork.Commit();
repository.AddOrUpdate(userType2);
repository.AddOrUpdate(userGroup2);
unitOfWork.Commit();
// Assert
Assert.That(userType1.HasIdentity, Is.True);
Assert.That(userType2.HasIdentity, Is.True);
Assert.That(userGroup1.HasIdentity, Is.True);
Assert.That(userGroup2.HasIdentity, Is.True);
}
}
@@ -209,10 +209,10 @@ namespace Umbraco.Tests.Persistence.Repositories
var unitOfWork = provider.GetUnitOfWork();
using (var repository = CreateRepository(unitOfWork))
{
var userTypes = CreateAndCommitMultipleUserGroups(repository, unitOfWork);
var userGroups = CreateAndCommitMultipleUserGroups(repository, unitOfWork);
// Act
var result = repository.GetAll(userTypes[0].Id, userTypes[1].Id);
var result = repository.GetAll(userGroups[0].Id, userGroups[1].Id);
// Assert
Assert.That(result, Is.Not.Null);
@@ -249,10 +249,10 @@ namespace Umbraco.Tests.Persistence.Repositories
var unitOfWork = provider.GetUnitOfWork();
using (var repository = CreateRepository(unitOfWork))
{
var userTypes = CreateAndCommitMultipleUserGroups(repository, unitOfWork);
var userGroups = CreateAndCommitMultipleUserGroups(repository, unitOfWork);
// Act
var exists = repository.Exists(userTypes[0].Id);
var exists = repository.Exists(userGroups[0].Id);
// Assert
Assert.That(exists, Is.True);
@@ -267,7 +267,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var unitOfWork = provider.GetUnitOfWork();
using (var repository = CreateRepository(unitOfWork))
{
var userTypes = CreateAndCommitMultipleUserGroups(repository, unitOfWork);
var userGroups = CreateAndCommitMultipleUserGroups(repository, unitOfWork);
// Act
var query = Query<IUserGroup>.Builder.Where(x => x.Alias == "testUserGroup1" || x.Alias == "testUserGroup2");

View File

@@ -36,7 +36,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var tagRepository = new TagRepository(unitOfWork, CacheHelper, Mock.Of<ILogger>(), SqlSyntax);
var repository = new MediaRepository(unitOfWork, CacheHelper, Mock.Of<ILogger>(), SqlSyntax, mediaTypeRepository, tagRepository, Mock.Of<IContentSection>());
return repository;
}
}
private ContentRepository CreateContentRepository(IScopeUnitOfWork unitOfWork, out IContentTypeRepository contentTypeRepository)
{
@@ -51,7 +51,7 @@ namespace Umbraco.Tests.Persistence.Repositories
contentTypeRepository = new ContentTypeRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, templateRepository);
var repository = new ContentRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, contentTypeRepository, templateRepository, tagRepository, Mock.Of<IContentSection>());
return repository;
}
}
private UserRepository CreateRepository(IScopeUnitOfWork unitOfWork)
{
@@ -86,7 +86,7 @@ namespace Umbraco.Tests.Persistence.Repositories
[Test]
public void Can_Perform_Add_With_Group()
{
var group = MockedUserGroup.CreateUserGroup();
var group = MockedUserGroup.CreateUserGroup();
// Arrange
var provider = new PetaPocoUnitOfWorkProvider(Logger);
@@ -95,22 +95,22 @@ namespace Umbraco.Tests.Persistence.Repositories
{
repository.AddOrUpdate(group);
unitOfWork.Commit();
}
}
using (var repository = CreateRepository(unitOfWork))
{
IUser user = MockedUser.CreateUser();
user.AddGroup(group.ToReadOnlyGroup());
user.AddGroup(group.ToReadOnlyGroup());
// Act
repository.AddOrUpdate(user);
unitOfWork.Commit();
user = repository.Get(user.Id);
user = repository.Get(user.Id);
// Assert
Assert.That(user.HasIdentity, Is.True);
Assert.AreEqual(1, user.Groups.Count());
Assert.AreEqual(1, user.Groups.Count());
Assert.AreEqual(group.Alias, user.Groups.ElementAt(0).Alias);
}
}
@@ -165,7 +165,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var ct = MockedContentTypes.CreateBasicContentType("test");
var content = MockedContent.CreateBasicContent(ct);
var mt = MockedContentTypes.CreateSimpleMediaType("testmedia", "TestMedia");
var media = MockedMedia.CreateSimpleMedia(mt, "asdf", -1);
var media = MockedMedia.CreateSimpleMedia(mt, "asdf", -1);
// Arrange
var provider = new PetaPocoUnitOfWorkProvider(Logger);
@@ -173,8 +173,8 @@ namespace Umbraco.Tests.Persistence.Repositories
IContentTypeRepository contentTypeRepo;
IMediaTypeRepository mediaTypeRepo;
using (var contentRepository = CreateContentRepository(unitOfWork, out contentTypeRepo))
using (var mediaRepository = CreateMediaRepository(unitOfWork, out mediaTypeRepo))
using (contentTypeRepo)
using (var mediaRepository = CreateMediaRepository(unitOfWork, out mediaTypeRepo))
using (contentTypeRepo)
using(mediaTypeRepo)
using (var userRepository = CreateRepository(unitOfWork))
using (var userGroupRepository = CreateUserGroupRepository(unitOfWork))
@@ -185,7 +185,7 @@ namespace Umbraco.Tests.Persistence.Repositories
contentRepository.AddOrUpdate(content);
mediaRepository.AddOrUpdate(media);
unitOfWork.Commit();
unitOfWork.Commit();
var user = CreateAndCommitUserWithGroup(userRepository, userGroupRepository, unitOfWork);
@@ -422,7 +422,7 @@ namespace Umbraco.Tests.Persistence.Repositories
var group = MockedUserGroup.CreateUserGroup();
userGroupRepository.AddOrUpdateGroupWithUsers(@group, new[] {user.Id});
unitOfWork.Commit();
unitOfWork.Commit();
return user;
}

View File

@@ -59,11 +59,23 @@
"Failed to retrieve user groups");
}
function deleteUserGroups(userGroupIds) {
var query = "userGroupIds=" + userGroupIds.join("&userGroupIds=");
return umbRequestHelper.resourcePromise(
$http.post(
umbRequestHelper.getApiUrl(
"userGroupsApiBaseUrl",
"PostDeleteUserGroups",
query)),
'Failed to delete user groups');
}
var resource = {
saveUserGroup: saveUserGroup,
getUserGroup: getUserGroup,
getUserGroups: getUserGroups,
getUserGroupScaffold: getUserGroupScaffold
getUserGroupScaffold: getUserGroupScaffold,
deleteUserGroups: deleteUserGroups
};
return resource;

View File

@@ -55,6 +55,18 @@
'Failed to enable the users ' + userIds.join(","));
}
function setUserGroupsOnUsers(userGroups, userIds) {
var userGroupAliases = userGroups.map(function(o) { return o.alias; });
var query = "userGroupAliases=" + userGroupAliases.join("&userGroupAliases=") + "&userIds=" + userIds.join("&userIds=");
return umbRequestHelper.resourcePromise(
$http.post(
umbRequestHelper.getApiUrl(
"userApiBaseUrl",
"PostSetUserGroupsOnUsers",
query)),
'Failed to set user groups ' + userGroupAliases.join(",") + ' on the users ' + userIds.join(","));
}
function getPagedResults(options) {
var defaults = {
pageSize: 25,
@@ -173,6 +185,7 @@
var resource = {
disableUsers: disableUsers,
enableUsers: enableUsers,
setUserGroupsOnUsers: setUserGroupsOnUsers,
getPagedResults: getPagedResults,
getUser: getUser,
createUser: createUser,

View File

@@ -22,7 +22,7 @@
vm.enableUser = enableUser;
vm.clearAvatar = clearAvatar;
vm.save = save;
vm.maxFileSize = Umbraco.Sys.ServerVariables.umbracoSettings.maxFileSize + "KB"
vm.maxFileSize = Umbraco.Sys.ServerVariables.umbracoSettings.maxFileSize + "KB";
vm.acceptedFileTypes = mediaHelper.formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.imageFileTypes);
vm.toggleChangePassword = toggleChangePassword;
vm.emailIsUsername = true;
@@ -56,8 +56,7 @@
vm.loading = false;
});
});
});
}
function toggleChangePassword() {
@@ -91,13 +90,9 @@
//the user has a password if they are not states: Invited, NoCredentials
vm.changePasswordModel.config.hasPassword = vm.user.userState !== 3 && vm.user.userState !== 4;
}, function (err) {
vm.page.saveButtonState = "error";
});
}
function goToPage(ancestor) {
@@ -303,7 +298,6 @@
});
}
function makeBreadcrumbs() {
vm.breadcrumbs = [
{
@@ -322,9 +316,6 @@
}
init();
}
angular.module("umbraco").controller("Umbraco.Editors.Users.UserController", UserEditController);
})();

View File

@@ -1,7 +1,7 @@
(function () {
"use strict";
function UserGroupsController($scope, $timeout, $location, userGroupsResource) {
function UserGroupsController($scope, $timeout, $location, userGroupsResource, formHelper) {
var vm = this;
@@ -12,6 +12,7 @@
vm.clickUserGroup = clickUserGroup;
vm.clearSelection = clearSelection;
vm.selectUserGroup = selectUserGroup;
vm.deleteUserGroups = deleteUserGroups;
function onInit() {
@@ -57,6 +58,18 @@
}
}
function deleteUserGroups() {
if (vm.selection.length > 0) {
userGroupsResource.deleteUserGroups(vm.selection).then(function (data) {
clearSelection();
onInit();
formHelper.showNotifications(data);
}, function(error) {
formHelper.showNotifications(error.data);
});
}
}
function clearSelection() {
angular.forEach(vm.userGroups, function (userGroup) {
userGroup.selected = false;

View File

@@ -32,7 +32,7 @@
type="button"
label="Delete"
icon="icon-trash"
action="vm.deleteUserGroup()"
action="vm.deleteUserGroups()"
size="xs">
</umb-button>
</umb-editor-sub-header-content-right>

View File

@@ -24,6 +24,8 @@
vm.newUser.userGroups = [];
vm.usersViewState = 'overview';
vm.selectedBulkUserGroups = [];
vm.allowDisableUser = true;
vm.allowEnableUser = true;
vm.allowSetUserGroup = true;
@@ -73,6 +75,7 @@
vm.clickUser = clickUser;
vm.disableUsers = disableUsers;
vm.enableUsers = enableUsers;
vm.openBulkUserGroupPicker = openBulkUserGroupPicker;
vm.openUserGroupPicker = openUserGroupPicker;
vm.removeSelectedUserGroup = removeSelectedUserGroup;
vm.selectAll = selectAll;
@@ -216,13 +219,47 @@
}
function getUserFromArrayById(userId, users) {
var userFound;
angular.forEach(users, function(user){
if(userId === user.id) {
userFound = user;
return _.find(users, function(u) { return u.id === userId });
}
function openBulkUserGroupPicker(event) {
var firstSelectedUser = getUserFromArrayById(vm.selection[0], vm.users);
vm.selectedBulkUserGroups = _.clone(firstSelectedUser.userGroups);
vm.userGroupPicker = {
title: "Select user groups",
view: "usergrouppicker",
selection: vm.selectedBulkUserGroups,
closeButtonLabel: "Cancel",
show: true,
submit: function (model) {
usersResource.setUserGroupsOnUsers(model.selection, vm.selection).then(function (data) {
// sorting to ensure they show up in right order when updating the UI
vm.selectedBulkUserGroups.sort(function (a, b) {
return a.alias > b.alias ? 1 : a.alias < b.alias ? -1 : 0;
});
// apply changes to UI
_.each(vm.selection,
function(userId) {
var user = getUserFromArrayById(userId, vm.users);
user.userGroups = vm.selectedBulkUserGroups;
});
vm.selectedBulkUserGroups = [];
vm.userGroupPicker.show = false;
vm.userGroupPicker = null;
formHelper.showNotifications(data);
clearSelection();
}, function (error) {
formHelper.showNotifications(error.data);
});
},
close: function (oldModel) {
vm.selectedBulkUserGroups = [];
vm.userGroupPicker.show = false;
vm.userGroupPicker = null;
}
});
return userFound;
};
}
function openUserGroupPicker(event) {
@@ -488,6 +525,8 @@
vm.allowEnableUser = true;
vm.allowSetUserGroup = true;
var firstSelectedUserGroups;
angular.forEach(users, function (user) {
if (!user.selected) {
@@ -514,6 +553,19 @@
vm.allowEnableUser = false;
}
// store the user group aliases of the first selected user
if (!firstSelectedUserGroups) {
firstSelectedUserGroups = user.userGroups.map(function (ug) { return ug.alias; });
vm.allowSetUserGroup = true;
} else if (vm.allowSetUserGroup === true) {
// for 2nd+ selected user, compare the user group aliases to determine if we should allow bulk editing.
// we don't allow bulk editing of users not currently having the same assigned user groups, as we can't
// really support that in the user group picker.
var userGroups = user.userGroups.map(function(ug) { return ug.alias; });
if (_.difference(firstSelectedUserGroups, userGroups).length > 0) {
vm.allowSetUserGroup = false;
}
}
});
}

View File

@@ -47,7 +47,7 @@
<umb-editor-sub-header-section>
<umb-button type="button"
label="Clear selection"
size="xs"
size="xs"
label-key="buttons_clearSelection"
action="vm.clearSelection()"
disabled="actionInProgress">
@@ -60,32 +60,32 @@
<umb-editor-sub-header-content-right ng-if="vm.selection.length > 0">
<div style="margin-right: 5px;">
<umb-button ng-if="vm.allowSetUserGroup"
type="button"
size="xs"
label="Set group"
icon="icon-users"
action="vm.setUserGroup()">
<umb-button ng-if="vm.allowSetUserGroup"
type="button"
size="xs"
label="Set group"
icon="icon-users"
action="vm.openBulkUserGroupPicker()">
</umb-button>
</div>
<div style="margin-right: 5px;">
<umb-button ng-if="vm.allowEnableUser"
type="button"
size="xs"
state="vm.enableUserButtonState"
label="Enable"
icon="icon-check"
action="vm.enableUsers()">
<umb-button ng-if="vm.allowEnableUser"
type="button"
size="xs"
state="vm.enableUserButtonState"
label="Enable"
icon="icon-check"
action="vm.enableUsers()">
</umb-button>
</div>
<div>
<umb-button ng-if="vm.allowDisableUser"
type="button"
size="xs"
state="vm.disableUserButtonState"
label="Disable"
icon="icon-block"
action="vm.disableUsers()">
<umb-button ng-if="vm.allowDisableUser"
type="button"
size="xs"
state="vm.disableUserButtonState"
label="Disable"
icon="icon-block"
action="vm.disableUsers()">
</umb-button>
</div>
</umb-editor-sub-header-content-right>

View File

@@ -1126,6 +1126,17 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="scriptErrorHeader">Script view not saved</key>
<key alias="scriptErrorText">An error occurred saving the file.</key>
<key alias="cssErrorText">An error occurred saving the file.</key>
<key alias="deleteUserGroupsSuccess">Deleted %0% user groups</key>
<key alias="deleteUserGroupSuccess">%0% was deleted</key>
<key alias="enableUsersSuccess">Enabled %0% users</key>
<key alias="enableUsersError">An error occurred while enabling the users</key>
<key alias="disableUsersSuccess">Disabled %0% users</key>
<key alias="disableUsersError">An error occurred while disabling the users</key>
<key alias="enableUserSuccess">%0% is now enabled</key>
<key alias="enableUserError">An error occurred while enabling the user</key>
<key alias="disableUserSuccess">%0% is now disabled</key>
<key alias="disableUserError">An error occurred while disabling the user</key>
<key alias="setUserGroupOnUsersSuccess">User groups have been set</key>
</area>
<area alias="stylesheet">
<key alias="aliasHelp">Uses CSS syntax ex: h1, .redHeader, .blueTex</key>

View File

@@ -1095,17 +1095,17 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="scriptErrorHeader">Script view not saved</key>
<key alias="scriptErrorText">An error occurred saving the file.</key>
<key alias="cssErrorText">An error occurred saving the file.</key>
<key alias="enableUsersSuccess">Enabled %0% users</key>
<key alias="enableUsersError">An error occurred while enabling the users</key>
<key alias="disableUsersSuccess">Disabled %0% users</key>
<key alias="disableUsersError">An error occurred while disabling the users</key>
<key alias="enableUserSuccess">%0% is now enabled </key>
<key alias="enableUserSuccess">%0% is now enabled</key>
<key alias="enableUserError">An error occurred while enabling the user</key>
<key alias="disableUserSuccess">%0% is now disabled</key>
<key alias="disableUserError">An error occurred while disabling the user</key>
<key alias="setUserGroupOnUsersSuccess">User groups have been set</key>
<key alias="deleteUserGroupsSuccess">Deleted %0% user groups</key>
<key alias="deleteUserGroupSuccess">%0% was deleted</key>
</area>
<area alias="stylesheet">
<key alias="aliasHelp">Uses CSS syntax ex: h1, .redHeader, .blueTex</key>

View File

@@ -19,6 +19,7 @@ using Umbraco.Web.Dynamics;
using System.Text.RegularExpressions;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using System.Web.Http.Controllers;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Xml;
namespace Umbraco.Web.Editors
@@ -541,11 +542,30 @@ namespace Umbraco.Web.Editors
var objectType = ConvertToObjectType(type);
if (objectType.HasValue)
{
IEnumerable<IUmbracoEntity> entities;
long totalRecords;
//if it's from root, don't return recycled
var entities = id == Constants.System.Root
? Services.EntityService.GetPagedDescendantsFromRoot(objectType.Value, pageNumber - 1, pageSize, out totalRecords, orderBy, orderDirection, filter, includeTrashed:false)
: Services.EntityService.GetPagedDescendants(id, objectType.Value, pageNumber - 1, pageSize, out totalRecords, orderBy, orderDirection, filter);
if (id == Constants.System.Root)
{
int[] aids = null;
switch (type)
{
case UmbracoEntityTypes.Document:
aids = Security.CurrentUser.AllStartContentIds;
break;
case UmbracoEntityTypes.Media:
aids = Security.CurrentUser.AllStartMediaIds;
break;
}
entities = aids != null && aids.Length > 0
? Services.EntityService.GetPagedDescendants(aids, objectType.Value, pageNumber - 1, pageSize, out totalRecords, orderBy, orderDirection, filter)
: Services.EntityService.GetPagedDescendantsFromRoot(objectType.Value, pageNumber - 1, pageSize, out totalRecords, orderBy, orderDirection, filter, includeTrashed: false);
}
else
{
entities = Services.EntityService.GetPagedDescendants(id, objectType.Value, pageNumber - 1, pageSize, out totalRecords, orderBy, orderDirection, filter);
}
if (totalRecords == 0)
{
@@ -618,9 +638,17 @@ namespace Umbraco.Web.Editors
{
if (startNode > 0)
{
// descendants
// "__Path: -1*,1234,*" -- the first "*" stands for path-to-1234
sb.Append("__Path: \\-1*\\,");
sb.Append(startNode.ToString(CultureInfo.InvariantCulture));
sb.Append("\\,* ");
// self
// "__Path: -1*,1234" -- the first "*" stands for path-to-1234
sb.Append("__Path: \\-1*\\,");
sb.Append(startNode.ToString(CultureInfo.InvariantCulture));
sb.Append(" ");
}
}
if (startNodes.Length > 0)
@@ -918,6 +946,37 @@ namespace Umbraco.Web.Editors
var ids = Services.EntityService.Get(id).Path.Split(',').Select(int.Parse).Distinct().ToArray();
int[] aids = null;
switch (entityType)
{
case UmbracoEntityTypes.Document:
aids = Security.CurrentUser.AllStartContentIds;
break;
case UmbracoEntityTypes.Media:
aids = Security.CurrentUser.AllStartMediaIds;
break;
}
if (aids != null && aids.Length > 0)
{
var lids = new List<int>();
var ok = false;
foreach (var i in ids)
{
if (ok)
{
lids.Add(i);
continue;
}
if (aids.Contains(i))
{
lids.Add(i);
ok = true;
}
}
ids = lids.ToArray();
}
return ids.Length == 0
? Enumerable.Empty<EntityBasic>()
: Services.EntityService.GetAll(objectType.Value, ids)

View File

@@ -250,6 +250,13 @@ namespace Umbraco.Web.Editors
}
#region GetChildren
private int[] _userStartNodes;
protected int[] UserStartNodes
{
get { return _userStartNodes ?? (_userStartNodes = Security.CurrentUser.AllStartMediaIds); }
}
/// <summary>
/// Returns the child media objects - using the entity INT id
/// </summary>
@@ -262,6 +269,25 @@ namespace Umbraco.Web.Editors
bool orderBySystemField = true,
string filter = "")
{
//if a request is made for the root node data but the user's start node is not the default, then
// we need to return their start nodes
if (id == Constants.System.Root && UserStartNodes.Length > 0 && UserStartNodes.Contains(Constants.System.Root) == false)
{
if (pageNumber > 0)
return new PagedResult<ContentItemBasic<ContentPropertyBasic, IMedia>>(0, 0, 0);
var nodes = Services.MediaService.GetByIds(UserStartNodes).ToArray();
if (nodes.Length == 0)
return new PagedResult<ContentItemBasic<ContentPropertyBasic, IMedia>>(0, 0, 0);
if (pageSize < nodes.Length) pageSize = nodes.Length; // bah
var pr = new PagedResult<ContentItemBasic<ContentPropertyBasic, IMedia>>(nodes.Length, pageNumber, pageSize)
{
Items = nodes.Select(Mapper.Map<IMedia, ContentItemBasic<ContentPropertyBasic, IMedia>>)
};
return pr;
}
// else proceed as usual
long totalChildren;
IMedia[] children;
if (pageNumber > 0 && pageSize > 0)

View File

@@ -5,7 +5,6 @@ using System.Net;
using System.Net.Http;
using System.Web.Http;
using AutoMapper;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Services;
using Umbraco.Web.Models.ContentEditing;
@@ -87,5 +86,21 @@ namespace Umbraco.Web.Editors
return display;
}
[HttpPost]
[HttpDelete]
public HttpResponseMessage PostDeleteUserGroups([FromUri] int[] userGroupIds)
{
var userGroups = Services.UserService.GetAllUserGroups(userGroupIds).ToArray();
foreach (var userGroup in userGroups)
{
Services.UserService.DeleteUserGroup(userGroup);
}
if (userGroups.Length > 1)
return Request.CreateNotificationSuccessResponse(
Services.TextService.Localize("speechBubbles/deleteUserGroupsSuccess", new[] {userGroups.Length.ToString()}));
return Request.CreateNotificationSuccessResponse(
Services.TextService.Localize("speechBubbles/deleteUserGroupSuccess", new[] {userGroups[0].Name}));
}
}
}

View File

@@ -546,6 +546,23 @@ namespace Umbraco.Web.Editors
Services.TextService.Localize("speechBubbles/enableUserSuccess", new[] { users[0].Name }));
}
public HttpResponseMessage PostSetUserGroupsOnUsers([FromUri]string[] userGroupAliases, [FromUri]int[] userIds)
{
var users = Services.UserService.GetUsersById(userIds).ToArray();
var userGroups = Services.UserService.GetUserGroupsByAlias(userGroupAliases).Select(x => x.ToReadOnlyGroup()).ToArray();
foreach (var u in users)
{
u.ClearGroups();
foreach (var userGroup in userGroups)
{
u.AddGroup(userGroup);
}
}
Services.UserService.Save(users);
return Request.CreateNotificationSuccessResponse(
Services.TextService.Localize("speechBubbles/setUserGroupOnUsersSuccess"));
}
public class PagedUserResult : PagedResult<UserBasic>
{
public PagedUserResult(long totalItems, long pageNumber, long pageSize) : base(totalItems, pageNumber, pageSize)

View File

@@ -46,8 +46,8 @@ namespace Umbraco.Web.Security.Providers
{
base.Initialize(name, config);
// test for membertype (if not specified, choose the first member type available)
// We'll support both names for legacy reasons: defaultUserTypeAlias & defaultUserGroupAlias
// test for membertype (if not specified, choose the first member type available)
// We'll support both names for legacy reasons: defaultUserTypeAlias & defaultUserGroupAlias
if (config["defaultUserTypeAlias"] != null)
{

View File

@@ -126,7 +126,7 @@ namespace umbraco.providers.members
_defaultMemberTypeAlias = config["defaultMemberTypeAlias"];
if (_defaultMemberTypeAlias.IsNullOrWhiteSpace())
{
throw new ProviderException("No default user group alias is specified in the web.config string. Please add a 'defaultUserTypeAlias' to the add element in the provider declaration in web.config");
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;
}