diff --git a/src/Orchard.Tests/UI/Navigation/NavigationManagerTests.cs b/src/Orchard.Tests/UI/Navigation/NavigationManagerTests.cs index 105f3ee3c..8f4e5e37c 100644 --- a/src/Orchard.Tests/UI/Navigation/NavigationManagerTests.cs +++ b/src/Orchard.Tests/UI/Navigation/NavigationManagerTests.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; using NUnit.Framework; +using Orchard.Security; +using Orchard.Security.Permissions; using Orchard.UI.Navigation; namespace Orchard.Tests.UI.Navigation { @@ -10,15 +12,21 @@ namespace Orchard.Tests.UI.Navigation { public class NavigationManagerTests { [Test] public void EmptyMenuIfNameDoesntMatch() { - var manager = new NavigationManager(new[] { new StubProvider() }); + var manager = new NavigationManager(new[] { new StubProvider() }, new StubAuth()); var menuItems = manager.BuildMenu("primary"); Assert.That(menuItems.Count(), Is.EqualTo(0)); } + public class StubAuth : IAuthorizationService { + public bool CheckAccess(IUser user, Permission permission) { + return true; + } + } + [Test] public void NavigationManagerShouldUseProvidersToBuildNamedMenu() { - var manager = new NavigationManager(new[] { new StubProvider() }); + var manager = new NavigationManager(new[] { new StubProvider() }, new StubAuth()); var menuItems = manager.BuildMenu("admin"); Assert.That(menuItems.Count(), Is.EqualTo(2)); @@ -30,7 +38,7 @@ namespace Orchard.Tests.UI.Navigation { [Test] public void NavigationManagerShouldMergeAndOrderNavigation() { - var manager = new NavigationManager(new INavigationProvider[] { new StubProvider(), new Stub2Provider() }); + var manager = new NavigationManager(new INavigationProvider[] { new StubProvider(), new Stub2Provider() }, new StubAuth()); var menuItems = manager.BuildMenu("admin"); Assert.That(menuItems.Count(), Is.EqualTo(3)); diff --git a/src/Orchard.Web/Packages/Orchard.CmsPages/AdminMenu.cs b/src/Orchard.Web/Packages/Orchard.CmsPages/AdminMenu.cs index fd24a26b2..bec506300 100644 --- a/src/Orchard.Web/Packages/Orchard.CmsPages/AdminMenu.cs +++ b/src/Orchard.Web/Packages/Orchard.CmsPages/AdminMenu.cs @@ -8,7 +8,7 @@ namespace Orchard.CmsPages { builder.Add("Pages", "1", menu => menu .Add("Manage Pages", "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.CmsPages" })) - .Add("Add a Page", "1.1", item => item.Action("Create", "Admin", new { area = "Orchard.CmsPages" })) + .Add("Add a Page", "1.1", item => item.Action("Create", "Admin", new { area = "Orchard.CmsPages" }).Permission(Permissions.CreatePages)) ); } } diff --git a/src/Orchard/UI/Navigation/MenuItem.cs b/src/Orchard/UI/Navigation/MenuItem.cs index e41d2fee7..bcee289e1 100644 --- a/src/Orchard/UI/Navigation/MenuItem.cs +++ b/src/Orchard/UI/Navigation/MenuItem.cs @@ -1,11 +1,19 @@ +using System; using System.Collections.Generic; +using System.Linq; using System.Web.Routing; +using Orchard.Security.Permissions; namespace Orchard.UI.Navigation { public class MenuItem { + public MenuItem() { + Permissions = Enumerable.Empty(); + } + public string Text { get; set; } public string Position { get; set; } public RouteValueDictionary RouteValues { get; set; } public IEnumerable Items { get; set; } + public IEnumerable Permissions { get; set; } } } \ No newline at end of file diff --git a/src/Orchard/UI/Navigation/NavigationBuilder.cs b/src/Orchard/UI/Navigation/NavigationBuilder.cs index da1e2db69..25050dc0c 100644 --- a/src/Orchard/UI/Navigation/NavigationBuilder.cs +++ b/src/Orchard/UI/Navigation/NavigationBuilder.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Web.Routing; +using Orchard.Security.Permissions; namespace Orchard.UI.Navigation { public class NavigationBuilder { @@ -56,6 +57,11 @@ namespace Orchard.UI.Navigation { return this; } + public NavigationItemBuilder Permission(Permission permission) { + _item.Permissions = _item.Permissions.Concat(new[]{permission}); + return this; + } + public new IEnumerable Build() { _item.Items = base.Build(); return new[] { _item }; diff --git a/src/Orchard/UI/Navigation/NavigationManager.cs b/src/Orchard/UI/Navigation/NavigationManager.cs index d99cef6b9..5acfd6377 100644 --- a/src/Orchard/UI/Navigation/NavigationManager.cs +++ b/src/Orchard/UI/Navigation/NavigationManager.cs @@ -1,7 +1,9 @@ -using System.Collections; +using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; +using Orchard.Security; namespace Orchard.UI.Navigation { public interface INavigationManager : IDependency { @@ -10,13 +12,32 @@ namespace Orchard.UI.Navigation { public class NavigationManager : INavigationManager { private readonly IEnumerable _providers; + private readonly IAuthorizationService _authorizationService; - public NavigationManager(IEnumerable providers) { + public NavigationManager(IEnumerable providers, IAuthorizationService authorizationService) { _providers = providers; + _authorizationService = authorizationService; } + public IUser CurrentUser { get; set; } + public IEnumerable BuildMenu(string menuName) { - return Merge(AllSources(menuName)).ToArray(); + return Reduce(Merge(AllSources(menuName))).ToArray(); + } + + private IEnumerable Reduce(IEnumerable items) { + foreach(var item in items) { + if (!item.Permissions.Any() || + item.Permissions.Any(x=>_authorizationService.CheckAccess(CurrentUser, x))) { + yield return new MenuItem { + Items = Reduce(item.Items), + Permissions = item.Permissions, + Position = item.Position, + RouteValues = item.RouteValues, + Text = item.Text, + }; + } + } } private IEnumerable> AllSources(string menuName) { @@ -46,7 +67,8 @@ namespace Orchard.UI.Navigation { Text = items.First().Text, RouteValues = items.First().RouteValues, Items = Merge(items.Select(x => x.Items)).ToArray(), - Position = SelectBestPositionValue(items.Select(x => x.Position)) + Position = SelectBestPositionValue(items.Select(x => x.Position)), + Permissions = items.SelectMany(x=>x.Permissions), }; return joined; }