Content types security refactoring

- Moved AuthorizationEventHandler to Contents.Security

--HG--
branch : dev
This commit is contained in:
Sebastien Ros
2010-10-07 15:49:07 -07:00
parent 46c33f7fe0
commit c5198b0fe8
4 changed files with 105 additions and 103 deletions

View File

@@ -1,91 +0,0 @@
using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.Core.Common.Models;
using Orchard.Core.Contents;
using Orchard.Core.Contents.Settings;
using Orchard.Security;
using Orchard.Security.Permissions;
namespace Orchard.Core.Common.Security
{
[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.Is<CommonPart>() ) {
if (OwnerVariationExists(context.Permission) &&
HasOwnership(context.User, context.Content)) {
context.Adjusted = true;
context.Permission = GetOwnerVariation(context.Permission);
}
var typeDefinition = context.Content.ContentItem.TypeDefinition;
// replace permission if a more specific version exists
if ( typeDefinition.Settings.GetModel<ContentTypeSettings>().Creatable ) {
var permission = context.Permission;
if ( context.Permission.Name == Contents.Permissions.PublishOwnContent.Name ) {
permission = DynamicPermissions.CreateDynamicPersion(DynamicPermissions.PublishOwnContent, typeDefinition);
}
else if ( context.Permission.Name == Contents.Permissions.EditOwnContent.Name ) {
permission = DynamicPermissions.CreateDynamicPersion(DynamicPermissions.EditOwnContent, typeDefinition);
}
else if ( context.Permission.Name == Contents.Permissions.DeleteOwnContent.Name ) {
permission = DynamicPermissions.CreateDynamicPersion(DynamicPermissions.DeleteOwnContent, typeDefinition);
}
else if ( context.Permission.Name == Contents.Permissions.PublishContent.Name ) {
permission = DynamicPermissions.CreateDynamicPersion(DynamicPermissions.PublishContent, typeDefinition);
}
else if ( context.Permission.Name == Contents.Permissions.EditContent.Name ) {
permission = DynamicPermissions.CreateDynamicPersion(DynamicPermissions.EditContent, typeDefinition);
}
else if ( context.Permission.Name == Contents.Permissions.DeleteContent.Name ) {
permission = DynamicPermissions.CreateDynamicPersion(DynamicPermissions.DeleteContent, typeDefinition);
}
if ( permission != context.Permission ) {
context.Adjusted = true;
context.Permission = permission;
}
}
}
}
private static bool HasOwnership(IUser user, IContent content)
{
if (user == null || content == null)
return false;
var common = content.As<ICommonPart>();
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 == Contents.Permissions.PublishContent.Name)
return Contents.Permissions.PublishOwnContent;
if (permission.Name == Contents.Permissions.EditContent.Name)
return Contents.Permissions.EditOwnContent;
if (permission.Name == Contents.Permissions.DeleteContent.Name)
return Contents.Permissions.DeleteOwnContent;
return null;
}
}
}

View File

