]> git.parisson.com Git - django-social-auth.git/commitdiff
Removed oauth module in favor of oauth original code
authorMatías Aguirre <matiasaguirre@gmail.com>
Mon, 15 Nov 2010 20:56:16 +0000 (18:56 -0200)
committerMatías Aguirre <matiasaguirre@gmail.com>
Mon, 15 Nov 2010 20:56:16 +0000 (18:56 -0200)
README.rst
social_auth/auth.py
social_auth/oauth.py [deleted file]

index da13a04f142a0cb71d135db4194d3ed1d5780352..f5f4e5e88cdc405a82f89a9268d8d9e5462a4c9d 100644 (file)
@@ -14,6 +14,7 @@ third parties.
 Dependencies
 ------------
    * OpenId support depends on python-openid_
+   * OAuth support depends on python-oauth_
    * Twitter and Facebook support demands an application registration
      on their corresponding sites.
 
@@ -130,6 +131,7 @@ django-openid-auth::
 .. _django-twitter-oauth: https://github.com/henriklied/django-twitter-oauth
 .. _django-openid-auth: https://launchpad.net/django-openid-auth
 .. _python-openid: http://pypi.python.org/pypi/python-openid/
+.. _python-oauth: https://github.com/leah/python-oauth
 .. _Login url: http://docs.djangoproject.com/en/dev/ref/settings/?from=olddocs#login-url
 .. _Login redirect url: http://docs.djangoproject.com/en/dev/ref/settings/?from=olddocs#login-redirect-url
 .. _Twitter development resources: http://dev.twitter.com/pages/auth
index 1df8706123646e05c71e4a3a7c1940bf444e19ce..35a02c823b187366528a8275cff41620cfb97886 100644 (file)
@@ -2,9 +2,12 @@
 import cgi
 import urllib
 import httplib
+
 from openid.consumer.consumer import Consumer, SUCCESS, CANCEL, FAILURE
 from openid.consumer.discover import DiscoveryFailure
 from openid.extensions import sreg, ax
+from oauth.oauth import OAuthConsumer, OAuthToken, OAuthRequest, \
+                        OAuthSignatureMethod_HMAC_SHA1
 
 from django.conf import settings
 from django.utils import simplejson
@@ -12,8 +15,6 @@ from django.contrib.auth import authenticate
 
 from .base import BaseAuth
 from .store import DjangoOpenIDStore
-from .oauth import OAuthConsumer, OAuthToken, OAuthRequest, \
-                   OAuthSignatureMethod_HMAC_SHA1
 from .conf import AX_ATTRS, SREG_ATTR, OPENID_ID_FIELD, SESSION_NAME, \
                   OPENID_GOOGLE_URL, OPENID_YAHOO_URL, TWITTER_SERVER, \
                   TWITTER_REQUEST_TOKEN_URL, TWITTER_ACCESS_TOKEN_URL, \
