Merge branch 'user-group-permissions' into temp-U4-10075
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
})();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user