Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Refactor oauth sig type to be based on scheme

  • Loading branch information...
commit 444e34611ed4dbaab4125951a48451b7ab0cc453 1 parent 00633ae
@muffinresearch muffinresearch authored
View
2  CHANGELOG
@@ -1,3 +1,5 @@
+* 0.7.7
+ * Refactor endpoints and oauth sigs to be based on scheme.
* 0.7.6
* Update defaults for 3-legged to match 2-legged
* Remove old tests
View
2  setup.py
@@ -7,7 +7,7 @@
from setuptools import setup, find_packages
README = open('README.rst').read()
-VERSION = "0.7.6"
+VERSION = "0.7.7"
setup(name='yql',
version=VERSION,
View
96 yql/__init__.py
@@ -29,7 +29,7 @@
__author__ = 'Stuart Colville'
-__version__ = '0.7.6'
+__version__ = '0.7.7'
__all__ = ['Public', 'TwoLegged', 'ThreeLegged']
@@ -38,12 +38,8 @@
REQUEST_TOKEN_URL = 'https://api.login.yahoo.com/oauth/v2/get_request_token'
ACCESS_TOKEN_URL = 'https://api.login.yahoo.com/oauth/v2/get_token'
AUTHORIZATION_URL = 'https://api.login.yahoo.com/oauth/v2/request_auth'
-
-PUBLIC_ENDPOINT = "query.yahooapis.com/v1/public/yql"
-PRIVATE_ENDPOINT = "query.yahooapis.com/v1/yql"
-HTTP_SCHEME = "http:"
-HTTPS_SCHEME = "https:"
-
+PUBLIC_ENDPOINT = 'https://query.yahooapis.com/v1/public/yql'
+PRIVATE_ENDPOINT = 'https://query.yahooapis.com/v1/yql'
yql_logger = get_logger()
@@ -251,25 +247,7 @@ def __init__(self, api_key=None, shared_secret=None, httplib2_inst=None):
self.api_key = api_key
self.secret = shared_secret
self.http = httplib2_inst or Http()
- self.scheme = HTTPS_SCHEME
- self.__endpoint = PUBLIC_ENDPOINT
- self.uri = self.get_endpoint_uri()
-
- def get_endpoint_uri(self):
- """Get endpoint"""
- return "http://%s" % self.endpoint
-
- def get_endpoint(self):
- """Gets the endpoint for requests"""
- return self.__endpoint
-
- def set_endpoint(self, value):
- """Sets the endpoint and updates the uri"""
- if value in (PRIVATE_ENDPOINT, PUBLIC_ENDPOINT):
- self.__endpoint = value
- self.uri = self.get_endpoint_uri()
- else:
- raise ValueError("Invalid endpoint: %s" % value)
+ self.endpoint = PUBLIC_ENDPOINT
def get_query_params(self, query, params, **kwargs):
"""Get the query params and validate placeholders"""
@@ -291,7 +269,7 @@ def get_uri(self, query, params=None, **kwargs):
query = YQLQuery(query)
params = self.get_query_params(query, params, **kwargs)
query_string = urlencode(params)
- uri = '%s?%s' % (self.uri, query_string)
+ uri = '%s?%s' % (self.endpoint, query_string)
uri = clean_url(uri)
return uri
@@ -299,16 +277,10 @@ def execute(self, query, params=None, **kwargs):
"""Execute YQL query"""
yqlquery = YQLQuery(query)
url = self.get_uri(yqlquery, params, **kwargs)
- # Just in time change to https avoids
- # invalid oauth sigs
- if self.scheme == HTTPS_SCHEME:
- url = url.replace(HTTP_SCHEME, HTTPS_SCHEME, 1)
-
yql_logger.debug("executed url: %s", url)
http_method = yqlquery.get_http_method()
if http_method in ["DELETE", "PUT", "POST"]:
data = {"q": query}
-
# Encode as json and set Content-Type header
# to reflect we are sending JSON
# Fixes LP: 629064
@@ -326,8 +298,6 @@ def execute(self, query, params=None, **kwargs):
else:
raise YQLError(resp, content)
- endpoint = property(get_endpoint, set_endpoint)
-
class TwoLegged(Public):
"""Two legged Auth is simple request which is signed prior to sending"""
@@ -336,10 +306,20 @@ def __init__(self, api_key, shared_secret, httplib2_inst=None):
"""Override init to ensure required args"""
super(TwoLegged, self).__init__(api_key, shared_secret, httplib2_inst)
self.endpoint = PRIVATE_ENDPOINT
- self.scheme = HTTPS_SCHEME
self.hmac_sha1_signature = oauth.SignatureMethod_HMAC_SHA1()
self.plaintext_signature = oauth.SignatureMethod_PLAINTEXT()
+ def get_signature(self, url):
+ url_parts = urlparse(url)
+ scheme = url_parts.scheme
+ if scheme == "http":
+ sig = self.hmac_sha1_signature
+ elif scheme == "https":
+ sig = self.plaintext_signature
+ else:
+ raise ValueError("Invalid scheme: %s " % scheme)
+ return sig
+
@staticmethod
def get_base_params():
"""Set-up the basic parameters needed for a request"""
@@ -350,22 +330,22 @@ def get_base_params():
params['oauth_timestamp'] = int(time.time())
return params
- def __two_legged_request(self, resource_url, parameters=None, method=None):
+ def __two_legged_request(self, parameters=None, method=None):
"""Sign a request for two-legged authentication"""
-
params = self.get_base_params()
if parameters:
params.update(parameters)
-
+ url = self.endpoint
yql_logger.debug("params: %s", params)
- yql_logger.debug("resource_url: %s", resource_url)
+ yql_logger.debug("endpoint_url: %s", url)
if not method:
method = "GET"
consumer = oauth.Consumer(self.api_key, self.secret)
- request = oauth.Request(method=method, url=resource_url,
- parameters=params)
- request.sign_request(self.hmac_sha1_signature, consumer, None)
+ request = oauth.Request(method=method, url=url, parameters=params)
+ sig = self.get_signature(url)
+ yql_logger.debug("signature: %s", sig)
+ request.sign_request(sig, consumer, None)
return request
def get_uri(self, query, params=None, **kwargs):
@@ -374,11 +354,10 @@ def get_uri(self, query, params=None, **kwargs):
query = YQLQuery(query)
query_params = self.get_query_params(query, params, **kwargs)
http_method = query.get_http_method()
- request = self.__two_legged_request(self.uri,
- parameters=query_params, method=http_method)
- uri = "%s?%s" % (self.uri, request.to_postdata())
- uri = clean_url(uri)
- return uri
+ request = self.__two_legged_request(parameters=query_params,
+ method=http_method)
+ url = request.to_url()
+ return clean_url(url)
class ThreeLegged(TwoLegged):
@@ -561,23 +540,24 @@ def get_uri(self, query, params=None, **kwargs):
query_params["oauth_yahoo_guid"] = getattr(token, "yahoo_guid")
if not token:
- raise ValueError("Without a token three-legged-auth cannot be"\
- " carried out")
+ raise ValueError("Without a token three-legged-auth cannot be"
+ " carried out")
yql_logger.debug("query_params: %s", query_params)
http_method = query.get_http_method()
+ url = self.endpoint
oauth_request = oauth.Request.from_consumer_and_token(
- self.consumer, http_url=self.uri,
- token=token, parameters=query_params,
- http_method=http_method)
+ self.consumer, http_url=url,
+ token=token, parameters=query_params,
+ http_method=http_method)
yql_logger.debug("oauth_request: %s", oauth_request)
# Sign request
- oauth_request.sign_request(
- self.hmac_sha1_signature, self.consumer, token)
-
+ sig = self.get_signature(url)
+ oauth_request.sign_request(sig, self.consumer, token)
yql_logger.debug("oauth_signed_request: %s", oauth_request)
- uri = "%s?%s" % (self.uri, oauth_request.to_postdata())
- return uri.replace('+', '%20').replace('%7E', '~')
+ url = oauth_request.to_url()
+ url = clean_url(url)
+ return url.replace('+', '%20').replace('%7E', '~')
class YahooToken(oauth.Token):
View
29 yql/tests/test_requests_responses.py
@@ -163,7 +163,7 @@ def test_urlencoding_for_public_yql(self):
query = 'SELECT * from foo'
y = TestPublic(httplib2_inst=httplib2.Http())
uri = y.execute(query)
- self.assertEqual(uri, "http://query.yahooapis.com/v1/public/yql?q=SELECT+%2A+from+foo&format=json")
+ self.assertEqual(uri, "https://query.yahooapis.com/v1/public/yql?q=SELECT+%2A+from+foo&format=json")
def test_env_for_public_yql(self):
query = 'SELECT * from foo'
@@ -201,15 +201,27 @@ def test_api_key_and_secret_attrs(self):
def test_get_two_legged_request_keys(self):
y = yql.TwoLegged('test-api-key', 'test-secret')
# Accessed this was because it's private
- request = y._TwoLegged__two_legged_request('http://google.com')
+ request = y._TwoLegged__two_legged_request()
self.assertEqual(set(['oauth_nonce', 'oauth_version', 'oauth_timestamp',
'oauth_consumer_key', 'oauth_signature_method', 'oauth_body_hash',
'oauth_version', 'oauth_signature']), set(request.keys()))
def test_get_two_legged_request_values(self):
y = yql.TwoLegged('test-api-key', 'test-secret')
+ y.endpoint = "https://query.yahooapis.com/v1/yql"
# Accessed this was because it's private
- request = y._TwoLegged__two_legged_request('http://google.com')
+ request = y._TwoLegged__two_legged_request()
+ self.assertTrue(y.endpoint.startswith("https"))
+ self.assertEqual(request['oauth_consumer_key'], 'test-api-key')
+ self.assertEqual(request['oauth_signature_method'], 'PLAINTEXT')
+ self.assertEqual(request['oauth_version'], '1.0')
+
+ def test_get_two_legged_request_values(self):
+ y = yql.TwoLegged('test-api-key', 'test-secret')
+ y.endpoint = "http://query.yahooapis.com/v1/yql"
+ # Accessed this was because it's private
+ request = y._TwoLegged__two_legged_request()
+ self.assertTrue(y.endpoint.startswith("http"))
self.assertEqual(request['oauth_consumer_key'], 'test-api-key')
self.assertEqual(request['oauth_signature_method'], 'HMAC-SHA1')
self.assertEqual(request['oauth_version'], '1.0')
@@ -217,8 +229,7 @@ def test_get_two_legged_request_values(self):
def test_get_two_legged_request_param(self):
y = yql.TwoLegged('test-api-key', 'test-secret')
# Accessed this way because it's private
- request = y._TwoLegged__two_legged_request('http://google.com',
- {"test-param": "test"})
+ request = y._TwoLegged__two_legged_request({"test-param": "test"})
self.assertEqual(request.get('test-param'), 'test')
@@ -257,13 +268,15 @@ def test_api_key_and_secret_attrs2(self):
def test_get_base_params(self):
y = yql.ThreeLegged('test-api-key', 'test-secret')
result = y.get_base_params()
- self.assertEqual(set(['oauth_nonce', 'oauth_version', 'oauth_timestamp']),
+ self.assertEqual(set(['oauth_nonce', 'oauth_version',
+ 'oauth_timestamp']),
set(result.keys()))
@raises(ValueError)
def test_raises_for_three_legged_with_no_token(self):
query = 'SELECT * from foo'
- y = TestThreeLegged('test-api-key', 'test-secret', httplib2_inst=httplib2.Http())
+ y = TestThreeLegged('test-api-key', 'test-secret',
+ httplib2_inst=httplib2.Http())
y.execute(query)
@@ -295,7 +308,7 @@ def test_three_legged_execution(self):
@raises(ValueError)
def test_three_legged_execution_raises_value_error_with_invalid_uri(self):
y = yql.ThreeLegged('test','test2', httplib2_inst=httplib2.Http())
- y.uri = "fail"
+ y.endpoint = "invalid"
token = yql.YahooToken('tes1t', 'test2')
y.execute("SELECT foo meh meh ", token=token)
View
12 yql/tests/test_services.py
@@ -1,12 +0,0 @@
-from unittest import TestCase
-
-from nose.tools import raises
-
-import yql
-
-
-class PublicTest(TestCase):
- @raises(ValueError)
- def test_cannot_use_unrecognizable_endpoint(self):
- y = yql.Public()
- y.endpoint = 'some-strange-endpoint'
View
6 yql/utils.py
@@ -1,7 +1,6 @@
""""Utility functions"""
import re
-
METHOD_MAP = (
("insert", "POST"),
("update", "PUT"),
@@ -23,13 +22,10 @@ def get_http_method(query):
return http_method
-
def clean_url(url):
"""Cleans up a uri/url"""
url = url.replace("\n", "")
- url = MULTI_PLUS.sub("+", url)
- return url
-
+ return MULTI_PLUS.sub("+", url)
def clean_query(query):
"""Cleans up a query"""

0 comments on commit 444e346

Please sign in to comment.
Something went wrong with that request. Please try again.