@@ -9,14 +9,21 @@ using Orchard.Security.Permissions;
namespace Orchard.Core.Contents {
public class DynamicPermissions : IPermissionProvider {
public static readonly Permission PublishContent = new Permission { Description = "Publish or unpublish {0} for others", Name = "Publish_{0}", ImpliedBy = new[] { Permissions.PublishContent } };
public static readonly Permission PublishOwnContent = new Permission { Description = "Publish or unpublish {0}", Name = "PublishOwn_{0}", ImpliedBy = new[] { PublishContent, Permissions.PublishOwnContent } };
public static readonly Permission EditContent = new Permission { Description = "Edit {0} for others", Name = "Edit_{0}", ImpliedBy = new[] { PublishContent, Permissions.PublishContent } };
public static readonly Permission EditOwnContent = new Permission { Description = "Edit {0}", Name = "EditOwn_{0}", ImpliedBy = new[] { EditContent, PublishOwnContent, Permissions.EditOwnContent } };
public static readonly Permission DeleteContent = new Permission { Description = "Delete {0} for others", Name = "Delete_{0}", ImpliedBy = new[] { Permissions.DeleteContent } };
public static readonly Permission DeleteOwnContent = new Permission { Description = "Delete {0}", Name = "DeleteOwn_{0}", ImpliedBy = new[] { DeleteContent, Permissions.DeleteOwnContent } };
private static readonly Permission PublishContent = new Permission { Description = "Publish or unpublish {0} for others", Name = "Publish_{0}", ImpliedBy = new[] { Permissions.PublishContent } };
private static readonly Permission PublishOwnContent = new Permission { Description = "Publish or unpublish {0}", Name = "PublishOwn_{0}", ImpliedBy = new[] { PublishContent, Permissions.PublishOwnContent } };
private static readonly Permission EditContent = new Permission { Description = "Edit {0} for others", Name = "Edit_{0}", ImpliedBy = new[] { PublishContent, Permissions.PublishContent } };
private static readonly Permission EditOwnContent = new Permission { Description = "Edit {0}", Name = "EditOwn_{0}", ImpliedBy = new[] { EditContent, PublishOwnContent, Permissions.EditOwnContent } };
private static readonly Permission DeleteContent = new Permission { Description = "Delete {0} for others", Name = "Delete_{0}", ImpliedBy = new[] { Permissions.DeleteContent } };
private static readonly Permission DeleteOwnContent = new Permission { Description = "Delete {0}", Name = "DeleteOwn_{0}", ImpliedBy = new[] { DeleteContent, Permissions.DeleteOwnContent } };
public static readonly Permission[] PermissionTemplates = new[] {PublishContent, PublishOwnContent, EditContent, EditOwnContent, DeleteContent, DeleteOwnContent};
public static readonly Dictionary<string, Permission> PermissionTemplates = new Dictionary<string, Permission> {
{Permissions.PublishContent.Name, PublishContent},
{Permissions.PublishOwnContent.Name, PublishOwnContent},
{Permissions.EditContent.Name, EditContent},
{Permissions.EditOwnContent.Name, EditOwnContent},
{Permissions.DeleteContent.Name, DeleteContent},
{Permissions.DeleteOwnContent.Name, DeleteOwnContent}
};
private readonly IContentDefinitionManager _contentDefinitionManager;
@@ -32,8 +39,8 @@ namespace Orchard.Core.Contents {
.Where(ctd => ctd.Settings.GetModel<ContentTypeSettings>().Creatable);
foreach(var typeDefinition in creatableTypes) {
foreach ( var permissionTemplate in PermissionTemplates ) {
yield return CreateDynamicPersion(permissionTemplate, typeDefinition);
foreach ( var permissionTemplate in PermissionTemplates.Values ) {
yield return CreateDynamicPermission(permissionTemplate, typeDefinition);
}
}
}
@@ -42,12 +49,26 @@ namespace Orchard.Core.Contents {
return Enumerable.Empty<PermissionStereotype>();
}
public static Permission CreateDynamicPersion(Permission template, ContentTypeDefinition typeDefinition) {
/// <summary>
/// Returns a dynamic permission for a content type, based on a global content permission template
/// </summary>
public static Permission ConvertToDynamicPermission(Permission permission) {
if (PermissionTemplates.ContainsKey(permission.Name) ) {
return PermissionTemplates[permission.Name];
}
return null;
}
/// <summary>
/// Generates a permission dynamically for a content type
/// </summary>
public static Permission CreateDynamicPermission(Permission template, ContentTypeDefinition typeDefinition) {
return new Permission {
Name = String.Format(template.Name, typeDefinition.Name),
Description = String.Format(template.Description, typeDefinition.DisplayName),
Category = typeDefinition.DisplayName,
ImpliedBy = (template.ImpliedBy ?? new Permission[0]).Select(t => CreateDynamicPersion(t, typeDefinition))
ImpliedBy = ( template.ImpliedBy ?? new Permission[0] ).Select(t => CreateDynamicPermission(t, typeDefinition))
};
}
}

View File

@@ -0,0 +1,72 @@
using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.ContentManagement.MetaData.Models;
using Orchard.Core.Common.Models;
using Orchard.Core.Contents.Settings;
using Orchard.Security;
using Orchard.Security.Permissions;
namespace Orchard.Core.Contents.Security
{
[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.Is<ICommonPart>() ) {
if (OwnerVariationExists(context.Permission) &&
HasOwnership(context.User, context.Content)) {
context.Adjusted = true;
context.Permission = GetOwnerVariation(context.Permission);
}
var typeDefinition = context.Content.ContentItem.TypeDefinition;
// replace permission if a content type specific version exists
if ( typeDefinition.Settings.GetModel<ContentTypeSettings>().Creatable ) {
var permission = GetContentTypeVariation(context.Permission);
if ( permission != null) {
context.Adjusted = true;
context.Permission = DynamicPermissions.CreateDynamicPermission(permission, typeDefinition);
}
}
}
}
private static bool HasOwnership(IUser user, IContent content) {
if (user == null || content == null)
return false;
var common = content.As<ICommonPart>();
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.PublishContent.Name)
return Permissions.PublishOwnContent;
if (permission.Name == Permissions.EditContent.Name)
return Permissions.EditOwnContent;
if (permission.Name == Permissions.DeleteContent.Name)
return Permissions.DeleteOwnContent;
return null;
}
private static Permission GetContentTypeVariation(Permission permission) {
return DynamicPermissions.ConvertToDynamicPermission(permission);
}
}
}

View File

@@ -72,7 +72,7 @@
<Compile Include="Common\Drivers\TextFieldDriver.cs" />
<Compile Include="Common\Extensions\HtmlHelperExtensions.cs" />
<Compile Include="Common\Fields\TextField.cs" />
<Compile Include="Common\Security\AuthorizationEventHandler.cs" />
<Compile Include="Contents\Security\AuthorizationEventHandler.cs" />
<Compile Include="Common\Services\BbcodeFilter.cs" />
<Compile Include="ContentsLocation\ResourceManifest.cs" />
<Compile Include="ContentsLocation\Models\LocationDefinition.cs" />