I think we need to make a few more modifications to Rhino Security. Break it
away from IRepository<T>, for a start, and maybe allow to use it using
Common Service Locator?

On Sat, Dec 13, 2008 at 3:17 PM, Ayende Rahien <[email protected]> wrote:

> Applied with a minor change to make this pass:
>
> [Test]
>         public void
> WillReturnTrueOnGlobalIfPermissionWasAllowedOnGlobalButDeniedOnSpecificEntity()
>         {
>             permissionsBuilderService
>                 .Allow("/Account/Edit")
>                 .For(user)
>                 .OnEverything()
>                 .DefaultLevel()
>                 .Save();
>             UnitOfWork.Current.TransactionalFlush();
>
>             permissionsBuilderService
>                 .Deny("/Account/Edit")
>                 .For(user)
>                 .On(account)
>                 .DefaultLevel()
>                 .Save();
>             UnitOfWork.Current.TransactionalFlush();
>
>             bool IsAllowed = authorizationService.IsAllowed(user,
> "/Account/Edit");
>             Assert.IsTrue(IsAllowed);
>
>         }
>
> On Sat, Dec 13, 2008 at 5:14 PM, Bart Reyserhove <
> [email protected]> wrote:
>
>> Patch attached.
>> I also added two new tests and changed the expectation of the one
>> discussed earlier in this thread.
>>
>> Bart
>>
>>
>> On Fri, Dec 12, 2008 at 11:59 PM, Ayende Rahien <[email protected]>wrote:
>>
>>> I think that this is a test that should be expected to fail after this
>>> change.
>>>
>>>
>>> On Fri, Dec 12, 2008 at 11:30 PM, Bart Reyserhove <
>>> [email protected]> wrote:
>>>
>>>> So I changed this method:
>>>> /// <summary>
>>>> /// Gets the permissions for the specified etntity
>>>>  /// </summary>
>>>> /// <param name="user">The user.</param>
>>>>  /// <param name="operationName">Name of the operation.</param>
>>>>  /// <returns></returns>
>>>>  public Permission[] GetPermissionsFor(IUser user, string
>>>> operationName)
>>>>  {
>>>> string[] operationNames = Strings.GetHierarchicalOperationNames(
>>>> operationName);
>>>>  DetachedCriteria criteria = DetachedCriteria.For<Permission>()
>>>>  .Add(Expression.Eq("User", user)
>>>>       || Subqueries.PropertyIn("UsersGroup.Id",
>>>>                                SecurityCriterions.AllGroups(
>>>> user).SetProjection(Projections.Id())))
>>>>  .CreateAlias("Operation", "op")
>>>>  .Add(Expression.In("op.Name", operationNames));
>>>>
>>>> return FindResults(criteria);
>>>>  }
>>>>
>>>> into:
>>>>
>>>> /// <summary>
>>>> /// Gets the global permissions without taking groups into account
>>>>  /// </summary>
>>>>  /// <param name="user">The user.</param>
>>>>  /// <param name="operationName">Name of the operation.</param>
>>>>  /// <returns></returns>
>>>>  public Permission[] GetGlobalPermissionsFor(IUser user, string
>>>> operationName)
>>>>  {
>>>> string[] operationNames =
>>>> Strings.GetHierarchicalOperationNames(operationName);
>>>>  DetachedCriteria criteria = DetachedCriteria.For<Permission>()
>>>>  .Add(Expression.Eq("User", user)
>>>>      || Subqueries.PropertyIn("UsersGroup.Id",
>>>>
>>>>  SecurityCriterions.AllGroups(user).SetProjection(Projections.Id())))
>>>>                 .Add(Expression.IsNull("EntitiesGroup"))
>>>> .CreateAlias("Operation", "op")
>>>>  .Add(Expression.In("op.Name", operationNames));
>>>>
>>>> return FindResults(criteria);
>>>>  }
>>>>
>>>> I added a test for it and I ran all tests. Two tests are failing now,
>>>> but it is actually only one case since it is tested for NHibernate and
>>>> ActiveRecord.
>>>>
>>>> The failing test:
>>>>
>>>>      [Test]
>>>>         public void
>>>> ExplainWhyAllowedIfPermissionWasGrantedToUsersGroupAssociatedWithUser()
>>>>         {
>>>>             permissionsBuilderService
>>>>                 .Allow("/Account/Edit")
>>>>                 .For("Administrators")
>>>>                 .On("Important Accounts")
>>>>                 .DefaultLevel()
>>>>                 .Save();
>>>>             UnitOfWork.Current.TransactionalFlush();
>>>>             AuthorizationInformation information =
>>>>                 authorizationService.GetAuthorizationInformation(user,
>>>> "/Account/Edit");
>>>>             string expected =
>>>>                 @"Permission (level 1) for operation '/Account/Edit' was
>>>> granted to group 'Administrators' on 'Important Accounts' ('Ayende' is a
>>>> member of 'Administrators')
>>>> ";
>>>>             Assert.AreEqual(expected, information.ToString());
>>>>         }
>>>>
>>>> Knowing the change this is quite logic, because in this test the
>>>> permission is only granted to a group and checked globally. Functionally
>>>> seen you could discuss about this. Permission was only granted to the
>>>> "Important accounts" and the question is "OnEverything". So one could argue
>>>> that it is correct that the permission is not granted, but of course this
>>>> could lead to breaking changes...
>>>>
>>>> What's your opinion?
>>>>
>>>> Bart
>>>>
>>>>
>>>> On Fri, Dec 12, 2008 at 8:27 AM, Bart Reyserhove <
>>>> [email protected]> wrote:
>>>>
>>>>> All right. I'll make a patch this weekend.
>>>>>
>>>>>
>>>>> On Thu, Dec 11, 2008 at 10:21 PM, Ayende Rahien <[email protected]>wrote:
>>>>>
>>>>>> Yes, so in this case, you are right.What we need to do is to change
>>>>>> the name of the method to GetGlobalPermissionsFor
>>>>>>
>>>>>>
>>>>>> On Thu, Dec 11, 2008 at 3:33 PM, Bart Reyserhove <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> I ask the question: IsAllowed(IUser user, string operation)
>>>>>>> I checked where GetPermissionsFor(IUser user, string operationName)
>>>>>>> is used and it is used in the following two methods:
>>>>>>>
>>>>>>> /// <summary>
>>>>>>> /// Determines whether the specified user is allowed to perform the
>>>>>>> /// specified operation on the entity.
>>>>>>>  /// </summary>
>>>>>>> /// <param name="user">The user.</param>
>>>>>>>  /// <param name="operation">The operation.</param>
>>>>>>> /// <returns>
>>>>>>>  /// <c>true</c> if the specified user is allowed; otherwise,
>>>>>>> <c>false</c>.
>>>>>>>  /// </returns>
>>>>>>> public bool IsAllowed(IUser user, string operation)
>>>>>>>  {
>>>>>>> Permission[] permissions = permissionsService.GetPermissionsFor(user,
>>>>>>> operation);
>>>>>>>  if (permissions.Length == 0)
>>>>>>> return false;
>>>>>>> return permissions[0].Allow;
>>>>>>>  }
>>>>>>>
>>>>>>> /// <summary>
>>>>>>> /// Gets the authorization information for the specified user and
>>>>>>> operation,
>>>>>>>  /// allows to easily understand why a given operation was granted /
>>>>>>> denied.
>>>>>>> /// </summary>
>>>>>>>  /// <param name="user">The user.</param>
>>>>>>> /// <param name="operation">The operation.</param>
>>>>>>>  /// <returns></returns>
>>>>>>> public AuthorizationInformation GetAuthorizationInformation(IUser
>>>>>>> user, string operation)
>>>>>>>  {
>>>>>>> AuthorizationInformation info;
>>>>>>> if (InitializeAuthorizationInfo(operation, out info))
>>>>>>>  return info;
>>>>>>> Permission[] permissions = permissionsService.GetPermissionsFor(user,
>>>>>>> operation);
>>>>>>>  AddPermissionDescriptionToAuthorizationInformation<object>(operation,
>>>>>>> info, user, permissions, null);
>>>>>>> return info;
>>>>>>>  }
>>>>>>>
>>>>>>> Both methods above do not take the entity into accoutn since the
>>>>>>> entity is not passed.
>>>>>>>
>>>>>>> I understand that you have to take the situation into account where
>>>>>>> the permission is directly given on the entity but shouldn't I use 
>>>>>>> IsAllowed<TEntity>(IUser
>>>>>>> user, TEntity entity, string operation) where TEntity : class then?
>>>>>>>
>>>>>>> Bart
>>>>>>>
>>>>>>>
>>>>>>> On Thu, Dec 11, 2008 at 4:56 PM, Ayende Rahien <[email protected]>wrote:
>>>>>>>
>>>>>>>> What question are you asking?
>>>>>>>> Get permissions isn't actually that useful for the user, it is the
>>>>>>>> question that you ask when you want to know if it has a permission to 
>>>>>>>> do X
>>>>>>>> on anything. Anything include entities group.
>>>>>>>> The question that you are likely asking is IsAllowed(), and in this
>>>>>>>> case, I think that you are correct, if it is allowed to do this in 
>>>>>>>> general,
>>>>>>>> it is allowed to do so.
>>>>>>>> The problem is that I am not sure that your solution is the
>>>>>>>> appropriate one.
>>>>>>>> GetPermissionsFor is used by the Rhino Security infrastructure, and
>>>>>>>> we need to review this to make sure it doesn't break things.
>>>>>>>> For that matter, we also need to handle the case where a permission
>>>>>>>> was given directly on an entity.
>>>>>>>>
>>>>>>>>
>>>>>>>> On Thu, Dec 11, 2008 at 3:18 AM, Bart Reyserhove <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> The "PermissionsService" contains the following method:
>>>>>>>>> /// <summary>
>>>>>>>>> /// Gets the permissions for the specified etntity
>>>>>>>>>  /// </summary>
>>>>>>>>> /// <param name="user">The user.</param>
>>>>>>>>>  /// <param name="operationName">Name of the operation.</param>
>>>>>>>>> /// <returns></returns>
>>>>>>>>>  public Permission[] GetPermissionsFor(IUser user, string
>>>>>>>>> operationName)
>>>>>>>>> {
>>>>>>>>>  string[] operationNames =
>>>>>>>>> Strings.GetHierarchicalOperationNames(operationName);
>>>>>>>>> DetachedCriteria criteria = DetachedCriteria.For<Permission>()
>>>>>>>>>  .Add(Expression.Eq("User", user)
>>>>>>>>>      || Subqueries.PropertyIn("UsersGroup.Id",
>>>>>>>>>
>>>>>>>>>  SecurityCriterions.AllGroups(user).SetProjection(Projections.Id())))
>>>>>>>>>
>>>>>>>>> .CreateAlias("Operation", "op")
>>>>>>>>>  .Add(Expression.In("op.Name", operationNames));
>>>>>>>>>
>>>>>>>>> return FindResults(criteria);
>>>>>>>>>  }
>>>>>>>>>
>>>>>>>>> This method returns all permissions for a user for a certain
>>>>>>>>> operation. With "All" I mean also the ones that are defined on
>>>>>>>>> entitiesgroups. I have for example an operation "/Department/List" 
>>>>>>>>> with the
>>>>>>>>> permission "on everything" set to "allow" and with the permission on 
>>>>>>>>> group
>>>>>>>>> "departments of company x" set on "deny". Now if the user wants to 
>>>>>>>>> access
>>>>>>>>> the "http://localhost/Department/List"; it is not allowed because
>>>>>>>>> Rhino.Security finds a "deny" permission for a certain entitiesgroup. 
>>>>>>>>> In my
>>>>>>>>> opinion it should not take the permissions on entititiesgroups into 
>>>>>>>>> account
>>>>>>>>> in this case. It could also be that I have configured it in the wrong 
>>>>>>>>> way of
>>>>>>>>> course.
>>>>>>>>>
>>>>>>>>> This fixed it for me:
>>>>>>>>>
>>>>>>>>> /// <summary>
>>>>>>>>> /// Gets the permissions for the specified etntity
>>>>>>>>>  /// </summary>
>>>>>>>>> /// <param name="user">The user.</param>
>>>>>>>>>  /// <param name="operationName">Name of the operation.</param>
>>>>>>>>> /// <returns></returns>
>>>>>>>>>  public Permission[] GetPermissionsFor(IUser user, string
>>>>>>>>> operationName)
>>>>>>>>> {
>>>>>>>>>  string[] operationNames =
>>>>>>>>> Strings.GetHierarchicalOperationNames(operationName);
>>>>>>>>> DetachedCriteria criteria = DetachedCriteria.For<Permission>()
>>>>>>>>>  .Add(Expression.Eq("User", user)
>>>>>>>>>      || Subqueries.PropertyIn("UsersGroup.Id",
>>>>>>>>>
>>>>>>>>>  SecurityCriterions.AllGroups(user).SetProjection(Projections.Id())))
>>>>>>>>>                 .Add(Expression.IsNull("EntitiesGroup"))
>>>>>>>>>  .CreateAlias("Operation", "op")
>>>>>>>>> .Add(Expression.In("op.Name", operationNames));
>>>>>>>>>
>>>>>>>>> return FindResults(criteria);
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> Bart
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>
>> >>
>>
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Rhino Tools Dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/rhino-tools-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to