您的位置:首页 > 其它

XAF 字段级权限扩展-根据对象选择属性

2011-05-21 10:46 555 查看
需要参考:/article/5190230.html

// Developer Express Code Central Example:
// How to implement the MemberLevel security manually (for example, to deny the 'Read' access for declared properties of some business class, and allow access for the inherited properties)
//
// Hello,
//
// This sample demonstrates how to implement the Member Level security
// manually.
//
// This is a workaround solution until we implement this feature in an
// out-of-the-box manner (see "Security.MemberLevel: Add an ability to protect some
// object's properties rather than an entire object (Field-level security)" at
// http://www.devexpress.com/issue=S19569). This approach doesn't protect
// information within Reports and Analysis modules, and anywhere else, where
// special controls are used.
//
// Currently, XAF Security is implemented at the UI
// level. For more details see:
// - "Allow injection of a new and independent
// functionality into the load business class process and into the 'get/set'
// methods of a certain property" at http://www.devexpress.com/issue=S30538 //
// For
// more details about this example, see:
// - "How to implement the MemberLevel
// security manually" at http://www.devexpress.com/kbid=K18110 //
// See also:
// -
// "Security: Roles that do not have a Read access level to an object should not
// see "protected content" items in Detail and List Views" at
// http://www.devexpress.com/issue=S30144 // - "Allow injection of a new and
// independent functionality into the load business class process and into the
// 'get/set' methods of a certain property" at
// http://www.devexpress.com/issue=S30538 // - "Security.MemberLevel: How to show a
// list of available properties (DropDown edit) for the "Member" editor (which is a
// TextEdit)?" at http://www.devexpress.com/issue=Q134009 //
// Thanks,
// Dan.
//
// You can find sample updates and versions for different programming languages here:
// http://www.devexpress.com/example=E485
using System;
using System.Collections.Generic;
using DevExpress.ExpressApp.Security;
using System.ComponentModel;
using DevExpress.Xpo;
using System.Security;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Xpo.Metadata;
using System.Collections;
using DevExpress.Xpo.Metadata.Helpers;
using DevExpress.ExpressApp;

namespace MemberLevelSecurityDemo.Module {
public enum MemberOperation { NotAssigned, Read, Write }

public class MemberAccessPermissionItem {
private string memberName;
private Type objectType;
private MemberOperation operation;
private ObjectAccessModifier modifier;
public MemberAccessPermissionItem() { }
public MemberAccessPermissionItem(MemberAccessPermissionItem source) {
this.memberName = source.memberName;
this.objectType = source.objectType;
this.operation = source.operation;
this.modifier = source.modifier;
}
public Type ObjectType {
get { return objectType; }
set { objectType = value; }
}

public string MemberName {
get { return memberName; }
set { memberName = value; }
}
public MemberOperation Operation {
get { return operation; }
set { operation = value; }
}
public ObjectAccessModifier Modifier {
get { return modifier; }
set { modifier = value; }
}
}

[NonPersistent, DefaultProperty("DisplayName")]
public class MemberAccessPermission : PermissionBase
{
public string DisplayName { get { return this.ToString(); } }
private List<MemberAccessPermissionItem> items = new List<MemberAccessPermissionItem>();
private MemberAccessPermissionItem GetDesignModeItem() {
if(items.Count > 1) {
throw new InvalidOperationException();
}
if(items.Count == 0) {
items.Add(new MemberAccessPermissionItem());
}
return items[0];
}
private List<MemberAccessPermissionItem> CloneItems() {
List<MemberAccessPermissionItem> clonedItems = new List<MemberAccessPermissionItem>();
foreach(MemberAccessPermissionItem item in items) {
clonedItems.Add(new MemberAccessPermissionItem(item));
}
return clonedItems;
}
public MemberAccessPermission() { }
public MemberAccessPermission(Type objectType, string memberName, MemberOperation operation)
: this(objectType, memberName, operation, ObjectAccessModifier.Allow) {
}
public MemberAccessPermission(Type objectType, string memberName, MemberOperation operation, ObjectAccessModifier modifier) {
this.ObjectType = objectType;
this.MemberName = memberName;
this.Operation = operation;
this.Modifier = modifier;
}
public override System.Security.IPermission Union(System.Security.IPermission target) {
MemberAccessPermission result = (MemberAccessPermission)Copy();
result.items.AddRange(((MemberAccessPermission)target).CloneItems());
return result;
}
public override bool IsSubsetOf(System.Security.IPermission target) {
if(base.IsSubsetOf(target)) {
foreach(MemberAccessPermissionItem targetItem in ((MemberAccessPermission)target).items) {
if(targetItem.ObjectType == ObjectType
&& targetItem.MemberName == MemberName
&& targetItem.Operation == Operation) {
return targetItem.Modifier == Modifier;
}
}
return true;
}
return false;
}

[TypeConverter(typeof(PermissionTargetBusinessClassListConverter))]
public Type ObjectType {
get { return GetDesignModeItem().ObjectType; }
set { GetDesignModeItem().ObjectType = value; }
}

[DataSourceProperty("Types")]
[Custom("PropertyEditorType", "MemberLevelSecurityDemo.Module.WinStringArrayComboPropertyEditor")]
public string MemberName {
get { return GetDesignModeItem().MemberName; }
set { GetDesignModeItem().MemberName = value; }
}
public MemberOperation Operation {
get { return GetDesignModeItem().Operation; }
set { GetDesignModeItem().Operation = value; }
}
public ObjectAccessModifier Modifier {
get { return GetDesignModeItem().Modifier; }
set { GetDesignModeItem().Modifier = value; }
}
public override System.Security.SecurityElement ToXml() {
SecurityElement result = base.ToXml();
SecurityElement itemElement = new SecurityElement("MemberAccessPermissionItem");
itemElement.AddAttribute("Operation", Operation.ToString());
itemElement.AddAttribute("ObjectType", (ObjectType != null) ? ObjectType.ToString() : "");
itemElement.AddAttribute("Modifier", Modifier.ToString());
itemElement.AddAttribute("MemberName", MemberName.ToString());
result.AddChild(itemElement);
return result;
}
public override void FromXml(System.Security.SecurityElement element) {
items.Clear();
if(element.Children != null) {
if(element.Children.Count != 1) {
throw new InvalidOperationException();
}
SecurityElement childElement = (SecurityElement)element.Children[0];
ObjectType = ReflectionHelper.FindType(childElement.Attributes["ObjectType"].ToString());
Operation = (MemberOperation)Enum.Parse(typeof(MemberOperation), childElement.Attributes["Operation"].ToString());
Modifier = (ObjectAccessModifier)Enum.Parse(typeof(ObjectAccessModifier), childElement.Attributes["Modifier"].ToString());
MemberName = childElement.Attributes["MemberName"].ToString();
}
}
public override string ToString() {
return ((ObjectType != null) ? ObjectType.Name : "N/A") + "." + MemberName + " - " + Modifier + " " + Operation;
//return base.ToString();
}
public override System.Security.IPermission Copy() {
MemberAccessPermission result = new MemberAccessPermission();
result.items.AddRange(CloneItems());
return result;
}

[Browsable(false)]
public object Types
{
get { return GetTypes(); }
}

public string[] GetTypes()
{
return GetObjectProperties(ObjectType);
}

public string[] GetObjectProperties(Type objectType)
{
if (objectType == null) return null;

XPClassInfo classInfo = CurrentUser.Session.Dictionary.GetClassInfo(objectType);
if (classInfo != null)
return GetObjectProperties(classInfo, new ArrayList());
return new string[] { };
}

public string[] GetObjectProperties(XPClassInfo xpoInfo, ArrayList processed)
{
if (processed.Contains(xpoInfo)) return new string[] { };
processed.Add(xpoInfo);
ArrayList result = new ArrayList();
foreach (XPMemberInfo m in xpoInfo.PersistentProperties)
if (!(m is ServiceField) && m.IsPersistent)
{
result.Add(m.Name);
if (m.ReferenceType != null)
{
string[] childProps = GetObjectProperties(m.ReferenceType, processed);
foreach (string child in childProps)
result.Add(string.Format("{0}.{1}", m.Name, child));
}
}

foreach (XPMemberInfo m in xpoInfo.CollectionProperties)
{
string[] childProps = GetObjectProperties(m.CollectionElementType, processed);
foreach (string child in childProps)
result.Add(string.Format("{0}.{1}", m.Name, child));
}
return result.ToArray(typeof(string)) as string[];
}

private readonly User CurrentUser = SecuritySystem.CurrentUser as User;

}
}

// Developer Express Code Central Example:
// How to implement the MemberLevel security manually (for example, to deny the 'Read' access for declared properties of some business class, and allow access for the inherited properties)
//
// Hello,
//
// This sample demonstrates how to implement the Member Level security
// manually.
//
// This is a workaround solution until we implement this feature in an
// out-of-the-box manner (see "Security.MemberLevel: Add an ability to protect some
// object's properties rather than an entire object (Field-level security)" at
// http://www.devexpress.com/issue=S19569). This approach doesn't protect
// information within Reports and Analysis modules, and anywhere else, where
// special controls are used.
//
// Currently, XAF Security is implemented at the UI
// level. For more details see:
// - "Allow injection of a new and independent
// functionality into the load business class process and into the 'get/set'
// methods of a certain property" at http://www.devexpress.com/issue=S30538 //
// For
// more details about this example, see:
// - "How to implement the MemberLevel
// security manually" at http://www.devexpress.com/kbid=K18110 //
// See also:
// -
// "Security: Roles that do not have a Read access level to an object should not
// see "protected content" items in Detail and List Views" at
// http://www.devexpress.com/issue=S30144 // - "Allow injection of a new and
// independent functionality into the load business class process and into the
// 'get/set' methods of a certain property" at
// http://www.devexpress.com/issue=S30538 // - "Security.MemberLevel: How to show a
// list of available properties (DropDown edit) for the "Member" editor (which is a
// TextEdit)?" at http://www.devexpress.com/issue=Q134009 //
// Thanks,
// Dan.
//
// You can find sample updates and versions for different programming languages here:
// http://www.devexpress.com/example=E485
using System;
using System.Collections.Generic;
using System.Text;
using DevExpress.ExpressApp.Security;
using DevExpress.Persistent.Base;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.DC;

namespace MemberLevelSecurityDemo.Module
{
public class MemberLevelObjectAccessComparer : ObjectAccessComparer
{
public override bool IsMemberReadGranted(Type requestedType, string propertyName, SecurityContextList securityContexts)
{
ITypeInfo typeInfo = XafTypesInfo.Instance.FindTypeInfo(requestedType);
IMemberInfo memberInfo = typeInfo.FindMember(propertyName);
foreach (IMemberInfo currentMemberInfo in memberInfo.GetPath())
{
if (!SecuritySystem.IsGranted(new MemberAccessPermission(currentMemberInfo.Owner.Type, currentMemberInfo.Name, MemberOperation.Read)))
{
return false;
}
}
return base.IsMemberReadGranted(requestedType, propertyName, securityContexts);
}
public override bool IsMemberModificationDenied(object targetObject, IMemberInfo memberInfo)
{
foreach (IMemberInfo currentMemberInfo in memberInfo.GetPath())
{
if (!SecuritySystem.IsGranted(new MemberAccessPermission(currentMemberInfo.Owner.Type, currentMemberInfo.Name, MemberOperation.Write)))
{
return true;
}
}
return base.IsMemberModificationDenied(targetObject, memberInfo);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: