User allowed to add/edit child but not Root

User allowed to add/edit child but not Root

Old forum URL: forums.lhotka.net/forums/t/10944.aspx


Annesh posted on Monday, December 05, 2011

Hi all

I have a root-child (Project => Tasks) scenario, whereby the user can NOT edit the project but may add/edit the tasks.

On Project.cs

Csla.Rules.BusinessRules.AddRule(typeof(Project), new IsInRole(Csla.Rules.AuthorizationActions.EditObject,"EditProjectRole"));

So my test

        [TestMethod]
        public void TestMethod1()
        {
            var tst = Project.Fetch();
            Assert.IsFalse(tst.IsSelfDirty);
            var child = tst.ProjectTasks.AddNew();
            child.TaskId = 2;
            child.TaskName = DateTime.Now.ToShortDateString();
            tst.Save();
        }

It breaks giving a security exception. My point is that the root is not dirty (selfdirty=false) so technically you are not updating the root but just the child.

The DataPortal.cs (in CSLA) there is a default else:

 else                 {                   methodName = "DataPortal_Update";                   if (!Csla.Rules.BusinessRules.HasPermission(Rules.AuthorizationActions.EditObject, obj))                     throw new System.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException,                       "save",                       objectType.Name));                 }

I believe that the HasPermission check should only be applied if (selfDity==true).


How then do i get around this issue?

Thanks

JonnyBee replied on Monday, December 05, 2011

You have misunderstood the authorization system.

The EditObject is only tested for on DataPortal root Save and Execute. You should rather have authorization rules on each property that deny the user the right to write a value to the property. This is done by AuthorizationActions.WriteProperty.

Another problem/issue is that a field can have only one authorization rule. So the simplest check is to add this code to your Project object:

    public override bool CanWriteProperty(IPropertyInfo property)
    {
      if (!base.CanWriteProperty(property)) return false;
      if (!ApplicationContext.User.IsInRole("EditProjectRole")) return false;
      return true;
    }

And remove the AuthorizationAction.EditObject.

Annesh replied on Tuesday, December 06, 2011

Thanks Johnny, this seems elegant :-)

Copyright (c) Marimer LLC