Archived
I think OAuth2 access token fetching might actually kind of almost work.
This commit is contained in:
1 parent
63894a93ff
commit
ec91fb6903
4 files changed
+96
-1
No files matched your search
@@ -1,3 +1,11 @@
|
||||
import logging
|
||||
import provider.oauth2
|
||||
|
||||
from django.http import HttpResponse
|
||||
from django.contrib.auth.models import AnonymousUser, User
|
||||
from django.utils import timezone
|
||||
from provider.oauth2.models import AccessToken
|
||||
from tastypie.authentication import Authentication
|
||||
from tastypie.authorization import DjangoAuthorization
|
||||
from tastypie.exceptions import Unauthorized
|
||||
|
||||
@@ -73,3 +81,86 @@ class MyDjangoAuthorization(DjangoAuthorization):
|
||||
|
||||
return True
|
||||
|
||||
|
||||
"""
|
||||
This is a simple OAuth 2.0 authentication model for tastypie
|
||||
|
||||
Copied nearly verbatim from amrox's example
|
||||
- https://github.com/amrox/django-tastypie-two-legged-oauth
|
||||
|
||||
Dependencies:
|
||||
- django-oauth2-provider: https://github.com/caffeinehit/django-oauth2-provider
|
||||
|
||||
Example:
|
||||
- http://ianalexandr.com
|
||||
"""
|
||||
|
||||
# stolen from piston
|
||||
class OAuthError(RuntimeError):
|
||||
"""Generic exception class."""
|
||||
def __init__(self, message='OAuth error occured.'):
|
||||
self.message = message
|
||||
|
||||
|
||||
class OAuth20Authentication(Authentication):
|
||||
"""
|
||||
OAuth authenticator.
|
||||
|
||||
This Authentication method checks for a provided HTTP_AUTHORIZATION
|
||||
and looks up to see if this is a valid OAuth Access Token
|
||||
"""
|
||||
def __init__(self, realm='API'):
|
||||
self.realm = realm
|
||||
|
||||
def is_authenticated(self, request, **kwargs):
|
||||
"""
|
||||
Verify 2-legged oauth request. Parameters accepted as
|
||||
values in "Authorization" header, or as a GET request
|
||||
or in a POST body.
|
||||
"""
|
||||
logging.info("OAuth20Authentication")
|
||||
|
||||
try:
|
||||
key = request.GET.get('oauth_consumer_key')
|
||||
if not key:
|
||||
key = request.POST.get('oauth_consumer_key')
|
||||
if not key:
|
||||
auth_header_value = request.META.get('HTTP_AUTHORIZATION')
|
||||
if auth_header_value:
|
||||
key = auth_header_value.split(' ')[1]
|
||||
if not key:
|
||||
logging.error('OAuth20Authentication. No consumer_key found.')
|
||||
return None
|
||||
"""
|
||||
If verify_access_token() does not pass, it will raise an error
|
||||
"""
|
||||
token = verify_access_token(key)
|
||||
|
||||
# If OAuth authentication is successful, set the request user to the token user for authorization
|
||||
request.user = token.user
|
||||
|
||||
# If OAuth authentication is successful, set oauth_consumer_key on request in case we need it later
|
||||
request.META['oauth_consumer_key'] = key
|
||||
return True
|
||||
except KeyError, e:
|
||||
logging.exception("Error in OAuth20Authentication.")
|
||||
request.user = AnonymousUser()
|
||||
return False
|
||||
except Exception, e:
|
||||
logging.exception("Error in OAuth20Authentication.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def verify_access_token(key):
|
||||
# Check if key is in AccessToken key
|
||||
try:
|
||||
token = AccessToken.objects.get(token=key)
|
||||
|
||||
# Check if token has expired
|
||||
if token.expires < timezone.now():
|
||||
raise OAuthError('AccessToken has expired.')
|
||||
except AccessToken.DoesNotExist, e:
|
||||
raise OAuthError("AccessToken not found at all.")
|
||||
|
||||
logging.info('Valid access')
|
||||
return token
|
||||
@@ -115,6 +115,8 @@ INSTALLED_APPS = (
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.admindocs',
|
||||
'provider',
|
||||
'provider.oauth2',
|
||||
'dusken',
|
||||
'tastypie',
|
||||
'south',
|
||||
|
||||
+2
-1
@@ -18,5 +18,6 @@ v1_api.register(InstitutionResource())
|
||||
urlpatterns = patterns('',
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
url(r'^api/', include(v1_api.urls)),
|
||||
url(r'^authenticate/', 'dusken.views.authenticate')
|
||||
url(r'^authenticate/', 'dusken.views.authenticate'),
|
||||
url(r'oauth2/', include('provider.oauth2.urls', namespace='oauth2')),
|
||||
)
|
||||
@@ -1,6 +1,7 @@
|
||||
Django==1.5.4
|
||||
django-cors-headers==0.12
|
||||
django-extensions==1.2.2
|
||||
django-oauth2-provider==0.2.6
|
||||
django-sphinxdoc==1.2.0
|
||||
django-tastypie==0.10.0
|
||||
psycopg2==2.5.1
|
||||
|
||||
Reference in new issue
Block a user