diff --git a/example/client.py b/example/client.py index 34f7dcb9..885f0979 100644 --- a/example/client.py +++ b/example/client.py @@ -28,7 +28,7 @@ import httplib import time -import oauth.oauth as oauth +import oauth2 # settings for the local test consumer SERVER = 'localhost' @@ -46,7 +46,7 @@ CONSUMER_SECRET = 'secret' # example client using httplib with headers -class SimpleOAuthClient(oauth.OAuthClient): +class SimpleClient(oauth2.Client): def __init__(self, server, port=httplib.HTTP_PORT, request_token_url='', access_token_url='', authorization_url=''): self.server = server @@ -59,21 +59,21 @@ def __init__(self, server, port=httplib.HTTP_PORT, request_token_url='', access_ def fetch_request_token(self, oauth_request): # via headers # -> OAuthToken - self.connection.request(oauth_request.http_method, self.request_token_url, headers=oauth_request.to_header()) + self.connection.request(oauth_request.method, self.request_token_url, headers=oauth_request.to_header()) response = self.connection.getresponse() - return oauth.OAuthToken.from_string(response.read()) + return oauth2.Token.from_string(response.read()) def fetch_access_token(self, oauth_request): # via headers # -> OAuthToken - self.connection.request(oauth_request.http_method, self.access_token_url, headers=oauth_request.to_header()) + self.connection.request(oauth_request.method, self.access_token_url, headers=oauth_request.to_header()) response = self.connection.getresponse() - return oauth.OAuthToken.from_string(response.read()) + return oauth2.Token.from_string(response.read()) def authorize_token(self, oauth_request): # via url # -> typically just some okay response - self.connection.request(oauth_request.http_method, oauth_request.to_url()) + self.connection.request(oauth_request.method, oauth_request.to_url()) response = self.connection.getresponse() return response.read() @@ -89,19 +89,20 @@ def run_example(): # setup print '** OAuth Python Library Example **' - client = SimpleOAuthClient(SERVER, PORT, REQUEST_TOKEN_URL, ACCESS_TOKEN_URL, AUTHORIZATION_URL) - consumer = oauth.OAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET) - signature_method_plaintext = oauth.OAuthSignatureMethod_PLAINTEXT() - signature_method_hmac_sha1 = oauth.OAuthSignatureMethod_HMAC_SHA1() + client = SimpleClient(SERVER, PORT, REQUEST_TOKEN_URL, ACCESS_TOKEN_URL, AUTHORIZATION_URL) + consumer = oauth2.Consumer(CONSUMER_KEY, CONSUMER_SECRET) + signature_method_plaintext = oauth2.SignatureMethod_PLAINTEXT() + signature_method_hmac_sha1 = oauth2.SignatureMethod_HMAC_SHA1() pause() # get request token print '* Obtain a request token ...' pause() - oauth_request = oauth.OAuthRequest.from_consumer_and_token(consumer, callback=CALLBACK_URL, http_url=client.request_token_url) + parameters = {'oauth_callback': CALLBACK_URL} + oauth_request = oauth2.Request.from_consumer_and_token(consumer, parameters=parameters, http_url=client.request_token_url) oauth_request.sign_request(signature_method_plaintext, consumer, None) print 'REQUEST (via headers)' - print 'parameters: %s' % str(oauth_request.parameters) + print 'parameters: %s' % str(get_parameters(oauth_request)) pause() token = client.fetch_request_token(oauth_request) print 'GOT' @@ -112,9 +113,9 @@ def run_example(): print '* Authorize the request token ...' pause() - oauth_request = oauth.OAuthRequest.from_token_and_callback(token=token, http_url=client.authorization_url) + oauth_request = oauth2.Request.from_token_and_callback(token=token, http_url=client.authorization_url) print 'REQUEST (via url query string)' - print 'parameters: %s' % str(oauth_request.parameters) + print 'parameters: %s' % str(get_parameters(oauth_request)) pause() # this will actually occur only on some callback response = client.authorize_token(oauth_request) @@ -131,10 +132,11 @@ def run_example(): # get access token print '* Obtain an access token ...' pause() - oauth_request = oauth.OAuthRequest.from_consumer_and_token(consumer, token=token, verifier=verifier, http_url=client.access_token_url) + parameters = {'oauth_verifier': verifier} + oauth_request = oauth2.Request.from_consumer_and_token(consumer, token=token, parameters=parameters, http_url=client.access_token_url) oauth_request.sign_request(signature_method_plaintext, consumer, token) print 'REQUEST (via headers)' - print 'parameters: %s' % str(oauth_request.parameters) + print 'parameters: %s' % str(get_parameters(oauth_request)) pause() token = client.fetch_access_token(oauth_request) print 'GOT' @@ -146,16 +148,19 @@ def run_example(): print '* Access protected resources ...' pause() parameters = {'file': 'vacation.jpg', 'size': 'original'} # resource specific params - oauth_request = oauth.OAuthRequest.from_consumer_and_token(consumer, token=token, http_method='POST', http_url=RESOURCE_URL, parameters=parameters) + oauth_request = oauth2.Request.from_consumer_and_token(consumer, token=token, http_method='POST', http_url=RESOURCE_URL, parameters=parameters) oauth_request.sign_request(signature_method_hmac_sha1, consumer, token) print 'REQUEST (via post body)' - print 'parameters: %s' % str(oauth_request.parameters) + print 'parameters: %s' % str(get_parameters(oauth_request)) pause() params = client.access_resource(oauth_request) print 'GOT' print 'non-oauth parameters: %s' % params pause() +def get_parameters(ob): + return dict([(k, v) for (k, v) in ob.iteritems() if k.startswith('oauth_')]) + def pause(): print '' time.sleep(1) diff --git a/example/server.py b/example/server.py index 5986b0e2..9f70b9d9 100644 --- a/example/server.py +++ b/example/server.py @@ -25,7 +25,7 @@ from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer import urllib -import oauth.oauth as oauth +import oauth2 # fake urls for the test server REQUEST_TOKEN_URL = 'https://photos.example.net/request_token' @@ -37,12 +37,12 @@ VERIFIER = 'verifier' # example store for one of each thing -class MockOAuthDataStore(oauth.OAuthDataStore): +class MockDataStore(object): def __init__(self): - self.consumer = oauth.OAuthConsumer('key', 'secret') - self.request_token = oauth.OAuthToken('requestkey', 'requestsecret') - self.access_token = oauth.OAuthToken('accesskey', 'accesssecret') + self.consumer = oauth2.Consumer('key', 'secret') + self.request_token = oauth2.Token('requestkey', 'requestsecret') + self.access_token = oauth2.Token('accesskey', 'accesssecret') self.nonce = 'nonce' self.verifier = VERIFIER @@ -59,56 +59,125 @@ def lookup_token(self, token_type, token): return token_attrib return None - def lookup_nonce(self, oauth_consumer, oauth_token, nonce): - if oauth_token and oauth_consumer.key == self.consumer.key and (oauth_token.key == self.request_token.key or oauth_token.key == self.access_token.key) and nonce == self.nonce: + def lookup_nonce(self, consumer, token, nonce): + if token and consumer.key == self.consumer.key and (token.key == self.request_token.key or token.key == self.access_token.key) and nonce == self.nonce: return self.nonce return None - def fetch_request_token(self, oauth_consumer, oauth_callback): - if oauth_consumer.key == self.consumer.key: - if oauth_callback: + def fetch_request_token(self, consumer, callback): + if consumer.key == self.consumer.key: + if callback: # want to check here if callback is sensible # for mock store, we assume it is - self.request_token.set_callback(oauth_callback) + self.request_token.set_callback(callback) return self.request_token return None - def fetch_access_token(self, oauth_consumer, oauth_token, oauth_verifier): - if oauth_consumer.key == self.consumer.key and oauth_token.key == self.request_token.key and oauth_verifier == self.verifier: + def fetch_access_token(self, consumer, token, verifier): + if consumer.key == self.consumer.key and token.key == self.request_token.key and verifier == self.verifier: # want to check here if token is authorized # for mock store, we assume it is return self.access_token return None - def authorize_request_token(self, oauth_token, user): - if oauth_token.key == self.request_token.key: + def authorize_request_token(self, token, user): + if token.key == self.request_token.key: # authorize the request token in the store # for mock store, do nothing return self.request_token return None +class DataStoreServer(oauth2.Server): + """ + Adds data storage abilities to the base OAuth Server + """ + def __init__(self, signature_methods=None, data_store=None): + self.data_store = data_store + super(DataStoreServer, self).__init__(signature_methods) + + def fetch_request_token(self, oauth_request): + """Processes a request_token request and returns the + request token on success. + """ + try: + # Get the request token for authorization. + token = self._get_token(oauth_request, 'request') + except oauth2.Error: + # No token required for the initial token request. + version = self._get_version(oauth_request) + consumer = self._get_consumer(oauth_request) + try: + callback = self.get_callback(oauth_request) + except oauth2.Error: + callback = None # 1.0, no callback specified. + self._check_signature(oauth_request, consumer, None) + # Fetch a new token. + token = self.data_store.fetch_request_token(consumer, callback) + return token + + def fetch_access_token(self, oauth_request): + """Processes an access_token request and returns the + access token on success. + """ + version = self._get_version(oauth_request) + consumer = self._get_consumer(oauth_request) + try: + verifier = self._get_verifier(oauth_request) + except oauth2.Error: + verifier = None + # Get the request token. + token = self._get_token(oauth_request, 'request') + self._check_signature(oauth_request, consumer, token) + new_token = self.data_store.fetch_access_token(consumer, token, verifier) + return new_token + + def authorize_token(self, token, user): + """Authorize a request token.""" + return self.data_store.authorize_request_token(token, user) + + def get_callback(self, oauth_request): + """Get the callback URL.""" + return oauth_request.get_parameter('oauth_callback') + + def _get_consumer(self, oauth_request): + consumer_key = oauth_request.get_parameter('oauth_consumer_key') + consumer = self.data_store.lookup_consumer(consumer_key) + if not consumer: + raise OAuthError('Invalid consumer.') + return consumer + + def _get_token(self, oauth_request, token_type='access'): + """Try to find the token for the provided request token key.""" + token_field = oauth_request.get_parameter('oauth_token') + token = self.data_store.lookup_token(token_type, token_field) + if not token: + raise OAuthError('Invalid %s token: %s' % (token_type, token_field)) + return token + + + class RequestHandler(BaseHTTPRequestHandler): def __init__(self, *args, **kwargs): - self.oauth_server = oauth.OAuthServer(MockOAuthDataStore()) - self.oauth_server.add_signature_method(oauth.OAuthSignatureMethod_PLAINTEXT()) - self.oauth_server.add_signature_method(oauth.OAuthSignatureMethod_HMAC_SHA1()) + self.oauth_server = DataStoreServer(data_store=MockDataStore()) + self.oauth_server.add_signature_method(oauth2.SignatureMethod_PLAINTEXT()) + self.oauth_server.add_signature_method(oauth2.SignatureMethod_HMAC_SHA1()) BaseHTTPRequestHandler.__init__(self, *args, **kwargs) # example way to send an oauth error - def send_oauth_error(self, err=None): + def send_error(self, err=None): # send a 401 error self.send_error(401, str(err.message)) # return the authenticate header - header = oauth.build_authenticate_header(realm=REALM) + header = oauth2.build_authenticate_header(realm=REALM) for k, v in header.iteritems(): - self.send_header(k, v) + self.send_header(k, v) def do_GET(self): # debug info #print self.command, self.path, self.headers - + # get the post data (if any) postdata = None if self.command == 'POST': @@ -119,7 +188,7 @@ def do_GET(self): pass # construct the oauth request from the request parameters - oauth_request = oauth.OAuthRequest.from_request(self.command, self.path, headers=self.headers, query_string=postdata) + oauth_request = oauth2.Request.from_request(self.command, self.path, headers=self.headers, query_string=postdata) # request token if self.path.startswith(REQUEST_TOKEN_URL): @@ -131,8 +200,8 @@ def do_GET(self): self.end_headers() # return the token self.wfile.write(token.to_string()) - except oauth.OAuthError, err: - self.send_oauth_error(err) + except oauth2.Error, err: + self.send_error(err) return # user authorization @@ -148,8 +217,8 @@ def do_GET(self): self.end_headers() # return the callback url (to show server has it) self.wfile.write(token.get_callback_url()) - except oauth.OAuthError, err: - self.send_oauth_error(err) + except oauth2.Error, err: + self.send_error(err) return # access token @@ -162,22 +231,24 @@ def do_GET(self): self.end_headers() # return the token self.wfile.write(token.to_string()) - except oauth.OAuthError, err: - self.send_oauth_error(err) + except oauth2.Error, err: + self.send_error(err) return # protected resources if self.path.startswith(RESOURCE_URL): try: # verify the request has been oauth authorized - consumer, token, params = self.oauth_server.verify_request(oauth_request) + consumer = self.oauth_server._get_consumer(oauth_request) + token = self.oauth_server._get_token(oauth_request, 'access') + params = self.oauth_server.verify_request(oauth_request, consumer, token) # send okay response self.send_response(200, 'OK') self.end_headers() # return the extra parameters - just for something to return self.wfile.write(str(params)) - except oauth.OAuthError, err: - self.send_oauth_error(err) + except oauth2.Error, err: + self.send_error(err) return def do_POST(self):