Skip to content

Commit

Permalink
Merge 6131885 into d45431e
Browse files Browse the repository at this point in the history
  • Loading branch information
dirkmoors committed Jun 23, 2015
2 parents d45431e + 6131885 commit c91cd35
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 40 deletions.
4 changes: 3 additions & 1 deletion oauth2_provider/admin.py
@@ -1,12 +1,14 @@
from django.contrib import admin

from .models import Grant, AccessToken, RefreshToken, get_application_model
from .models import Grant, get_access_token_model, get_refresh_token_model, get_application_model


class RawIDAdmin(admin.ModelAdmin):
raw_id_fields = ('user',)

Application = get_application_model()
AccessToken = get_access_token_model()
RefreshToken = get_refresh_token_model()

admin.site.register(Application, RawIDAdmin)
admin.site.register(Grant, RawIDAdmin)
Expand Down
41 changes: 41 additions & 0 deletions oauth2_provider/migrations/0002_auto_20150623_0630.py
@@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from oauth2_provider.settings import oauth2_settings
from django.db import models, migrations
from django.conf import settings


class Migration(migrations.Migration):

dependencies = [
('oauth2_provider', '0001_initial'),
]

operations = [
migrations.AlterField(
model_name='accesstoken',
name='application',
field=models.ForeignKey(related_name='accesstoken_set', to=oauth2_settings.APPLICATION_MODEL),
),
migrations.AlterField(
model_name='accesstoken',
name='user',
field=models.ForeignKey(null=True, to=settings.AUTH_USER_MODEL, blank=True, related_name='accesstoken_set'),
),
migrations.AlterField(
model_name='refreshtoken',
name='access_token',
field=models.OneToOneField(related_name='refresh_token', to=oauth2_settings.ACCESS_TOKEN_MODEL),
),
migrations.AlterField(
model_name='refreshtoken',
name='application',
field=models.ForeignKey(related_name='refreshtoken_set', to=oauth2_settings.APPLICATION_MODEL),
),
migrations.AlterField(
model_name='refreshtoken',
name='user',
field=models.ForeignKey(related_name='refreshtoken_set', to=settings.AUTH_USER_MODEL),
),
]
105 changes: 76 additions & 29 deletions oauth2_provider/models.py
Expand Up @@ -164,26 +164,15 @@ def __str__(self):
return self.code


@python_2_unicode_compatible
class AccessToken(models.Model):
"""
An AccessToken instance represents the actual access token to
access user's resources, as in :rfc:`5`.
Fields:
* :attr:`user` The Django user representing resources' owner
* :attr:`token` Access token
* :attr:`application` Application instance
* :attr:`expires` Date and time of token expiration, in DateTime format
* :attr:`scope` Allowed scopes
"""
user = models.ForeignKey(AUTH_USER_MODEL, blank=True, null=True)
token = models.CharField(max_length=255, db_index=True)
application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL)
class AbstractAccessToken(models.Model):
user = models.ForeignKey(AUTH_USER_MODEL, related_name='accesstoken_set', blank=True, null=True)
application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, related_name='accesstoken_set')
expires = models.DateTimeField()
scope = models.TextField(blank=True)

class Meta:
abstract = True

def is_valid(self, scopes=None):
"""
Checks if the access token is valid.
Expand Down Expand Up @@ -219,12 +208,50 @@ def revoke(self):
"""
self.delete()


@python_2_unicode_compatible
class AccessToken(AbstractAccessToken):
"""
An AccessToken instance represents the actual access token to
access user's resources, as in :rfc:`5`.
Fields:
* :attr:`user` The Django user representing resources' owner
* :attr:`token` Access token
* :attr:`application` Application instance
* :attr:`expires` Expire time in seconds, defaults to
:data:`settings.ACCESS_TOKEN_EXPIRE_SECONDS`
* :attr:`scope` Allowed scopes
"""
token = models.CharField(max_length=255, db_index=True)

def __str__(self):
return self.token

# Add swappable like this to not break django 1.4 compatibility
AccessToken._meta.swappable = 'OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL'


class AbstractRefreshToken(models.Model):
user = models.ForeignKey(AUTH_USER_MODEL, related_name='refreshtoken_set')
application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, related_name='refreshtoken_set')
access_token = models.OneToOneField(oauth2_settings.ACCESS_TOKEN_MODEL,
related_name='refresh_token')

class Meta:
abstract = True

def revoke(self):
"""
Delete this refresh token along with related access token
"""
get_access_token_model().objects.get(id=self.access_token.id).revoke()
self.delete()


@python_2_unicode_compatible
class RefreshToken(models.Model):
class RefreshToken(AbstractRefreshToken):
"""
A RefreshToken instance represents a token that can be swapped for a new
access token when it expires.
Expand All @@ -237,22 +264,14 @@ class RefreshToken(models.Model):
* :attr:`access_token` AccessToken instance this refresh token is
bounded to
"""
user = models.ForeignKey(AUTH_USER_MODEL)
token = models.CharField(max_length=255, db_index=True)
application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL)
access_token = models.OneToOneField(AccessToken,
related_name='refresh_token')

def revoke(self):
"""
Delete this refresh token along with related access token
"""
AccessToken.objects.get(id=self.access_token.id).revoke()
self.delete()

def __str__(self):
return self.token

# Add swappable like this to not break django 1.4 compatibility
RefreshToken._meta.swappable = 'OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL'


def get_application_model():
""" Return the Application model that is active in this project. """
Expand All @@ -266,3 +285,31 @@ def get_application_model():
e = "APPLICATION_MODEL refers to model {0} that has not been installed"
raise ImproperlyConfigured(e.format(oauth2_settings.APPLICATION_MODEL))
return app_model


def get_access_token_model():
""" Return the AccessToken model that is active in this project. """
try:
app_label, model_name = oauth2_settings.ACCESS_TOKEN_MODEL.split('.')
except ValueError:
e = "ACCESS_TOKEN_MODEL must be of the form 'app_label.model_name'"
raise ImproperlyConfigured(e)
access_token_model = get_model(app_label, model_name)
if access_token_model is None:
e = "ACCESS_TOKEN_MODEL refers to model {0} that has not been installed"
raise ImproperlyConfigured(e.format(oauth2_settings.ACCESS_TOKEN_MODEL))
return access_token_model


def get_refresh_token_model():
""" Return the RefreshToken model that is active in this project. """
try:
app_label, model_name = oauth2_settings.REFRESH_TOKEN_MODEL.split('.')
except ValueError:
e = "REFRESH_TOKEN_MODEL must be of the form 'app_label.model_name'"
raise ImproperlyConfigured(e)
refresh_token_model = get_model(app_label, model_name)
if refresh_token_model is None:
e = "REFRESH_TOKEN_MODEL refers to model {0} that has not been installed"
raise ImproperlyConfigured(e.format(oauth2_settings.REFRESH_TOKEN_MODEL))
return refresh_token_model
21 changes: 20 additions & 1 deletion oauth2_provider/oauth2_validators.py
Expand Up @@ -11,7 +11,7 @@
from oauthlib.oauth2 import RequestValidator

from .compat import unquote_plus
from .models import Grant, AccessToken, RefreshToken, get_application_model, AbstractApplication
from .models import Grant, get_access_token_model, get_refresh_token_model, get_application_model, AbstractApplication
from .settings import oauth2_settings

log = logging.getLogger('oauth2_provider')
Expand Down Expand Up @@ -212,6 +212,9 @@ def validate_bearer_token(self, token, scopes, request):
if not token:
return False

# Load the AccessToken model
AccessToken = get_access_token_model()

try:
access_token = AccessToken.objects.select_related("application", "user").get(
token=token)
Expand Down Expand Up @@ -283,6 +286,13 @@ def save_bearer_token(self, token, request, *args, **kwargs):
Save access and refresh token, If refresh token is issued, remove old refresh tokens as
in rfc:`6`
"""

# Load the AccessToken model
AccessToken = get_access_token_model()

# Load the RefreshToken model
RefreshToken = get_refresh_token_model()

if request.refresh_token:
# remove used refresh token
try:
Expand Down Expand Up @@ -325,6 +335,12 @@ def revoke_token(self, token, token_type_hint, request, *args, **kwargs):
if token_type_hint not in ['access_token', 'refresh_token']:
token_type_hint = None

# Load the AccessToken model
AccessToken = get_access_token_model()

# Load the RefreshToken model
RefreshToken = get_refresh_token_model()

token_types = {
'access_token': AccessToken,
'refresh_token': RefreshToken,
Expand Down Expand Up @@ -359,6 +375,9 @@ def validate_refresh_token(self, refresh_token, client, request, *args, **kwargs
Check refresh_token exists and refers to the right client.
Also attach User instance to the request object
"""
# Load the RefreshToken model
RefreshToken = get_refresh_token_model()

try:
rt = RefreshToken.objects.get(token=refresh_token)
request.user = rt.user
Expand Down
2 changes: 2 additions & 0 deletions oauth2_provider/settings.py
Expand Up @@ -41,6 +41,8 @@
'AUTHORIZATION_CODE_EXPIRE_SECONDS': 60,
'ACCESS_TOKEN_EXPIRE_SECONDS': 36000,
'APPLICATION_MODEL': getattr(settings, 'OAUTH2_PROVIDER_APPLICATION_MODEL', 'oauth2_provider.Application'),
'ACCESS_TOKEN_MODEL': getattr(settings, 'OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL', 'oauth2_provider.AccessToken'),
'REFRESH_TOKEN_MODEL': getattr(settings, 'OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL', 'oauth2_provider.RefreshToken'),
'REQUEST_APPROVAL_PROMPT': 'force',
'ALLOWED_REDIRECT_URI_SCHEMES': ['http', 'https'],

