private static User CreateOwningUserEntry(AclProbe aclProbe, User user, AccessControlEntry ace) { User owningUser; switch (ace.UserCondition) { case UserCondition.Owner: // Undecideable constraint: For ACE to match the SecurityToken.OwningUser must be equal to the user's user. // Since this is undeciadeable, set the owning user so he will match, and record the constraint as an access condition. owningUser = user; aclProbe.AccessConditions.IsOwningUserRequired = true; break; case UserCondition.SpecificUser: owningUser = null; // Decideable constraint => no condition. Either Principal matches or he does not. break; case UserCondition.SpecificPosition: owningUser = null; // Decideable constraint => no condition. Either Principal's position matches or it does not. break; case UserCondition.None: owningUser = null; // No constraint => no condition (will always match). break; default: throw new ArgumentException(String.Format("ace.UserSelection={0} is currently not supported by this method. Please extend method to handle the new UserSelection state.", ace.UserCondition)); } return(owningUser); }
/// <summary> /// Factory method to create an <see cref="AclProbe"/> from the passed <see cref="User"/>, <see cref="Role"/> and <see cref="AccessControlEntry"/>. /// </summary> /// <returns></returns> public static AclProbe CreateAclProbe(User user, Role role, AccessControlEntry ace) { ArgumentUtility.CheckNotNull("user", user); ArgumentUtility.CheckNotNull("role", role); ArgumentUtility.CheckNotNull("ace", ace); var aclProbe = new AclProbe(); var owningUser = CreateOwningUserEntry(aclProbe, user, ace); var owningGroup = CreateOwningGroupEntry(aclProbe, role, ace); var owningTenant = CreateOwningTenantEntry(aclProbe, user, ace); var abstractRoles = CreateAbstractRolesEntry(aclProbe, ace); // Create a new Principal which has only the one role we are currently probing for. // If we don't do that and set all the user's roles for the principal, // another role of the user could match the ACE.SpecificPosition // for case GroupSelection.All or GroupSelection.OwningGroup, giving access rights // which the user does not have due to the currently tested role. // (Note that the user is in fact always in all roles at the same time, so he will, in fact, // always have the access rights returned; this is just not the information we want to present in the // ACL-expansion, where we distinguish which role gives rise to which access rights). var principal = new Principal( user.Tenant.GetHandle(), user.GetSafeHandle(), EnumerableUtility.Singleton(new PrincipalRole(role.Position.GetHandle(), role.Group.GetHandle()))); aclProbe._securityToken = SecurityToken.Create(principal, owningTenant, owningGroup, owningUser, abstractRoles); return(aclProbe); }
private static Tenant CreateOwningTenantEntry(AclProbe aclProbe, User user, AccessControlEntry ace) { Tenant owningTenant; switch (ace.TenantCondition) { case TenantCondition.OwningTenant: // Undecideable constraint: For ACE to match the SecurityToken.OwningTenant must be equal to the user's tenant. // Since this is undecideable, set the owning tenant so he will match, and record the constraint as an access condition, // keeping in mind the TenantHierarchyCondition. // Owning tenant will be set to the user's tenant, which should never be empty. Assertion.IsNotNull(user.Tenant); // TenantHierarchyCondition should always contain the flag for "this tenant"; // if this condition is violated, using owningTenant = user.Tenant will no longer work, since it will not match. Assertion.IsTrue((ace.TenantHierarchyCondition & TenantHierarchyCondition.This) != 0); owningTenant = user.Tenant; aclProbe.AccessConditions.OwningTenant = owningTenant; aclProbe.AccessConditions.TenantHierarchyCondition = ace.TenantHierarchyCondition; break; case TenantCondition.SpecificTenant: owningTenant = null; // Decideable constraint => no condition. Either Principal.Tenant matches or he does not. break; case TenantCondition.None: owningTenant = null; // No constraint => no condition (will always match). break; default: throw new ArgumentException(String.Format("ace.TenantSelection={0} is currently not supported by this method. Please extend method to handle the new TenantSelection state.", ace.TenantCondition)); } return(owningTenant); }
private static Group CreateOwningGroupEntry(AclProbe aclProbe, Role role, AccessControlEntry ace) { Group owningGroup; switch (ace.GroupCondition) { case GroupCondition.OwningGroup: // Owning group will be set to the role group, which should never be empty. Assertion.IsNotNull(role.Group); // GroupHierarchyCondition should always contain the flag for "this group"; // if this condition is violated, using owningGroup = role.Group will no longer work, since it will not match. Assertion.IsTrue((ace.GroupHierarchyCondition & GroupHierarchyCondition.This) != 0); owningGroup = role.Group; aclProbe.AccessConditions.OwningGroup = owningGroup; aclProbe.AccessConditions.GroupHierarchyCondition = ace.GroupHierarchyCondition; break; case GroupCondition.BranchOfOwningGroup: Assertion.IsNotNull(role.Group); owningGroup = FindFirstGroupInThisAndParentHierarchyWhichHasGroupType(role.Group, ace.SpecificGroupType); aclProbe.AccessConditions.OwningGroup = owningGroup; aclProbe.AccessConditions.GroupHierarchyCondition = GroupHierarchyCondition.ThisAndChildren; break; case GroupCondition.SpecificGroup: owningGroup = null; // Decideable constraint => no condition. Either the Principal's groups contain the specifc group or not. break; case GroupCondition.AnyGroupWithSpecificGroupType: owningGroup = null; // Decideable constraint => no condition. Either one of the Principal's groups is of the specifc group type or not. break; case GroupCondition.None: owningGroup = null; // No constraint => no condition (will always match). break; default: throw new ArgumentException(String.Format("ace.GroupSelection={0} is currently not supported by this method. Please extend method to handle the new GroupSelection state.", ace.GroupCondition)); } return(owningGroup); }
public virtual AclExpansionEntryCreator_GetAccessTypesResult GetAccessTypes(UserRoleAclAceCombination userRoleAclAce) { if (ClientTransaction.Current == null) { throw new InvalidOperationException("No ClientTransaction has been associated with the current thread."); } var aclProbe = AclProbe.CreateAclProbe(userRoleAclAce.User, userRoleAclAce.Role, userRoleAclAce.Ace); // Note: The aclProbe created above will NOT always match the ACE it was designed to probe; the reason for this // is that its SecurityToken created by the AclProbe is only designed to match the non-decideable access conditions // (e.g. abstract role, owning tenant, owning group, etc) of the ACE. If this were not the case, then the AclProbe would need // to reproduce code from the SecurityManager, to be able to decide beforehand, whether decideable access condtions // (e.g. specific tenant, specific user) will match or not. // // The "non-decideable" here refers to the information context of the AclExpander, which is lacking some information // available during normal SecurityManager access rights querying. // For decideable access conditons (e.g. specific tenant or specific group), the created SecurityToken // is not guaranteed to match, therefore the AccessTypeStatistics returned by Acl.GetAccessTypes are used to filter out these cases. // // One could also try to remove these entries by removing all AclExpansionEntry|s which are identical to another AclExpansionEntry, // apart from having more restrictive AccessConditions; note however that such "double" entries can also come from ACEs which are // being shadowed by a 2nd, less restrictive ACE. // // Note also that it does not suffice to get the access types for the current ACE only, since these rights might be denied // by another matching ACE in the current ACL (deny rights always win). var accessTypeStatistics = new AccessTypeStatistics(); var roles = aclProbe.SecurityToken.Principal.Roles; Assertion.IsTrue(roles.Count == 1); Assertion.IsTrue(object.ReferenceEquals(roles[0].Position.GetObjectReference(), userRoleAclAce.Role.Position)); Assertion.IsTrue(object.ReferenceEquals(roles[0].Group.GetObjectReference(), userRoleAclAce.Role.Group)); AccessInformation accessInformation = userRoleAclAce.Acl.GetAccessTypes(aclProbe.SecurityToken, accessTypeStatistics); return(new AclExpansionEntryCreator_GetAccessTypesResult(accessInformation, aclProbe, accessTypeStatistics)); }
private static IList <IDomainObjectHandle <AbstractRoleDefinition> > CreateAbstractRolesEntry(AclProbe aclProbe, AccessControlEntry ace) { var abstractRoles = new List <IDomainObjectHandle <AbstractRoleDefinition> > (); if (ace.SpecificAbstractRole != null) { var abstractRole = ace.SpecificAbstractRole; abstractRoles.Add(abstractRole.GetHandle()); aclProbe.AccessConditions.AbstractRole = abstractRole; } return(abstractRoles); }
public AclExpansionEntryCreator_GetAccessTypesResult(AccessInformation accessInformation, AclProbe aclProbe, AccessTypeStatistics accessTypeStatistics) { AclProbe = aclProbe; AccessTypeStatistics = accessTypeStatistics; AccessInformation = accessInformation; }