From aca883f54a45f52142dd5d83d728eafae24ba53b Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 5 Oct 2010 16:35:55 -0700 Subject: [PATCH] Adding dynamic content type rights management --HG-- branch : dev --- .../Contents/AuthorizationEventHandler.cs | 63 +++++++++++++++++++ .../Core/Contents/DynamicPermissions.cs | 25 +++++--- src/Orchard.Web/Core/Orchard.Core.csproj | 1 + 3 files changed, 79 insertions(+), 10 deletions(-) create mode 100644 src/Orchard.Web/Core/Contents/AuthorizationEventHandler.cs diff --git a/src/Orchard.Web/Core/Contents/AuthorizationEventHandler.cs b/src/Orchard.Web/Core/Contents/AuthorizationEventHandler.cs new file mode 100644 index 000000000..306f4682e --- /dev/null +++ b/src/Orchard.Web/Core/Contents/AuthorizationEventHandler.cs @@ -0,0 +1,63 @@ +using System; +using JetBrains.Annotations; +using Orchard.ContentManagement; +using Orchard.ContentManagement.Aspects; +using Orchard.Core.Contents.Settings; +using Orchard.Security; +using Orchard.Security.Permissions; + +namespace Orchard.Core.Contents +{ + [UsedImplicitly] + public class AuthorizationEventHandler : IAuthorizationServiceEventHandler { + public void Checking(CheckAccessContext context) { } + public void Complete(CheckAccessContext context) { } + + public void Adjust(CheckAccessContext context) { + if ( context.Granted || context.Content == null ) + return; + + var typeDefinition = context.Content.ContentItem.TypeDefinition; + + // replace permission if more specific version exists + if ( typeDefinition.Settings.GetModel().Creatable ) { + Permission permission = context.Permission; + + if ( context.Permission.Name == Permissions.PublishContent.Name ) + permission = DynamicPermissions.CreateDynamicPersion(DynamicPermissions.PublishContent, typeDefinition); + if ( context.Permission.Name == Permissions.EditContent.Name) + permission = DynamicPermissions.CreateDynamicPersion(DynamicPermissions.EditContent, typeDefinition); + if ( context.Permission.Name == Permissions.DeleteContent.Name) + permission = DynamicPermissions.CreateDynamicPersion(DynamicPermissions.DeleteContent, typeDefinition); + + // converts the permission if the owner is someone else + if ( HasOtherOwner(context.User, context.Content) ) { + + if ( permission.Name == String.Format(DynamicPermissions.PublishContent.Name, typeDefinition.Name) ) + permission = DynamicPermissions.CreateDynamicPersion(DynamicPermissions.PublishOthersContent, typeDefinition); + if ( permission.Name == String.Format(DynamicPermissions.EditContent.Name, typeDefinition.Name) ) + permission = DynamicPermissions.CreateDynamicPersion(DynamicPermissions.EditOthersContent, typeDefinition); + if ( permission.Name == String.Format(DynamicPermissions.DeleteContent.Name, typeDefinition.Name) ) + permission = DynamicPermissions.CreateDynamicPersion(DynamicPermissions.DeleteOthersContent, typeDefinition); + } + + if ( permission != context.Permission ) { + context.Adjusted = true; + context.Permission = permission; + } + } + } + + private static bool HasOtherOwner(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; + } + } +} + diff --git a/src/Orchard.Web/Core/Contents/DynamicPermissions.cs b/src/Orchard.Web/Core/Contents/DynamicPermissions.cs index 2aea39dba..b4fdecde7 100644 --- a/src/Orchard.Web/Core/Contents/DynamicPermissions.cs +++ b/src/Orchard.Web/Core/Contents/DynamicPermissions.cs @@ -9,7 +9,14 @@ using Orchard.Security.Permissions; namespace Orchard.Core.Contents { public class DynamicPermissions : IPermissionProvider { - public static readonly Permission ManageContentType = new Permission { Name = "ManageContentType{0}", Description = "Manage {0}" }; + public static readonly Permission PublishOthersContent = new Permission { Description = "Publish or unpublish {0} for others", Name = "PublishOthers_{0}", ImpliedBy = new[] { Permissions.PublishOthersContent } }; + public static readonly Permission PublishContent = new Permission { Description = "Publish or unpublish {0}", Name = "Publish_{0}", ImpliedBy = new[] { PublishOthersContent, Permissions.PublishContent } }; + public static readonly Permission EditOthersContent = new Permission { Description = "Edit {0} for others", Name = "EditOthers_{0}", ImpliedBy = new[] { PublishOthersContent, Permissions.EditOthersContent } }; + public static readonly Permission EditContent = new Permission { Description = "Edit {0}", Name = "EditContent", ImpliedBy = new[] { EditOthersContent, PublishContent, Permissions.EditContent } }; + public static readonly Permission DeleteOthersContent = new Permission { Description = "Delete {0} for others", Name = "DeleteOthers_{0}", ImpliedBy = new[] { Permissions.DeleteOthersContent } }; + public static readonly Permission DeleteContent = new Permission { Description = "Delete {0}", Name = "Delete_{0}", ImpliedBy = new[] { DeleteOthersContent, Permissions.DeleteContent } }; + + public static readonly Permission[] PermissionTemplates = new[] {PublishOthersContent, PublishContent, EditOthersContent, EditContent, DeleteOthersContent, DeleteContent}; private readonly IContentDefinitionManager _contentDefinitionManager; @@ -25,24 +32,22 @@ namespace Orchard.Core.Contents { .Where(ctd => ctd.Settings.GetModel().Creatable); foreach(var typeDefinition in creatableTypes) { - yield return CreateDynamicPersion(ManageContentType, typeDefinition); + foreach ( var permissionTemplate in PermissionTemplates ) { + yield return CreateDynamicPersion(permissionTemplate, typeDefinition); + } } } public IEnumerable GetDefaultStereotypes() { - return new[] { - new PermissionStereotype { - Name = "Administrator", - Permissions = _contentDefinitionManager.ListTypeDefinitions().Select(typeDefinition => CreateDynamicPersion(ManageContentType, typeDefinition)) - } - }; + return Enumerable.Empty(); } - private static Permission CreateDynamicPersion(Permission template, ContentTypeDefinition typeDefinition) { + public static Permission CreateDynamicPersion(Permission template, ContentTypeDefinition typeDefinition) { return new Permission { Name = String.Format(template.Name, typeDefinition.Name), Description = String.Format(template.Description, typeDefinition.DisplayName), - Category = typeDefinition.DisplayName + Category = typeDefinition.DisplayName, + ImpliedBy = (template.ImpliedBy ?? new Permission[0]).Select(t => CreateDynamicPersion(t, typeDefinition)) }; } } diff --git a/src/Orchard.Web/Core/Orchard.Core.csproj b/src/Orchard.Web/Core/Orchard.Core.csproj index 85c9ffd70..0275d63d5 100644 --- a/src/Orchard.Web/Core/Orchard.Core.csproj +++ b/src/Orchard.Web/Core/Orchard.Core.csproj @@ -86,6 +86,7 @@ +