diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogPostAdminController.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogPostAdminController.cs index d60e3e56d..47bfce9df 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogPostAdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogPostAdminController.cs @@ -9,6 +9,8 @@ using Orchard.ContentManagement.Aspects; using Orchard.Core.Contents.Settings; using Orchard.Localization; using Orchard.Mvc.AntiForgery; +using Orchard.Security; +using Orchard.Security.Permissions; using Orchard.UI.Admin; using Orchard.UI.Notify; @@ -84,9 +86,6 @@ namespace Orchard.Blogs.Controllers { //todo: the content shape template has extra bits that the core contents module does not (remove draft functionality) //todo: - move this extra functionality there or somewhere else that's appropriate? public ActionResult Edit(int blogId, int postId) { - if (!Services.Authorizer.Authorize(Permissions.EditOwnBlogPost, T("Couldn't edit blog post"))) - return new HttpUnauthorizedResult(); - var blog = _blogService.Get(blogId, VersionOptions.Latest); if (blog == null) return HttpNotFound(); @@ -95,6 +94,9 @@ namespace Orchard.Blogs.Controllers { if (post == null) return HttpNotFound(); + if (!Services.Authorizer.Authorize(Permissions.EditOthersBlogPost, post.ContentItem, T("Couldn't edit blog post"))) + return new HttpUnauthorizedResult(); + dynamic model = Services.ContentManager.BuildEditor(post); // Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation. return View((object)model); diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj b/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj index 485adb414..2283d6feb 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj @@ -82,6 +82,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Security/BlogAuthorizationEventHandler.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Security/BlogAuthorizationEventHandler.cs new file mode 100644 index 000000000..fb0585f71 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Security/BlogAuthorizationEventHandler.cs @@ -0,0 +1,49 @@ +using JetBrains.Annotations; +using Orchard.ContentManagement; +using Orchard.ContentManagement.Aspects; +using Orchard.Security; +using Orchard.Security.Permissions; + +namespace Orchard.Blogs.Security { + [UsedImplicitly] + public class BlogAuthorizationEventHandler : IAuthorizationServiceEventHandler { + public void Checking(CheckAccessContext context) { } + public void Complete(CheckAccessContext context) { } + + public void Adjust(CheckAccessContext context) { + if (!context.Granted && + context.Content.Is()) { + if (OwnerVariationExists(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(); + if (common == null || common.Owner == null) + return false; + + return user.Id == common.Owner.Id; + } + + private static bool OwnerVariationExists(Permission permission) { + return GetOwnerVariation(permission) != null; + } + + private static Permission GetOwnerVariation(Permission permission) { + if (permission.Name == Permissions.PublishOthersBlogPost.Name) + return Permissions.PublishOwnBlogPost; + if (permission.Name == Permissions.EditOthersBlogPost.Name) + return Permissions.EditOwnBlogPost; + if (permission.Name == Permissions.DeleteOthersBlogPost.Name) + return Permissions.DeleteOwnBlogPost; + return null; + } + } +} \ No newline at end of file