Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python 3.4 and 3.3 Compatibility (includes django 1.7 compatibility) #95

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions provider/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def _clean_fields(self):
"""
try:
super(OAuthForm, self)._clean_fields()
except OAuthValidationError, e:
except OAuthValidationError as e:
self._errors.update(e.args[0])

def _clean_form(self):
Expand All @@ -60,5 +60,5 @@ def _clean_form(self):
"""
try:
super(OAuthForm, self)._clean_form()
except OAuthValidationError, e:
except OAuthValidationError as e:
self._errors.update(e.args[0])
15 changes: 9 additions & 6 deletions provider/oauth2/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import backends
import forms
import managers
import models
import urls
import views
from __future__ import absolute_import
from . import backends
from . import forms
from . import managers
from . import models
from . import urls
from . import views

default_app_config = 'provider.oauth2.apps.Oauth2'
6 changes: 6 additions & 0 deletions provider/oauth2/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig

class Oauth2(AppConfig):
name = 'provider.oauth2'
label = 'oauth2'
verbose_name = "Provider Oauth2"
9 changes: 6 additions & 3 deletions provider/oauth2/backends.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import base64
from future.builtins import object
from ..utils import now
from .forms import ClientAuthForm, PublicPasswordGrantForm
from .models import AccessToken
Expand Down Expand Up @@ -28,9 +30,10 @@ def authenticate(self, request=None):
return None

try:
basic, base64 = auth.split(' ')
client_id, client_secret = base64.decode('base64').split(':')

basic, base64str = auth.split(' ')
client_id, client_secret = base64str.split(':')
client_id =client_id.encode('utf-8')
client_secret = client_secret.encode('utf-8')
form = ClientAuthForm({
'client_id': client_id,
'client_secret': client_secret})
Expand Down
2 changes: 1 addition & 1 deletion provider/oauth2/forms.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django import forms
from django.contrib.auth import authenticate
from django.utils.encoding import smart_unicode
from django.utils.encoding import smart_str as smart_unicode
from django.utils.translation import ugettext as _
from .. import scope
from ..constants import RESPONSE_TYPE_CHOICES, SCOPES
Expand Down
17 changes: 17 additions & 0 deletions provider/oauth2/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
implement these models with fields and and methods to be compatible with the
views in :attr:`provider.views`.
"""
from future.builtins import object

from django.db import models
from django.conf import settings
Expand Down Expand Up @@ -81,6 +82,10 @@ def deserialize(cls, data):

return cls(**kwargs)

class Meta(object):
app_label = 'oauth2'
db_table = 'oauth2_client'


class Grant(models.Model):
"""
Expand Down Expand Up @@ -108,6 +113,10 @@ class Grant(models.Model):
def __unicode__(self):
return self.code

class Meta(object):
app_label = 'oauth2'
db_table = 'oauth2_grant'


class AccessToken(models.Model):
"""
Expand Down Expand Up @@ -165,6 +174,10 @@ def get_expire_delta(self, reference=None):
timedelta = expiration - reference
return timedelta.days*86400 + timedelta.seconds

class Meta(object):
app_label = 'oauth2'
db_table = 'oauth2_accesstoken'


class RefreshToken(models.Model):
"""
Expand All @@ -188,3 +201,7 @@ class RefreshToken(models.Model):

def __unicode__(self):
return self.token

class Meta(object):
app_label = 'oauth2'
db_table = 'oauth2_refreshtoken'
72 changes: 40 additions & 32 deletions provider/oauth2/tests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from __future__ import division
from future import standard_library
standard_library.install_hooks()
from past.utils import old_div
import base64
import json
import urlparse
import datetime
from django.http import QueryDict
from django.conf import settings
Expand All @@ -16,6 +20,10 @@
from .backends import BasicClientBackend, RequestParamsClientBackend
from .backends import AccessTokenBackend

try:
from urllib import parse as urllib_parse
except ImportError:
import urlparse as urllib_parse

@skipIfCustomUser
class BaseOAuth2TestCase(TestCase):
Expand Down Expand Up @@ -73,7 +81,7 @@ def test_authorization_requires_login(self):

# Login redirect
self.assertEqual(302, response.status_code)
self.assertEqual('/login/', urlparse.urlparse(response['Location']).path)
self.assertEqual('/login/', urllib_parse.urlparse(response['Location']).path)

self.login()

Expand All @@ -89,35 +97,35 @@ def test_authorization_requires_client_id(self):
response = self.client.get(self.auth_url2())

self.assertEqual(400, response.status_code)
self.assertTrue("An unauthorized client tried to access your resources." in response.content)
self.assertTrue("An unauthorized client tried to access your resources." in response.content.decode('utf-8'))

def test_authorization_rejects_invalid_client_id(self):
self.login()
response = self.client.get(self.auth_url() + '?client_id=123')
response = self.client.get(self.auth_url2())

self.assertEqual(400, response.status_code)
self.assertTrue("An unauthorized client tried to access your resources." in response.content)
self.assertTrue("An unauthorized client tried to access your resources." in response.content.decode('utf-8'))

def test_authorization_requires_response_type(self):
self.login()
response = self.client.get(self.auth_url() + '?client_id=%s' % self.get_client().client_id)
response = self.client.get(self.auth_url2())

self.assertEqual(400, response.status_code)
self.assertTrue(escape(u"No 'response_type' supplied.") in response.content)
self.assertTrue(escape(u"No 'response_type' supplied.") in response.content.decode('utf-8'))

def test_authorization_requires_supported_response_type(self):
self.login()
response = self.client.get(self.auth_url() + '?client_id=%s&response_type=unsupported' % self.get_client().client_id)
response = self.client.get(self.auth_url2())

self.assertEqual(400, response.status_code)
self.assertTrue(escape(u"'unsupported' is not a supported response type.") in response.content)
self.assertTrue(escape(u"'unsupported' is not a supported response type.") in response.content.decode('utf-8'))

response = self.client.get(self.auth_url() + '?client_id=%s&response_type=code' % self.get_client().client_id)
response = self.client.get(self.auth_url2())
self.assertEqual(200, response.status_code, response.content)
self.assertEqual(200, response.status_code, response.content.decode('utf-8'))

response = self.client.get(self.auth_url() + '?client_id=%s&response_type=token' % self.get_client().client_id)
response = self.client.get(self.auth_url2())
Expand All @@ -132,7 +140,7 @@ def test_authorization_requires_a_valid_redirect_uri(self):
response = self.client.get(self.auth_url2())

self.assertEqual(400, response.status_code)
self.assertTrue(escape(u"The requested redirect didn't match the client settings.") in response.content)
self.assertTrue(escape(u"The requested redirect didn't match the client settings.") in response.content.decode('utf-8'))

response = self.client.get(self.auth_url() + '?client_id=%s&response_type=code&redirect_uri=%s' % (
self.get_client().client_id,
Expand All @@ -148,7 +156,7 @@ def test_authorization_requires_a_valid_scope(self):
response = self.client.get(self.auth_url2())

self.assertEqual(400, response.status_code)
self.assertTrue(escape(u"'invalid' is not a valid scope.") in response.content)
self.assertTrue(escape(u"'invalid' is not a valid scope.") in response.content.decode('utf-8'))

response = self.client.get(self.auth_url() + '?client_id=%s&response_type=code&scope=%s' % (
self.get_client().client_id,
Expand Down Expand Up @@ -223,7 +231,7 @@ def test_fetching_access_token_with_invalid_client(self):
'client_secret': self.get_client().client_secret, })

self.assertEqual(400, response.status_code, response.content)
self.assertEqual('invalid_client', json.loads(response.content)['error'])
self.assertEqual('invalid_client', json.loads(response.content.decode())['error'])

def test_fetching_access_token_with_invalid_grant(self):
self.login()
Expand All @@ -236,7 +244,7 @@ def test_fetching_access_token_with_invalid_grant(self):
'code': '123'})

self.assertEqual(400, response.status_code, response.content)
self.assertEqual('invalid_grant', json.loads(response.content)['error'])
self.assertEqual('invalid_grant', json.loads(response.content.decode())['error'])

def _login_authorize_get_token(self):
required_props = ['access_token', 'token_type']
Expand All @@ -245,7 +253,7 @@ def _login_authorize_get_token(self):
self._login_and_authorize()

response = self.client.get(self.redirect_url())
query = QueryDict(urlparse.urlparse(response['Location']).query)
query = QueryDict(urllib_parse.urlparse(response['Location']).query)
code = query['code']

response = self.client.post(self.access_token_url(), {
Expand All @@ -256,7 +264,7 @@ def _login_authorize_get_token(self):

self.assertEqual(200, response.status_code, response.content)

token = json.loads(response.content)
token = json.loads(response.content.decode())

for prop in required_props:
self.assertIn(prop, token, "Access token response missing "
Expand All @@ -272,7 +280,7 @@ def test_fetching_access_token_with_invalid_grant_type(self):
self._login_and_authorize()
response = self.client.get(self.redirect_url())

query = QueryDict(urlparse.urlparse(response['Location']).query)
query = QueryDict(urllib_parse.urlparse(response['Location']).query)
code = query['code']

response = self.client.post(self.access_token_url(), {
Expand All @@ -283,7 +291,7 @@ def test_fetching_access_token_with_invalid_grant_type(self):
})

self.assertEqual(400, response.status_code)
self.assertEqual('unsupported_grant_type', json.loads(response.content)['error'],
self.assertEqual('unsupported_grant_type', json.loads(response.content.decode())['error'],
response.content)

def test_fetching_single_access_token(self):
Expand Down Expand Up @@ -324,7 +332,7 @@ def test_fetching_access_token_multiple_times(self):
'code': code})

self.assertEqual(400, response.status_code)
self.assertEqual('invalid_grant', json.loads(response.content)['error'])
self.assertEqual('invalid_grant', json.loads(response.content.decode())['error'])

def test_escalating_the_scope(self):
self.login()
Expand All @@ -339,7 +347,7 @@ def test_escalating_the_scope(self):
'scope': 'read write'})

self.assertEqual(400, response.status_code)
self.assertEqual('invalid_scope', json.loads(response.content)['error'])
self.assertEqual('invalid_scope', json.loads(response.content.decode())['error'])

def test_refreshing_an_access_token(self):
token = self._login_authorize_get_token()
Expand All @@ -361,7 +369,7 @@ def test_refreshing_an_access_token(self):
})

self.assertEqual(400, response.status_code)
self.assertEqual('invalid_grant', json.loads(response.content)['error'],
self.assertEqual('invalid_grant', json.loads(response.content.decode())['error'],
response.content)

def test_password_grant_public(self):
Expand All @@ -378,9 +386,9 @@ def test_password_grant_public(self):
})

self.assertEqual(200, response.status_code, response.content)
self.assertNotIn('refresh_token', json.loads(response.content))
expires_in = json.loads(response.content)['expires_in']
expires_in_days = round(expires_in / (60.0 * 60.0 * 24.0))
self.assertNotIn('refresh_token', json.loads(response.content.decode()))
expires_in = json.loads(response.content.decode())['expires_in']
expires_in_days = round(old_div(expires_in, (60.0 * 60.0 * 24.0)))
self.assertEqual(expires_in_days, constants.EXPIRE_DELTA_PUBLIC.days)

def test_password_grant_confidential(self):
Expand All @@ -397,7 +405,7 @@ def test_password_grant_confidential(self):
})

self.assertEqual(200, response.status_code, response.content)
self.assertTrue(json.loads(response.content)['refresh_token'])
self.assertTrue(json.loads(response.content.decode())['refresh_token'])

def test_password_grant_confidential_no_secret(self):
c = self.get_client()
Expand All @@ -411,7 +419,7 @@ def test_password_grant_confidential_no_secret(self):
'password': self.get_password(),
})

self.assertEqual('invalid_client', json.loads(response.content)['error'])
self.assertEqual('invalid_client', json.loads(response.content.decode())['error'])

def test_password_grant_invalid_password_public(self):
c = self.get_client()
Expand All @@ -426,7 +434,7 @@ def test_password_grant_invalid_password_public(self):
})

self.assertEqual(400, response.status_code, response.content)
self.assertEqual('invalid_client', json.loads(response.content)['error'])
self.assertEqual('invalid_client', json.loads(response.content.decode())['error'])

def test_password_grant_invalid_password_confidential(self):
c = self.get_client()
Expand All @@ -442,7 +450,7 @@ def test_password_grant_invalid_password_confidential(self):
})

self.assertEqual(400, response.status_code, response.content)
self.assertEqual('invalid_grant', json.loads(response.content)['error'])
self.assertEqual('invalid_grant', json.loads(response.content.decode())['error'])

def test_access_token_response_valid_token_type(self):
token = self._login_authorize_get_token()
Expand All @@ -456,8 +464,8 @@ def test_basic_client_backend(self):
request = type('Request', (object,), {'META': {}})()
request.META['HTTP_AUTHORIZATION'] = "Basic " + "{0}:{1}".format(
self.get_client().client_id,
self.get_client().client_secret).encode('base64')

self.get_client().client_secret,
)
self.assertEqual(BasicClientBackend().authenticate(request).id,
2, "Didn't return the right client.")

Expand Down Expand Up @@ -496,13 +504,13 @@ def test_authorization_enforces_SSL(self):
response = self.client.get(self.auth_url())

self.assertEqual(400, response.status_code)
self.assertTrue("A secure connection is required." in response.content)
self.assertTrue("A secure connection is required." in response.content.decode('utf-8'))

def test_access_token_enforces_SSL(self):
response = self.client.post(self.access_token_url(), {})

self.assertEqual(400, response.status_code)
self.assertTrue("A secure connection is required." in response.content)
self.assertTrue("A secure connection is required." in response.content.decode('utf-8'))


class ClientFormTest(TestCase):
Expand Down Expand Up @@ -578,7 +586,7 @@ def test_clear_expired(self):
self.assertTrue('code' in location)

# verify that Grant with code exists
code = urlparse.parse_qs(location)['code'][0]
code = urllib_parse.parse_qs(location)['code'][0]
self.assertTrue(Grant.objects.filter(code=code).exists())

# use the code/grant
Expand All @@ -588,7 +596,7 @@ def test_clear_expired(self):
'client_secret': self.get_client().client_secret,
'code': code})
self.assertEquals(200, response.status_code)
token = json.loads(response.content)
token = json.loads(response.content.decode())
self.assertTrue('access_token' in token)
access_token = token['access_token']
self.assertTrue('refresh_token' in token)
Expand All @@ -610,7 +618,7 @@ def test_clear_expired(self):
'client_secret': self.get_client().client_secret,
})
self.assertEqual(200, response.status_code)
token = json.loads(response.content)
token = json.loads(response.content.decode())
self.assertTrue('access_token' in token)
self.assertNotEquals(access_token, token['access_token'])
self.assertTrue('refresh_token' in token)
Expand Down
Loading