Refactoring menu permissions

This commit is contained in:
Sebastien Ros
2014-08-20 17:12:50 -07:00
parent 126efc2028
commit 4157896464
11 changed files with 128 additions and 24 deletions

View File

@@ -1,18 +1,36 @@
using Orchard.Localization;
using Orchard.ContentManagement;
using Orchard.Localization;
using Orchard.UI.Navigation;
using System.Linq;
namespace Orchard.Core.Navigation {
public class AdminMenu : INavigationProvider {
public Localizer T { get; set; }
public string MenuName { get { return "admin"; } }
public IOrchardServices Services { get; set; }
public AdminMenu(IOrchardServices services) {
Services = services;
}
public void GetNavigation(NavigationBuilder builder) {
//todo: - add new menu? and list menus? ...and remove hard-coded menu name here
var user = Services.WorkContext.CurrentUser;
// if the current user cannot manage menus, check if they can manage at least one
if (!Services.Authorizer.Authorize(Permissions.ManageMenus)) {
var menus = Services.ContentManager.Query("Menu").List();
if (!menus.Any(x => Services.Authorizer.Authorize(Permissions.ManageMenus, x))) {
return;
}
}
builder.AddImageSet("navigation")
.Add(T("Navigation"), "7",
menu => menu
.Add(T("Main Menu"), "0", item => item.Action("Index", "Admin", new { area = "Navigation" })
.Permission(Permissions.ManageMainMenu)));
));
}
}
}

View File

