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):
sha1 = hashlib.sha1()
sha1.update(body)
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(
uri=unicode(urllib.unquote(url)),
headers=headers,
body=u"",
decoded_body=u"",
oauth_params=params,
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)
mock_request.oauth_params.append((u'oauth_signature', sig))
new_headers = parameters.prepare_headers(mock_request.oauth_params, headers, realm=None)
......
......@@ -128,9 +128,15 @@ class LTIAuthBackend(BaseAuth):
request = Request(
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)
current_time = calendar.timegm(time.gmtime())
return cls._get_validated_lti_params_from_values(
request=request, current_time=current_time,
lti_consumer_valid=lti_consumer_valid,
......@@ -148,42 +154,42 @@ class LTIAuthBackend(BaseAuth):
# 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.
# However, as noted there, the value of doing this is dubious.
base_uri = normalize_base_string_uri(request.uri)
parameters = collect_parameters(uri_query=request.uri_query, body=request.body)
parameters_string = normalize_parameters(parameters)
base_string = construct_base_string(request.http_method, base_uri, parameters_string)
computed_signature = sign_hmac_sha1(base_string, unicode(lti_consumer_secret), '')
submitted_signature = request.oauth_signature
data = {parameter_value_pair[0]: parameter_value_pair[1] for parameter_value_pair in parameters}
def safe_int(value):
"""
Interprets parameter as an int or returns 0 if not possible
"""
try:
return int(value)
except (ValueError, TypeError):
return 0
oauth_timestamp = safe_int(request.oauth_timestamp)
# 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.
valid = (lti_consumer_valid)
valid = valid & (submitted_signature == computed_signature)
valid = valid & (request.oauth_version == '1.0')
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 & (oauth_timestamp >= current_time - lti_max_timestamp_age)
valid = valid & (oauth_timestamp <= current_time)
if valid:
return data
else:
return None
try:
base_uri = normalize_base_string_uri(request.uri)
parameters = collect_parameters(uri_query=request.uri_query, body=request.body)
parameters_string = normalize_parameters(parameters)
base_string = construct_base_string(request.http_method, base_uri, parameters_string)
computed_signature = sign_hmac_sha1(base_string, unicode(lti_consumer_secret), '')
submitted_signature = request.oauth_signature
data = {parameter_value_pair[0]: parameter_value_pair[1] for parameter_value_pair in parameters}
def safe_int(value):
"""
Interprets parameter as an int or returns 0 if not possible
"""
try:
return int(value)
except (ValueError, TypeError):
return 0
oauth_timestamp = safe_int(request.oauth_timestamp)
# 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.
valid = (lti_consumer_valid)
valid = valid & (submitted_signature == computed_signature)
valid = valid & (request.oauth_version == '1.0')
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 & (oauth_timestamp >= current_time - lti_max_timestamp_age)
valid = valid & (oauth_timestamp <= current_time)
if valid:
return data
except AttributeError as error:
log.error("'{}' not found.".format(error.message))
return None
@classmethod
def load_lti_consumer(cls, lti_consumer_key):
......
......@@ -121,7 +121,7 @@ class IntegrationTestLTI(testutil.TestCase):
def test_reject_bad_login(self):
login_response = self.client.post(
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
# (auth_entry defaults to login for this provider)
......
......@@ -109,16 +109,16 @@ class LTI20ModuleMixin(object):
log.debug("[LTI] oauth_body_hash = {}".format(oauth_body_hash))
client_key, client_secret = self.get_client_key_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(
uri=unicode(urllib.unquote(request.url)),
headers=request.headers,
body=u"",
decoded_body=u"",
oauth_params=params,
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)
mock_request.oauth_params.append((u'oauth_signature', sig))
......
......@@ -65,7 +65,7 @@ mongoengine==0.10.0
MySQL-python==1.2.5
networkx==1.7
nose-xunitmp==0.3.2
oauthlib==0.7.2
oauthlib==1.0.3
paramiko==1.9.0
path.py==7.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