38
38
39
39
class Error (RuntimeError ):
40
40
"""Generic exception class."""
41
+
41
42
def __init__ (self , message = 'OAuth error occured.' ):
42
43
self ._message = message
43
44
@@ -110,6 +111,7 @@ def __init__(self, key, secret):
110
111
if self .key is None or self .secret is None :
111
112
raise ValueError ("Key and secret must be set." )
112
113
114
+
113
115
class Token (object ):
114
116
"""An OAuth credential used to request authorization or a protected
115
117
resource.
@@ -197,7 +199,8 @@ def from_string(s):
197
199
try :
198
200
secret = params ['oauth_token_secret' ][0 ]
199
201
except Exception :
200
- raise ValueError ("'oauth_token_secret' not found in OAuth request." )
202
+ raise ValueError ("'oauth_token_secret' not found in "
203
+ "OAuth request." )
201
204
202
205
token = Token (key , secret )
203
206
try :
@@ -209,6 +212,7 @@ def from_string(s):
209
212
def __str__ (self ):
210
213
return self .to_string ()
211
214
215
+
212
216
def setter (setter ):
213
217
name = setter .__name__
214
218
@@ -223,6 +227,7 @@ def deleter(self):
223
227
224
228
return property (getter , setter , deleter )
225
229
230
+
226
231
class Request (dict ):
227
232
228
233
"""The parameters and information for an HTTP request, suitable for
@@ -270,11 +275,13 @@ def _get_timestamp_nonce(self):
270
275
271
276
def get_nonoauth_parameters (self ):
272
277
"""Get any non-OAuth parameters."""
273
- return dict ([(k , v ) for k , v in self .iteritems () if not k .startswith ('oauth_' )])
278
+ return dict ([(k , v ) for k , v in self .iteritems ()
279
+ if not k .startswith ('oauth_' )])
274
280
275
281
def to_header (self , realm = '' ):
276
282
"""Serialize as a header for an HTTPAuth request."""
277
- oauth_params = ((k , v ) for k , v in self .iteritems () if k .startswith ('oauth_' ))
283
+ oauth_params = ((k , v ) for k , v in self .iteritems ()
284
+ if k .startswith ('oauth_' ))
278
285
stringy_params = ((k , escape (str (v ))) for k , v in oauth_params )
279
286
header_params = ('%s="%s"' % (k , v ) for k , v in stringy_params )
280
287
params_header = ', ' .join (header_params )
@@ -371,7 +378,8 @@ def from_consumer_and_token(cls, oauth_consumer, token=None,
371
378
return OAuthRequest (http_method , http_url , parameters )
372
379
373
380
@classmethod
374
- def from_token_and_callback (cls , token , callback = None , http_method = HTTP_METHOD ,
381
+ def from_token_and_callback (cls , token , callback = None ,
382
+ http_method = HTTP_METHOD ,
375
383
http_url = None , parameters = None ):
376
384
if not parameters :
377
385
parameters = {}
@@ -410,7 +418,20 @@ def _split_url_string(param_str):
410
418
411
419
412
420
class Server (object ):
413
- """A worker to check the validity of a request against a data store."""
421
+ """A skeletal implementation of a service provider, providing protected
422
+ resources to requests from authorized consumers.
423
+
424
+ This class implements the logic to check requests for authorization. You
425
+ can use it with your web server or web framework to protect certain
426
+ resources with OAuth.
427
+
428
+ As this class has no knowledge of how your application stores data, you
429
+ have to give it an object it can use to load OAuth objects. Implement a
430
+ subclass of `oauth.interface.DataStore` for your storage system and supply
431
+ it to the `Server` instance as `data_store`.
432
+
433
+ """
434
+
414
435
timestamp_threshold = 300 # In seconds, five minutes.
415
436
version = VERSION
416
437
signature_methods = None
@@ -463,7 +484,9 @@ def fetch_access_token(self, oauth_request):
463
484
# Get the request token.
464
485
token = self ._get_token (oauth_request , 'request' )
465
486
self ._check_signature (oauth_request , consumer , token )
466
- new_token = self .data_store .fetch_access_token (consumer , token , verifier )
487
+ new_token = self .data_store .fetch_access_token (consumer ,
488
+ token , verifier )
489
+
467
490
return new_token
468
491
469
492
def verify_request (self , oauth_request ):
@@ -539,19 +562,25 @@ def _check_signature(self, oauth_request, consumer, token):
539
562
self ._check_timestamp (timestamp )
540
563
self ._check_nonce (consumer , token , nonce )
541
564
signature_method = self ._get_signature_method (oauth_request )
565
+
542
566
try :
543
567
signature = oauth_request .get_parameter ('oauth_signature' )
544
568
except :
545
569
raise Error ('Missing signature.' )
570
+
546
571
# Validate the signature.
547
572
valid_sig = signature_method .check_signature (oauth_request , consumer ,
548
573
token , signature )
574
+
549
575
if not valid_sig :
550
576
key , base = signature_method .build_signature_base_string (
551
577
oauth_request , consumer , token )
578
+
552
579
raise Error ('Invalid signature. Expected signature base '
553
580
'string: %s' % base )
554
- built = signature_method .build_signature (oauth_request , consumer , token )
581
+
582
+ built = signature_method .build_signature (oauth_request ,
583
+ consumer , token )
555
584
556
585
def _check_timestamp (self , timestamp ):
557
586
"""Verify that timestamp is recentish."""
@@ -599,7 +628,15 @@ def access_resource(self, oauth_request):
599
628
600
629
601
630
class DataStore (object ):
602
- """A database abstraction used to lookup consumers and tokens."""
631
+ """A database abstraction used to lookup consumers and tokens.
632
+
633
+ To use your backend store with the `oauth` module, implement a subclass of
634
+ this class that performs its methods using your database or storage
635
+ system. Then, when using `oauth.Server`, supply it with an instance of
636
+ your custom `DataStore` class to have objects stored in natively in your
637
+ own data store.
638
+
639
+ """
603
640
604
641
def lookup_consumer (self , key ):
605
642
"""-> OAuthConsumer."""
@@ -627,12 +664,20 @@ def authorize_request_token(self, oauth_token, user):
627
664
628
665
629
666
class SignatureMethod (object ):
630
- """A strategy class that implements a signature method."""
667
+ """A way of signing requests.
668
+
669
+ The OAuth protocol lets consumers and service providers pick a way to sign
670
+ requests. This interface shows the methods expected by the other `oauth`
671
+ modules for signing requests. Subclass it and implement its methods to
672
+ provide a new way to sign requests.
673
+ """
674
+
631
675
def get_name (self ):
632
676
"""-> str."""
633
677
raise NotImplementedError
634
678
635
- def build_signature_base_string (self , oauth_request , oauth_consumer , oauth_token ):
679
+ def build_signature_base_string (self , oauth_request ,
680
+ oauth_consumer , oauth_token ):
636
681
"""-> str key, str raw."""
637
682
raise NotImplementedError
638
683
0 commit comments