Implemented new pluggable auth system into binder. Implemented basic auth handler...
authorJosh Roesslein <jroesslein@gmail.com>
Thu, 30 Jul 2009 20:55:20 +0000 (15:55 -0500)
committerJosh Roesslein <jroesslein@gmail.com>
Thu, 30 Jul 2009 20:55:20 +0000 (15:55 -0500)
oauth/__init__.py [deleted file]
tweepy/__init__.py
tweepy/api.py
tweepy/auth.py [new file with mode: 0644]
tweepy/binder.py
tweepy/error.py
tweepy/oauth.py [moved from oauth/oauth.py with 100% similarity]

diff --git a/oauth/__init__.py b/oauth/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
index ab4d5eb3bd908aed965edfcf5a307178a5c0fbf3..e3543c7b0d4ab9af34d4d831ae7d97923a2ab26c 100644 (file)
@@ -11,6 +11,7 @@ from models import *
 from error import TweepError
 from api import API
 from cache import *
+from auth import BasicAuthHandler, OAuthHandler
 
 # Global, unauthenticated instance of API
 api = API()
index 8880c653f80d6cbe3c3eec5c9679e35aec16f474..5b480536bf8ea4967305d33aa9e3d098cdfce7f3 100644 (file)
@@ -2,8 +2,6 @@
 # Copyright 2009 Joshua Roesslein
 # See LICENSE
 
-import base64
-
 from binder import bind_api
 from parsers import *
 from models import User, Status, DirectMessage, Friendship, SavedSearch, SearchResult
@@ -12,24 +10,15 @@ from error import TweepError
 """Twitter API"""
 class API(object):
 
-  def __init__(self, username=None, password=None, host='twitter.com',
-                cache=None, secure=False,
-                classes={'user': User, 'status': Status,
+  def __init__(self, auth_handler=None, host='twitter.com', cache=None,
+                secure=False, classes={'user': User, 'status': Status,
                 'direct_message': DirectMessage, 'friendship': Friendship,
                 'saved_search': SavedSearch, 'search_result': SearchResult}):
-    if username and password:
-      self.set_credentials(username, password)
-    else:
-      self._b64up = None
+    self.auth_handler = auth_handler
     self.host = host
     self.cache = cache
     self.secure = secure
     self.classes = classes
-    self.username = username
-
-  def set_credentials(self, username, password):
-    self._b64up = base64.b64encode('%s:%s' % (username, password))
-    self.username = username
 
   """Get public timeline"""
   public_timeline = bind_api(
diff --git a/tweepy/auth.py b/tweepy/auth.py
new file mode 100644 (file)
index 0000000..db7db97
--- /dev/null
@@ -0,0 +1,75 @@
+# Tweepy
+# Copyright 2009 Joshua Roesslein
+# See LICENSE
+
+from urllib2 import Request, urlopen
+import base64
+
+import oauth
+from error import TweepError
+
+class AuthHandler(object):
+
+  def apply_auth(self, headers):
+    """Apply authentication headers to request"""
+    raise NotImplemented
+
+class BasicAuthHandler(AuthHandler):
+
+  def __init__(self, username, password):
+    self._b64up = base64.b64encode('%s:%s' % (username, password))
+
+  def apply_auth(self, headers):
+    headers['Authorization'] = 'Basic %s' % self._b64up
+
+"""OAuth authentication handler"""
+class OAuthHandler(AuthHandler):
+
+  REQUEST_TOKEN_URL = 'http://twitter.com/oauth/request_token'
+  AUTHORIZATION_URL = 'http://twitter.com/oauth/authorize'
+  ACCESS_TOKEN_URL = 'http://twitter.com/oauth/access_token'
+
+  def __init__(self, consumer_key, consumer_secrete):
+    self._consumer = oauth.OAuthConsumer(consumer_key, consumer_secrete)
+    self._sigmethod = oauth.OAuthSignatureMethod_HMAC_SHA1()
+    self.request_token = None
+    self.access_token = None
+
+  def _get_request_token(self):
+    try:
+      request = oauth.OAuthRequest.from_consumer_and_token(self._consumer, http_url = self.REQUEST_TOKEN_URL)
+      request.sign_request(self._sigmethod, self._consumer, None)
+      resp = urlopen(Request(self.REQUEST_TOKEN_URL, headers=request.to_header()))
+      return oauth.OAuthToken.from_string(resp.read())
+
+    except Exception, e:
+      raise TweepError(e)
+
+  def get_authorization_url(self, callback=None):
+    try:
+      # get the request token
+      self.request_token = self._get_request_token()
+
+      # build auth request and return as url
+      request = oauth.OAuthRequest.from_token_and_callback(
+          token=token, callback=callback, http_url=self.AUTHORIZATION_URL)
+      return request.to_url()
+
+    except Exception, e:
+      raise TweepError(e)
+
+  def get_access_token(self):
+    try:
+      # build request
+      request = oauth.OAuthRequest.from_consumer_and_token(self._consumer,
+          token=self.request_token, http_url=self.ACCESS_TOKEN_URL)
+      request.sign_request(self._sigmethod, self._consumer, self.request_token)
+
+      # send request
+      resp = urlopen(Request(self.ACCESS_TOKEN_URL, headers=request.to_header()))
+      self.access_token = oauth.OAuthToken.from_string(resp.read())
+    except Exception, e:
+      raise TweepError(e)
+      
+
+
index 43a43b9830568f8139b5f53008856176ffcafc5a..57f11ab3f85306a79cc43e72db42769cb36a6bc2 100644 (file)
@@ -13,7 +13,7 @@ def bind_api(path, parser, allowed_param=None, method='GET', require_auth=False,
 
   def _call(api, *args, **kargs):
     # If require auth, throw exception if credentials not provided
-    if require_auth and not api._b64up:
+    if not api.auth_handler:
       raise TweepError('Authentication required!')
 
     # Filter out unallowed parameters
@@ -50,8 +50,10 @@ def bind_api(path, parser, allowed_param=None, method='GET', require_auth=False,
     headers = {
       'User-Agent': 'tweepy'
     }
-    if api._b64up:
-      headers['Authorization'] = 'Basic %s' % api._b64up
+
+    # Apply authentication
+    if api.auth_handler:
+      api.auth_handler.apply_auth(headers)
 
     # Build request
     conn.request(method, url, headers=headers)
index 04924fe6d25786651a102e4e9398a3dc91cae7a5..2905beebbdbf877cb412f373cf0d07af96f6195e 100644 (file)
@@ -8,7 +8,7 @@ Tweepy exception
 class TweepError(Exception):
 
   def __init__(self, reason):
-    self.reason = reason
+    self.reason = str(reason)
 
   def __str__(self):
     return self.reason
similarity index 100%
rename from oauth/oauth.py
rename to tweepy/oauth.py