tornadoweb / tornado

Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.
http://www.tornadoweb.org/
Apache License 2.0
21.72k stars 5.5k forks source link

Problem with nested requests when using the FacebookGraphMixin get_authenticated_user call #1426

Open pfrantz opened 9 years ago

pfrantz commented 9 years ago

When using the FacebookGraphMixin and calling get_authenticated_user with the extra_fields parameter set to a list of fields that contain nested fields, the returned dictionary will not contain any fields which are nested.

With the Facebook graph api you can specify nested fields which contain modifier and sub selectors. For example you can specify limit by adding a .limit(nn) to a field name.

for example a call lilke:-

auth_info = yield self.get_authenticated_user( redirect_uri=my_url, client_id=client_id, client_secret=client_secret, code=self.get_argument('code'), extra_fields=['email', 'gender', 'age_range', 'permissions', 'friends.limit(5000)'])

will not return the friend list because it don't realise that .limit(5000) is a modifier and the returned field name is friends not friends.limit(5000).

the fix is relatively easy in auth.py by changing the method FacebookGraphMixin._on_get_user_info to remove modifiers prior to mapping the results. Something like this at the start of the method would do

fields = [field.split('.', 1)[0] for field in fields]

bdarnell commented 1 year ago

Per https://developers.facebook.com/docs/graph-api/guides/field-expansion, there are a few different formats this can take:

field.split('.', 1) only addresses the first. It would be simple to add the second if I could find a grammar for this field. The third form is much trickier and requires an exact match between tornado's grammar and facebooks to avoid smuggling attacks.

I'd be fine just not supporting this third case, but I'd rather not add support for the first case without the second, which means we still need some sort of grammar for this field.

Also, I think anyone affected by this has a workaround by not passing extra_fields to get_authenticated_user and instead making a second call with facebook_request where you can pass and parse whatever arguments you want.