diff --git a/requirements.txt b/requirements.txt index 6f2c3df..0e0f6ca 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ nose==1.3.0 oauthlib==0.6.0 requests==2.0.1 requests-oauthlib==0.4.0 +Werkzeug==0.9.4 diff --git a/tests.py b/tests.py index f485777..6f7cb90 100644 --- a/tests.py +++ b/tests.py @@ -3,6 +3,7 @@ import requests import unittest import time +import werkzeug.datastructures class HttpClientMock(object): def __init__(self, paths): @@ -62,6 +63,18 @@ def test_arrays_get_flattened_for_validate(self): except toopher.SignatureValidationError: self.fail() + def test_immutable_dictionaries_get_copied_for_validate(self): + data = werkzeug.datastructures.ImmutableMultiDict([ + ('foo', 'bar'), + ('timestamp', '1000'), + ('session_token', ToopherIframeTests.request_token), + ('toopher_sig', '6d2c7GlQssGmeYYGpcf+V/kirOI=') + ]) + try: + self.iframe_api.validate(data, ToopherIframeTests.request_token) + except toopher.SignatureValidationError: + self.fail() + def test_get_pair_uri(self): expected = 'https://api.toopher.test/v1/web/pair?username=jdoe&reset_email=jdoe%40example.com&expires=1100&v=2&oauth_nonce=12345678&oauth_timestamp=1000&oauth_version=1.0&oauth_signature_method=HMAC-SHA1&oauth_consumer_key=abcdefg&oauth_signature=UGlgBEUF6UZEhYPxevJeagqy6D4%3D' self.assertEqual(expected, self.iframe_api.pair_uri('jdoe', 'jdoe@example.com')) diff --git a/toopher/__init__.py b/toopher/__init__.py index 5aacf3f..4d8ebf1 100644 --- a/toopher/__init__.py +++ b/toopher/__init__.py @@ -64,6 +64,9 @@ def login_uri(self, username, reset_email, request_token): return self.auth_uri(username, reset_email, 'Log In', True, False, request_token, 'None', DEFAULT_IFRAME_TTL) def validate(self, data, request_token=None, ttl=DEFAULT_IFRAME_TTL): + # make a mutable copy of the data + data = dict(data) + # flatten data if necessary if hasattr(data.values()[0], '__iter__'): data = dict((k,v[0]) for (k,v) in data.items()) @@ -75,7 +78,7 @@ def validate(self, data, request_token=None, ttl=DEFAULT_IFRAME_TTL): if missing_keys: raise SignatureValidationError("Missing required keys: {0}".format(missing_keys)) - + if request_token: if request_token != data.get('session_token'): raise SignatureValidationError("Session token does not match expected value!")