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.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);
}
}
}
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);
}
}
}