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 {  get private   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);
        }
    }
}

 

转载于:https://www.cnblogs.com/Tonyyang/archive/2011/03/15/1985083.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值