locked
Specify field list in QueryInterceptor RRS feed

  • Question

  • I would like to return a specific list of fields when a specific user is querying against my datasource.. So is it possible to specify which fields to return in the QueryInterceptor method?

    I would like to do the following

    if user = 'A'

        return return p => true;

    else if user = 'B'

        return return p => false;

    else if user = 'C'

        return p.FieldA, p. FieldB

     

    Thanks

    Henrik

    Thursday, August 5, 2010 11:33 AM

Answers

  • Hi,

    This is currently not possible from the query interceptor.

    A rather complex workaround might be possible if you provide a custom host (IDataServiceHost2). In the custom host you can modify the incomming URL of the request. So you can check which user it is, and inject $select option to the URL to only ask for the properties you want. Note though that this will not be a "Security" feature anymore as there are other ways to get to the properties. Direct query for that property (you would have to recognize that and filter it out), $filter or $orderby based on a property (Wan't return the value, but can be used to test the value), replies to POST/PUT/MERGE will include all the properties (and there's no way to apply the $select here).

    Thanks,


    Vitek Karas [MSFT]
    Thursday, August 5, 2010 11:52 AM
    Moderator
  • Hi,

    Actually there is a way to make this work correctly all the time, but it's lot of work and complicated. You could implement a custom provider which changes the metadata based on the user. So each user could see a different model of the data (which is effectively what you want). Doing so will make sure that everything will work correctly ($metadata would show the correct model, queries would show correct data, query options would only allow referencing the right properties and so on and on). It's probably not worth it if you want to hide a few properties.

    Another possible solution would be to split the entity into two. You would have two entities A and B. A would have the properties everybody can see and B would have the rest. Then you could use query interceptors to filter out the Bs for certain users. You would also probably add nav properties between the two so that it's easy to get one from the other. This would again be a "clean" solution, meaning that there's no way around it.

    Thanks,


    Vitek Karas [MSFT]
    Thursday, August 5, 2010 9:23 PM
    Moderator

All replies

  • Hi,

    This is currently not possible from the query interceptor.

    A rather complex workaround might be possible if you provide a custom host (IDataServiceHost2). In the custom host you can modify the incomming URL of the request. So you can check which user it is, and inject $select option to the URL to only ask for the properties you want. Note though that this will not be a "Security" feature anymore as there are other ways to get to the properties. Direct query for that property (you would have to recognize that and filter it out), $filter or $orderby based on a property (Wan't return the value, but can be used to test the value), replies to POST/PUT/MERGE will include all the properties (and there's no way to apply the $select here).

    Thanks,


    Vitek Karas [MSFT]
    Thursday, August 5, 2010 11:52 AM
    Moderator
  • That was a shame.

     

    Thanks

    Henrik

    Thursday, August 5, 2010 7:49 PM
  • Hi,

    Actually there is a way to make this work correctly all the time, but it's lot of work and complicated. You could implement a custom provider which changes the metadata based on the user. So each user could see a different model of the data (which is effectively what you want). Doing so will make sure that everything will work correctly ($metadata would show the correct model, queries would show correct data, query options would only allow referencing the right properties and so on and on). It's probably not worth it if you want to hide a few properties.

    Another possible solution would be to split the entity into two. You would have two entities A and B. A would have the properties everybody can see and B would have the rest. Then you could use query interceptors to filter out the Bs for certain users. You would also probably add nav properties between the two so that it's easy to get one from the other. This would again be a "clean" solution, meaning that there's no way around it.

    Thanks,


    Vitek Karas [MSFT]
    Thursday, August 5, 2010 9:23 PM
    Moderator
  • Hi again,

    I have actually thought of solution B as well, and I think that would work out for me.

    Thanks

    Henrik

    Friday, August 6, 2010 8:53 AM