params = { "client_id": App.facebook_app_id, "client_secret": App.facebook_app_secret, "redirect_uri": get_facebook_token_callback_url(oauth_map), "code": oauth_map.facebook_authorization_code, } try: response = get_response(FB_URL_ACCESS_TOKEN, params) except Exception, e: raise OAuthError(e.message) response_params = get_parsed_params(response) if not response_params or not response_params.get("access_token"): raise OAuthError( "Cannot get access_token from Facebook's /oauth/access_token response" ) # Associate our access token and Google/Facebook's oauth_map.facebook_access_token = response_params["access_token"][0] expires_seconds = 0 try: expires_seconds = int(response_params["expires"][0]) except (ValueError, KeyError): pass if expires_seconds: oauth_map.expires = datetime.datetime.now() + datetime.timedelta( seconds=expires_seconds)
if oauth_server is None: return oauth_error_response(OAuthError('Invalid request parameters.')) try: # Create our request token token = oauth_server.fetch_request_token(oauth_request) except OAuthError, e: return oauth_error_response(e) if OAuthMap.get_from_request_token(token.key_): logging.error("OAuth key %s already used" % token.key_) params = dict([(key, request.get(key)) for key in request.arguments()]) logging.info("params: %r" % params) logging.info("Authorization: %s", request.headers.get('Authorization')) return oauth_error_response(OAuthError("OAuth parameters already used.")) # Start a new OAuth mapping oauth_map = OAuthMap() oauth_map.request_token_secret = token.secret oauth_map.request_token = token.key_ oauth_map.callback_url = requested_oauth_callback() if request.values.get("view") == "mobile": oauth_map.view = "mobile" oauth_map.put() chooser_url = "/login/mobileoauth?oauth_map_id=%s&view=%s" % (oauth_map.key().id(), oauth_map.view) oauth_consumer = oauth_server._get_consumer(oauth_request)
def access_token_response(oauth_map): if not oauth_map: raise OAuthError("Missing oauth_map while returning access_token_response") return "oauth_token=%s&oauth_token_secret=%s" % (oauth_map.access_token, oauth_map.access_token_secret)
# identity providers we consume (Google/Facebook) # disagree, we act as if our token is no longer valid. return oauth_error_response( OAuthError( "Unable to get current user from oauth token")) except OAuthError, e: return oauth_error_response(e) elif util.allow_cookie_based_auth(): if not util.get_current_user_id_from_cookies_unsafe(): return oauth_error_response( OAuthError("Unable to read user value from cookies")) else: return oauth_error_response( OAuthError("Invalid parameters to Oauth request")) # Request validated - proceed with the method. return func(*args, **kwargs) return wrapper return outer_wrapper def oauth_optional(require_anointed_consumer=False): """ Decorator for validating an oauth request and storing the OAuthMap for use in the rest of the request. If oauth credentials don't pass, continue on, but util.get_current_user_id() may return None.
# in case Facebook or Google is slow. c_tries_left = 5 while not result and c_tries_left > 0: try: result = urlfetch.fetch(url_with_params, deadline=10) except Exception, e: c_tries_left -= 1 logging.warning("Trying to get response for %s again (tries left: %s) due to error: %s" % (url, c_tries_left, e.message)) if result: if result.status_code == 200: return result.content else: raise OAuthError("Error in get_response, received status %s for url %s" % (result.status_code, url)) elif c_tries_left == 0: raise OAuthError("Failed to get response for %s due to errors." % url) return "" def append_url_params(url, params={}): if params: if "?" in url: url += "&" else: url += "?" url += urllib.urlencode(params) return url