예제 #1
0
        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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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));
        }
예제 #6
0
        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);
        }
예제 #7
0
 public AclExpansionEntryCreator_GetAccessTypesResult(AccessInformation accessInformation, AclProbe aclProbe, AccessTypeStatistics accessTypeStatistics)
 {
     AclProbe             = aclProbe;
     AccessTypeStatistics = accessTypeStatistics;
     AccessInformation    = accessInformation;
 }