Per-type authorization (which is a little different now) where you can ask:
Can the user create an instance of this type? <we can do this one>
Can the user get/fetch an instance of this type? <we can do this one>
Can the user edit/save an instance of this type? <we can do this one>
Can the user delete an instance of this type?
And the new per-instance authorization where you can ask:
Can the user create the instance you already have? (silly, but possible)
Can the user get/fetch the instance you already have? (silly, but possible)
Can the user edit/save this instance?
Can the user delete this instance? <we want to do this one, but error> <what are we missing?>
Our projects Authorization rules work with WriteProperty where we want to disable and enable xaml objects 100%, we just had to play with the rulesets: example 1 see below
now we are trying to use the "per-instance authorization where you can ask. Can the user delete this instance?" my problem is my execute method's context object is null, why? what am I missing? see example 2 see below
example 1:
BusinessRules.AddRule(new AuthorisationPropertyRule(AuthorizationActions.WriteProperty, PresentStatusIDProperty, new List<string> { "IsClosed", "FutureDate" }));
private class AuthorisationPropertyRule : AuthorizationRule
{
private List<string> _ruleSets;
//Creates an instance of the rule.
public AuthorisationPropertyRule(AuthorizationActions action, List<string> ruleSets)
: base(action)
{
_ruleSets = ruleSets;
}
/// Creates an instance of the rule.
public AuthorisationPropertyRule(AuthorizationActions action, Csla.Core.IMemberInfo element, List<string> ruleSets)
: base(action, element)
{
_ruleSets = ruleSets;
}
/// Rule implementation.
protected override void Execute(AuthorizationContext context)
{
bool hasPermission = true;
var target = (RowCallDetailsEC)context.Target;
//Check all conditions
if (_ruleSets.Count > 0)
{
foreach (var ruleSet in _ruleSets)
{
switch (ruleSet)
{
case "IsClosed":
//if (target.IsClosed == true)
if (IsClosedConditionBroken(target))
hasPermission = false;
break;
case "FutureDate":
if (IsFutureDateConditionBroken(target))
hasPermission = false;
break;
case "PresentStatusComment":
if (IsCommentConditionBroken(target))
hasPermission = false;
break;
case "LeaveTypeSet":
if (IsLeaveTypeSetConditionBroken(target))
hasPermission = false;
break;
}
if (hasPermission == false)
break;
}
}
context.HasPermission = hasPermission;
}
}
example 2:
protected override void AddBusinessRules()
{
base.AddBusinessRules();
BusinessRules.AddRule(new AuthorisationCanRemoveObjectRule(AuthorizationActions.DeleteObject, this, new List<string> { "" }));
}
public class AuthorisationCanRemoveObjectRule : AuthorizationRule
{
private List<string> _ruleSets;
private CompanyGroupEC _instance;
//Creates an instance of the rule.
public AuthorisationCanRemoveObjectRule(AuthorizationActions action, List<string> ruleSets)
: base(action)
{
_ruleSets = ruleSets;
_instance = null;
}
/// Creates an instance of the rule.
public AuthorisationCanRemoveObjectRule(AuthorizationActions action, CompanyGroupEC instance, List<string> ruleSets)
: base(action)
{
_ruleSets = ruleSets;
_instance = instance;
}
/// Rule implementation.
protected override void Execute(AuthorizationContext context)
{
bool hasPermission = true;
var target = (CompanyGroupEC)context.Target; //is null
//var ptarget = _instance; is null
//var ptarget = this.Element; is null
try
{
if (target.haveChildren)
hasPermission = false;
}
catch (Exception eeee) { }
context.HasPermission = hasPermission;
}
}
// BusinessRules.CheckRules(); is in the other partial class
Question 2: When will the CSLA.net 4 videos be online and examples?
You are saying that context is null? Or that context.Target is null?
The Target property isn't always available, because there isn't aways an object instance.
For create, fetch and immediate delete operations there is no business object - so there's no way to provide a Target value.
For execute, insert, update and deferred delete operations there is a business object, so there should be a Target value. If you are doing one of these operations and you aren't seeing a Target value, that may be a bug in CSLA.
"For execute, insert, update and deferred delete operations there is a business object, so there should be a Target value. If you are doing one of these operations and you aren't seeing a Target value, that may be a bug in CSLA."
I have a list of objects: TestERL<BusinessListBase> with TestER<BusinessBase>'s
in ViewModel
public void RemoveInstance(Object sender, EventArgs e) //testing method binded to a trigger action binded to a button in the xaml
{
Csla.Xaml.TriggerAction TriggerAction_ = (Csla.Xaml.TriggerAction)sender;
StackPanel stack_ = (StackPanel)TriggerAction_.Tag;
TestER TestER_ = (TestER)stack_.DataContext;
TestERL TestERL_ = (TestERL)Model;
TestERL_.Remove(TestER_);
}
When TestERL_.Remove(TestER_); it executes:
protected override void Execute(AuthorizationContext context)
{
bool hasPermission = true;
try
{
TestER target = (TestER)context.Target;
if (target != null)
{
if (target.ValueA == 1)
hasPermission = false;
}
}
catch (Exception eeee) { }
context.HasPermission = hasPermission;
}
target is always null ; why? is it a bug?
Ive tried these posts not working or do not give me enough information on delete instance or maybe I read something missing: :-)
http://forums.lhotka.net/forums/p/9373/44440.aspx //feedback: I do not use system role sets, but we use the role sets like he use it.
http://forums.lhotka.net/forums/p/9019/42914.aspx //feedback: my xaml do not display the data if i use this:
//protected static void AddObjectAuthorizationRules() //xaml not displaying
//{
// //// per-type/per-instance rules go here
// //BusinessRules.AddRule(typeof(TestER),new AuthorisationCanRemoveObjectRule(AuthorizationActions.DeleteObject, new List<string> { "All" }));
//}
this works better for delete instance, but the context is always null:
protected override void AddBusinessRules()
{
//// per-property and per-method rules go here
base.AddBusinessRules();
BusinessRules.AddRule(new AuthorisationCanRemoveObjectRule(AuthorizationActions.DeleteObject, new List<string> { "All" }));
//public class AuthorisationCanRemoveObjectRule : Csla.Rules.BusinessRule // not working //Creates an instance of the rule. ///// Creates an instance of the rule. /// Rule implementation. bool hasPermission = true; if (target != null) } }
}
public class AuthorisationCanRemoveObjectRule : AuthorizationRule
{
private List<string> _ruleSets; //Roles
//private List<string> _SysRuleSets; //SysRoles
//private TestER _instance;
public AuthorisationCanRemoveObjectRule(AuthorizationActions action, List<string> ruleSets)
: base(action)
{
_ruleSets = ruleSets;
//_instance = new TestER();
}
//public AuthorisationCanRemoveObjectRule(Type type_ ,AuthorizationActions action, TestER instance, List<string> ruleSets)
// : base(action)
//{
// _ruleSets = ruleSets;
// _instance = instance;
//}
protected override void Execute(AuthorizationContext context)
{
try
{
TestER target = (TestER)context.Target;
//var ptarget = _instance;
//var ptarget = this.Element;
{
if (target.ValueA == 1)
hasPermission = false;
}
catch (Exception eeee) { }
context.HasPermission = hasPermission;
}
I don't think that BusinessListBase checks any authorization rules when Remove() is called to remove a child object.
You are saying that you have an authorization rule that is running when you call Remove()? What runs that rule?
its running by itself after I call parent.remove(child); the Authorization Rules is set on the child not on the parent.
its running by itself after I call parent.remove(child); the Authorization Rules is set on the child not on the parent.
Don't i miss a dataAnnotation or a Using or a IF_SILVERLIGHT code?
I am trying to replicate what you are seeing. I really don't see anywhere in CSLA that an authorization rule is called on a child object when that object is removed from a BusinessListBase. To confirm this, I added a unit test:
[TestMethod]
public void AuthorizeRemoveFromList()
{
var root = new RootList();
root.RemoveAt(0);
}
[Serializable]
public class RootList : BusinessListBase<RootList, ChildItem>
{
public RootList()
{
RaiseListChangedEvents = false;
Add(Csla.DataPortal.CreateChild<ChildItem>());
RaiseListChangedEvents = true;
}
}
[Serializable]
public class ChildItem : BusinessBase<ChildItem>
{
protected override void AddBusinessRules()
{
base.AddBusinessRules();
BusinessRules.AddRule(new NoAuth(AuthorizationActions.DeleteObject));
}
private class NoAuth : Csla.Rules.AuthorizationRule
{
public NoAuth(AuthorizationActions action)
: base(action)
{}
protected override void Execute(AuthorizationContext context)
{
context.HasPermission = false;
}
}
}
The NoAuth rule is never invoked. At no point does its Execute() method get called. Which is exactly what I expected to happen, because no authz rules are run when a child object is removed from a BusinessListBase.
how can I send my project code to you? Will you compile it to see it happen?
The xaml "remove button" trigger the viewmodel function: "void RemoveInstance" it run this code in the function:
TestER TestER_ = (TestER)stack_.DataContext; //TestER BusinessBase class
TestERL TestERL_ = (TestERL)Model; //TestERL BusinessListBase class
TestERL_.Remove(TestER_);
the TestERL_.Remove(TestER_) run the execute function of the Auth Rule:
public AuthorisationCanRemoveObjectRule...
the target is null, big problem?
you need to create a businessbase and its parent businessListbase class, you need to create its xaml and viewmodel with bxf navigation and the button and function I specify above.
I read your book Using CSLA 4: Creating Business Objects: answer:
implement own Auth rule and use Csla.Rules.BusinessRules.HasPermission method and add instance of object in there for context not to be null when it do the execute of the method...
BI object:
public bool CanCreate
{
get
{
if (AppUser.IsRoleDeveloper)
return true;
else if (IsSystemRole == true)
return false;
else
return true;
}
}
public bool CanDelete
{
get
{
if (AppUser.IsRoleDeveloper)
return true;
else if (IsSystemRole == true)
return false;
else
return true;
}
}
public class MyAuthorizationRuleDelete : Csla.Rules.AuthorizationRule
{
private List<string> _roles;
public MyAuthorizationRuleDelete(Csla.Rules.AuthorizationActions action, Csla.Core.IMemberInfo element, List<string> pRoles)
: base(action, element)
{
_roles = pRoles;
}
protected override void Execute(Csla.Rules.AuthorizationContext context)
{
UserSecurityEC userSecurity = (UserSecurityEC)context.Target;
bool hasPermission = true;
if (userSecurity != null)
hasPermission = userSecurity.CanDelete;
if (hasPermission)
{
foreach (var item in _roles)
if (Csla.ApplicationContext.User.IsInRole(item.ToString()))
{
context.HasPermission = true;
break;
}
}
else
context.HasPermission = hasPermission;
}
}
public class MyAuthorizationRuleCreate : Csla.Rules.AuthorizationRule
{
private List<string> _roles;
public MyAuthorizationRuleCreate(Csla.Rules.AuthorizationActions action, Csla.Core.IMemberInfo element, List<string> pRoles)
: base(action, element)
{
_roles = pRoles;
}
protected override void Execute(Csla.Rules.AuthorizationContext context)
{
UserSecurityEC userSecurity = (UserSecurityEC)context.Target;
bool hasPermission = true;
if (userSecurity != null)
hasPermission = userSecurity.CanCreate;
if (hasPermission)
{
foreach (var item in _roles)
if (Csla.ApplicationContext.User.IsInRole(item.ToString()))
{
context.HasPermission = true;
break;
}
}
else
context.HasPermission = hasPermission;
}
}
#if SILVERLIGHT
public static void AddObjectAuthorizationRules()
{
Csla.Rules.BusinessRules.AddRule(typeof(UserSecurityEC), new MyAuthorizationRuleCreate(Csla.Rules.AuthorizationActions.EditObject, null, new List<string> { "Developer", "Company Administrator" }));
Csla.Rules.BusinessRules.AddRule(typeof(UserSecurityEC), new MyAuthorizationRuleDelete(Csla.Rules.AuthorizationActions.DeleteObject, null, new List<string> { "Developer", "Company Administrator" }));
}
#else
#endif
viewModel or code-behind:
UserSecurityEC pop = (UserSecurityEC)ListItem.SelectedItem;
if (pop != null)
{
Type sourceType = typeof(UserSecurityEC);
bool returnValue = (Csla.Rules.BusinessRules.HasPermission(Csla.Rules.AuthorizationActions.DeleteObject, pop));
if (returnValue)
menuItems.Add(new ContextMenuItem("RemoveSecurityRoleUsed", "Remove Security Role - " + pop.SecurityRole, true));
else
menuItems.Add(new ContextMenuItem("RemoveSecurityRoleUsed", "Remove Security Role - " + pop.SecurityRole, false)); //cannot remove it yes ha ha
...
Copyright (c) Marimer LLC