diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js
index e629bb0beb..49c3745970 100644
--- a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js
+++ b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js
@@ -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(
diff --git a/src/Umbraco.Web.UI.Client/src/views/content/content.rights.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/content.rights.controller.js
index 614be714f5..764aaac3ca 100644
--- a/src/Umbraco.Web.UI.Client/src/views/content/content.rights.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/content/content.rights.controller.js
@@ -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;
});
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/content/rights.html b/src/Umbraco.Web.UI.Client/src/views/content/rights.html
index defedb550e..2f58f8618b 100644
--- a/src/Umbraco.Web.UI.Client/src/views/content/rights.html
+++ b/src/Umbraco.Web.UI.Client/src/views/content/rights.html
@@ -59,11 +59,11 @@
Set permissions for {{ vm.selectedUserGroup.name }}
Nam tellus purus, malesuada sed purus ut, semper sollicitudin odio.
-
+
-
{{ group.groupName }}
+
{{ category }}
-
+
);
}
+
+ ///
+ /// Returns the user group permissions for user groups assigned to this node
+ ///
+ ///
+ ///
+ ///
+ /// Permission check is done for letter 'R' which is for which the user must have access to to view
+ ///
+ [EnsureUserPermissionForContent("contentId", 'R')]
+ public IEnumerable 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>(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;
+ }
///
/// Returns an item to be used to display the recycle bin for content
@@ -303,6 +355,7 @@ namespace Umbraco.Web.Editors
///
/// Returns permissions for all nodes passed in for the current user
+ /// TODO: This should be moved to the CurrentUserController?
///
///
///
@@ -312,8 +365,15 @@ namespace Umbraco.Web.Editors
return Services.UserService
.GetPermissions(Security.CurrentUser, nodeIds)
.ToDictionary(x => x.EntityId, x => x.AssignedPermissions);
- }
+ }
+ ///
+ /// Checks a nodes permission for the current user
+ /// TODO: This should be moved to the CurrentUserController?
+ ///
+ ///
+ ///
+ ///
[HttpGet]
public bool HasPermission(string permissionToCheck, int nodeId)
{
diff --git a/src/Umbraco.Web/Models/ContentEditing/AssignedUserGroupPermissions.cs b/src/Umbraco.Web/Models/ContentEditing/AssignedUserGroupPermissions.cs
new file mode 100644
index 0000000000..8875550454
--- /dev/null
+++ b/src/Umbraco.Web/Models/ContentEditing/AssignedUserGroupPermissions.cs
@@ -0,0 +1,18 @@
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace Umbraco.Web.Models.ContentEditing
+{
+ ///
+ /// The user group permissions assigned to a content node
+ ///
+ [DataContract(Name = "contentPermission", Namespace = "")]
+ public class AssignedUserGroupPermissions : EntityBasic
+ {
+ ///
+ /// The default permissions for the user group organized by permission group name
+ ///
+ [DataMember(Name = "permissions")]
+ public IDictionary> AssignedPermissions { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Models/ContentEditing/Permission.cs b/src/Umbraco.Web/Models/ContentEditing/Permission.cs
index c2b76c9ca7..a47a1d5c33 100644
--- a/src/Umbraco.Web/Models/ContentEditing/Permission.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/Permission.cs
@@ -22,5 +22,11 @@ namespace Umbraco.Web.Models.ContentEditing
///
[IgnoreDataMember]
internal string Category { get; set; }
+
+ ///
+ /// Used internall to carry the permission letter from the IAction
+ ///
+ [IgnoreDataMember]
+ internal string Letter { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Models/ContentEditing/UserGroupBasic.cs b/src/Umbraco.Web/Models/ContentEditing/UserGroupBasic.cs
index df39a9fdab..e610eec7e0 100644
--- a/src/Umbraco.Web/Models/ContentEditing/UserGroupBasic.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/UserGroupBasic.cs
@@ -4,16 +4,6 @@ using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
- [DataContract(Name = "userGroup", Namespace = "")]
- public class UserGroupPermission : EntityBasic
- {
- ///
- /// The default permissions for the user group organized by permission group name
- ///
- [DataMember(Name = "permissions")]
- public IDictionary> DefaultPermissions { get; set; }
- }
-
[DataContract(Name = "userGroup", Namespace = "")]
public class UserGroupBasic : EntityBasic, INotificationModel
{
diff --git a/src/Umbraco.Web/Models/Mapping/PermissionsResolver.cs b/src/Umbraco.Web/Models/Mapping/PermissionsResolver.cs
index f4be88c39a..5bbee5acf5 100644
--- a/src/Umbraco.Web/Models/Mapping/PermissionsResolver.cs
+++ b/src/Umbraco.Web/Models/Mapping/PermissionsResolver.cs
@@ -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;
}
}
diff --git a/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs b/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs
index 41dd6ade35..4436f79d7f 100644
--- a/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs
+++ b/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs
@@ -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()
@@ -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()
+ .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()
.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())
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 857a4e38af..9a512b2b92 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -367,6 +367,7 @@
+