Extending security model for owned/other content permission support

Added an IContent parameter to IAuthorizationService and IAuthorizer
Added an IAuthorizationServiceEvents interface for modules to participate in the process
Updated the role-based authorization service to fire events and recheck access based on adjustments
Added hook in Orchard.Pages/Security/Authorization.cs with "pages" specific auth adjustments

--HG--
extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4045861
This commit is contained in:
loudej
2010-01-22 22:11:10 +00:00
parent 09c88f124c
commit e9b32d59ca
18 changed files with 260 additions and 80 deletions

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Orchard.ContentManagement;
using Orchard.Security;
using Orchard.Security.Permissions;
using Orchard.UI.Navigation;
@@ -19,10 +20,10 @@ namespace Orchard.Tests.UI.Navigation {
}
public class StubAuth : IAuthorizationService {
public void CheckAccess(IUser user, Permission permission) {
public void CheckAccess(Permission permission, IUser user, IContent content) {
}
public bool TryCheckAccess(IUser user, Permission permission) {
public bool TryCheckAccess(Permission permission, IUser user, IContent content) {
return true;
}
}

View File

@@ -134,7 +134,7 @@ namespace Orchard.Core.Common.Providers {
private void GetEditor(BuildEditorModelContext context, CommonAspect instance) {
var currentUser = _authenticationService.GetAuthenticatedUser();
if (!_authorizationService.TryCheckAccess(currentUser, Permissions.ChangeOwner)) {
if (!_authorizationService.TryCheckAccess(Permissions.ChangeOwner, currentUser, instance)) {
return;
}
var viewModel = new OwnerEditorViewModel();
@@ -152,7 +152,7 @@ namespace Orchard.Core.Common.Providers {
instance.VersionModifiedUtc = _clock.UtcNow;
var currentUser = _authenticationService.GetAuthenticatedUser();
if (!_authorizationService.TryCheckAccess(currentUser, Permissions.ChangeOwner)) {
if (!_authorizationService.TryCheckAccess(Permissions.ChangeOwner, currentUser, instance)) {
return;
}

View File

@@ -46,7 +46,7 @@ namespace Orchard.Media.Services {
XRpcStruct file) {
var user = _membershipService.ValidateUser(userName, password);
if (!_authorizationService.TryCheckAccess(user, Permissions.UploadMediaFiles)) {
if (!_authorizationService.TryCheckAccess(Permissions.UploadMediaFiles, user, null)) {
//TEMP: return appropriate access-denied response for user
throw new ApplicationException("Access denied");
}

View File

@@ -14,15 +14,15 @@ using Orchard.UI.Notify;
namespace Orchard.Pages.Controllers {
[ValidateInput(false)]
public class AdminController : Controller, IUpdateModel {
private readonly IOrchardServices _services;
private readonly IPageService _pageService;
public AdminController(IOrchardServices services, IPageService pageService) {
_services = services;
Services = services;
_pageService = pageService;
T = NullLocalizer.Instance;
}
public IOrchardServices Services { get; private set; }
private Localizer T { get; set; }
public ActionResult List(PagesOptions options) {
@@ -58,7 +58,7 @@ namespace Orchard.Pages.Controllers {
case PagesBulkAction.None:
break;
case PagesBulkAction.PublishNow:
if (!_services.Authorizer.Authorize(Permissions.PublishPages, T("Couldn't publish page")))
if (!Services.Authorizer.Authorize(Permissions.PublishPages, T("Couldn't publish page")))
return new HttpUnauthorizedResult();
foreach (PageEntry entry in checkedEntries) {
@@ -67,7 +67,7 @@ namespace Orchard.Pages.Controllers {
}
break;
case PagesBulkAction.Unpublish:
if (!_services.Authorizer.Authorize(Permissions.PublishPages, T("Couldn't unpublish page")))
if (!Services.Authorizer.Authorize(Permissions.PublishPages, T("Couldn't unpublish page")))
return new HttpUnauthorizedResult();
foreach (PageEntry entry in checkedEntries) {
var page = _pageService.GetLatest(entry.PageId);
@@ -75,7 +75,7 @@ namespace Orchard.Pages.Controllers {
}
break;
case PagesBulkAction.Delete:
if (!_services.Authorizer.Authorize(Permissions.DeletePages, T("Couldn't delete page")))
if (!Services.Authorizer.Authorize(Permissions.DeletePages, T("Couldn't delete page")))
return new HttpUnauthorizedResult();
foreach (PageEntry entry in checkedEntries) {
@@ -99,10 +99,10 @@ namespace Orchard.Pages.Controllers {
}
public ActionResult Create() {
if (!_services.Authorizer.Authorize(Permissions.EditPages, T("Not allowed to create a page")))
if (!Services.Authorizer.Authorize(Permissions.EditPages, T("Not allowed to create a page")))
return new HttpUnauthorizedResult();
var page = _services.ContentManager.BuildEditorModel(_services.ContentManager.New<Page>("page"));
var page = Services.ContentManager.BuildEditorModel(Services.ContentManager.New<Page>("page"));
var model = new PageCreateViewModel {
Page = page
@@ -113,7 +113,7 @@ namespace Orchard.Pages.Controllers {
[HttpPost, ActionName("Create")]
public ActionResult CreatePOST(PageCreateViewModel model) {
if (!_services.Authorizer.Authorize(Permissions.EditPages, T("Couldn't create page")))
if (!Services.Authorizer.Authorize(Permissions.EditPages, T("Couldn't create page")))
return new HttpUnauthorizedResult();
//TODO: (erikpo) Move this duplicate code somewhere else
@@ -129,38 +129,37 @@ namespace Orchard.Pages.Controllers {
}
}
model.Page = _services.ContentManager.UpdateEditorModel(_services.ContentManager.New<Page>("page"), this);
model.Page = Services.ContentManager.UpdateEditorModel(Services.ContentManager.New<Page>("page"), this);
if (!publishNow && publishDate != null)
model.Page.Item.Published = publishDate.Value;
if (!ModelState.IsValid) {
_services.TransactionManager.Cancel();
Services.TransactionManager.Cancel();
return View(model);
}
_services.ContentManager.Create(model.Page.Item.ContentItem, publishNow ? VersionOptions.Published : VersionOptions.Draft);
Services.ContentManager.Create(model.Page.Item.ContentItem, publishNow ? VersionOptions.Published : VersionOptions.Draft);
if (publishNow)
_services.Notifier.Information(T("Page has been published"));
Services.Notifier.Information(T("Page has been published"));
else if (publishDate != null)
_services.Notifier.Information(T("Page has been scheduled for publishing"));
Services.Notifier.Information(T("Page has been scheduled for publishing"));
else
_services.Notifier.Information(T("Page draft has been saved"));
Services.Notifier.Information(T("Page draft has been saved"));
return RedirectToAction("Edit", "Admin", new { id = model.Page.Item.ContentItem.Id });
}
public ActionResult Edit(int id) {
if (!_services.Authorizer.Authorize(Permissions.EditPages, T("Couldn't edit page")))
return new HttpUnauthorizedResult();
Page page = _pageService.GetLatest(id);
if (page == null)
return new NotFoundResult();
if (!Services.Authorizer.Authorize(Permissions.EditOthersPages, page, T("Couldn't edit page")))
return new HttpUnauthorizedResult();
var model = new PageEditViewModel {
Page = _services.ContentManager.BuildEditorModel(page)
Page = Services.ContentManager.BuildEditorModel(page)
};
return View(model);
@@ -168,14 +167,14 @@ namespace Orchard.Pages.Controllers {
[HttpPost, ActionName("Edit")]
public ActionResult EditPOST(int id) {
if (!_services.Authorizer.Authorize(Permissions.EditPages, T("Couldn't edit page")))
return new HttpUnauthorizedResult();
Page page = _pageService.GetPageOrDraft(id);
if (page == null)
return new NotFoundResult();
if (!Services.Authorizer.Authorize(Permissions.EditOthersPages, page, T("Couldn't edit page")))
return new HttpUnauthorizedResult();
//TODO: (erikpo) Move this duplicate code somewhere else
DateTime? publishDate = null;
bool publishNow = false;
@@ -198,40 +197,39 @@ namespace Orchard.Pages.Controllers {
_pageService.Unpublish(page);
var model = new PageEditViewModel {
Page = _services.ContentManager.UpdateEditorModel(page, this)
Page = Services.ContentManager.UpdateEditorModel(page, this)
};
TryUpdateModel(model);
if (!ModelState.IsValid) {
_services.TransactionManager.Cancel();
Services.TransactionManager.Cancel();
return View(model);
}
if (publishNow)
_services.Notifier.Information(T("Page has been published"));
Services.Notifier.Information(T("Page has been published"));
else if (publishDate != null)
_services.Notifier.Information(T("Page has been scheduled for publishing"));
Services.Notifier.Information(T("Page has been scheduled for publishing"));
else
_services.Notifier.Information(T("Page draft has been saved"));
Services.Notifier.Information(T("Page draft has been saved"));
return RedirectToAction("Edit", "Admin", new { id = model.Page.Item.ContentItem.Id });
}
[HttpPost]
public ActionResult Delete(int id) {
if (!_services.Authorizer.Authorize(Permissions.DeletePages, T("Couldn't delete page")))
return new HttpUnauthorizedResult();
Page page = _pageService.Get(id);
if (page == null)
return new NotFoundResult();
if (!Services.Authorizer.Authorize(Permissions.DeleteOthersPages, page, T("Couldn't delete page")))
return new HttpUnauthorizedResult();
_pageService.Delete(page);
_services.Notifier.Information(T("Page was successfully deleted"));
Services.Notifier.Information(T("Page was successfully deleted"));
return RedirectToAction("List");
}

View File

@@ -82,6 +82,7 @@
<Compile Include="Permissions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Routes.cs" />
<Compile Include="Security\Authorization.cs" />
<Compile Include="Services\IPageService.cs" />
<Compile Include="Services\PageService.cs" />
<Compile Include="Services\SlugConstraint.cs">

View File

@@ -0,0 +1,96 @@
using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.Pages.Models;
using Orchard.Security;
using Orchard.Security.Permissions;
namespace Orchard.Pages.Security {
[UsedImplicitly]
public class Authorization : AuthorizationServiceEvents {
public override void Adjust(CheckAccessContext context) {
if (context.Granted == false &&
context.Content.Is<Page>() &&
HasOwnerVariation(context.Permission) &&
HasOwnership(context.User, context.Content)) {
context.Adjusted = true;
context.Permission = GetOwnerVariation(context.Permission);
}
}
private static bool HasOwnership(IUser user, IContent content) {
if (user==null || content==null)
return false;
var common = content.As<ICommonAspect>();
if (common==null || common.Owner==null)
return false;
return user.Id == common.Owner.Id;
}
private static bool HasOwnerVariation(Permission permission) {
return GetOwnerVariation(permission) != null;
}
private static Permission GetOwnerVariation(Permission permission) {
if (permission.Name == Permissions.PublishOthersPages.Name)
return Permissions.PublishPages;
if (permission.Name == Permissions.EditOthersPages.Name)
return Permissions.EditPages;
if (permission.Name == Permissions.DeleteOthersPages.Name)
return Permissions.DeletePages;
return null;
}
}
}
using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.Pages.Models;
using Orchard.Security;
using Orchard.Security.Permissions;
namespace Orchard.Pages.Security {
[UsedImplicitly]
public class Authorization : AuthorizationServiceEvents {
public override void Adjust(CheckAccessContext context) {
if (context.Granted == false &&
context.Content.Is<Page>() &&
HasOwnerVariation(context.Permission) &&
HasOwnership(context.User, context.Content)) {
context.Adjusted = true;
context.Permission = GetOwnerVariation(context.Permission);
}
}
private static bool HasOwnership(IUser user, IContent content) {
if (user==null || content==null)
return false;
var common = content.As<ICommonAspect>();
if (common==null || common.Owner==null)
return false;
return user.Id == common.Owner.Id;
}
private static bool HasOwnerVariation(Permission permission) {
return GetOwnerVariation(permission) != null;
}
private static Permission GetOwnerVariation(Permission permission) {
if (permission.Name == Permissions.PublishOthersPages.Name)
return Permissions.PublishPages;
if (permission.Name == Permissions.EditOthersPages.Name)
return Permissions.EditPages;
if (permission.Name == Permissions.DeleteOthersPages.Name)
return Permissions.DeletePages;
return null;
}
}
}

View File

@@ -111,7 +111,7 @@ namespace Orchard.Roles.Controllers {
var simulation = UserSimulation.Create(role.Name);
model.EffectivePermissions = model.PackagePermissions
.SelectMany(group => group.Value)
.Where(permission => _authorizationService.TryCheckAccess(simulation, permission))
.Where(permission => _authorizationService.TryCheckAccess(permission, simulation, null))
.Select(permission=>permission.Name)
.Distinct()
.ToList();

View File

@@ -40,7 +40,7 @@ namespace Orchard.Roles.Controllers {
protected override DriverResult Editor(UserRoles userRoles) {
// don't show editor without apply roles permission
if (!_authorizationService.TryCheckAccess(_authenticationService.GetAuthenticatedUser(), Permissions.ApplyRoles))
if (!_authorizationService.TryCheckAccess(Permissions.ApplyRoles, _authenticationService.GetAuthenticatedUser(), userRoles))
return null;
var roles =
@@ -61,7 +61,7 @@ namespace Orchard.Roles.Controllers {
protected override DriverResult Editor(UserRoles userRoles, IUpdateModel updater) {
// don't apply editor without apply roles permission
if (!_authorizationService.TryCheckAccess(_authenticationService.GetAuthenticatedUser(), Permissions.ApplyRoles))
if (!_authorizationService.TryCheckAccess(Permissions.ApplyRoles, _authenticationService.GetAuthenticatedUser(), userRoles))
return null;
var model = new UserRolesViewModel {

View File

@@ -13,9 +13,11 @@ using Orchard.Settings;
namespace Orchard.Roles.Services {
public class RolesBasedAuthorizationService : IAuthorizationService {
private readonly IRoleService _roleService;
private readonly IEnumerable<IAuthorizationServiceEvents> _events;
public RolesBasedAuthorizationService(IRoleService roleService) {
public RolesBasedAuthorizationService(IRoleService roleService, IEnumerable<IAuthorizationServiceEvents> events) {
_roleService = roleService;
_events = events;
Logger = NullLogger.Instance;
}
@@ -24,37 +26,54 @@ namespace Orchard.Roles.Services {
#region Implementation of IAuthorizationService
public void CheckAccess(IUser user, Permission permission) {
if (!TryCheckAccess(user, permission)) {
public void CheckAccess(Permission permission, IUser user, IContent content) {
if (!TryCheckAccess(permission, user, content)) {
throw new OrchardSecurityException { PermissionName = permission.Name };
}
}
public bool TryCheckAccess(IUser user, Permission permission) {
if (user == null) {
return false;
}
public bool TryCheckAccess(Permission permission, IUser user, IContent content) {
var context = new CheckAccessContext { Permission = permission, User = user, Content = content };
if (String.Equals(user.UserName, "Administrator", StringComparison.OrdinalIgnoreCase) ||
((!String.IsNullOrEmpty(CurrentSite.SuperUser) &&
String.Equals(user.UserName, CurrentSite.SuperUser, StringComparison.OrdinalIgnoreCase)))) {
return true;
}
_events.Invoke(x => x.Checking(context), Logger);
var grantingNames = PermissionNames(permission, Enumerable.Empty<string>()).ToArray();
IEnumerable<string> rolesForUser = user.As<IUserRoles>().Roles;
foreach (var role in rolesForUser) {
RoleRecord roleRecord = _roleService.GetRoleByName(role);
foreach (var permissionName in _roleService.GetPermissionsForRole(roleRecord.Id)) {
string possessedName = permissionName;
if (grantingNames.Any(grantingName => String.Equals(possessedName, grantingName, StringComparison.OrdinalIgnoreCase))) {
return true;
for (var adjustmentLimiter = 0; adjustmentLimiter != 3; ++adjustmentLimiter) {
if (!context.Granted && context.User != null) {
if (String.Equals(context.User.UserName, "Administrator", StringComparison.OrdinalIgnoreCase) ||
((!String.IsNullOrEmpty(CurrentSite.SuperUser) &&
String.Equals(context.User.UserName, CurrentSite.SuperUser, StringComparison.OrdinalIgnoreCase)))) {
context.Granted = true;
}
}
if (!context.Granted && context.User != null && context.User.Has<IUserRoles>()) {
var grantingNames = PermissionNames(context.Permission, Enumerable.Empty<string>()).ToArray();
IEnumerable<string> rolesForUser = context.User.As<IUserRoles>().Roles;
foreach (var role in rolesForUser) {
RoleRecord roleRecord = _roleService.GetRoleByName(role);
foreach (var permissionName in _roleService.GetPermissionsForRole(roleRecord.Id)) {
string possessedName = permissionName;
if (grantingNames.Any(grantingName => String.Equals(possessedName, grantingName, StringComparison.OrdinalIgnoreCase))) {
context.Granted = true;
}
if (context.Granted)
break;
}
if (context.Granted)
break;
}
}
context.Adjusted = false;
_events.Invoke(x => x.Adjust(context), Logger);
}
return false;
_events.Invoke(x => x.Complete(context), Logger);
return context.Granted;
}
private static IEnumerable<string> PermissionNames(Permission permission, IEnumerable<string> stack) {

View File

@@ -28,7 +28,7 @@ namespace Orchard.Tags.Controllers {
}
protected override DriverResult Editor(HasTags part) {
if (!_authorizationService.TryCheckAccess(CurrentUser, Permissions.ApplyTag))
if (!_authorizationService.TryCheckAccess(Permissions.ApplyTag, CurrentUser, part))
return null;
var model = new EditTagsViewModel {
@@ -38,7 +38,7 @@ namespace Orchard.Tags.Controllers {
}
protected override DriverResult Editor(HasTags part, IUpdateModel updater) {
if (!_authorizationService.TryCheckAccess(CurrentUser, Permissions.ApplyTag))
if (!_authorizationService.TryCheckAccess(Permissions.ApplyTag, CurrentUser, part))
return null;
var model = new EditTagsViewModel();

View File

@@ -66,7 +66,7 @@ namespace Orchard.Tags.Services {
public void CreateTag(string tagName) {
if (_tagRepository.Get(x => x.TagName == tagName) == null) {
_authorizationService.CheckAccess(CurrentUser, Permissions.CreateTag);
_authorizationService.CheckAccess(Permissions.CreateTag, CurrentUser, null);
Tag tag = new Tag { TagName = tagName };
_tagRepository.Create(tag);
@@ -129,7 +129,7 @@ namespace Orchard.Tags.Services {
foreach (var tagContentItem in currentTagsForContentItem) {
if (!newTagsForContentItem.Contains(tagContentItem.TagId)) {
_authorizationService.CheckAccess(CurrentUser, Permissions.ApplyTag);
_authorizationService.CheckAccess(Permissions.ApplyTag, CurrentUser, null);
_tagsContentItemsRepository.Delete(tagContentItem);
}
@@ -139,7 +139,7 @@ namespace Orchard.Tags.Services {
}
foreach (var newTagForContentItem in newTagsForContentItem) {
_authorizationService.CheckAccess(CurrentUser, Permissions.ApplyTag);
_authorizationService.CheckAccess(Permissions.ApplyTag, CurrentUser, null);
_tagsContentItemsRepository.Create(new TagsContentItems { ContentItemId = contentItemId, TagId = newTagForContentItem });
}

View File

@@ -26,7 +26,7 @@ namespace Orchard.Users.Controllers {
public ActionResult Index() {
if (!Services.Authorizer.Authorize(Permissions.ManageUsers, T("Not authorized to manage settings")))
if (!Services.Authorizer.Authorize(Permissions.ManageUsers, T("Not authorized to list users")))
return new HttpUnauthorizedResult();
var users = Services.ContentManager
@@ -44,7 +44,7 @@ namespace Orchard.Users.Controllers {
}
public ActionResult Create() {
if (!Services.Authorizer.Authorize(Permissions.ManageUsers, T("Not authorized to manage settings")))
if (!Services.Authorizer.Authorize(Permissions.ManageUsers, T("Not authorized to manage users")))
return new HttpUnauthorizedResult();
var user = Services.ContentManager.New<IUser>(UserDriver.ContentType.Name);
@@ -56,7 +56,7 @@ namespace Orchard.Users.Controllers {
[HttpPost, ActionName("Create")]
public ActionResult CreatePOST() {
if (!Services.Authorizer.Authorize(Permissions.ManageUsers, T("Not authorized to manage settings")))
if (!Services.Authorizer.Authorize(Permissions.ManageUsers, T("Not authorized to manage users")))
return new HttpUnauthorizedResult();
var model = new UserCreateViewModel();
@@ -83,7 +83,7 @@ namespace Orchard.Users.Controllers {
}
public ActionResult Edit(int id) {
if (!Services.Authorizer.Authorize(Permissions.ManageUsers, T("Not authorized to manage settings")))
if (!Services.Authorizer.Authorize(Permissions.ManageUsers, T("Not authorized to manage users")))
return new HttpUnauthorizedResult();
return View(new UserEditViewModel {
@@ -93,7 +93,7 @@ namespace Orchard.Users.Controllers {
[HttpPost, ActionName("Edit")]
public ActionResult EditPOST(int id) {
if (!Services.Authorizer.Authorize(Permissions.ManageUsers, T("Not authorized to manage settings")))
if (!Services.Authorizer.Authorize(Permissions.ManageUsers, T("Not authorized to manage users")))
return new HttpUnauthorizedResult();
var model = new UserEditViewModel {

View File

@@ -137,6 +137,7 @@
<Compile Include="Extensions\Loaders\AreaExtensionLoader.cs" />
<Compile Include="Extensions\UriExtensions.cs" />
<Compile Include="OrchardException.cs" />
<Compile Include="Security\IAuthorizationServiceEvents.cs" />
<Compile Include="Security\StandardPermissions.cs" />
<Compile Include="Security\OrchardSecurityException.cs" />
<Compile Include="Tasks\Scheduling\IScheduledTask.cs" />

View File

@@ -1,4 +1,7 @@
using JetBrains.Annotations;
using System;
using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.Localization;
using Orchard.Security.Permissions;
using Orchard.UI.Notify;
@@ -6,6 +9,7 @@ using Orchard.UI.Notify;
namespace Orchard.Security {
public interface IAuthorizer : IDependency {
bool Authorize(Permission permission, LocalizedString message);
bool Authorize(Permission permission, IContent content, LocalizedString message);
}
public class Authorizer : IAuthorizer {
@@ -24,7 +28,11 @@ namespace Orchard.Security {
public Localizer T { get; set; }
public bool Authorize(Permission permission, LocalizedString message) {
if (_authorizationService.TryCheckAccess(CurrentUser, permission))
return Authorize(permission, null, message);
}
public bool Authorize(Permission permission, IContent content, LocalizedString message) {
if (_authorizationService.TryCheckAccess(permission, CurrentUser, content))
return true;
if (CurrentUser == null) {
@@ -37,5 +45,6 @@ namespace Orchard.Security {
}
return false;
}
}
}

View File

@@ -1,4 +1,5 @@
using Orchard.Security.Permissions;
using Orchard.ContentManagement;
using Orchard.Security.Permissions;
namespace Orchard.Security {
/// <summary>
@@ -6,7 +7,9 @@ namespace Orchard.Security {
/// provided by default.
/// </summary>
public interface IAuthorizationService : IDependency {
void CheckAccess(IUser user, Permission permission);
bool TryCheckAccess(IUser user, Permission permission);
void CheckAccess(Permission permission, IUser user, IContent content);
bool TryCheckAccess(Permission permission, IUser user, IContent content);
}
}

View File

@@ -0,0 +1,50 @@
using System;
using Orchard.ContentManagement;
using Orchard.Security.Permissions;
namespace Orchard.Security {
public interface IAuthorizationServiceEvents : IEvents {
void Checking(CheckAccessContext context);
void Adjust(CheckAccessContext context);
void Complete(CheckAccessContext context);
}
public class CheckAccessContext {
public Permission Permission { get; set; }
public IUser User { get; set; }
public IContent Content { get; set; }
public bool Granted { get; set; }
public bool Adjusted { get; set; }
}
public abstract class AuthorizationServiceEvents : IAuthorizationServiceEvents {
public virtual void Checking(CheckAccessContext context) { }
public virtual void Adjust(CheckAccessContext context) { }
public virtual void Complete(CheckAccessContext context) { }
}
}
using System;
using Orchard.ContentManagement;
using Orchard.Security.Permissions;
namespace Orchard.Security {
public interface IAuthorizationServiceEvents : IEvents {
void Checking(CheckAccessContext context);
void Adjust(CheckAccessContext context);
void Complete(CheckAccessContext context);
}
public class CheckAccessContext {
public Permission Permission { get; set; }
public IUser User { get; set; }
public IContent Content { get; set; }
public bool Granted { get; set; }
public bool Adjusted { get; set; }
}
public abstract class AuthorizationServiceEvents : IAuthorizationServiceEvents {
public virtual void Checking(CheckAccessContext context) { }
public virtual void Adjust(CheckAccessContext context) { }
public virtual void Complete(CheckAccessContext context) { }
}
}

View File

@@ -5,7 +5,9 @@ namespace Orchard.Security.Permissions {
public class Permission {
public string Name { get; set; }
public string Description { get; set; }
public IEnumerable<Permission> ImpliedBy { get; set; }
public bool RequiresOwnership { get; set; }
public static Permission Named(string name) {
return new Permission { Name = name };

View File

@@ -34,11 +34,11 @@ namespace Orchard.UI.Navigation {
}
private IEnumerable<MenuItem> Reduce(IEnumerable<MenuItem> items) {
var hasDebugShowAllMenuItems = _authorizationService.TryCheckAccess(CurrentUser, Permission.Named("DebugShowAllMenuItems"));
var hasDebugShowAllMenuItems = _authorizationService.TryCheckAccess(Permission.Named("DebugShowAllMenuItems"), CurrentUser, null);
foreach (var item in items) {
if (hasDebugShowAllMenuItems ||
!item.Permissions.Any() ||
item.Permissions.Any(x => _authorizationService.TryCheckAccess(CurrentUser, x))) {
item.Permissions.Any(x => _authorizationService.TryCheckAccess(x, CurrentUser, null))) {
yield return new MenuItem {
Items = Reduce(item.Items),
Permissions = item.Permissions,