zoukankan      html  css  js  c++  java
  • XAF 有条件的对象访问权限

    Conditional Object Access Permission:http://www.devexpress.com/Support/Center/p/Q267964.aspx

    Custom ObjectAccessPermission type is ignored by the Security system :http://www.devexpress.com/Support/Center/p/Q268440.aspx

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security;
    using DevExpress.Xpo;
    using DevExpress.ExpressApp.Security;
    using System.Security.Permissions;
    using DevExpress.ExpressApp.Editors;
    using DevExpress.Persistent.Base;
    using DevExpress.Persistent.Base.Security;
    using DevExpress.ExpressApp.Filtering;
    using DevExpress.Data.Filtering.Helpers;
    using DevExpress.ExpressApp;

    namespace ConditionPermission.Module
    {
        [NonPersistent]
        
    public class ConditionalObjectAccessPermission : ObjectAccessPermission
        {
            
    public ConditionalObjectAccessPermission() { }
            
    public ConditionalObjectAccessPermission(PermissionState permissionState)
                : 
    base(permissionState) { }
            
    public ConditionalObjectAccessPermission(Type objectType, ObjectAccess access)
                : 
    base(objectType, access) { }
            
    public ConditionalObjectAccessPermission(Type objectType, ObjectAccess access, SecurityContextList contexts)
                : 
    base(objectType, access, contexts) { }
            
    public ConditionalObjectAccessPermission(Type objectType, ObjectAccess objectAccess, ObjectAccessModifier modifier)
                : 
    base(objectType, objectAccess, modifier) { }
            
    public ConditionalObjectAccessPermission(Type objectType, ObjectAccess access, params DevExpress.ExpressApp.Security.SecurityContext[] securityContexts)
                : 
    base(objectType, access, securityContexts) { }

            
    const string conditionAttr = "condition";
            
    public override SecurityElement ToXml()
            {
                SecurityElement result 
    = base.ToXml();
                
    if (result != null && condition != null)
                    
    foreach(SecurityElement particularAccessItemElement in result.Children) 
                        particularAccessItemElement.AddAttribute(conditionAttr, SecurityElement.Escape(condition));
                
    return result;
            }
            
    public override void FromXml(SecurityElement element)
            {
                
    base.FromXml(element);
                condition 
    = null;
                
    if (element != null)
                    
    foreach(SecurityElement particularAccessItemElement in element.Children) 
                    {
                        
    string tempCondition = particularAccessItemElement.Attribute(conditionAttr);
                        
    if (condition != null && condition != tempCondition)
                            
    throw new ArgumentException("Stored particular access item conditions do not match!");
                        condition 
    = tempCondition ?? condition;
                    }
                var newAccessList 
    = AccessItemList.Select(item => new ConditionalParticularAccessItem(item.ObjectType, item.Access, item.Modifier, condition)).ToList();
                AccessItemList.Clear();
                
    foreach (ParticularAccessItem item in newAccessList)
                    AccessItemList.Add(item);
            }

            
    string condition = string.Empty;
            [CriteriaObjectTypeMember(
    "ObjectType"), Size(-1), ImmediatePostData]
            
    public string Condition
            {
                
    get { return condition; }
                
    set { condition = value; }
            }
            
    public override string ToString()
            {
                
    return string.IsNullOrEmpty(condition) ? base.ToString() : string.Format("{0} ({1})"base.ToString(), condition);
            }
            
    public override IPermission Copy()
            {
                ConditionalObjectAccessPermission result 
    = new ConditionalObjectAccessPermission { ObjectType = ObjectType };
                
    foreach(ConditionalParticularAccessItem item in AccessItemList)
                    result.AccessItemList.Add(item);
                
    return result;
            }
            
    public override IPermission Union(IPermission target)
            {
                
    return Union<ConditionalObjectAccessPermission>(target);
            }
            
    public virtual IPermission Union<TActualResultType>(IPermission target) where TActualResultType : ObjectAccessPermission
            {
                
    if (!(target is ObjectAccessPermission))
                    
    throw new ArgumentException("Can't unite anything other than an ObjectAccessPermission or one of its descendants!");
                
    if (!typeof(ObjectAccessPermission).IsAssignableFrom(typeof(TActualResultType)))
                    
    throw new ArgumentException("Resultant object Type must be an ObjectAccessPermission or one of its descendants!");
                List
    <ParticularAccessItem> resultItems = new List<ParticularAccessItem>();
                IEnumerable
    <ParticularAccessItem> allItems = AccessItemList.Union(((ObjectAccessPermission)target).AccessItemList);
                
    if (target is ConditionalObjectAccessPermission)
                    resultItems.AddRange(allItems.Distinct());
                
    else
                    
    foreach (ParticularAccessItem item in allItems)
                    {
                        
    // only process items not already stored in the result set
                        if (!resultItems.Exists(i => i.ObjectType == item.ObjectType && i.Access == item.Access))
                        {
                            
    // a conditional item (with an actual condition) has precedence over unconditional items...
                            
    // NOTE: multiple non mutually-exclusive conditional items will be ignored!
                            ConditionalParticularAccessItem conditionalItem = item as ConditionalParticularAccessItem;
                            
    if (conditionalItem == null || conditionalItem != null && string.IsNullOrEmpty(conditionalItem.Condition))
                            {
                                var duplicateItems 
    = allItems.Where(i => i.ObjectType == item.ObjectType && i.Access == item.Access && !object.ReferenceEquals(i, item));
                                conditionalItem 
    =
                                    (ConditionalParticularAccessItem)duplicateItems.FirstOrDefault(i 
    => i is ConditionalParticularAccessItem && !string.IsNullOrEmpty(((ConditionalParticularAccessItem)i).Condition));
                            }
                            
    if (conditionalItem != null)
                                resultItems.Add(
    new ConditionalParticularAccessItem(conditionalItem.ObjectType, conditionalItem.Access, conditionalItem.Modifier, conditionalItem.Condition));
                            
    else
                                resultItems.Add(
    new ParticularAccessItem(item.ObjectType, item.Access, item.Modifier));
                        }
                    }
                ObjectAccessPermission result 
    = (ObjectAccessPermission)Activator.CreateInstance(typeof(TActualResultType));
                resultItems.ForEach(item 
    => result.AccessItemList.Add(item));
                
    return result;
            }
            
    public virtual ConditionalObjectAccessPermission FilterUnfitItems(object contextObject)
            {
                Type objectType 
    = contextObject.GetType();
                ObjectSpace objectSpace 
    = (ObjectSpace)ObjectSpace.FindObjectSpaceByObject(contextObject);
                EvaluatorContextDescriptor descriptor 
    = objectSpace != null ? objectSpace.GetEvaluatorContextDescriptor(objectType) : new EvaluatorContextDescriptorDefault(objectType);
                ConditionalObjectAccessPermission result 
    = new ConditionalObjectAccessPermission();
                
    foreach (ConditionalParticularAccessItem item in AccessItemList)
                {
                    
    bool itemFits = string.IsNullOrEmpty(item.Condition);
                    
    if (!itemFits && item.ObjectType == objectType)
                    {
                        LocalizedCriteriaWrapper wrapper 
    = new LocalizedCriteriaWrapper(objectType, item.Condition);
                        wrapper.UpdateParametersValues(contextObject);
                        ExpressionEvaluator evaluator 
    = new ExpressionEvaluator(descriptor, wrapper.CriteriaOperator);
                        itemFits 
    = evaluator.Fit(contextObject);
                    }
                    
    if (itemFits)
                        result.AccessItemList.Add(item);
                } 
                
    return result;
            }
        }

        
    public class ConditionalParticularAccessItem : ParticularAccessItem, IEquatable<ConditionalParticularAccessItem>
        {
            
    public ConditionalParticularAccessItem(Type objectType, ObjectAccess particularAccess, ObjectAccessModifier modifier)
                : 
    this(objectType, particularAccess, modifier, string.Empty) { }
            
    public ConditionalParticularAccessItem(Type objectType, ObjectAccess particularAccess, ObjectAccessModifier modifier, string condition)
                : 
    base(objectType, particularAccess, modifier) {
                Condition 
    = condition ?? string.Empty;
            }
            
    public string Condition { getprivate set; }
            
    public override bool Equals(object obj)
            {
                ConditionalParticularAccessItem item 
    = obj as ConditionalParticularAccessItem;
                
    if (ReferenceEquals(item, null))
                    
    return false;
                
    return Equals(item);
            }
            
    public bool Equals(ConditionalParticularAccessItem item)
            {
                
    if (ReferenceEquals(item, null))
                    
    return false;
                
    return ObjectType == item.ObjectType && Access == item.Access && Modifier == item.Modifier && Condition == item.Condition;
            }
            
    public static bool operator ==(ConditionalParticularAccessItem i1, ConditionalParticularAccessItem i2)
            {
                
    if (ReferenceEquals(i1, null))
                    
    if (ReferenceEquals(i2, null))
                        
    return true;
                    
    else
                        
    return false;
                
    return i1.Equals(i2);
            }
            
    public static bool operator !=(ConditionalParticularAccessItem i1, ConditionalParticularAccessItem i2)
            {
                
    return !(i1 == i2);
            }
            
    public override int GetHashCode()
            {
                
    return ObjectType.GetHashCode() ^ Access.GetHashCode() ^ Modifier.GetHashCode() ^ Condition.GetHashCode();
            }
        }

        
    public class ConditionalObjectAccessComparer: ObjectAccessComparer
        {
            
    public ConditionalObjectAccessComparer() { }
            
    public ConditionalObjectAccessComparer(ObjectAccessCompareMode objectAccessCompareMode)
                : 
    base(objectAccessCompareMode) { }

            
    public override bool IsSubsetOf(ObjectAccessPermission sourcePermission, ObjectAccessPermission targetPermission)
            {
                ObjectAccessPermission mergedTargetPermission 
    = MergeTargetWithConditionalPermission(targetPermission, sourcePermission.Contexts);
                
    return base.IsSubsetOf(sourcePermission, mergedTargetPermission);
            }
            
    static ObjectAccessPermission MergeTargetWithConditionalPermission(ObjectAccessPermission targetPermission, SecurityContextList contexts)
            {
                
    if (contexts.TargetObjectContext != null && contexts.TargetObjectContext.TargetObject != null)
                {
                    
    object targetObject = contexts.TargetObjectContext.TargetObject;
                    ConditionalObjectAccessPermission validatedConditionalPermission 
    = ConditionalPermission.FilterUnfitItems(targetObject);
                    
    return (ObjectAccessPermission)validatedConditionalPermission.Union<ObjectAccessPermission>(targetPermission);
                }
                
    return targetPermission;
            }
            
    static ConditionalObjectAccessPermission ConditionalPermission
            {
                
    get
                {
                    IUser user 
    = (IUser)SecuritySystem.Instance.User;
                    
    if (user != null)
                        
    return user.GetUserPermission<ConditionalObjectAccessPermission>() ?? new ConditionalObjectAccessPermission();
                    
    return new ConditionalObjectAccessPermission();
                }
            }
        }

        
    public static class IUserHelper
        {
            
    static public TPermissionType GetUserPermission<TPermissionType>(this IUser user) where TPermissionType : class, IPermission
            {
                PermissionSet permissions 
    = new PermissionSet(PermissionState.None);
                
    foreach (IPermission currentPermission in user.Permissions)
                    permissions.AddPermission(currentPermission);
                TPermissionType result 
    = permissions.GetPermission(typeof(TPermissionType)) as TPermissionType;
                
    return result;
            }
        }
    }

    ///

    using System;

    using DevExpress.ExpressApp.Updating;
    using DevExpress.Xpo;
    using DevExpress.Data.Filtering;
    using DevExpress.Persistent.BaseImpl;
    using DevExpress.ExpressApp.Security;

    namespace ConditionPermission.Module
    {
        
    public class Updater : ModuleUpdater
        {
            
    public Updater(Session session, Version currentDBVersion) : base(session, currentDBVersion) { }

            Role CreateRole(
    string roleName)
            {
                
    // if the role does not exist, create it
                Role role =
                    Session.FindObject
    <Role>(new BinaryOperator("Name", roleName)) ??
                    
    new Role(Session) { Name = roleName, };
                
    // remove all currently assigned permissions to the bundled roles
                while (role.PersistentPermissions.Count > 0)
                    Session.Delete(role.PersistentPermissions[
    0]);
                
    // Allow full access to all objects (this should be added to all Roles by default)
                role.AddPermission(new ObjectAccessPermission(typeof(object), ObjectAccess.AllAccess));
                
    return role;
            }

            User AddUserToRole(
    string userName, string password, string personName, Role role)
            {
                User user 
    = Session.FindObject<User>(new BinaryOperator("UserName", userName));
                
    if (user == null)
                {
                    user 
    = new User(Session);
                    user.UserName 
    = userName;
                    user.FirstName 
    = personName;
                    user.SetPassword(password);
                }
                user.Roles.Add(role);
                user.Save();
                
    return user;
            }

            
    public override void UpdateDatabaseAfterUpdateSchema()
            {
                
    base.UpdateDatabaseAfterUpdateSchema();

                Role admins 
    = CreateRole("Administrator");
                admins.AddPermission(
    new ConditionalObjectAccessPermission(typeof(Employee), ObjectAccess.Delete, ObjectAccessModifier.Allow) { Condition = "[FullName] Like 'Felipe%'" });
                admins.AddPermission(
    new ConditionalObjectAccessPermission(typeof(Employee), ObjectAccess.Delete, ObjectAccessModifier.Deny) { Condition = "[FullName] Like 'Vitor%'" });
                admins.AddPermission(
    new ConditionalObjectAccessPermission(typeof(Employee), ObjectAccess.Delete, ObjectAccessModifier.Deny));
                admins.Save();
                AddUserToRole(
    "Admin""admin""Administrator", admins);

                Role staff 
    = CreateRole("Staff");
                staff.AddPermission(
    new ConditionalObjectAccessPermission(typeof(Employee), ObjectAccess.Delete, ObjectAccessModifier.Allow) { Condition = "[FullName] Like 'Felipe%'" });
                staff.AddPermission(
    new ConditionalObjectAccessPermission(typeof(Employee), ObjectAccess.Delete, ObjectAccessModifier.Deny) { Condition = "[FullName] Like 'Vitor%'" });
                
    // the following OVERRIDES all previous conditional permissions because of code inside DeleteObjectViewController that tests if the delete action should be enabled 
                
    // without passing the current object or testing the selected objects, effectivelly IMPOSING the more general permission over the object's specific permissions...
                
    // to avoid this behavior, use the ConditionalObjectAccessPermission without a permission, because it only applies to individual objects (see the Admin conditions above!)
                staff.AddPermission(new ObjectAccessPermission(typeof(Employee), ObjectAccess.Delete, ObjectAccessModifier.Deny));
                staff.Save();
                AddUserToRole(
    "User""user""StaffUser", staff);
            }
        }
    }
  • 相关阅读:
    剑指OFFER----面试题54. 二叉搜索树的第k大节点
    剑指OFFER----面试题53
    剑指OFFER----面试题53
    DevExpress ASP.NET Core v19.1版本亮点:Visual Studio集成
    Kendo UI for jQuery使用教程:初始化jQuery插件
    代码自动补全插件CodeMix全新发布CI 2019.7.15|改进CSS颜色辅助
    MyEclipse使用教程:使用工作集组织工作区
    DevExpress ASP.NET Core v19.1版本亮点:Pivot Grid控件等
    Kendo UI for jQuery使用教程:小部件DOM元素结构
    MyEclipse使用教程——使用DevStyle Icon Designer(二)
  • 原文地址:https://www.cnblogs.com/Tonyyang/p/1985083.html
Copyright © 2011-2022 走看看