Expand Down
4 changes: 2 additions & 2 deletions oauth2_provider/tests/test_auth_backends.py
Expand Up @@ -7,13 +7,13 @@

from ..compat import get_user_model
from ..models import get_application_model
from ..models import AccessToken
from ..models import get_access_token_model
from ..backends import OAuth2Backend
from ..middleware import OAuth2TokenMiddleware

UserModel = get_user_model()
ApplicationModel = get_application_model()

AccessToken = get_access_token_model()

class BaseTest(TestCase):
"""
Expand Down
4 changes: 3 additions & 1 deletion oauth2_provider/tests/test_authorization_code.py
Expand Up @@ -10,14 +10,16 @@
from django.utils import timezone

from ..compat import urlparse, parse_qs, urlencode, get_user_model
from ..models import get_application_model, Grant, AccessToken, RefreshToken
from ..models import get_application_model, Grant, get_access_token_model, get_refresh_token_model
from ..settings import oauth2_settings
from ..views import ProtectedResourceView

from .test_utils import TestCaseUtils


Application = get_application_model()
AccessToken = get_access_token_model()
RefreshToken = get_access_token_model()
UserModel = get_user_model()


Expand Down
3 changes: 2 additions & 1 deletion oauth2_provider/tests/test_client_credential.py
Expand Up @@ -13,7 +13,7 @@

from oauthlib.oauth2 import BackendApplicationServer

from ..models import get_application_model, AccessToken
from ..models import get_application_model, get_access_token_model
from ..oauth2_backends import OAuthLibCore
from ..oauth2_validators import OAuth2Validator
from ..settings import oauth2_settings
Expand All @@ -24,6 +24,7 @@


Application = get_application_model()
AccessToken = get_access_token_model()
UserModel = get_user_model()


Expand Down
3 changes: 2 additions & 1 deletion oauth2_provider/tests/test_decorators.py
Expand Up @@ -6,12 +6,13 @@

from ..decorators import protected_resource, rw_protected_resource
from ..settings import oauth2_settings
from ..models import get_application_model, AccessToken
from ..models import get_application_model, get_access_token_model
from ..compat import get_user_model
from .test_utils import TestCaseUtils


Application = get_application_model()
AccessToken = get_access_token_model()
UserModel = get_user_model()


Expand Down
4 changes: 3 additions & 1 deletion oauth2_provider/tests/test_models.py
Expand Up @@ -11,11 +11,13 @@
from django.core.exceptions import ValidationError
from django.utils import timezone

from ..models import get_application_model, Grant, AccessToken, RefreshToken
from ..models import get_application_model, Grant, get_access_token_model, get_refresh_token_model
from ..compat import get_user_model


Application = get_application_model()
AccessToken = get_access_token_model()
RefreshToken = get_refresh_token_model()
UserModel = get_user_model()


Expand Down
3 changes: 2 additions & 1 deletion oauth2_provider/tests/test_rest_framework.py
Expand Up @@ -7,12 +7,13 @@


from .test_utils import TestCaseUtils
from ..models import AccessToken, get_application_model
from ..models import get_access_token_model, get_application_model
from ..settings import oauth2_settings
from ..compat import get_user_model


Application = get_application_model()
AccessToken = get_access_token_model()
UserModel = get_user_model()


Expand Down
3 changes: 2 additions & 1 deletion oauth2_provider/tests/test_scopes.py
Expand Up @@ -8,11 +8,12 @@

from .test_utils import TestCaseUtils
from ..compat import urlparse, parse_qs, get_user_model, urlencode
from ..models import get_application_model, Grant, AccessToken
from ..models import get_application_model, Grant, get_access_token_model
from ..settings import oauth2_settings
from ..views import ScopedProtectedResourceView, ReadWriteScopedResourceView

Application = get_application_model()
AccessToken = get_access_token_model()
UserModel = get_user_model()


Expand Down
4 changes: 3 additions & 1 deletion oauth2_provider/tests/test_token_revocation.py
Expand Up @@ -7,13 +7,15 @@
from django.utils import timezone

from ..compat import urlencode, get_user_model
from ..models import get_application_model, AccessToken, RefreshToken
from ..models import get_application_model, get_access_token_model, get_refresh_token_model
from ..settings import oauth2_settings

from .test_utils import TestCaseUtils


Application = get_application_model()
AccessToken = get_access_token_model()
RefreshToken = get_refresh_token_model()
UserModel = get_user_model()


Expand Down

0 comments on commit c91cd35

Please sign in to comment.