Commit 733abe37 by wajeeha-khalid Committed by GitHub

Merge pull request #12988 from edx/jia/MA-2591

MA-2591 update oauthlib version to 1.0.3
parents d4ff39a3 03cee389
...@@ -256,16 +256,16 @@ class StubLtiHandler(StubHttpRequestHandler): ...@@ -256,16 +256,16 @@ class StubLtiHandler(StubHttpRequestHandler):
sha1 = hashlib.sha1() sha1 = hashlib.sha1()
sha1.update(body) sha1.update(body)
oauth_body_hash = unicode(base64.b64encode(sha1.digest())) oauth_body_hash = unicode(base64.b64encode(sha1.digest()))
params = client.get_oauth_params(None)
params.append((u'oauth_body_hash', oauth_body_hash))
mock_request = mock.Mock( mock_request = mock.Mock(
uri=unicode(urllib.unquote(url)), uri=unicode(urllib.unquote(url)),
headers=headers, headers=headers,
body=u"", body=u"",
decoded_body=u"", decoded_body=u"",
oauth_params=params,
http_method=unicode(method), http_method=unicode(method),
) )
params = client.get_oauth_params(mock_request)
mock_request.oauth_params = params
mock_request.oauth_params.append((u'oauth_body_hash', oauth_body_hash))
sig = client.get_oauth_signature(mock_request) sig = client.get_oauth_signature(mock_request)
mock_request.oauth_params.append((u'oauth_signature', sig)) mock_request.oauth_params.append((u'oauth_signature', sig))
new_headers = parameters.prepare_headers(mock_request.oauth_params, headers, realm=None) new_headers = parameters.prepare_headers(mock_request.oauth_params, headers, realm=None)
......
...@@ -128,9 +128,15 @@ class LTIAuthBackend(BaseAuth): ...@@ -128,9 +128,15 @@ class LTIAuthBackend(BaseAuth):
request = Request( request = Request(
uri=strategy.request.build_absolute_uri(), http_method=strategy.request.method, body=strategy.request.body uri=strategy.request.build_absolute_uri(), http_method=strategy.request.method, body=strategy.request.body
) )
lti_consumer_key = request.oauth_consumer_key
try:
lti_consumer_key = request.oauth_consumer_key
except AttributeError:
return None
(lti_consumer_valid, lti_consumer_secret, lti_max_timestamp_age) = cls.load_lti_consumer(lti_consumer_key) (lti_consumer_valid, lti_consumer_secret, lti_max_timestamp_age) = cls.load_lti_consumer(lti_consumer_key)
current_time = calendar.timegm(time.gmtime()) current_time = calendar.timegm(time.gmtime())
return cls._get_validated_lti_params_from_values( return cls._get_validated_lti_params_from_values(
request=request, current_time=current_time, request=request, current_time=current_time,
lti_consumer_valid=lti_consumer_valid, lti_consumer_valid=lti_consumer_valid,
...@@ -148,42 +154,42 @@ class LTIAuthBackend(BaseAuth): ...@@ -148,42 +154,42 @@ class LTIAuthBackend(BaseAuth):
# Taking a cue from oauthlib, to avoid leaking information through a timing attack, # Taking a cue from oauthlib, to avoid leaking information through a timing attack,
# we proceed through the entire validation before rejecting any request for any reason. # we proceed through the entire validation before rejecting any request for any reason.
# However, as noted there, the value of doing this is dubious. # However, as noted there, the value of doing this is dubious.
try:
base_uri = normalize_base_string_uri(request.uri) base_uri = normalize_base_string_uri(request.uri)
parameters = collect_parameters(uri_query=request.uri_query, body=request.body) parameters = collect_parameters(uri_query=request.uri_query, body=request.body)
parameters_string = normalize_parameters(parameters) parameters_string = normalize_parameters(parameters)
base_string = construct_base_string(request.http_method, base_uri, parameters_string) base_string = construct_base_string(request.http_method, base_uri, parameters_string)
computed_signature = sign_hmac_sha1(base_string, unicode(lti_consumer_secret), '') computed_signature = sign_hmac_sha1(base_string, unicode(lti_consumer_secret), '')
submitted_signature = request.oauth_signature submitted_signature = request.oauth_signature
data = {parameter_value_pair[0]: parameter_value_pair[1] for parameter_value_pair in parameters} data = {parameter_value_pair[0]: parameter_value_pair[1] for parameter_value_pair in parameters}
def safe_int(value): def safe_int(value):
""" """
Interprets parameter as an int or returns 0 if not possible Interprets parameter as an int or returns 0 if not possible
""" """
try: try:
return int(value) return int(value)
except (ValueError, TypeError): except (ValueError, TypeError):
return 0 return 0
oauth_timestamp = safe_int(request.oauth_timestamp) oauth_timestamp = safe_int(request.oauth_timestamp)
# As this must take constant time, do not use shortcutting operators such as 'and'. # As this must take constant time, do not use shortcutting operators such as 'and'.
# Instead, use constant time operators such as '&', which is the bitwise and. # Instead, use constant time operators such as '&', which is the bitwise and.
valid = (lti_consumer_valid) valid = (lti_consumer_valid)
valid = valid & (submitted_signature == computed_signature) valid = valid & (submitted_signature == computed_signature)
valid = valid & (request.oauth_version == '1.0') valid = valid & (request.oauth_version == '1.0')
valid = valid & (request.oauth_signature_method == 'HMAC-SHA1') valid = valid & (request.oauth_signature_method == 'HMAC-SHA1')
valid = valid & ('user_id' in data) # Not required by LTI but can't log in without one valid = valid & ('user_id' in data) # Not required by LTI but can't log in without one
valid = valid & (oauth_timestamp >= current_time - lti_max_timestamp_age) valid = valid & (oauth_timestamp >= current_time - lti_max_timestamp_age)
valid = valid & (oauth_timestamp <= current_time) valid = valid & (oauth_timestamp <= current_time)
if valid:
if valid: return data
return data except AttributeError as error:
else: log.error("'{}' not found.".format(error.message))
return None return None
@classmethod @classmethod
def load_lti_consumer(cls, lti_consumer_key): def load_lti_consumer(cls, lti_consumer_key):
......
...@@ -121,7 +121,7 @@ class IntegrationTestLTI(testutil.TestCase): ...@@ -121,7 +121,7 @@ class IntegrationTestLTI(testutil.TestCase):
def test_reject_bad_login(self): def test_reject_bad_login(self):
login_response = self.client.post( login_response = self.client.post(
path=LTI_TPA_LOGIN_URL, content_type=FORM_ENCODED, path=LTI_TPA_LOGIN_URL, content_type=FORM_ENCODED,
data="invalid=login" data="invalid=login",
) )
# The user should be redirected to the login page with an error message # The user should be redirected to the login page with an error message
# (auth_entry defaults to login for this provider) # (auth_entry defaults to login for this provider)
......
...@@ -109,16 +109,16 @@ class LTI20ModuleMixin(object): ...@@ -109,16 +109,16 @@ class LTI20ModuleMixin(object):
log.debug("[LTI] oauth_body_hash = {}".format(oauth_body_hash)) log.debug("[LTI] oauth_body_hash = {}".format(oauth_body_hash))
client_key, client_secret = self.get_client_key_secret() client_key, client_secret = self.get_client_key_secret()
client = Client(client_key, client_secret) client = Client(client_key, client_secret)
params = client.get_oauth_params(None)
params.append((u'oauth_body_hash', oauth_body_hash))
mock_request = mock.Mock( mock_request = mock.Mock(
uri=unicode(urllib.unquote(request.url)), uri=unicode(urllib.unquote(request.url)),
headers=request.headers, headers=request.headers,
body=u"", body=u"",
decoded_body=u"", decoded_body=u"",
oauth_params=params,
http_method=unicode(request.method), http_method=unicode(request.method),
) )
params = client.get_oauth_params(mock_request)
mock_request.oauth_params = params
mock_request.oauth_params.append((u'oauth_body_hash', oauth_body_hash))
sig = client.get_oauth_signature(mock_request) sig = client.get_oauth_signature(mock_request)
mock_request.oauth_params.append((u'oauth_signature', sig)) mock_request.oauth_params.append((u'oauth_signature', sig))
......
...@@ -65,7 +65,7 @@ mongoengine==0.10.0 ...@@ -65,7 +65,7 @@ mongoengine==0.10.0
MySQL-python==1.2.5 MySQL-python==1.2.5
networkx==1.7 networkx==1.7
nose-xunitmp==0.3.2 nose-xunitmp==0.3.2
oauthlib==0.7.2 oauthlib==1.0.3
paramiko==1.9.0 paramiko==1.9.0
path.py==7.2 path.py==7.2
piexif==1.0.2 piexif==1.0.2
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment