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
commit 33: 38b34bb24b52
parent 32: 338320d4634a
branch: default
Handle 1.0a out-of-band case the right way, inspired by Toby White's fork. Note: never lie in your tests, cheater.
David Larlet / david
12 months ago

Changed (Δ1.0 KB):

raw changeset »

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

oauth_provider/stores.py (2 lines added, 2 lines removed)

oauth_provider/tests.py (20 lines added, 2 lines removed)

oauth_provider/views.py (14 lines added, 4 lines removed)

Up to file-list oauth_provider/consts.py:

@@ -21,3 +21,5 @@ CONSUMER_STATES = (
21
21
PARAMETERS_NAMES = ('consumer_key', 'token', 'signature',
22
22
                    'signature_method', 'timestamp', 'nonce')
23
23
OAUTH_PARAMETERS_NAMES = ['oauth_'+s for s in PARAMETERS_NAMES]
24
25
OUT_OF_BAND = 'oob'

Up to file-list oauth_provider/stores.py:

@@ -3,7 +3,7 @@ from urlparse import urlparse
3
3
from oauth.oauth import OAuthDataStore, OAuthError, escape
4
4
5
5
from models import Nonce, Token, Consumer, Resource, generate_random
6
from consts import VERIFIER_SIZE, MAX_URL_LENGTH
6
from consts import VERIFIER_SIZE, MAX_URL_LENGTH, OUT_OF_BAND
7
7
8
8
9
9
class DataStore(OAuthDataStore):
@@ -51,7 +51,7 @@ class DataStore(OAuthDataStore):
51
51
        callback = None
52
52
        callback_confirmed = False
53
53
        if oauth_callback:
54
            if oauth_callback != "oob":
54
            if oauth_callback != OUT_OF_BAND:
55
55
                if check_valid_callback(oauth_callback):
56
56
                    callback = oauth_callback
57
57
                    callback_confirmed = True

Up to file-list oauth_provider/tests.py:

@@ -670,8 +670,26 @@ redirects her back to the Consumer's cal
670
670
    'http://printer.example.com/request_token_ready?error=Access%20not%20granted%20by%20user.'
671
671
    >>> c.logout()
672
672
673
With OAuth 1.0a, the callback is required, hence the ``OAUTH_CALLBACK_VIEW`` 
674
setting is useless.
673
With OAuth 1.0a, the callback argument can be set to "oob" (out-of-band), 
674
you can specify your own default callback view with the
675
``OAUTH_CALLBACK_VIEW`` setting::
676
677
    >>> from oauth_provider.consts import OUT_OF_BAND
678
    >>> token.callback = OUT_OF_BAND
679
    >>> token.save()
680
    >>> parameters = {
681
    ...     'oauth_token': token.key,
682
    ... }
683
    >>> c.login(username='jane', password='toto')
684
    True
685
    >>> response = c.get("/oauth/authorize/", parameters)
686
    >>> parameters['authorize_access'] = 0
687
    >>> response = c.post("/oauth/authorize/", parameters)
688
    >>> response.status_code
689
    200
690
    >>> response.content
691
    'Fake callback view.'
692
    >>> c.logout()
675
693
676
694
677
695
Obtaining an Access Token

Up to file-list oauth_provider/views.py:

@@ -8,6 +8,8 @@ from django.core.urlresolvers import get
8
8
9
9
from utils import initialize_server_request, send_oauth_error
10
10
from decorators import oauth_required
11
from stores import check_valid_callback
12
from consts import OUT_OF_BAND
11
13
12
14
OAUTH_AUTHORIZE_VIEW = 'OAUTH_AUTHORIZE_VIEW'
13
15
OAUTH_CALLBACK_VIEW = 'OAUTH_CALLBACK_VIEW'
@@ -50,9 +52,21 @@ def user_authorization(request):
50
52
    try:
51
53
        # get the request callback, though there might not be one
52
54
        callback = oauth_server.get_callback(oauth_request)
55
        
56
        # OAuth 1.0a: this parameter should not be present on this version
57
        if token.callback_confirmed:
58
            return HttpResponseBadRequest("Cannot specify oauth_callback at authorization step for 1.0a protocol")
59
        if not check_valid_callback(callback):
60
            return HttpResponseBadRequest("Invalid callback URL")
53
61
    except OAuthError:
54
62
        callback = None
55
63
64
    # OAuth 1.0a: use the token's callback if confirmed
65
    if token.callback_confirmed:
66
        callback = token.callback
67
        if callback == OUT_OF_BAND:
68
            callback = None
69
56
70
    # entry point for the user
57
71
    if request.method == 'GET':
58
72
        # try to get custom authorize view
@@ -82,10 +96,6 @@ def user_authorization(request):
82
96
                    args = 'error=%s' % _('Access not granted by user.')
83
97
            except OAuthError, err:
84
98
                response = send_oauth_error(err)
85
                
86
            # OAuth 1.0a: use the token's callback if confirmed
87
            if token.callback_confirmed:
88
                callback = token.callback
89
99
            
90
100
            if callback:
91
101
                if "?" in callback: