oauth 1.0a compat, outsourcing secret/verifier generation to django, updating a few oauth models

This commit is contained in:
Jesper Noehr 2009-09-11 12:15:31 +03:00
Родитель 2a61bcefca
Коммит b25314ac87
5 изменённых файлов: 57 добавлений и 13 удалений

Просмотреть файл

@ -101,7 +101,11 @@ def initialize_server_request(request):
# request.META['CONTENT_TYPE'] == "application/x-www-form-urlencoded":
params = dict(request.REQUEST.items())
else:
params = {}
params = { }
# Seems that we want to put HTTP_AUTHORIZATION into 'Authorization'
# for oauth.py to understand. Lovely.
request.META['Authorization'] = request.META.get('HTTP_AUTHORIZATION', '')
oauth_request = oauth.OAuthRequest.from_request(
request.method, request.build_absolute_uri(),
@ -149,7 +153,7 @@ def oauth_request_token(request):
def oauth_auth_view(request, token, callback, params):
form = forms.OAuthAuthenticationForm(initial={
'oauth_token': token.key,
'oauth_callback': callback,
'oauth_callback': token.get_callback_url() or callback,
})
return render_to_response('piston/authorize_token.html',
@ -171,7 +175,7 @@ def oauth_user_auth(request):
callback = oauth_server.get_callback(oauth_request)
except:
callback = None
if request.method == "GET":
params = oauth_request.get_normalized_parameters()

Просмотреть файл

@ -76,7 +76,6 @@ class Emitter(object):
if not handler:
return { }
has = dir(handler)
ret = dict()
for field in fields - Emitter.RESERVED_FIELDS:

Просмотреть файл

@ -23,7 +23,7 @@ class ModelForm(forms.ModelForm):
class OAuthAuthenticationForm(forms.Form):
oauth_token = forms.CharField(widget=forms.HiddenInput)
oauth_callback = forms.CharField(widget=forms.HiddenInput)
oauth_callback = forms.CharField(widget=forms.HiddenInput, required=False)
authorize_access = forms.BooleanField(required=True)
csrf_signature = forms.CharField(widget=forms.HiddenInput)

Просмотреть файл

@ -1,4 +1,4 @@
import urllib, time
import urllib, time, urlparse
# Django imports
from django.db.models.signals import post_save, post_delete
@ -13,6 +13,7 @@ from signals import consumer_post_save, consumer_post_delete
KEY_SIZE = 18
SECRET_SIZE = 32
VERIFIER_SIZE = 10
CONSUMER_STATES = (
('pending', 'Pending'),
@ -21,6 +22,9 @@ CONSUMER_STATES = (
('rejected', 'Rejected')
)
def generate_random(length=SECRET_SIZE):
return User.objects.make_random_password(length=length)
class Nonce(models.Model):
token_key = models.CharField(max_length=KEY_SIZE)
consumer_key = models.CharField(max_length=KEY_SIZE)
@ -58,11 +62,10 @@ class Consumer(models.Model):
c.generate_random_codes()
"""
key = User.objects.make_random_password(length=KEY_SIZE)
secret = User.objects.make_random_password(length=SECRET_SIZE)
secret = generate_random(SECRET_SIZE)
while Consumer.objects.filter(key__exact=key, secret__exact=secret).count():
secret = User.objects.make_random_password(length=SECRET_SIZE)
secret = generate_random(SECRET_SIZE)
self.key = key
self.secret = secret
@ -77,6 +80,7 @@ class Token(models.Model):
key = models.CharField(max_length=KEY_SIZE)
secret = models.CharField(max_length=SECRET_SIZE)
verifier = models.CharField(max_length=VERIFIER_SIZE)
token_type = models.IntegerField(choices=TOKEN_TYPES)
timestamp = models.IntegerField(default=long(time.time()))
is_approved = models.BooleanField(default=False)
@ -84,6 +88,9 @@ class Token(models.Model):
user = models.ForeignKey(User, null=True, blank=True, related_name='tokens')
consumer = models.ForeignKey(Consumer)
callback = models.CharField(max_length=255, null=True, blank=True)
callback_confirmed = models.BooleanField(default=False)
objects = TokenManager()
def __unicode__(self):
@ -92,23 +99,50 @@ class Token(models.Model):
def to_string(self, only_key=False):
token_dict = {
'oauth_token': self.key,
'oauth_token_secret': self.secret
'oauth_token_secret': self.secret,
'oauth_callback_confirmed': 'true',
}
if self.verifier:
token_dict.update({ 'oauth_verifier': self.verifier })
if only_key:
del token_dict['oauth_token_secret']
return urllib.urlencode(token_dict)
def generate_random_codes(self):
key = User.objects.make_random_password(length=KEY_SIZE)
secret = User.objects.make_random_password(length=SECRET_SIZE)
secret = generate_random(SECRET_SIZE)
while Token.objects.filter(key__exact=key, secret__exact=secret).count():
secret = User.objects.make_random_password(length=SECRET_SIZE)
secret = generate_random(SECRET_SIZE)
self.key = key
self.secret = secret
self.save()
# -- OAuth 1.0a stuff
def get_callback_url(self):
if self.callback and self.verifier:
# Append the oauth_verifier.
parts = urlparse.urlparse(self.callback)
scheme, netloc, path, params, query, fragment = parts[:6]
if query:
query = '%s&oauth_verifier=%s' % (query, self.verifier)
else:
query = 'oauth_verifier=%s' % self.verifier
return urlparse.urlunparse((scheme, netloc, path, params,
query, fragment))
return self.callback
def set_callback(self, callback):
if callback != "oob": # out of band, says "we can't do this!"
self.callback = callback
self.callback_confirmed = True
self.save()
admin.site.register(Token)
# Attach our signals

Просмотреть файл

@ -1,6 +1,7 @@
import oauth
from models import Nonce, Token, Consumer
from models import generate_random, VERIFIER_SIZE
class DataStore(oauth.OAuthDataStore):
"""Layer between Python OAuth and Django database."""
@ -44,12 +45,17 @@ class DataStore(oauth.OAuthDataStore):
self.request_token = Token.objects.create_token(consumer=self.consumer,
token_type=Token.REQUEST,
timestamp=self.timestamp)
if oauth_callback:
self.request_token.set_callback(oauth_callback)
return self.request_token
return None
def fetch_access_token(self, oauth_consumer, oauth_token, oauth_callback):
def fetch_access_token(self, oauth_consumer, oauth_token, oauth_verifier):
if oauth_consumer.key == self.consumer.key \
and oauth_token.key == self.request_token.key \
and oauth_verifier == self.request_token.verifier \
and self.request_token.is_approved:
self.access_token = Token.objects.create_token(consumer=self.consumer,
token_type=Token.ACCESS,
@ -63,6 +69,7 @@ class DataStore(oauth.OAuthDataStore):
# authorize the request token in the store
self.request_token.is_approved = True
self.request_token.user = user
self.request_token.verifier = generate_random(VERIFIER_SIZE)
self.request_token.save()
return self.request_token
return None