david / django-oauth (http://oauth.net/)

Support of OAuth in Django. Note that http://code.welldev.org/django-oauth-plus will use python-oauth2 if you're interested in it.

Clone this repository (size: 114.7 KB): HTTPS / SSH
$ hg clone http://code.welldev.org/django-oauth

Changed (Δ898 bytes):

raw changeset »

AUTHORS (2 lines added, 0 lines removed)

oauth_provider/consts.py (1 lines added, 0 lines removed)

oauth_provider/stores.py (35 lines added, 16 lines removed)

oauth_provider/tests.py (10 lines added, 0 lines removed)

Up to file-list AUTHORS:

@@ -2,3 +2,5 @@ David Larlet <http://david.larlet.fr>
2
2
Dan Wilson
3
3
Jay Graves
4
4
Ariel Nunez
5
Jesper Noerh
6
Toby White

Up to file-list oauth_provider/consts.py:

@@ -4,6 +4,7 @@ KEY_SIZE = 16
4
4
SECRET_SIZE = 16
5
5
VERIFIER_SIZE = 10
6
6
CONSUMER_KEY_SIZE = 256
7
MAX_URL_LENGTH = 2083
7
8
8
9
PENDING = 1
9
10
ACCEPTED = 2

Up to file-list oauth_provider/stores.py:

1
from urlparse import urlparse
2
1
3
from oauth.oauth import OAuthDataStore, OAuthError, escape
2
4
3
5
from models import Nonce, Token, Consumer, Resource, generate_random
4
from consts import VERIFIER_SIZE
6
from consts import VERIFIER_SIZE, MAX_URL_LENGTH
5
7
6
8
7
9
class DataStore(OAuthDataStore):
@@ -42,21 +44,28 @@ class DataStore(OAuthDataStore):
42
44
            return nonce.key
43
45
44
46
    def fetch_request_token(self, oauth_consumer, oauth_callback):
45
        if oauth_consumer.key == self.consumer.key:
46
            try:
47
                resource = Resource.objects.get(name=self.scope)
48
            except:
49
                raise OAuthError('Resource %s does not exist.' % escape(self.scope))
50
            self.request_token = Token.objects.create_token(consumer=self.consumer,
51
                                                            token_type=Token.REQUEST,
52
                                                            timestamp=self.timestamp,
53
                                                            resource=resource)
54
            # OAuth 1.0a: if there is a callback, set it
55
            if oauth_callback:
56
                self.request_token.set_callback(oauth_callback)
57
            
58
            return self.request_token
59
        raise OAuthError('Consumer key does not match.')
47
        if oauth_consumer.key != self.consumer.key:
48
            raise OAuthError('Consumer key does not match.')
49
        
50
        # OAuth 1.0a: if there is a callback, check its validity
51
        if oauth_callback and \
52
            not (oauth_callback == "oob" or check_valid_callback(oauth_callback)):
53
            raise OAuthError('Invalid callback URL.')
54
55
        try:
56
            resource = Resource.objects.get(name=self.scope)
57
        except:
58
            raise OAuthError('Resource %s does not exist.' % escape(self.scope))
59
        self.request_token = Token.objects.create_token(consumer=self.consumer,
60
                                                        token_type=Token.REQUEST,
61
                                                        timestamp=self.timestamp,
62
                                                        resource=resource)
63
        # OAuth 1.0a: if there is a callback, set it
64
        if oauth_callback:
65
            self.request_token.set_callback(oauth_callback)
66
        
67
        return self.request_token
68
        
60
69
61
70
    def fetch_access_token(self, oauth_consumer, oauth_token, oauth_verifier):
62
71
        if oauth_consumer.key == self.consumer.key \
@@ -89,3 +98,13 @@ class DataStore(OAuthDataStore):
89
98
            self.request_token.save()
90
99
            return self.request_token
91
100
        raise OAuthError('Token key does not match.')
101
102
103
def check_valid_callback(callback):
104
    """
105
    Checks the size and nature of the callback.
106
    """
107
    callback_url = urlparse(callback)
108
    return (callback_url.scheme in ['http', 'https'] 
109
            and callback_url.hostname
110
            and len(callback) < MAX_URL_LENGTH)

Up to file-list oauth_provider/tests.py:

@@ -595,6 +595,16 @@ If you try to access a resource with a w
595
595
    401
596
596
    >>> response.content
597
597
    'Resource videos does not exist.'
598
    >>> parameters['scope'] = 'photos' # restore
599
600
If you try to put a wrong callback, it will return an error::
601
602
    >>> parameters['oauth_callback'] = 'wrongcallback'
603
    >>> response = c.get("/oauth/request_token/", parameters)
604
    >>> response.status_code
605
    401
606
    >>> response.content
607
    'Invalid callback URL.'
598
608
599
609
600
610
Requesting User Authorization