@@ -28,44 +28,46 @@ def decode(self):
28
28
for k , v in self .items ():
29
29
self [k ] = v .decode ('utf-8' )
30
30
31
- uri_query = "b5=%3D%253D&a3=a&c%40=&a2=r%20b&c2=&a3=2+q "
31
+ uri_query = "b5=%3D%253D&a3=a&c%40=&a2=r%20b"
32
32
authorization_header = """OAuth realm="Example",
33
33
oauth_consumer_key="9djdj82h48djs9d2",
34
34
oauth_token="kkk9d7dh3k39sjv7",
35
35
oauth_signature_method="HMAC-SHA1",
36
36
oauth_timestamp="137131201",
37
37
oauth_nonce="7d8f3e4a",
38
38
oauth_signature="djosJKDKJSD8743243%2Fjdk33klY%3D" """ .strip ()
39
- body = "content=This+is+being+the+body+of+things "
39
+ body = "c2&a3=2+q "
40
40
http_method = b"post"
41
- base_string_url = quote ("http://example.com/request?b5=%3D%253D"
42
- "&a3=a&c%40=&a2=r%20b" ).encode ('utf-8' )
43
- normalized_encoded_request_parameters = quote (
44
- 'OAuth realm="Example",'
45
- 'oauth_consumer_key="9djdj82h48djs9d2",'
46
- 'oauth_token="kkk9d7dh3k39sjv7",'
47
- 'oauth_signature_method="HMAC-SHA1",'
48
- 'oauth_timestamp="137131201",'
49
- 'oauth_nonce="7d8f3e4a",'
50
- 'oauth_signature="bYT5CMsGcbgUdFHObYMEfcx6bsw%3D"'
51
- ).encode ('utf-8' )
41
+ base_string_url = (
42
+ "http://example.com/request?{}" .format (uri_query )).encode ('utf-8' )
43
+ unnormalized_request_parameters = [
44
+ ('OAuth realm' ,"Example" ),
45
+ ('oauth_consumer_key' ,"9djdj82h48djs9d2" ),
46
+ ('oauth_token' ,"kkk9d7dh3k39sjv7" ),
47
+ ('oauth_signature_method' ,"HMAC-SHA1" ),
48
+ ('oauth_timestamp' ,"137131201" ),
49
+ ('oauth_nonce' ,"7d8f3e4a" ),
50
+ ('oauth_signature' ,"bYT5CMsGcbgUdFHObYMEfcx6bsw%3D" )
51
+ ]
52
+ normalized_encoded_request_params = sorted (
53
+ [(quote (k ), quote (v )) for k , v in unnormalized_request_parameters
54
+ if k .lower () != "oauth realm" ])
52
55
client_secret = b"ECrDNoq1VYzzzzzzzzzyAK7TwZNtPnkqatqZZZZ"
53
56
resource_owner_secret = b"just-a-string asdasd"
54
57
control_base_string = (
55
- "POST&http%253A%2F%2Fexample.com%2Frequest%253F"
56
- "b5%253D%25253D%2525253D%2526"
57
- "a3%253D"
58
- "a%2526"
59
- "c%252540%253D%2526"
60
- "a2%253D"
61
- "r%252520b&"
62
- "OAuth%2520realm%253D%2522Example%2522%252C"
63
- "oauth_consumer_key%253D%25229djdj82h48djs9d2%2522%252C"
64
- "oauth_token%253D%2522kkk9d7dh3k39sjv7%2522%252C"
65
- "oauth_signature_method%253D%2522HMAC-SHA1%2522%252C"
66
- "oauth_timestamp%253D%2522137131201%2522%252C"
67
- "oauth_nonce%253D%25227d8f3e4a%2522%252C"
68
- "oauth_signature%253D%2522bYT5CMsGcbgUdFHObYMEfcx6bsw%25253D%2522" )
58
+ "POST&http%3A%2F%2Fexample.com%2Frequest&"
59
+ "a2%3Dr%2520b%26"
60
+ "a3%3D2%2520q%26"
61
+ "a3%3Da%26"
62
+ "b5%3D%253D%25253D%26"
63
+ "c%2540%3D%26"
64
+ "c2%3D%26"
65
+ "oauth_consumer_key%3D9djdj82h48djs9d2%26"
66
+ "oauth_nonce%3D7d8f3e4a%26"
67
+ "oauth_signature_method%3DHMAC-SHA1%26"
68
+ "oauth_timestamp%3D137131201%26"
69
+ "oauth_token%3Dkkk9d7dh3k39sjv7"
70
+ )
69
71
70
72
def setUp (self ):
71
73
self .client = self .MockClient (
@@ -87,34 +89,42 @@ def test_signature_base_string(self):
87
89
oauth_timestamp="137131201",
88
90
oauth_nonce="7d8f3e4a",
89
91
oauth_signature="bYT5CMsGcbgUdFHObYMEfcx6bsw%3D"
92
+ c2&a3=2+q
90
93
91
94
Sample Base string generated and tested against::
92
-
93
- POST&http%253A%2F%2Fexample.com%2Frequest%253Fb5%253D%25253D%252525
94
- 3D%2526a3%253Da%2526c%252540%253D%2526a2%253Dr%252520b&OAuth%2520re
95
- alm%253D%2522Example%2522%252Coauth_consumer_key%253D%25229djdj82h4
96
- 8djs9d2%2522%252Coauth_token%253D%2522kkk9d7dh3k39sjv7%2522%252Coau
97
- th_signature_method%253D%2522HMAC-SHA1%2522%252Coauth_timestamp%253
98
- D%2522137131201%2522%252Coauth_nonce%253D%25227d8f3e4a%2522%252Coau
99
- th_signature%253D%2522bYT5CMsGcbgUdFHObYMEfcx6bsw%25253D%2522
95
+ POST&http%3A%2F%2Fexample.com%2Frequest&a2%3Dr%2520b%26a3%3D2%2520q
96
+ %26a3%3Da%26b5%3D%253D%25253D%26c%2540%3D%26c2%3D%26oauth_consumer_
97
+ key%3D9djdj82h48djs9d2%26oauth_nonce%3D7d8f3e4a%26oauth_signature_m
98
+ ethod%3DHMAC-SHA1%26oauth_timestamp%3D137131201%26oauth_token%3Dkkk
99
+ 9d7dh3k39sjv7
100
100
"""
101
+
102
+ self .assertRaises (ValueError , base_string_uri , self .base_string_url )
103
+ base_string_url = base_string_uri (self .base_string_url .decode ('utf-8' ))
104
+ base_string_url = base_string_url .encode ('utf-8' )
105
+ querystring = self .base_string_url .split (b'?' , 1 )[1 ]
106
+ query_params = collect_parameters (querystring .decode ('utf-8' ),
107
+ body = self .body )
108
+ normalized_encoded_query_params = sorted (
109
+ [(quote (k ), quote (v )) for k , v in query_params ])
110
+ normalized_request_string = "&" .join (sorted (
111
+ ['=' .join ((k , v )) for k , v in (
112
+ self .normalized_encoded_request_params +
113
+ normalized_encoded_query_params )
114
+ if k .lower () != 'oauth_signature' ]))
101
115
self .assertRaises (ValueError , signature_base_string ,
102
116
self .http_method ,
103
- self . base_string_url ,
104
- self . normalized_encoded_request_parameters )
117
+ base_string_url ,
118
+ normalized_request_string )
105
119
self .assertRaises (ValueError , signature_base_string ,
106
120
self .http_method .decode ('utf-8' ),
107
- self .base_string_url ,
108
- self .normalized_encoded_request_parameters )
109
- self .assertRaises (ValueError , signature_base_string ,
110
- self .http_method .decode ('utf-8' ),
111
- self .base_string_url .decode ('utf-8' ),
112
- self .normalized_encoded_request_parameters )
121
+ base_string_url ,
122
+ normalized_request_string )
113
123
114
124
base_string = signature_base_string (
115
125
self .http_method .decode ('utf-8' ),
116
- self . base_string_url .decode ('utf-8' ),
117
- self . normalized_encoded_request_parameters . decode ( 'utf-8' )
126
+ base_string_url .decode ('utf-8' ),
127
+ normalized_request_string
118
128
)
119
129
120
130
self .assertEqual (self .control_base_string , base_string )
@@ -182,9 +192,7 @@ def test_collect_parameters(self):
182
192
correct_parameters = [('b5' , '=%3D' ),
183
193
('a3' , 'a' ),
184
194
('c@' , '' ),
185
- ('a2' , 'r b' ),
186
- ('c2' , '' ),
187
- ('a3' , '2 q' )]
195
+ ('a2' , 'r b' )]
188
196
self .assertEqual (sorted (parameters ), sorted (correct_parameters ))
189
197
190
198
headers = {'Authorization' : self .authorization_header }
@@ -208,13 +216,14 @@ def test_collect_parameters(self):
208
216
sorted (correct_parameters_with_realm ))
209
217
210
218
# Add in the body.
211
- # TODO: Add more content for the body. Daniel Greenfeld 2012/03/12
212
219
# Redo again the checks against all the parameters. Duplicated code
213
220
# but better safety
214
221
parameters = collect_parameters (
215
222
uri_query = self .uri_query , body = self .body , headers = headers )
216
223
correct_parameters += [
217
- ('content' , 'This is being the body of things' )]
224
+ ('c2' , '' ),
225
+ ('a3' , '2 q' )
226
+ ]
218
227
self .assertEqual (sorted (parameters ), sorted (correct_parameters ))
219
228
220
229
def test_normalize_parameters (self ):
@@ -230,7 +239,7 @@ def test_normalize_parameters(self):
230
239
231
240
# Lets see if things are in order
232
241
# check to see that querystring keys come in alphanumeric order:
233
- querystring_keys = ['a2' , 'a3' , 'b5' , 'content' , ' oauth_consumer_key' ,
242
+ querystring_keys = ['a2' , 'a3' , 'b5' , 'oauth_consumer_key' ,
234
243
'oauth_nonce' , 'oauth_signature_method' ,
235
244
'oauth_timestamp' , 'oauth_token' ]
236
245
index = - 1 # start at -1 because the 'a2' key starts at index 0
@@ -240,7 +249,8 @@ def test_normalize_parameters(self):
240
249
241
250
# Control signature created using openssl:
242
251
# echo -n $(cat <message>) | openssl dgst -binary -hmac <key> | base64
243
- control_signature = "Uau4O9Kpd2k6rvh7UZN/RN+RG7Y="
252
+ control_signature = "mwd09YMxVd2XJ1gudNaBuAuKKuY="
253
+ control_signature_s = "wsdNmjGB7lvis0UJuPAmjvX/PXw="
244
254
245
255
def test_sign_hmac_sha1 (self ):
246
256
"""Verifying HMAC-SHA1 signature against one created by OpenSSL."""
@@ -250,10 +260,22 @@ def test_sign_hmac_sha1(self):
250
260
251
261
sign = sign_hmac_sha1 (self .control_base_string ,
252
262
self .client_secret .decode ('utf-8' ),
253
- self . resource_owner_secret . decode ( 'utf-8' ) )
263
+ b'' )
254
264
self .assertEqual (len (sign ), 28 )
255
265
self .assertEqual (sign , self .control_signature )
256
266
267
+ def test_sign_hmac_sha1_with_secret (self ):
268
+ """Verifying HMAC-SHA1 signature against one created by OpenSSL."""
269
+
270
+ self .assertRaises (ValueError , sign_hmac_sha1 , self .control_base_string ,
271
+ self .client_secret , self .resource_owner_secret )
272
+
273
+ sign = sign_hmac_sha1 (self .control_base_string ,
274
+ self .client_secret .decode ('utf-8' ),
275
+ self .resource_owner_secret .decode ('utf-8' ))
276
+ self .assertEqual (len (sign ), 28 )
277
+ self .assertEqual (sign , self .control_signature_s )
278
+
257
279
def test_sign_hmac_sha1_with_client (self ):
258
280
self .assertRaises (ValueError ,
259
281
sign_hmac_sha1_with_client ,
@@ -265,19 +287,16 @@ def test_sign_hmac_sha1_with_client(self):
265
287
self .control_base_string , self .client )
266
288
267
289
self .assertEqual (len (sign ), 28 )
268
- self .assertEqual (sign , self .control_signature )
290
+ self .assertEqual (sign , self .control_signature_s )
269
291
270
292
271
293
control_base_string_rsa_sha1 = (
272
- b"POST&http%253A%2F%2Fexample.com%2Frequest%253Fb5%253D"
273
- b"%25253D%2525253D%2526a3%253Da%2526c%252540%253D%2526"
274
- b"a2%253Dr%252520b&OAuth%2520realm%253D%2522Example%25"
275
- b"22%252Coauth_consumer_key%253D%25229djdj82h48djs9d2"
276
- b"%2522%252Coauth_token%253D%2522kkk9d7dh3k39sjv7%2522"
277
- b"%252Coauth_signature_method%253D%2522HMAC-SHA1%2522"
278
- b"%252Coauth_timestamp%253D%2522137131201%2522%252Coau"
279
- b"th_nonce%253D%25227d8f3e4a%2522%252Coauth_signature"
280
- b"%253D%2522bYT5CMsGcbgUdFHObYMEfcx6bsw%25253D%2522" )
294
+ b"POST&http%3A%2F%2Fexample.com%2Frequest&a2%3Dr%2520b%26a3%3D2%2520q"
295
+ b"%26a3%3Da%26b5%3D%253D%25253D%26c%2540%3D%26c2%3D%26oauth_consumer_"
296
+ b"key%3D9djdj82h48djs9d2%26oauth_nonce%3D7d8f3e4a%26oauth_signature_m"
297
+ b"ethod%3DHMAC-SHA1%26oauth_timestamp%3D137131201%26oauth_token%3Dkkk"
298
+ b"9d7dh3k39sjv7"
299
+ )
281
300
282
301
# Generated using: $ openssl genrsa -out <key>.pem 1024
283
302
# PEM encoding requires the key to be concatenated with
@@ -301,14 +320,14 @@ def test_sign_hmac_sha1_with_client(self):
301
320
@property
302
321
def control_signature_rsa_sha1 (self ):
303
322
# Base string saved in "<message>". Signature obtained using:
304
- # $ echo -n $(cat <message >) | openssl dgst -sign <key>.pem | base64
323
+ # $ echo -n $(cat <msg >) | openssl dgst -sha1 -sign <key>.pem | base64
305
324
# where echo -n suppresses the last linebreak.
306
325
return (
307
- "zV5g8ArdMuJuOXlH8XOqfLHS11XdthfIn4HReDm7jz8JmgLabHGmVBqCkCfZoFJPH"
308
- "dka7tLvCplK/jsV4FUOnftrJOQhbXguuBdi87/hmxOFKLmQYqqlEW7BdXmwKLZcki"
309
- "qq3qE5XziBgKSAFRkxJ4gmJAymvJBtrJYN9728rK8="
310
- )
326
+ "mFY2KOEnlYWsTvUA+5kxuBIcvBYXu+ljw9ttVJQxKduMueGSVPCB1tK1PlqVLK738"
327
+ "HK0t19ecBJfb6rMxUwrriw+MlBO+jpojkZIWccw1J4cAb4qu4M81DbpUAq4j/1w/Q"
328
+ "yTR4TWCODlEfN7Zfgy8+pf+TjiXfIwRC1jEWbuL1E="
311
329
330
+ )
312
331
313
332
def test_sign_rsa_sha1 (self ):
314
333
"""Verify RSA-SHA1 signature against one created by OpenSSL."""
0 commit comments