diff --git a/social_auth/oauth.py b/social_auth/oauth.py
deleted file mode 100644 (file)
index ad75b9f..0000000
+++ /dev/null
@@ -1,521 +0,0 @@
-import cgi
-import urllib
-import time
-import random
-import urlparse
-import hmac
-import binascii
-
-VERSION = '1.0' # Hi Blaine!
-HTTP_METHOD = 'GET'
-SIGNATURE_METHOD = 'PLAINTEXT'
-
-# Generic exception class
-class OAuthError(RuntimeError):
-    def __init__(self, message='OAuth error occured.'):
-        self.message = message
-
-# optional WWW-Authenticate header (401 error)
-def build_authenticate_header(realm=''):
-    return {'WWW-Authenticate': 'OAuth realm="%s"' % realm}
-
-# url escape
-def escape(s):
-    # escape '/' too
-    return urllib.quote(s, safe='~')
-
-# util function: current timestamp
-# seconds since epoch (UTC)
-def generate_timestamp():
-    return int(time.time())
-
-# util function: nonce
-# pseudorandom number
-def generate_nonce(length=8):
-    return ''.join([str(random.randint(0, 9)) for i in range(length)])
-
-# OAuthConsumer is a data type that represents the identity of the Consumer
-# via its shared secret with the Service Provider.
-class OAuthConsumer(object):
-    key = None
-    secret = None
-
-    def __init__(self, key, secret):
-        self.key = key
-        self.secret = secret
-
-# OAuthToken is a data type that represents an End User via either an access
-# or request token.     
-class OAuthToken(object):
-    # access tokens and request tokens
-    key = None
-    secret = None
-
-    '''
-    key = the token
-    secret = the token secret
-    '''
-    def __init__(self, key, secret):
-        self.key = key
-        self.secret = secret
-
-    def to_string(self):
-        return urllib.urlencode({'oauth_token': self.key, 'oauth_token_secret': self.secret})
-
-    # return a token from something like:
-    # oauth_token_secret=digg&oauth_token=digg
-    def from_string(s):
-        params = cgi.parse_qs(s, keep_blank_values=False)
-        key = params['oauth_token'][0]
-        secret = params['oauth_token_secret'][0]
-        return OAuthToken(key, secret)
-    from_string = staticmethod(from_string)
-
-    def __str__(self):
-        return self.to_string()
-
-# OAuthRequest represents the request and can be serialized
-class OAuthRequest(object):
-    '''
-    OAuth parameters:
-        - oauth_consumer_key 
-        - oauth_token
-        - oauth_signature_method
-        - oauth_signature 
-        - oauth_timestamp 
-        - oauth_nonce
-        - oauth_version
-        ... any additional parameters, as defined by the Service Provider.
-    '''
-    parameters = None # oauth parameters
-    http_method = HTTP_METHOD
-    http_url = None
-    version = VERSION
-
-    def __init__(self, http_method=HTTP_METHOD, http_url=None, parameters=None):
-        self.http_method = http_method
-        self.http_url = http_url
-        self.parameters = parameters or {}
-
-    def set_parameter(self, parameter, value):
-        self.parameters[parameter] = value
-
-    def get_parameter(self, parameter):
-        try:
-            return self.parameters[parameter]
-        except:
-            raise OAuthError('Parameter not found: %s' % parameter)
-
-    def _get_timestamp_nonce(self):
-        return self.get_parameter('oauth_timestamp'), self.get_parameter('oauth_nonce')
-
-    # get any non-oauth parameters
-    def get_nonoauth_parameters(self):
-        parameters = {}
-        for k, v in self.parameters.iteritems():
-            # ignore oauth parameters
-            if k.find('oauth_') < 0:
-                parameters[k] = v
-        return parameters
-
-    # serialize as a header for an HTTPAuth request
-    def to_header(self, realm=''):
-        auth_header = 'OAuth realm="%s"' % realm
-        # add the oauth parameters
-        if self.parameters:
-            for k, v in self.parameters.iteritems():
-                if k[:6] == 'oauth_':
-                    auth_header += ', %s="%s"' % (k, escape(str(v)))
-        return {'Authorization': auth_header}
-
-    # serialize as post data for a POST request
-    def to_postdata(self):
-        return '&'.join(['%s=%s' % (escape(str(k)), escape(str(v))) for k, v in self.parameters.iteritems()])
-
-    # serialize as a url for a GET request
-    def to_url(self):
-        return '%s?%s' % (self.get_normalized_http_url(), self.to_postdata())
-
-    # return a string that consists of all the parameters that need to be signed
-    def get_normalized_parameters(self):
-        params = self.parameters
-        try:
-            # exclude the signature if it exists
-            del params['oauth_signature']
-        except:
-            pass
-        key_values = params.items()
-        # sort lexicographically, first after key, then after value
-        key_values.sort()
-        # combine key value pairs in string and escape
-        return '&'.join(['%s=%s' % (escape(str(k)), escape(str(v))) for k, v in key_values])
-
-    # just uppercases the http method
-    def get_normalized_http_method(self):
-        return self.http_method.upper()
-
-    # parses the url and rebuilds it to be scheme://host/path
-    def get_normalized_http_url(self):
-        parts = urlparse.urlparse(self.http_url)
-        url_string = '%s://%s%s' % (parts[0], parts[1], parts[2]) # scheme, netloc, path
-        return url_string
-        
-    # set the signature parameter to the result of build_signature
-    def sign_request(self, signature_method, consumer, token):
-        # set the signature method
-        self.set_parameter('oauth_signature_method', signature_method.get_name())
-        # set the signature
-        self.set_parameter('oauth_signature', self.build_signature(signature_method, consumer, token))
-
-    def build_signature(self, signature_method, consumer, token):
-        # call the build signature method within the signature method
-        return signature_method.build_signature(self, consumer, token)
-
-    def from_request(http_method, http_url, headers=None, parameters=None, query_string=None):
-        # combine multiple parameter sources
-        if parameters is None:
-            parameters = {}
-
-        # headers
-        if headers and 'Authorization' in headers:
-            auth_header = headers['Authorization']
-            # check that the authorization header is OAuth
-            if auth_header.index('OAuth') > -1:
-                try:
-                    # get the parameters from the header
-                    header_params = OAuthRequest._split_header(auth_header)
-                    parameters.update(header_params)
-                except:
-                    raise OAuthError('Unable to parse OAuth parameters from Authorization header.')
-
-        # GET or POST query string
-        if query_string:
-            query_params = OAuthRequest._split_url_string(query_string)
-            parameters.update(query_params)
-
-        # URL parameters
-        param_str = urlparse.urlparse(http_url)[4] # query
-        url_params = OAuthRequest._split_url_string(param_str)
-        parameters.update(url_params)
-
-        if parameters:
-            return OAuthRequest(http_method, http_url, parameters)
-
-        return None
-    from_request = staticmethod(from_request)
-
-    def from_consumer_and_token(oauth_consumer, token=None, http_method=HTTP_METHOD, http_url=None, parameters=None):
-        if not parameters:
-            parameters = {}
-
-        defaults = {
-            'oauth_consumer_key': oauth_consumer.key,
-            'oauth_timestamp': generate_timestamp(),
-            'oauth_nonce': generate_nonce(),
-            'oauth_version': OAuthRequest.version,
-        }
-
-        defaults.update(parameters)
-        parameters = defaults
-
-        if token:
-            parameters['oauth_token'] = token.key
-
-        return OAuthRequest(http_method, http_url, parameters)
-    from_consumer_and_token = staticmethod(from_consumer_and_token)
-
-    def from_token_and_callback(token, callback=None, http_method=HTTP_METHOD, http_url=None, parameters=None):
-        if not parameters:
-            parameters = {}
-
-        parameters['oauth_token'] = token.key
-
-        if callback:
-            parameters['oauth_callback'] = callback
-
-        return OAuthRequest(http_method, http_url, parameters)
-    from_token_and_callback = staticmethod(from_token_and_callback)
-
-    # util function: turn Authorization: header into parameters, has to do some unescaping
-    def _split_header(header):
-        params = {}
-        parts = header.split(',')
-        for param in parts:
-            # ignore realm parameter
-            if param.find('OAuth realm') > -1:
-                continue
-            # remove whitespace
-            param = param.strip()
-            # split key-value
-            param_parts = param.split('=', 1)
-            # remove quotes and unescape the value
-            params[param_parts[0]] = urllib.unquote(param_parts[1].strip('\"'))
-        return params
-    _split_header = staticmethod(_split_header)
-    
-    # util function: turn url string into parameters, has to do some unescaping
-    def _split_url_string(param_str):
-        parameters = cgi.parse_qs(param_str, keep_blank_values=False)
-        for k, v in parameters.iteritems():
-            parameters[k] = urllib.unquote(v[0])
-        return parameters
-    _split_url_string = staticmethod(_split_url_string)
-
-# OAuthServer is a worker to check a requests validity against a data store
-class OAuthServer(object):
-    timestamp_threshold = 300 # in seconds, five minutes
-    version = VERSION
-    signature_methods = None
-    data_store = None
-
-    def __init__(self, data_store=None, signature_methods=None):
-        self.data_store = data_store
-        self.signature_methods = signature_methods or {}
-
-    def set_data_store(self, oauth_data_store):
-        self.data_store = oauth_data_store
-
-    def get_data_store(self):
-        return self.data_store
-
-    def add_signature_method(self, signature_method):
-        self.signature_methods[signature_method.get_name()] = signature_method
-        return self.signature_methods
-
-    # process a request_token request
-    # returns the request token on success
-    def fetch_request_token(self, oauth_request):
-        try:
-            # get the request token for authorization
-            token = self._get_token(oauth_request, 'request')
-        except OAuthError:
-            # no token required for the initial token request
-            consumer = self._get_consumer(oauth_request)
-            self._check_signature(oauth_request, consumer, None)
-            # fetch a new token
-            token = self.data_store.fetch_request_token(consumer)
-        return token
-
-    # process an access_token request
-    # returns the access token on success
-    def fetch_access_token(self, oauth_request):
-        consumer = self._get_consumer(oauth_request)
-        # 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)
-        return new_token
-
-    # verify an api call, checks all the parameters
-    def verify_request(self, oauth_request):
-        # -> consumer and token
-        consumer = self._get_consumer(oauth_request)
-        # get the access token
-        token = self._get_token(oauth_request, 'access')
-        self._check_signature(oauth_request, consumer, token)
-        parameters = oauth_request.get_nonoauth_parameters()
-        return consumer, token, parameters
-
-    # authorize a request token
-    def authorize_token(self, token, user):
-        return self.data_store.authorize_request_token(token, user)
-    
-    # get the callback url
-    def get_callback(self, oauth_request):
-        return oauth_request.get_parameter('oauth_callback')
-
-    # optional support for the authenticate header   
-    def build_authenticate_header(self, realm=''):
-        return {'WWW-Authenticate': 'OAuth realm="%s"' % realm}
-
-    # verify the correct version request for this server
-    def _get_version(self, oauth_request):
-        try:
-            version = oauth_request.get_parameter('oauth_version')
-        except:
-            version = VERSION
-        if version and version != self.version:
-            raise OAuthError('OAuth version %s not supported.' % str(version))
-        return version
-
-    # figure out the signature with some defaults
-    def _get_signature_method(self, oauth_request):
-        try:
-            signature_method = oauth_request.get_parameter('oauth_signature_method')
-        except:
-            signature_method = SIGNATURE_METHOD
-        try:
-            # get the signature method object
-            signature_method = self.signature_methods[signature_method]
-        except:
-            signature_method_names = ', '.join(self.signature_methods.keys())
-            raise OAuthError('Signature method %s not supported try one of the following: %s' % (signature_method, signature_method_names))
-
-        return signature_method
-
-    def _get_consumer(self, oauth_request):
-        consumer_key = oauth_request.get_parameter('oauth_consumer_key')
-        if not consumer_key:
-            raise OAuthError('Invalid consumer key.')
-        consumer = self.data_store.lookup_consumer(consumer_key)
-        if not consumer:
-            raise OAuthError('Invalid consumer.')
-        return consumer
-
-    # try to find the token for the provided request token key
-    def _get_token(self, oauth_request, token_type='access'):
-        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
-
-    def _check_signature(self, oauth_request, consumer, token):
-        timestamp, nonce = oauth_request._get_timestamp_nonce()
-        self._check_timestamp(timestamp)
-        self._check_nonce(consumer, token, nonce)
-        signature_method = self._get_signature_method(oauth_request)
-        try:
-            signature = oauth_request.get_parameter('oauth_signature')
-        except:
-            raise OAuthError('Missing signature.')
-        # validate the signature
-        valid_sig = signature_method.check_signature(oauth_request, consumer, token, signature)
-        if not valid_sig:
-            key, base = signature_method.build_signature_base_string(oauth_request, consumer, token)
-            raise OAuthError('Invalid signature. Expected signature base string: %s' % base)
-        signature_method.build_signature(oauth_request, consumer, token)
-
-    def _check_timestamp(self, timestamp):
-        # verify that timestamp is recentish
-        timestamp = int(timestamp)
-        now = int(time.time())
-        lapsed = now - timestamp
-        if lapsed > self.timestamp_threshold:
-            raise OAuthError('Expired timestamp: given %d and now %s has a greater difference than threshold %d' % (timestamp, now, self.timestamp_threshold))
-
-    def _check_nonce(self, consumer, token, nonce):
-        # verify that the nonce is uniqueish
-        nonce = self.data_store.lookup_nonce(consumer, token, nonce)
-        if nonce:
-            raise OAuthError('Nonce already used: %s' % str(nonce))
-
-# OAuthClient is a worker to attempt to execute a request
-class OAuthClient(object):
-    consumer = None
-    token = None
-
-    def __init__(self, oauth_consumer, oauth_token):
-        self.consumer = oauth_consumer
-        self.token = oauth_token
-
-    def get_consumer(self):
-        return self.consumer
-
-    def get_token(self):
-        return self.token
-
-    def fetch_request_token(self, oauth_request):
-        # -> OAuthToken
-        raise NotImplementedError
-
-    def fetch_access_token(self, oauth_request):
-        # -> OAuthToken
-        raise NotImplementedError
-
-    def access_resource(self, oauth_request):
-        # -> some protected resource
-        raise NotImplementedError
-
-# OAuthDataStore is a database abstraction used to lookup consumers and tokens
-class OAuthDataStore(object):
-
-    def lookup_consumer(self, key):
-        # -> OAuthConsumer
-        raise NotImplementedError
-
-    def lookup_token(self, oauth_consumer, token_type, token_token):
-        # -> OAuthToken
-        raise NotImplementedError
-
-    def lookup_nonce(self, oauth_consumer, oauth_token, nonce, timestamp):
-        # -> OAuthToken
-        raise NotImplementedError
-
-    def fetch_request_token(self, oauth_consumer):
-        # -> OAuthToken
-        raise NotImplementedError
-
-    def fetch_access_token(self, oauth_consumer, oauth_token):
-        # -> OAuthToken
-        raise NotImplementedError
-
-    def authorize_request_token(self, oauth_token, user):
-        # -> OAuthToken
-        raise NotImplementedError
-
-# OAuthSignatureMethod is a strategy class that implements a signature method
-class OAuthSignatureMethod(object):
-    def get_name(self):
-        # -> str
-        raise NotImplementedError
-
-    def build_signature_base_string(self, oauth_request, oauth_consumer, oauth_token):
-        # -> str key, str raw
-        raise NotImplementedError
-
-    def build_signature(self, oauth_request, oauth_consumer, oauth_token):
-        # -> str
-        raise NotImplementedError
-
-    def check_signature(self, oauth_request, consumer, token, signature):
-        built = self.build_signature(oauth_request, consumer, token)
-        return built == signature
-
-class OAuthSignatureMethod_HMAC_SHA1(OAuthSignatureMethod):
-
-    def get_name(self):
-        return 'HMAC-SHA1'
-        
-    def build_signature_base_string(self, oauth_request, consumer, token):
-        sig = (
-            escape(oauth_request.get_normalized_http_method()),
-            escape(oauth_request.get_normalized_http_url()),
-            escape(oauth_request.get_normalized_parameters()),
-        )
-
-        key = '%s&' % escape(consumer.secret)
-        if token:
-            key += escape(token.secret)
-        raw = '&'.join(sig)
-        return key, raw
-
-    def build_signature(self, oauth_request, consumer, token):
-        # build the base signature string
-        key, raw = self.build_signature_base_string(oauth_request, consumer, token)
-
-        # hmac object
-        try:
-            import hashlib # 2.5
-            hashed = hmac.new(key, raw, hashlib.sha1)
-        except:
-            import sha # deprecated
-            hashed = hmac.new(key, raw, sha)
-
-        # calculate the digest base 64
-        return binascii.b2a_base64(hashed.digest())[:-1]
-
-class OAuthSignatureMethod_PLAINTEXT(OAuthSignatureMethod):
-
-    def get_name(self):
-        return 'PLAINTEXT'
-
-    def build_signature_base_string(self, oauth_request, consumer, token):
-        # concatenate the consumer key and secret
-        sig = escape(consumer.secret) + '&'
-        if token:
-            sig = sig + escape(token.secret)
-        return sig
-
-    def build_signature(self, oauth_request, consumer, token):
-        return self.build_signature_base_string(oauth_request, consumer, token)