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.
| 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.
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 != |
|
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: |
