/// <summary>
        ///     Gets the current instances.
        /// </summary>
        /// <returns>
        ///     An enumeration of the current entities.
        /// </returns>
        private IEnumerable <TEntity> GetCurrentInstances( )
        {
            using (var ctx = new SourceEntityContext( ))
            {
                ctx.Writable = !SourceIsReadOnly;

                return(Entity.Get <TEntity>(_tracker.Select(pair => pair.Key)));
            }
        }
        /// <summary>
        ///     Gets the parent roles.
        /// </summary>
        /// <param name="roles">The roles.</param>
        /// <param name="relAlias"></param>
        private static void GetRelatedRoles(ISet <long> roles, string relAlias)
        {
            /////
            // Sanity check.
            /////
            if (roles == null || roles.Count <= 0)
            {
                return;
            }

            var rolesProcessed = new HashSet <long>();
            var rolesToProcess = new Queue <long>(roles);

            while (rolesToProcess.Count > 0)
            {
                long role = rolesToProcess.Dequeue();

                if (rolesProcessed.Contains(role))
                {
                    continue;
                }

                rolesProcessed.Add(role);

                /////
                // Get the relationships of the 'includedByRoles' type.
                /////
                IChangeTracker <IMutableIdKey> relationshipMembers = Entity.GetRelationships(new EntityRef(role), new EntityRef("core", relAlias), Direction.Reverse);

                if (relationshipMembers != null && relationshipMembers.Count > 0)
                {
                    foreach (long parentRole in relationshipMembers.Select(pair => pair.Key))
                    {
                        rolesToProcess.Enqueue(parentRole);
                    }
                }
            }

            roles.UnionWith(rolesProcessed);
        }
        /// <summary>
        /// Load the roles recursively for a user.
        /// </summary>
        /// <param name="subjectId">
        /// The user to load the roles for. This cannot be negative.
        /// </param>
        /// <returns>
        /// The roles the user is recursively a member of.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// <paramref name="subjectId"/> cannot be negative.
        /// </exception>
        public ISet <long> GetUserRoles(long subjectId)
        {
            if (subjectId < 0)
            {
                throw new ArgumentException(@"Invalid user ID.", nameof(subjectId));
            }

            EntityRef userHasRoleEntityRef;

            userHasRoleEntityRef = new EntityRef(WellKnownAliases.CurrentTenant.UserHasRole);
            using (new SecurityBypassContext())
            {
                HashSet <long> roles = null;

                // Get the subject
                IEntity subject = Entity.Get(subjectId);

                if (Entity.Is <UserAccount>(subject))
                {
                    // Get the relationships of the 'userHasRole' type.
                    IChangeTracker <IMutableIdKey> relationshipMembers = Entity.GetRelationships(new EntityRef(subjectId), userHasRoleEntityRef, Direction.Forward);
                    if (relationshipMembers != null)
                    {
                        roles = new HashSet <long>(relationshipMembers.Select(pair => pair.Key));

                        GetParentRoles(roles);

                        roles.UnionWith(EveryoneRoles);
                    }
                    else
                    {
                        roles = new HashSet <long>( );
                    }

                    using (CacheContext cacheContext = CacheContext.GetContext( ))
                    {
                        cacheContext.Entities.Add(subjectId);
                        if (roles != null)
                        {
                            cacheContext.Entities.Add(roles);
                        }
                        cacheContext.EntityInvalidatingRelationshipTypes.Add(WellKnownAliases.CurrentTenant.UserHasRole);
                        cacheContext.EntityInvalidatingRelationshipTypes.Add(WellKnownAliases.CurrentTenant.IncludesRoles);
                    }
                }
                else if (Entity.Is <Role>(Entity.Get(subjectId)))
                {
                    // The subject is a role, so include just include itself, then fetch included roles.
                    roles = new HashSet <long>( );
                    roles.Add(subjectId);

                    GetParentRoles(roles);

                    roles.UnionWith(EveryoneRoles);

                    using (CacheContext cacheContext = CacheContext.GetContext( ))
                    {
                        cacheContext.Entities.Add(roles);
                        cacheContext.EntityInvalidatingRelationshipTypes.Add(WellKnownAliases.CurrentTenant.IncludesRoles);
                    }
                }
                else
                {
                    roles = new HashSet <long>( );
                }

                return(roles);
            }
        }
Beispiel #4
0
 public void CopyTo(TEntity[] array, int arrayIndex)
 {
     Entity.Get <TEntity>(_tracker.Select(pair => pair.Key)).ToArray( ).CopyTo(array, arrayIndex);
 }