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 31: | 4f12d70ae49d |
| parent 30: | 95a6aab951cd |
| branch: | default |
Check callback's validity, comes from Toby White's fork, thanks.
12 months ago
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)
| … | … | @@ -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 |
|
|
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 |
