/// <summary>
        /// Initializes a new instance of the <see cref="ImpersonationContext"/> class.
        /// </summary>
        /// <param name="principal">The principal.</param>
        /// <param name="outerContext">The outer context.</param>
        public ImpersonationContext(IPrincipal principal, ImpersonationContext outerContext)
            : base(principal.Session)
        {
            ArgumentValidator.EnsureArgumentNotNull(principal, "principal");

            this.outerContext = outerContext;
            Principal         = principal;
            Permissions       = new PermissionSet(principal.Roles);

            QueryEndpoint insecureQuery;
            var           existingBuilder = Session.Query.RootBuilder as SecureQueryRootBuilder;

            if (existingBuilder != null)
            {
                insecureQuery = existingBuilder.InsecureQuery;
            }
            else
            {
                insecureQuery = Session.Query;
            }

            queryRootScope = Session.OverrideQueryRoot(
                new SecureQueryRootBuilder(Session, insecureQuery));
        }
Ejemplo n.º 2
0
        private IQueryable <T> GetSecureQuery <T>(ImpersonationContext context) where T : class, IEntity
        {
            var candidates = new List <IQueryable <T> >();
            var queryType  = typeof(T);

            foreach (var permission in context.Permissions)
            {
                var permissionType = permission.Type;

                // Query<Animal> & Permission<Animal>
                if (queryType == permissionType)
                {
                    // Permission doesn't have restrictive query. Investigation of other permissions doesn't make sense
                    if (permission.Query == null)
                    {
                        return(InsecureQuery.All <T>());
                    }

                    candidates.Add((IQueryable <T>)permission.Query(context, InsecureQuery));
                }
                // Query<Animal> && Permission<Dog>
                else if (queryType.IsAssignableFrom(permissionType))
                {
                    // Permission doesn't have restrictive query. Adding Query<Dog> to candidates
                    if (permission.Query == null)
                    {
                        candidates.Add((IQueryable <T>)InsecureQuery.All(permissionType));
                        continue;
                    }
                    var p = Expression.Parameter(queryType, "p");
                    var where = (Expression <Func <T, bool> >)Expression.Lambda(Expression.Not(Expression.TypeIs(p, permissionType)), p);
                    candidates.Add(InsecureQuery.All <T>().Where(where).Concat(permission.Query(context, InsecureQuery).OfType <T>()));
                }
                // Query<Dog> && Permission<Animal>
                else if (permissionType.IsAssignableFrom(queryType))
                {
                    // Permission doesn't have restrictive query. Investigation of other permissions doesn't make sense
                    if (permission.Query == null)
                    {
                        return(InsecureQuery.All <T>());
                    }

                    candidates.Add(permission.Query(context, InsecureQuery).OfType <T>());
                }
            }
            if (candidates.Count == 0)
            {
                return(InsecureQuery.All <T>());
            }

            if (candidates.Count == 1)
            {
                return(candidates[0]);
            }

            var result = candidates[0];

            for (int i = 1; i < candidates.Count; i++)
            {
                result = result.Union(candidates[i]);
            }

            return(result);
        }