mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Content types security refactoring
- Moved AuthorizationEventHandler to Contents.Security --HG-- branch : dev
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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" />
|
||||
|
Reference in New Issue
Block a user