@@ -44,17 +44,18 @@ namespace Orchard.Core.Navigation.Controllers {
public IOrchardServices Services { get; set; }
public ActionResult Index(NavigationManagementViewModel model, int? menuId) {
var menus = Services.ContentManager.Query<TitlePart, TitlePartRecord>().OrderBy(x => x.Title).ForType("Menu").List().ToList();
var menus = Services.ContentManager.Query("Menu").List().ToList()
.OrderBy(x => x.ContentManager.GetItemMetadata(x).DisplayText);
if (!menus.Any()) {
if (!Services.Authorizer.Authorize(Permissions.ManageMainMenu, T("Not allowed to manage menus"))) {
if (!Services.Authorizer.Authorize(Permissions.ManageMenus, T("Not allowed to manage menus"))) {
return new HttpUnauthorizedResult();
}
return RedirectToAction("Create", "Admin", new { area = "Contents", id = "Menu", returnUrl = Request.RawUrl });
}
var allowedMenus = menus.Where(menu => Services.Authorizer.Authorize(Permissions.ManageMainMenu, menu)).ToList();
var allowedMenus = menus.Where(menu => Services.Authorizer.Authorize(Permissions.ManageMenus, menu)).ToList();
if (!allowedMenus.Any()) {
return new HttpUnauthorizedResult();
@@ -86,7 +87,7 @@ namespace Orchard.Core.Navigation.Controllers {
[HttpPost, ActionName("Index")]
public ActionResult IndexPOST(IList<MenuItemEntry> menuItemEntries, int? menuId) {
if (!Services.Authorizer.Authorize(Permissions.ManageMainMenu, T("Couldn't manage the main menu")))
if (!Services.Authorizer.Authorize(Permissions.ManageMenus, T("Couldn't manage the main menu")))
return new HttpUnauthorizedResult();
// See http://orchard.codeplex.com/workitem/17116
@@ -115,7 +116,7 @@ namespace Orchard.Core.Navigation.Controllers {
[HttpPost]
public ActionResult Delete(int id) {
if (!Services.Authorizer.Authorize(Permissions.ManageMainMenu, T("Couldn't manage the main menu")))
if (!Services.Authorizer.Authorize(Permissions.ManageMenus, T("Couldn't manage the main menu")))
return new HttpUnauthorizedResult();
MenuPart menuPart = _menuService.Get(id);
@@ -154,7 +155,7 @@ namespace Orchard.Core.Navigation.Controllers {
}
public ActionResult CreateMenuItem(string id, int menuId, string returnUrl) {
if (!Services.Authorizer.Authorize(Permissions.ManageMainMenu, _menuService.GetMenu(menuId), T("Couldn't manage the main menu")))
if (!Services.Authorizer.Authorize(Permissions.ManageMenus, _menuService.GetMenu(menuId), T("Couldn't manage the main menu")))
return new HttpUnauthorizedResult();
// create a new temporary menu item
@@ -186,7 +187,7 @@ namespace Orchard.Core.Navigation.Controllers {
[HttpPost, ActionName("CreateMenuItem")]
public ActionResult CreateMenuItemPost(string id, int menuId, string returnUrl) {
if (!Services.Authorizer.Authorize(Permissions.ManageMainMenu, _menuService.GetMenu(menuId), T("Couldn't manage the main menu")))
if (!Services.Authorizer.Authorize(Permissions.ManageMenus, _menuService.GetMenu(menuId), T("Couldn't manage the main menu")))
return new HttpUnauthorizedResult();
var menuPart = Services.ContentManager.New<MenuPart>(id);

View File

@@ -38,7 +38,7 @@ namespace Orchard.Core.Navigation.Drivers {
protected override DriverResult Editor(AdminMenuPart part, dynamic shapeHelper) {
// todo: we need a 'ManageAdminMenu' too?
if (!_authorizationService.TryCheckAccess(Permissions.ManageMainMenu, _orchardServices.WorkContext.CurrentUser, part)) {
if (!_authorizationService.TryCheckAccess(Permissions.ManageMenus, _orchardServices.WorkContext.CurrentUser, part)) {
return null;
}
@@ -51,7 +51,7 @@ namespace Orchard.Core.Navigation.Drivers {
}
protected override DriverResult Editor(AdminMenuPart part, IUpdateModel updater, dynamic shapeHelper) {
if (!_authorizationService.TryCheckAccess(Permissions.ManageMainMenu, _orchardServices.WorkContext.CurrentUser, part))
if (!_authorizationService.TryCheckAccess(Permissions.ManageMenus, _orchardServices.WorkContext.CurrentUser, part))
return null;
updater.TryUpdateModel(part, Prefix, null, null);

View File

@@ -17,7 +17,7 @@ namespace Orchard.Core.Navigation.Drivers {
protected override DriverResult Editor(MenuItemPart part, dynamic shapeHelper) {
var currentUser = _workContextAccessor.GetContext().CurrentUser;
if (!_authorizationService.TryCheckAccess(Permissions.ManageMainMenu, currentUser, part))
if (!_authorizationService.TryCheckAccess(Permissions.ManageMenus, currentUser, part))
return null;
return ContentShape("Parts_MenuItem_Edit",
@@ -26,7 +26,7 @@ namespace Orchard.Core.Navigation.Drivers {
protected override DriverResult Editor(MenuItemPart part, IUpdateModel updater, dynamic shapeHelper) {
var currentUser = _workContextAccessor.GetContext().CurrentUser;
if (!_authorizationService.TryCheckAccess(Permissions.ManageMainMenu, currentUser, part))
if (!_authorizationService.TryCheckAccess(Permissions.ManageMenus, currentUser, part))
return null;
if (updater != null) {

View File

@@ -39,7 +39,7 @@ namespace Orchard.Core.Navigation.Drivers {
}
protected override DriverResult Editor(MenuPart part, dynamic shapeHelper) {
var allowedMenus = _menuService.GetMenus().Where(menu => _authorizationService.TryCheckAccess(Permissions.ManageMainMenu, _orchardServices.WorkContext.CurrentUser, menu)).ToList();
var allowedMenus = _menuService.GetMenus().Where(menu => _authorizationService.TryCheckAccess(Permissions.ManageMenus, _orchardServices.WorkContext.CurrentUser, menu)).ToList();
if (!allowedMenus.Any())
return null;
@@ -63,7 +63,7 @@ namespace Orchard.Core.Navigation.Drivers {
if(updater.TryUpdateModel(model, Prefix, null, null)) {
var menu = model.OnMenu ? _orchardServices.ContentManager.Get(model.CurrentMenuId) : null;
if (!_authorizationService.TryCheckAccess(Permissions.ManageMainMenu, _orchardServices.WorkContext.CurrentUser, menu))
if (!_authorizationService.TryCheckAccess(Permissions.ManageMenus, _orchardServices.WorkContext.CurrentUser, menu))
return null;
part.MenuText = model.MenuText;

View File

@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData.Models;
using Orchard.Core.Navigation.Services;
using Orchard.Core.Title.Models;
using Orchard.Environment.Extensions.Models;
using Orchard.Security.Permissions;
namespace Orchard.Core.Navigation {
public class DynamicPermissions : IPermissionProvider {
private static readonly Permission ManageMenu = new Permission { Description = "Manage '{0}' menu", Name = "Manage_{0}", ImpliedBy = new[] { Permissions.ManageMenus } };
private readonly IMenuService _menuService;
private readonly IContentManager _contentManager;
public virtual Feature Feature { get; set; }
public DynamicPermissions(
IMenuService menuService,
IContentManager contentManager) {
_menuService = menuService;
_contentManager = contentManager;
}
public IEnumerable<Permission> GetPermissions() {
return _menuService.GetMenus().Select(menu => CreateMenuPermission(menu, _contentManager));
}
public IEnumerable<PermissionStereotype> GetDefaultStereotypes() {
return Enumerable.Empty<PermissionStereotype>();
}
public static Permission CreateMenuPermission(ContentItem menu, IContentManager contentManager) {
var metadata = contentManager.GetItemMetadata(menu);
return new Permission {
Name = String.Format(ManageMenu.Name, metadata.Identity),
Description = String.Format(ManageMenu.Description, metadata.DisplayText),
Category = "Navigation Feature",
ImpliedBy = new[] { Permissions.ManageMenus }
};
}
}
}

View File

@@ -4,13 +4,13 @@ using Orchard.Security.Permissions;
namespace Orchard.Core.Navigation {
public class Permissions : IPermissionProvider {
public static readonly Permission ManageMainMenu = new Permission { Name = "ManageMainMenu", Description = "Manage main menu" };
public static readonly Permission ManageMenus = new Permission { Name = "ManageMenus", Description = "Manage all menus" };
public virtual Feature Feature { get; set; }
public IEnumerable<Permission> GetPermissions() {
return new[] {
ManageMainMenu
ManageMenus
};
}
@@ -18,7 +18,7 @@ namespace Orchard.Core.Navigation {
return new[] {
new PermissionStereotype {
Name = "Administrator",
Permissions = new[] {ManageMainMenu}
Permissions = new[] {ManageMenus}
}
};
}

View File

@@ -0,0 +1,30 @@
using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.Security;
namespace Orchard.Core.Navigation.Security {
[UsedImplicitly]
public class AuthorizationEventHandler : IAuthorizationServiceEventHandler {
private readonly IContentManager _contentManager;
public AuthorizationEventHandler(IContentManager contentManager) {
_contentManager = contentManager;
}
public void Checking(CheckAccessContext context) { }
public void Complete(CheckAccessContext context) { }
public void Adjust(CheckAccessContext context) {
if (!context.Granted && context.Permission.Name == Permissions.ManageMenus.Name && context.Content != null) {
var menuAsContentItem = context.Content.As<ContentItem>();
if (menuAsContentItem == null || menuAsContentItem.Id <= 0) {
return;
}
context.Adjusted = true;
context.Permission = DynamicPermissions.CreateMenuPermission(menuAsContentItem, _contentManager);
}
}
}
}

View File

@@ -9,6 +9,8 @@
Script.Require("jQueryUI_Sortable").AtFoot();
Script.Include("jquery.mjs.nestedSortable.js").AtFoot();
Script.Include("navigation-admin.js").AtFoot();
var hasPermission = Authorizer.Authorize(Orchard.Core.Navigation.Permissions.ManageMenus);
}
<div id="save-message" class="message message-Warning">@T("You need to hit \"Save All\" in order to save your changes.")</div>
@@ -23,14 +25,17 @@
@Html.SelectOption(Model.CurrentMenu.Id, menu.Id, Convert.ToString(Html.ItemDisplayText(menu)))
}
</select>
<button type="submit" class="apply-bulk-actions-auto">@T("Show")</button>
@Html.ActionLink(T("Edit").Text, "Edit", "Admin", new { area = "Contents", id = Model.CurrentMenu.Id, returnUrl = Url.Action("Index", "Admin", new { area = "Navigation", menuId = Model.CurrentMenu.Id }) }, new { @class = "button" })
@if (hasPermission) {
@Html.ActionLink(T("Edit").Text, "Edit", "Admin", new { area = "Contents", id = Model.CurrentMenu.Id, returnUrl = Url.Action("Index", "Admin", new { area = "Navigation", menuId = Model.CurrentMenu.Id }) }, new { @class = "button" })
}
</fieldset>
}
}
@if (hasPermission) {
<div id="navigation-menu-add">
@Html.Link(T("Add a new menu...").Text, Url.Action("Create", "Admin", new { area = "Contents", id = "Menu", returnUrl = Request.RawUrl }))
</div>
}
</div>
@@ -131,6 +136,10 @@
<script type="text/javascript">
//<![CDATA[
var leaveConfirmation = '@T("Some items where not saved.")';
$('#menuId').change(function () {
$(this).parents('form').submit();
});
//]]>
</script>
}

View File

@@ -43,7 +43,7 @@ namespace Orchard.ContentPicker.Drivers {
protected override DriverResult Editor(ContentMenuItemPart part, IUpdateModel updater, dynamic shapeHelper) {
var currentUser = _workContextAccessor.GetContext().CurrentUser;
if (!_authorizationService.TryCheckAccess(Permissions.ManageMainMenu, currentUser, part))
if (!_authorizationService.TryCheckAccess(Permissions.ManageMenus, currentUser, part))
return null;
var model = new ContentMenuItemEditViewModel();

View File

@@ -46,7 +46,7 @@ namespace Orchard.ContentPicker.Drivers {
protected override DriverResult Editor(NavigationPart part, dynamic shapeHelper) {
var currentUser = _workContextAccessor.GetContext().CurrentUser;
var allowedMenus = _menuService.GetMenus().Where(menu => _authorizationService.TryCheckAccess(Permissions.ManageMainMenu, currentUser, menu)).ToList();
var allowedMenus = _menuService.GetMenus().Where(menu => _authorizationService.TryCheckAccess(Permissions.ManageMenus, currentUser, menu)).ToList();
if (!allowedMenus.Any())
return null;
@@ -70,7 +70,7 @@ namespace Orchard.ContentPicker.Drivers {
protected override DriverResult Editor(NavigationPart part, IUpdateModel updater, dynamic shapeHelper) {
var currentUser = _workContextAccessor.GetContext().CurrentUser;
var allowedMenus = _menuService.GetMenus().Where(menu => _authorizationService.TryCheckAccess(Permissions.ManageMainMenu, currentUser, menu)).ToList();
var allowedMenus = _menuService.GetMenus().Where(menu => _authorizationService.TryCheckAccess(Permissions.ManageMenus, currentUser, menu)).ToList();
if (!allowedMenus.Any())
return null;