Adds GetDetailedPermissions to the content controller which is used in the permissions dialog

This commit is contained in:
Shannon
2017-06-29 01:00:52 +10:00
parent 3cd39fee94
commit 85d988e75e
10 changed files with 128 additions and 123 deletions

View File

@@ -40,6 +40,8 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
return {
getRecycleBin: function () {
return umbRequestHelper.resourcePromise(
$http.get(
@@ -554,6 +556,15 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
'Failed to check permission for item ' + id);
},
getDetailedPermissions: function (contentId) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"contentApiBaseUrl",
"GetDetailedPermissions", { contentId: contentId })),
'Failed to retrieve permissions for content item ' + contentId);
},
getPermissions: function (nodeIds) {
return umbRequestHelper.resourcePromise(
$http.post(

View File

@@ -1,7 +1,7 @@
(function () {
"use strict";
function ContentRightsController($scope, usersResource) {
function ContentRightsController($scope, contentResource) {
var vm = this;
@@ -19,106 +19,9 @@
function onInit() {
vm.loading = true;
usersResource.getUserGroups().then(function (userGroups) {
contentResource.getDetailedPermissions($scope.currentNode.id).then(function (userGroups) {
vm.availableUserGroups = userGroups;
vm.loading = false;
// fake permissions
angular.forEach(vm.availableUserGroups, function(userGroup){
userGroup.permissions = [
{
"groupName": "Content",
"permissions": [
{
"name": "Edit content (save)",
"description": "Lorem ipsum dolor sit amet",
"checked": false
},
{
"name": "Browse content",
"description": "Nullam egestas porta mi, quis finibus nisl commodo a",
"checked": true
},
{
"name": "Publish",
"description": "Aliquam molestie consequat felis",
"checked": true
},
{
"name": "Send to publish",
"description": "Sed pharetra sodales enim quis molestie",
"checked": true
},
{
"name": "Delete",
"description": "Vitae porta mauris turpis sit amet ligula",
"checked": true
},
{
"name": "Create",
"description": "Vestibulum pretium sapien id turpis elementum viverra",
"checked": true
},
]
},
{
"groupName": "Structure",
"permissions": [
{
"name": "Move",
"description": "Vestibulum pretium sapien id turpis elementum viverra",
"checked": true
},
{
"name": "Copy",
"description": "Phasellus sagittis, dolor vel accumsan porttitor",
"checked": false
},
{
"name": "Sort",
"description": "Aliquam erat volutpat",
"checked": false
}
]
},
{
"groupName": "Administration",
"permissions": [
{
"name": "Culture and Hostnames",
"description": "Lorem ipsum dolor sit amet",
"checked": true
},
{
"name": "Audit Trail",
"description": "Lorem ipsum dolor sit amet",
"checked": true
},
{
"name": "Translate",
"description": "Lorem ipsum dolor sit amet",
"checked": true
},
{
"name": "Change document type",
"description": "Lorem ipsum dolor sit amet",
"checked": true
},
{
"name": "Public access",
"description": "Lorem ipsum dolor sit amet",
"checked": true
},
{
"name": "Rollback",
"description": "Lorem ipsum dolor sit amet",
"checked": true
}
]
}
];
});
vm.loading = false;
});
}

View File

@@ -59,11 +59,11 @@
<h5>Set permissions for {{ vm.selectedUserGroup.name }}</h5>
<p class="abstract" style="margin-bottom: 20px;">Nam tellus purus, malesuada sed purus ut, semper sollicitudin odio.</p>
<div ng-repeat="group in vm.selectedUserGroup.permissions">
<div ng-repeat="(category, permissions) in vm.selectedUserGroup.permissions">
<h5>{{ group.groupName }}</h5>
<h5>{{ category }}</h5>
<div class="umb-permission" ng-repeat="permission in group.permissions">
<div class="umb-permission" ng-repeat="permission in permissions">
<umb-toggle
class="umb-permission__toggle"
checked="permission.checked"

View File

@@ -9,6 +9,7 @@ using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.ModelBinding;
using AutoMapper;
using umbraco.BusinessLogic.Actions;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
@@ -81,6 +82,57 @@ namespace Umbraco.Web.Editors
var foundContent = Services.ContentService.GetByIds(ids);
return foundContent.Select(Mapper.Map<IContent, ContentItemDisplay>);
}
/// <summary>
/// Returns the user group permissions for user groups assigned to this node
/// </summary>
/// <param name="contentId"></param>
/// <returns></returns>
/// <remarks>
/// Permission check is done for letter 'R' which is for <see cref="ActionRights"/> which the user must have access to to view
/// </remarks>
[EnsureUserPermissionForContent("contentId", 'R')]
public IEnumerable<AssignedUserGroupPermissions> GetDetailedPermissions(int contentId)
{
if (contentId <= 0) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
var found = Services.ContentService.GetById(contentId);
if (found == null) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
//get all user groups and map their default permissions to the AssignedUserGroupPermissions model.
//we do this because not all groups will have true assigned permissions for this node so if they don't have assigned permissions, we need to show the defaults.
var allUserGroups = Services.UserService.GetAllUserGroups();
var defaultPermissionsByGroup = Mapper.Map<IEnumerable<AssignedUserGroupPermissions>>(allUserGroups)
.ToDictionary(x => Convert.ToInt32(x.Id), x => x);
//get the actual assigned permissions
var assignedPermissionsByGroup = Services.ContentService.GetPermissionsForEntity(found).ToArray();
//iterate over assigned and update the defaults with the real values
foreach (var assignedGroupPermission in assignedPermissionsByGroup)
{
var defaultUserGroupPermissions = defaultPermissionsByGroup[assignedGroupPermission.UserGroupId];
//iterate each assigned permission for this group, the permission is essentially the letter of the action
foreach (var assignedPermission in assignedGroupPermission.AssignedPermissions)
{
//find this permission letter in the default model
//iterate through the dictionary
foreach (var defaultUserGroupPermissionByGroup in defaultUserGroupPermissions.AssignedPermissions)
{
//iterate through the key/value pair values
foreach (var permissionInGroup in defaultUserGroupPermissionByGroup.Value)
{
//assigned the checked parameter based on the actual assigned permission
permissionInGroup.Checked = permissionInGroup.Letter == assignedPermission;
}
}
}
}
return defaultPermissionsByGroup.Values;
}
/// <summary>
/// Returns an item to be used to display the recycle bin for content
@@ -303,6 +355,7 @@ namespace Umbraco.Web.Editors
/// <summary>
/// Returns permissions for all nodes passed in for the current user
/// TODO: This should be moved to the CurrentUserController?
/// </summary>
/// <param name="nodeIds"></param>
/// <returns></returns>
@@ -312,8 +365,15 @@ namespace Umbraco.Web.Editors
return Services.UserService
.GetPermissions(Security.CurrentUser, nodeIds)
.ToDictionary(x => x.EntityId, x => x.AssignedPermissions);
}
}
/// <summary>
/// Checks a nodes permission for the current user
/// TODO: This should be moved to the CurrentUserController?
/// </summary>
/// <param name="permissionToCheck"></param>
/// <param name="nodeId"></param>
/// <returns></returns>
[HttpGet]
public bool HasPermission(string permissionToCheck, int nodeId)
{

View File

@@ -0,0 +1,18 @@
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// The user group permissions assigned to a content node
/// </summary>
[DataContract(Name = "contentPermission", Namespace = "")]
public class AssignedUserGroupPermissions : EntityBasic
{
/// <summary>
/// The default permissions for the user group organized by permission group name
/// </summary>
[DataMember(Name = "permissions")]
public IDictionary<string, IEnumerable<Permission>> AssignedPermissions { get; set; }
}
}

View File

@@ -22,5 +22,11 @@ namespace Umbraco.Web.Models.ContentEditing
/// </summary>
[IgnoreDataMember]
internal string Category { get; set; }
/// <summary>
/// Used internall to carry the permission letter from the IAction
/// </summary>
[IgnoreDataMember]
internal string Letter { get; set; }
}
}

View File

@@ -4,16 +4,6 @@ using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "userGroup", Namespace = "")]
public class UserGroupPermission : EntityBasic
{
/// <summary>
/// The default permissions for the user group organized by permission group name
/// </summary>
[DataMember(Name = "permissions")]
public IDictionary<string, IEnumerable<Permission>> DefaultPermissions { get; set; }
}
[DataContract(Name = "userGroup", Namespace = "")]
public class UserGroupBasic : EntityBasic, INotificationModel
{

View File

@@ -46,9 +46,8 @@ namespace Umbraco.Web.Models.Mapping
: attribute.Name;
result.Description = _textService.Localize(String.Format("actionDescriptions/{0}", action.Alias));
result.Icon = action.Icon;
result.Checked = source.Permissions.Contains(action.Letter.ToString(CultureInfo.InvariantCulture));
result.Letter = action.Letter.ToString(CultureInfo.InvariantCulture);
return result;
}
}

View File

@@ -27,18 +27,18 @@ namespace Umbraco.Web.Models.Mapping
.ConstructUsing((UserGroupSave save) => new UserGroup() { CreateDate = DateTime.Now })
.IgnoreAllUnmapped()
.ForMember(user => user.Alias, expression => expression.MapFrom(save => save.Alias))
.ForMember(user => user.Name, expression => expression.MapFrom(save => save.Name))
.ForMember(user => user.Icon, expression => expression.MapFrom(save => save.Icon))
.ForMember(user => user.StartMediaId, expression => expression.MapFrom(save => save.StartMediaId))
.ForMember(user => user.StartContentId, expression => expression.MapFrom(save => save.StartContentId))
.ForMember(user => user.Name, expression => expression.MapFrom(save => save.Name))
.ForMember(user => user.Icon, expression => expression.MapFrom(save => save.Icon))
.ForMember(user => user.StartMediaId, expression => expression.MapFrom(save => save.StartMediaId))
.ForMember(user => user.StartContentId, expression => expression.MapFrom(save => save.StartContentId))
.AfterMap((save, userGroup) =>
{
userGroup.ClearAllowedSections();
foreach (var section in save.Sections)
{
{
userGroup.AddAllowedSection(section);
}
});
});
//Used for merging existing UserSave to an existing IUser instance - this will not create an IUser instance!
config.CreateMap<UserSave, IUser>()
@@ -100,6 +100,22 @@ namespace Umbraco.Web.Models.Mapping
MapUserGroupBasic(applicationContext.Services, group, display);
});
//create a map to assign a user group's default permissions to the AssignedUserGroupPermissions instance
config.CreateMap<IUserGroup, AssignedUserGroupPermissions>()
.ForMember(detail => detail.Udi, opt => opt.Ignore())
.ForMember(detail => detail.Trashed, opt => opt.Ignore())
.ForMember(detail => detail.AdditionalData, opt => opt.Ignore())
.ForMember(detail => detail.Id, opt => opt.MapFrom(group => group.Id))
.ForMember(detail => detail.ParentId, opt => opt.UseValue(-1))
.ForMember(detail => detail.Path, opt => opt.MapFrom(userGroup => "-1," + userGroup.Id))
.ForMember(detail => detail.AssignedPermissions, expression => expression.ResolveUsing(new PermissionsResolver(applicationContext.Services.TextService)))
.AfterMap((group, display) =>
{
if (display.Icon.IsNullOrWhiteSpace())
{
display.Icon = "icon-users";
}
});
config.CreateMap<IUserGroup, UserGroupDisplay>()
.ForMember(detail => detail.StartContentId, opt => opt.Ignore())
.ForMember(detail => detail.StartMediaId, opt => opt.Ignore())
@@ -110,7 +126,7 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(detail => detail.ParentId, opt => opt.UseValue(-1))
.ForMember(detail => detail.Path, opt => opt.MapFrom(userGroup => "-1," + userGroup.Id))
.ForMember(detail => detail.AdditionalData, opt => opt.Ignore())
.ForMember(detail => detail.Users, opt => opt.Ignore())
.ForMember(detail => detail.Users, opt => opt.Ignore())
.ForMember(detail => detail.DefaultPermissions, expression => expression.ResolveUsing(new PermissionsResolver(applicationContext.Services.TextService)))
.AfterMap((group, display) =>
{
@@ -138,6 +154,7 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(detail => detail.Notifications, opt => opt.Ignore())
.ForMember(detail => detail.Udi, opt => opt.Ignore())
.ForMember(detail => detail.Icon, opt => opt.Ignore())
.ForMember(detail => detail.IsCurrentUser, opt => opt.Ignore())
.ForMember(detail => detail.Trashed, opt => opt.Ignore())
.ForMember(detail => detail.ResetPasswordValue, opt => opt.Ignore())
.ForMember(detail => detail.Alias, opt => opt.Ignore())

View File

@@ -367,6 +367,7 @@
<Compile Include="HealthCheck\StatusResultType.cs" />
<Compile Include="HealthCheck\Checks\DataIntegrity\XmlDataIntegrityHealthCheck.cs" />
<Compile Include="IHttpContextAccessor.cs" />
<Compile Include="Models\ContentEditing\AssignedUserGroupPermissions.cs" />
<Compile Include="Models\ContentEditing\ContentRedirectUrl.cs" />
<Compile Include="Models\ContentEditing\GetAvailableCompositionsFilter.cs" />
<Compile Include="Editors\IEditorValidator.cs" />