Mercurial > hg > pmhd
comparison musixmatch-master/7digital-python/lib/oauth.py @ 7:8c29444cb5fd
Just did some work
author | Yading Song <yading.song@eecs.qmul.ac.uk> |
---|---|
date | Sat, 20 Apr 2013 19:01:57 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:e0a7176da80a | 7:8c29444cb5fd |
---|---|
1 """ | |
2 The MIT License | |
3 | |
4 Copyright (c) 2007 Leah Culver | |
5 | |
6 Permission is hereby granted, free of charge, to any person obtaining a copy | |
7 of this software and associated documentation files (the "Software"), to deal | |
8 in the Software without restriction, including without limitation the rights | |
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
10 copies of the Software, and to permit persons to whom the Software is | |
11 furnished to do so, subject to the following conditions: | |
12 | |
13 The above copyright notice and this permission notice shall be included in | |
14 all copies or substantial portions of the Software. | |
15 | |
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
22 THE SOFTWARE. | |
23 """ | |
24 | |
25 import cgi | |
26 import urllib | |
27 import time | |
28 import random | |
29 import urlparse | |
30 import hmac | |
31 import binascii | |
32 import re | |
33 | |
34 | |
35 VERSION = '1.0' # Hi Blaine! | |
36 HTTP_METHOD = 'GET' | |
37 SIGNATURE_METHOD = 'PLAINTEXT' | |
38 | |
39 | |
40 class OAuthError(RuntimeError): | |
41 """Generic exception class.""" | |
42 def __init__(self, message='OAuth error occured.'): | |
43 self.message = message | |
44 | |
45 def build_authenticate_header(realm=''): | |
46 """Optional WWW-Authenticate header (401 error)""" | |
47 return {'WWW-Authenticate': 'OAuth realm="%s"' % realm} | |
48 | |
49 def escape(s): | |
50 """Escape a URL including any /.""" | |
51 return urllib.quote(s, safe='~') | |
52 | |
53 def _utf8_str(s): | |
54 """Convert unicode to utf-8.""" | |
55 if isinstance(s, unicode): | |
56 return s.encode("utf-8") | |
57 else: | |
58 return str(s) | |
59 | |
60 def generate_timestamp(): | |
61 """Get seconds since epoch (UTC).""" | |
62 return int(time.time()) | |
63 | |
64 def generate_nonce(length=8): | |
65 """Generate pseudorandom number.""" | |
66 return ''.join([str(random.randint(0, 9)) for i in range(length)]) | |
67 | |
68 def generate_verifier(length=8): | |
69 """Generate pseudorandom number.""" | |
70 return ''.join([str(random.randint(0, 9)) for i in range(length)]) | |
71 | |
72 | |
73 class OAuthConsumer(object): | |
74 """Consumer of OAuth authentication. | |
75 | |
76 OAuthConsumer is a data type that represents the identity of the Consumer | |
77 via its shared secret with the Service Provider. | |
78 | |
79 """ | |
80 key = None | |
81 secret = None | |
82 | |
83 def __init__(self, key, secret): | |
84 self.key = key | |
85 self.secret = secret | |
86 | |
87 | |
88 class OAuthToken(object): | |
89 """OAuthToken is a data type that represents an End User via either an access | |
90 or request token. | |
91 | |
92 key -- the token | |
93 secret -- the token secret | |
94 | |
95 """ | |
96 key = None | |
97 secret = None | |
98 callback = None | |
99 callback_confirmed = None | |
100 verifier = None | |
101 | |
102 def __init__(self, key, secret): | |
103 self.key = key | |
104 self.secret = secret | |
105 | |
106 def set_callback(self, callback): | |
107 self.callback = callback | |
108 self.callback_confirmed = 'true' | |
109 | |
110 def set_verifier(self, verifier=None): | |
111 if verifier is not None: | |
112 self.verifier = verifier | |
113 else: | |
114 self.verifier = generate_verifier() | |
115 | |
116 def get_callback_url(self): | |
117 if self.callback and self.verifier: | |
118 # Append the oauth_verifier. | |
119 parts = urlparse.urlparse(self.callback) | |
120 scheme, netloc, path, params, query, fragment = parts[:6] | |
121 if query: | |
122 query = '%s&oauth_verifier=%s' % (query, self.verifier) | |
123 else: | |
124 query = 'oauth_verifier=%s' % self.verifier | |
125 return urlparse.urlunparse((scheme, netloc, path, params, | |
126 query, fragment)) | |
127 return self.callback | |
128 | |
129 def to_string(self): | |
130 data = { | |
131 'oauth_token': self.key, | |
132 'oauth_token_secret': self.secret, | |
133 } | |
134 if self.callback_confirmed is not None: | |
135 data['oauth_callback_confirmed'] = self.callback_confirmed | |
136 return urllib.urlencode(data) | |
137 | |
138 def from_string(s): | |
139 """ Returns a token from something like: | |
140 oauth_token_secret=xxx&oauth_token=xxx | |
141 """ | |
142 print "******* %s" % s.__class__ | |
143 #params = urlparse.parse_qs(s, keep_blank_values=False) | |
144 | |
145 key = re.search("<oauth_token>(\w.+)</oauth_token>", s).groups()[0] | |
146 print "@@@@@@ key: %s" %key | |
147 secret = re.search("<oauth_token_secret>(\w.+)</oauth_token_secret>", s).groups()[0] | |
148 print "@@@@@@ secret: %s" % secret | |
149 token = OAuthToken(key, secret) | |
150 | |
151 return token | |
152 from_string = staticmethod(from_string) | |
153 | |
154 def __str__(self): | |
155 return self.to_string() | |
156 | |
157 | |
158 class OAuthRequest(object): | |
159 """OAuthRequest represents the request and can be serialized. | |
160 | |
161 OAuth parameters: | |
162 - oauth_consumer_key | |
163 - oauth_token | |
164 - oauth_signature_method | |
165 - oauth_signature | |
166 - oauth_timestamp | |
167 - oauth_nonce | |
168 - oauth_version | |
169 - oauth_verifier | |
170 ... any additional parameters, as defined by the Service Provider. | |
171 """ | |
172 parameters = None # OAuth parameters. | |
173 http_method = HTTP_METHOD | |
174 http_url = None | |
175 version = VERSION | |
176 | |
177 def __init__(self, http_method=HTTP_METHOD, http_url=None, parameters=None): | |
178 self.http_method = http_method | |
179 self.http_url = http_url | |
180 self.parameters = parameters or {} | |
181 | |
182 def set_parameter(self, parameter, value): | |
183 self.parameters[parameter] = value | |
184 | |
185 def get_parameter(self, parameter): | |
186 try: | |
187 return self.parameters[parameter] | |
188 except: | |
189 raise OAuthError('Parameter not found: %s' % parameter) | |
190 | |
191 def _get_timestamp_nonce(self): | |
192 return self.get_parameter('oauth_timestamp'), self.get_parameter( | |
193 'oauth_nonce') | |
194 | |
195 def get_nonoauth_parameters(self): | |
196 """Get any non-OAuth parameters.""" | |
197 parameters = {} | |
198 for k, v in self.parameters.iteritems(): | |
199 # Ignore oauth parameters. | |
200 if k.find('oauth_') < 0: | |
201 parameters[k] = v | |
202 return parameters | |
203 | |
204 def to_header(self, realm=''): | |
205 """Serialize as a header for an HTTPAuth request.""" | |
206 auth_header = 'OAuth realm="%s"' % realm | |
207 # Add the oauth parameters. | |
208 if self.parameters: | |
209 for k, v in self.parameters.iteritems(): | |
210 if k[:6] == 'oauth_': | |
211 auth_header += ', %s="%s"' % (k, escape(str(v))) | |
212 return {'Authorization': auth_header} | |
213 | |
214 def to_postdata(self): | |
215 """Serialize as post data for a POST request.""" | |
216 return '&'.join(['%s=%s' % (escape(str(k)), escape(str(v))) \ | |
217 for k, v in self.parameters.iteritems()]) | |
218 | |
219 def to_url(self): | |
220 """Serialize as a URL for a GET request.""" | |
221 return '%s?%s' % (self.get_normalized_http_url(), self.to_postdata()) | |
222 | |
223 def get_normalized_parameters(self): | |
224 """Return a string that contains the parameters that must be signed.""" | |
225 params = self.parameters | |
226 try: | |
227 # Exclude the signature if it exists. | |
228 del params['oauth_signature'] | |
229 except: | |
230 pass | |
231 # Escape key values before sorting. | |
232 key_values = [(escape(_utf8_str(k)), escape(_utf8_str(v))) \ | |
233 for k,v in params.items()] | |
234 # Sort lexicographically, first after key, then after value. | |
235 key_values.sort() | |
236 # Combine key value pairs into a string. | |
237 return '&'.join(['%s=%s' % (k, v) for k, v in key_values]) | |
238 | |
239 def get_normalized_http_method(self): | |
240 """Uppercases the http method.""" | |
241 return self.http_method.upper() | |
242 | |
243 def get_normalized_http_url(self): | |
244 """Parses the URL and rebuilds it to be scheme://host/path.""" | |
245 parts = urlparse.urlparse(self.http_url) | |
246 scheme, netloc, path = parts[:3] | |
247 # Exclude default port numbers. | |
248 if scheme == 'http' and netloc[-3:] == ':80': | |
249 netloc = netloc[:-3] | |
250 elif scheme == 'https' and netloc[-4:] == ':443': | |
251 netloc = netloc[:-4] | |
252 return '%s://%s%s' % (scheme, netloc, path) | |
253 | |
254 def sign_request(self, signature_method, consumer, token): | |
255 """Set the signature parameter to the result of build_signature.""" | |
256 # Set the signature method. | |
257 self.set_parameter('oauth_signature_method', | |
258 signature_method.get_name()) | |
259 # Set the signature. | |
260 self.set_parameter('oauth_signature', | |
261 self.build_signature(signature_method, consumer, token)) | |
262 | |
263 def build_signature(self, signature_method, consumer, token): | |
264 """Calls the build signature method within the signature method.""" | |
265 return signature_method.build_signature(self, consumer, token) | |
266 | |
267 def from_request(http_method, http_url, headers=None, parameters=None, | |
268 query_string=None): | |
269 """Combines multiple parameter sources.""" | |
270 if parameters is None: | |
271 parameters = {} | |
272 | |
273 # Headers | |
274 if headers and 'Authorization' in headers: | |
275 auth_header = headers['Authorization'] | |
276 # Check that the authorization header is OAuth. | |
277 if auth_header[:6] == 'OAuth ': | |
278 auth_header = auth_header[6:] | |
279 try: | |
280 # Get the parameters from the header. | |
281 header_params = OAuthRequest._split_header(auth_header) | |
282 parameters.update(header_params) | |
283 except: | |
284 raise OAuthError('Unable to parse OAuth parameters from ' | |
285 'Authorization header.') | |
286 | |
287 # GET or POST query string. | |
288 if query_string: | |
289 query_params = OAuthRequest._split_url_string(query_string) | |
290 parameters.update(query_params) | |
291 | |
292 # URL parameters. | |
293 param_str = urlparse.urlparse(http_url)[4] # query | |
294 url_params = OAuthRequest._split_url_string(param_str) | |
295 parameters.update(url_params) | |
296 | |
297 if parameters: | |
298 return OAuthRequest(http_method, http_url, parameters) | |
299 | |
300 return None | |
301 from_request = staticmethod(from_request) | |
302 | |
303 def from_consumer_and_token(oauth_consumer, token=None, | |
304 callback=None, verifier=None, http_method=HTTP_METHOD, | |
305 http_url=None, parameters=None): | |
306 if not parameters: | |
307 parameters = {} | |
308 | |
309 defaults = { | |
310 'oauth_consumer_key': oauth_consumer.key, | |
311 'oauth_timestamp': generate_timestamp(), | |
312 'oauth_nonce': generate_nonce(), | |
313 'oauth_version': OAuthRequest.version, | |
314 } | |
315 | |
316 defaults.update(parameters) | |
317 parameters = defaults | |
318 | |
319 if token: | |
320 parameters['oauth_token'] = token.key | |
321 if token.callback: | |
322 parameters['oauth_callback'] = token.callback | |
323 # 1.0a support for verifier. | |
324 if verifier: | |
325 parameters['oauth_verifier'] = verifier | |
326 elif callback: | |
327 # 1.0a support for callback in the request token request. | |
328 parameters['oauth_callback'] = callback | |
329 | |
330 return OAuthRequest(http_method, http_url, parameters) | |
331 from_consumer_and_token = staticmethod(from_consumer_and_token) | |
332 | |
333 def from_token_and_callback(token, callback=None, http_method=HTTP_METHOD, | |
334 http_url=None, parameters=None): | |
335 if not parameters: | |
336 parameters = {} | |
337 | |
338 parameters['oauth_token'] = token.key | |
339 | |
340 if callback: | |
341 parameters['oauth_callback'] = callback | |
342 | |
343 return OAuthRequest(http_method, http_url, parameters) | |
344 from_token_and_callback = staticmethod(from_token_and_callback) | |
345 | |
346 def _split_header(header): | |
347 """Turn Authorization: header into parameters.""" | |
348 params = {} | |
349 parts = header.split(',') | |
350 for param in parts: | |
351 # Ignore realm parameter. | |
352 if param.find('realm') > -1: | |
353 continue | |
354 # Remove whitespace. | |
355 param = param.strip() | |
356 # Split key-value. | |
357 param_parts = param.split('=', 1) | |
358 # Remove quotes and unescape the value. | |
359 params[param_parts[0]] = urllib.unquote(param_parts[1].strip('\"')) | |
360 return params | |
361 _split_header = staticmethod(_split_header) | |
362 | |
363 def _split_url_string(param_str): | |
364 """Turn URL string into parameters.""" | |
365 parameters = cgi.parse_qs(param_str, keep_blank_values=False) | |
366 for k, v in parameters.iteritems(): | |
367 parameters[k] = urllib.unquote(v[0]) | |
368 return parameters | |
369 _split_url_string = staticmethod(_split_url_string) | |
370 | |
371 class OAuthServer(object): | |
372 """A worker to check the validity of a request against a data store.""" | |
373 timestamp_threshold = 300 # In seconds, five minutes. | |
374 version = VERSION | |
375 signature_methods = None | |
376 data_store = None | |
377 | |
378 def __init__(self, data_store=None, signature_methods=None): | |
379 self.data_store = data_store | |
380 self.signature_methods = signature_methods or {} | |
381 | |
382 def set_data_store(self, data_store): | |
383 self.data_store = data_store | |
384 | |
385 def get_data_store(self): | |
386 return self.data_store | |
387 | |
388 def add_signature_method(self, signature_method): | |
389 self.signature_methods[signature_method.get_name()] = signature_method | |
390 return self.signature_methods | |
391 | |
392 def fetch_request_token(self, oauth_request): | |
393 """Processes a request_token request and returns the | |
394 request token on success. | |
395 """ | |
396 try: | |
397 # Get the request token for authorization. | |
398 token = self._get_token(oauth_request, 'request') | |
399 except OAuthError: | |
400 # No token required for the initial token request. | |
401 version = self._get_version(oauth_request) | |
402 consumer = self._get_consumer(oauth_request) | |
403 try: | |
404 callback = self.get_callback(oauth_request) | |
405 except OAuthError: | |
406 callback = None # 1.0, no callback specified. | |
407 self._check_signature(oauth_request, consumer, None) | |
408 # Fetch a new token. | |
409 token = self.data_store.fetch_request_token(consumer, callback) | |
410 return token | |
411 | |
412 def fetch_access_token(self, oauth_request): | |
413 """Processes an access_token request and returns the | |
414 access token on success. | |
415 """ | |
416 version = self._get_version(oauth_request) | |
417 consumer = self._get_consumer(oauth_request) | |
418 try: | |
419 verifier = self._get_verifier(oauth_request) | |
420 except OAuthError: | |
421 verifier = None | |
422 # Get the request token. | |
423 token = self._get_token(oauth_request, 'request') | |
424 self._check_signature(oauth_request, consumer, token) | |
425 new_token = self.data_store.fetch_access_token(consumer, token, verifier) | |
426 return new_token | |
427 | |
428 def verify_request(self, oauth_request): | |
429 """Verifies an api call and checks all the parameters.""" | |
430 # -> consumer and token | |
431 version = self._get_version(oauth_request) | |
432 consumer = self._get_consumer(oauth_request) | |
433 # Get the access token. | |
434 token = self._get_token(oauth_request, 'access') | |
435 self._check_signature(oauth_request, consumer, token) | |
436 parameters = oauth_request.get_nonoauth_parameters() | |
437 return consumer, token, parameters | |
438 | |
439 def authorize_token(self, token, user): | |
440 """Authorize a request token.""" | |
441 return self.data_store.authorize_request_token(token, user) | |
442 | |
443 def get_callback(self, oauth_request): | |
444 """Get the callback URL.""" | |
445 return oauth_request.get_parameter('oauth_callback') | |
446 | |
447 def build_authenticate_header(self, realm=''): | |
448 """Optional support for the authenticate header.""" | |
449 return {'WWW-Authenticate': 'OAuth realm="%s"' % realm} | |
450 | |
451 def _get_version(self, oauth_request): | |
452 """Verify the correct version request for this server.""" | |
453 try: | |
454 version = oauth_request.get_parameter('oauth_version') | |
455 except: | |
456 version = VERSION | |
457 if version and version != self.version: | |
458 raise OAuthError('OAuth version %s not supported.' % str(version)) | |
459 return version | |
460 | |
461 def _get_signature_method(self, oauth_request): | |
462 """Figure out the signature with some defaults.""" | |
463 try: | |
464 signature_method = oauth_request.get_parameter( | |
465 'oauth_signature_method') | |
466 except: | |
467 signature_method = SIGNATURE_METHOD | |
468 try: | |
469 # Get the signature method object. | |
470 signature_method = self.signature_methods[signature_method] | |
471 except: | |
472 signature_method_names = ', '.join(self.signature_methods.keys()) | |
473 raise OAuthError('Signature method %s not supported try one of the ' | |
474 'following: %s' % (signature_method, signature_method_names)) | |
475 | |
476 return signature_method | |
477 | |
478 def _get_consumer(self, oauth_request): | |
479 consumer_key = oauth_request.get_parameter('oauth_consumer_key') | |
480 consumer = self.data_store.lookup_consumer(consumer_key) | |
481 if not consumer: | |
482 raise OAuthError('Invalid consumer.') | |
483 return consumer | |
484 | |
485 def _get_token(self, oauth_request, token_type='access'): | |
486 """Try to find the token for the provided request token key.""" | |
487 token_field = oauth_request.get_parameter('oauth_token') | |
488 token = self.data_store.lookup_token(token_type, token_field) | |
489 if not token: | |
490 raise OAuthError('Invalid %s token: %s' % (token_type, token_field)) | |
491 return token | |
492 | |
493 def _get_verifier(self, oauth_request): | |
494 return oauth_request.get_parameter('oauth_verifier') | |
495 | |
496 def _check_signature(self, oauth_request, consumer, token): | |
497 timestamp, nonce = oauth_request._get_timestamp_nonce() | |
498 self._check_timestamp(timestamp) | |
499 self._check_nonce(consumer, token, nonce) | |
500 signature_method = self._get_signature_method(oauth_request) | |
501 try: | |
502 signature = oauth_request.get_parameter('oauth_signature') | |
503 except: | |
504 raise OAuthError('Missing signature.') | |
505 # Validate the signature. | |
506 valid_sig = signature_method.check_signature(oauth_request, consumer, | |
507 token, signature) | |
508 if not valid_sig: | |
509 key, base = signature_method.build_signature_base_string( | |
510 oauth_request, consumer, token) | |
511 raise OAuthError('Invalid signature. Expected signature base ' | |
512 'string: %s' % base) | |
513 built = signature_method.build_signature(oauth_request, consumer, token) | |
514 | |
515 def _check_timestamp(self, timestamp): | |
516 """Verify that timestamp is recentish.""" | |
517 timestamp = int(timestamp) | |
518 now = int(time.time()) | |
519 lapsed = abs(now - timestamp) | |
520 if lapsed > self.timestamp_threshold: | |
521 raise OAuthError('Expired timestamp: given %d and now %s has a ' | |
522 'greater difference than threshold %d' % | |
523 (timestamp, now, self.timestamp_threshold)) | |
524 | |
525 def _check_nonce(self, consumer, token, nonce): | |
526 """Verify that the nonce is uniqueish.""" | |
527 nonce = self.data_store.lookup_nonce(consumer, token, nonce) | |
528 if nonce: | |
529 raise OAuthError('Nonce already used: %s' % str(nonce)) | |
530 | |
531 | |
532 class OAuthClient(object): | |
533 """OAuthClient is a worker to attempt to execute a request.""" | |
534 consumer = None | |
535 token = None | |
536 | |
537 def __init__(self, oauth_consumer, oauth_token): | |
538 self.consumer = oauth_consumer | |
539 self.token = oauth_token | |
540 | |
541 def get_consumer(self): | |
542 return self.consumer | |
543 | |
544 def get_token(self): | |
545 return self.token | |
546 | |
547 def fetch_request_token(self, oauth_request): | |
548 """-> OAuthToken.""" | |
549 raise NotImplementedError | |
550 | |
551 def fetch_access_token(self, oauth_request): | |
552 """-> OAuthToken.""" | |
553 raise NotImplementedError | |
554 | |
555 def access_resource(self, oauth_request): | |
556 """-> Some protected resource.""" | |
557 raise NotImplementedError | |
558 | |
559 | |
560 class OAuthDataStore(object): | |
561 """A database abstraction used to lookup consumers and tokens.""" | |
562 | |
563 def lookup_consumer(self, key): | |
564 """-> OAuthConsumer.""" | |
565 raise NotImplementedError | |
566 | |
567 def lookup_token(self, oauth_consumer, token_type, token_token): | |
568 """-> OAuthToken.""" | |
569 raise NotImplementedError | |
570 | |
571 def lookup_nonce(self, oauth_consumer, oauth_token, nonce): | |
572 """-> OAuthToken.""" | |
573 raise NotImplementedError | |
574 | |
575 def fetch_request_token(self, oauth_consumer, oauth_callback): | |
576 """-> OAuthToken.""" | |
577 raise NotImplementedError | |
578 | |
579 def fetch_access_token(self, oauth_consumer, oauth_token, oauth_verifier): | |
580 """-> OAuthToken.""" | |
581 raise NotImplementedError | |
582 | |
583 def authorize_request_token(self, oauth_token, user): | |
584 """-> OAuthToken.""" | |
585 raise NotImplementedError | |
586 | |
587 | |
588 class OAuthSignatureMethod(object): | |
589 """A strategy class that implements a signature method.""" | |
590 def get_name(self): | |
591 """-> str.""" | |
592 raise NotImplementedError | |
593 | |
594 def build_signature_base_string(self, oauth_request, oauth_consumer, oauth_token): | |
595 """-> str key, str raw.""" | |
596 raise NotImplementedError | |
597 | |
598 def build_signature(self, oauth_request, oauth_consumer, oauth_token): | |
599 """-> str.""" | |
600 raise NotImplementedError | |
601 | |
602 def check_signature(self, oauth_request, consumer, token, signature): | |
603 built = self.build_signature(oauth_request, consumer, token) | |
604 return built == signature | |
605 | |
606 | |
607 class OAuthSignatureMethod_HMAC_SHA1(OAuthSignatureMethod): | |
608 | |
609 def get_name(self): | |
610 return 'HMAC-SHA1' | |
611 | |
612 def build_signature_base_string(self, oauth_request, consumer, token): | |
613 sig = ( | |
614 escape(oauth_request.get_normalized_http_method()), | |
615 escape(oauth_request.get_normalized_http_url()), | |
616 escape(oauth_request.get_normalized_parameters()), | |
617 ) | |
618 | |
619 key = '%s&' % escape(consumer.secret) | |
620 if token: | |
621 key += escape(token.secret) | |
622 raw = '&'.join(sig) | |
623 return key, raw | |
624 | |
625 def build_signature(self, oauth_request, consumer, token): | |
626 """Builds the base signature string.""" | |
627 key, raw = self.build_signature_base_string(oauth_request, consumer, | |
628 token) | |
629 | |
630 # HMAC object. | |
631 try: | |
632 import hashlib # 2.5 | |
633 hashed = hmac.new(key, raw, hashlib.sha1) | |
634 except: | |
635 import sha # Deprecated | |
636 hashed = hmac.new(key, raw, sha) | |
637 | |
638 # Calculate the digest base 64. | |
639 return binascii.b2a_base64(hashed.digest())[:-1] | |
640 | |
641 | |
642 class OAuthSignatureMethod_PLAINTEXT(OAuthSignatureMethod): | |
643 | |
644 def get_name(self): | |
645 return 'PLAINTEXT' | |
646 | |
647 def build_signature_base_string(self, oauth_request, consumer, token): | |
648 """Concatenates the consumer key and secret.""" | |
649 sig = '%s&' % escape(consumer.secret) | |
650 if token: | |
651 sig = sig + escape(token.secret) | |
652 return sig, sig | |
653 | |
654 def build_signature(self, oauth_request, consumer, token): | |
655 key, raw = self.build_signature_base_string(oauth_request, consumer, | |
656 token) | |
657 return key |