diff --git a/tornado/auth.py b/tornado/auth.py index a5bc0cd1..f513585c 100644 --- a/tornado/auth.py +++ b/tornado/auth.py @@ -922,7 +922,7 @@ class FacebookGraphMixin(OAuth2Mixin): _OAUTH_NO_CALLBACKS = False def get_authenticated_user(self, redirect_uri, client_id, client_secret, - code, callback): + code, callback, extra_fields=None): """ Handles the login for the Facebook user, returning a user object. Example usage: @@ -955,42 +955,48 @@ class FacebookGraphMixin(OAuth2Mixin): "client_secret": client_secret, } + if extra_fields and not isinstance(extra_fields, (set, frozenset)): + extra_fields = set(extra_fields) + http.fetch(self._oauth_request_token_url(**args), self.async_callback(self._on_access_token, redirect_uri, client_id, - client_secret, callback)) + client_secret, callback, extra_fields)) def _on_access_token(self, redirect_uri, client_id, client_secret, - callback, response): + callback, extra_fields, response): + if response.error: + logging.warning('Facebook auth error: %s' % str(response)) + callback(None) + return + session = { - "access_token": cgi.parse_qs(response.body)["access_token"][-1], - "expires": cgi.parse_qs(response.body).get("expires") + "access_token": cgi.parse_qs(response.body)["access_token"][-1], + "expires": cgi.parse_qs(response.body).get("expires") } self.facebook_request( path="/me", callback=self.async_callback( - self._on_get_user_info, callback, session), + self._on_get_user_info, callback, session, extra_fields), access_token=session["access_token"], - fields="picture" + fields="picture" # This one's exceptional in that it appends to fields returned ) - def _on_get_user_info(self, callback, session, user): + def _on_get_user_info(self, callback, session, extra_fields, user): if user is None: callback(None) return - callback({ - "name": user["name"], - "first_name": user["first_name"], - "last_name": user["last_name"], - "id": user["id"], - "locale": user["locale"], - "picture": user.get("picture"), - "link": user["link"], - "username": user.get("username"), - "access_token": session["access_token"], - "session_expires": session.get("expires"), - }) + + fields = set(['id', 'name', 'first_name', 'last_name', 'locale', 'picture', 'link']) + if extra_fields: fields.update(extra_fields) + + fieldmap = {} + for field in fields: + fieldmap[field] = user.get(field) + + fieldmap.update({"access_token": session["access_token"], "session_expires": session.get("expires")}) + callback(fieldmap) def facebook_request(self, path, callback, access_token=None, post_args=None, **args):