Print Page | Close Window

Filtering Anonymous Types in QueryIntercepter

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce 2010
Forum Discription: For .NET 4.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=2784
Printed Date: 16-Apr-2024 at 3:10pm


Topic: Filtering Anonymous Types in QueryIntercepter
Posted By: gregweb
Subject: Filtering Anonymous Types in QueryIntercepter
Date Posted: 21-Jun-2011 at 7:03am
I use the QueryIntercepter to intercept queries and add additional filters for security reasons. 

elementType = this.Query.ElementType;

 

if (elementType == typeof(EmailMessageAddressEntity))

{

FilterEmailMessageAddressEntities();

}

This works just fine.  However, when I use an anonymous type, the Query.ElementType becomes "_IB_f__AnonymousType0`2AxjSHFNiSHhJp_ddt" Thus it doesn't get filtered.  This is the query:
 

var query =           

this.EmailEntityManager.EmailMessageAddressEntities

.Select(a =>

new { a.Name, a.Address }).Distinct().OrderBy(a=> a.Name);

 
So the question is what is the best way to Filter Anonymous Types in the QueryInterceptor?
 
Greg



Replies:
Posted By: sbelini
Date Posted: 23-Jun-2011 at 5:55pm
Hi Greg,
 
You could simply add the filter in the interceptor without checking the type:
 
// if (elementType == typeof(EmailMessageAddressEntity)) {
  FilterEmailMessageAddressEntities();
//}
 
Note that regardless of whether you are returning an Entity Collection or an AnonymousType Collection, adding a filter for the entity initially being queried (i.e. EmailMessageAddressEntity) will still filter the results.
 
Now, if you must check for the type of just don't want to add the filter for every single query, then I suggest checking the type name: (not fail proof, as one might - unlikely - create an entity containing "__AnonymousType" in it's name)
 
if (this.Query.ElementType.ToString().Contains("__AnonymousType")) {
  FilterEmailMessageAddressEntities();
}
 
Regards,
   Silvio.


Posted By: gregweb
Date Posted: 23-Jun-2011 at 8:19pm
I didn't know the first point - that you don't need to check the type first. 
I rewrote my security filters so every query gets filtered for every entity type.  It seems that is the only way to ensure that every query is filtered whether it's an anonymous type or non-anonymous type. (That's a funny word - non-anonymous - say that three times fast!) 
It's a lot of filtering, but it works and doesn't seem to slow up anything.
 
Greg


Posted By: brakowski
Date Posted: 16-Sep-2011 at 6:28am
Could you provide a code for FilterEmailMessageAddressEntities() ?

I mean, if I try to add filters with the use of QueryFilters.AddFilter<T> it only is executed for queries that are related to T type.
Now, let suppose I have MyUserEntity type.
Let suppose I know how to filter set of MyUserEntity (i.e. every IQueryable<MyUserEntity>).

But in my model I also have:
-MyOrderEntity,
-MyArticleEntity,
-MyInvoiceEntity
...and many many others
so one can access MyUserEntity entities starting from any of the related entity types.
I do not want to translate all the relations MyOrderEntity<->MyUserEntity, MyArticleEntity<->MyUserEntity... into filters (but I still want have the limited access to MyUserEntities regardless of base type of the query). So, how to do it? It looks like you did it
somehow in FilterEmailMessageAddressEntities().

Also if we talk about AnonymousType queries I want to :
a) find a way not to authorize any of the AnonymousType queries which use MyUserEntity
or
b) a way to filter every AnonymousType query so it would "see" as only authorized MyUserEntity entities were in the database
How to do this part?


Posted By: sbelini
Date Posted: 19-Sep-2011 at 4:01pm
Hi Brakowski,
 
You can find details about adding filters in the http://drc.ideablade.com/xwiki/bin/view/Documentation/filtering-queries-globally - DevForce Resource Center .
 
Basically you'd replace FilterEmailMessageAddressEntities() with:
 
this.QueryFilters.AddFilter((IQueryable<EmailMessageAddress> qFilter) => qFilter.Where(eMA => eMA.UserID.StartsWith("s")));
 
As for your questions:
a) you'd override the AuthorizeQuery method:
 
protected override bool AuthorizeQuery() {
  if (this.Query.ElementType.ToString().Contains("__AnonymousType")) {
    if (this.Query.QueryableType == typeof(MyUserEntity)) {
      return false;
    }
  }
  return base.AuthorizeQuery();
}
 
b) you can use what I suggested in my earlier post:
 
if (this.Query.ElementType.ToString().Contains("__AnonymousType")) {
  FilterEmailMessageAddressEntities();
}
 
Again, this approach is not fail proof as one might (unlikely) create an entity containing "__AnonymousType" in it's name.
 
Regards,
Silvio.
 



Print Page | Close Window