/// <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)); }
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); }