From 6a8b1faa4f62e7d548448e4d0bd70a71c0812a40 Mon Sep 17 00:00:00 2001 From: Dirk Moors Date: Fri, 22 May 2015 14:01:29 +0200 Subject: [PATCH 01/12] Implemented configurable AccessToken and RefreshToken --- oauth2_provider/admin.py | 4 +- oauth2_provider/models.py | 48 +++++++++++++++++-- oauth2_provider/oauth2_validators.py | 21 +++++++- oauth2_provider/settings.py | 2 + oauth2_provider/tests/test_auth_backends.py | 4 +- .../tests/test_authorization_code.py | 3 +- .../tests/test_client_credential.py | 3 +- oauth2_provider/tests/test_decorators.py | 3 +- oauth2_provider/tests/test_models.py | 4 +- oauth2_provider/tests/test_rest_framework.py | 3 +- oauth2_provider/tests/test_scopes.py | 3 +- .../tests/test_token_revocation.py | 4 +- 12 files changed, 88 insertions(+), 14 deletions(-) diff --git a/oauth2_provider/admin.py b/oauth2_provider/admin.py index d3c764adf..2135877b1 100644 --- a/oauth2_provider/admin.py +++ b/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) diff --git a/oauth2_provider/models.py b/oauth2_provider/models.py index d3091fd2a..4e018aa16 100644 --- a/oauth2_provider/models.py +++ b/oauth2_provider/models.py @@ -165,7 +165,7 @@ def __str__(self): @python_2_unicode_compatible -class AccessToken(models.Model): +class AbstractAccessToken(models.Model): """ An AccessToken instance represents the actual access token to access user's resources, as in :rfc:`5`. @@ -217,8 +217,15 @@ def __str__(self): return self.token +class AccessToken(AbstractAccessToken): + pass + +# Add swappable like this to not break django 1.4 compatibility +AccessToken._meta.swappable = 'OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL' + + @python_2_unicode_compatible -class RefreshToken(models.Model): +class AbstractRefreshToken(models.Model): """ A RefreshToken instance represents a token that can be swapped for a new access token when it expires. @@ -234,13 +241,20 @@ class RefreshToken(models.Model): 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, + access_token = models.OneToOneField(oauth2_settings.ACCESS_TOKEN_MODEL, related_name='refresh_token') def __str__(self): return self.token +class RefreshToken(AbstractRefreshToken): + pass + +# 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. """ try: @@ -253,3 +267,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 diff --git a/oauth2_provider/oauth2_validators.py b/oauth2_provider/oauth2_validators.py index d40dbdfdf..fa29d54e3 100644 --- a/oauth2_provider/oauth2_validators.py +++ b/oauth2_provider/oauth2_validators.py @@ -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') @@ -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) @@ -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: @@ -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, @@ -358,6 +374,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 diff --git a/oauth2_provider/settings.py b/oauth2_provider/settings.py index db5768686..e0a37b937 100644 --- a/oauth2_provider/settings.py +++ b/oauth2_provider/settings.py @@ -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'], diff --git a/oauth2_provider/tests/test_auth_backends.py b/oauth2_provider/tests/test_auth_backends.py index 24944664e..d44f3af41 100644 --- a/oauth2_provider/tests/test_auth_backends.py +++ b/oauth2_provider/tests/test_auth_backends.py @@ -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): """ diff --git a/oauth2_provider/tests/test_authorization_code.py b/oauth2_provider/tests/test_authorization_code.py index 5e437988b..532ab0caf 100644 --- a/oauth2_provider/tests/test_authorization_code.py +++ b/oauth2_provider/tests/test_authorization_code.py @@ -10,7 +10,7 @@ from django.utils import timezone from ..compat import urlparse, parse_qs, urlencode, get_user_model -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 ProtectedResourceView @@ -18,6 +18,7 @@ Application = get_application_model() +AccessToken = get_access_token_model() UserModel = get_user_model() diff --git a/oauth2_provider/tests/test_client_credential.py b/oauth2_provider/tests/test_client_credential.py index 301ae3263..98ef2f930 100644 --- a/oauth2_provider/tests/test_client_credential.py +++ b/oauth2_provider/tests/test_client_credential.py @@ -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 @@ -24,6 +24,7 @@ Application = get_application_model() +AccessToken = get_access_token_model() UserModel = get_user_model() diff --git a/oauth2_provider/tests/test_decorators.py b/oauth2_provider/tests/test_decorators.py index c55b034ba..951af361f 100644 --- a/oauth2_provider/tests/test_decorators.py +++ b/oauth2_provider/tests/test_decorators.py @@ -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() diff --git a/oauth2_provider/tests/test_models.py b/oauth2_provider/tests/test_models.py index 3fbac1969..4c280de2a 100644 --- a/oauth2_provider/tests/test_models.py +++ b/oauth2_provider/tests/test_models.py @@ -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() diff --git a/oauth2_provider/tests/test_rest_framework.py b/oauth2_provider/tests/test_rest_framework.py index ccf4e0b5a..d2767611c 100644 --- a/oauth2_provider/tests/test_rest_framework.py +++ b/oauth2_provider/tests/test_rest_framework.py @@ -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() diff --git a/oauth2_provider/tests/test_scopes.py b/oauth2_provider/tests/test_scopes.py index 76e8ea51a..6fd7ff109 100644 --- a/oauth2_provider/tests/test_scopes.py +++ b/oauth2_provider/tests/test_scopes.py @@ -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() diff --git a/oauth2_provider/tests/test_token_revocation.py b/oauth2_provider/tests/test_token_revocation.py index b9db99e1a..55eb2da4b 100644 --- a/oauth2_provider/tests/test_token_revocation.py +++ b/oauth2_provider/tests/test_token_revocation.py @@ -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() From 77c920858735a0cd4ab91ba41a10ab8480ca9a65 Mon Sep 17 00:00:00 2001 From: Dirk Moors Date: Fri, 22 May 2015 14:15:00 +0200 Subject: [PATCH 02/12] Added correct meta flag to AbstractAccessToken and AbstractRefreshToken --- oauth2_provider/models.py | 56 +++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/oauth2_provider/models.py b/oauth2_provider/models.py index 4e018aa16..5b5599d0d 100644 --- a/oauth2_provider/models.py +++ b/oauth2_provider/models.py @@ -166,25 +166,14 @@ def __str__(self): @python_2_unicode_compatible class AbstractAccessToken(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` Expire time in seconds, defaults to - :data:`settings.ACCESS_TOKEN_EXPIRE_SECONDS` - * :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) 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. @@ -218,7 +207,20 @@ def __str__(self): class AccessToken(AbstractAccessToken): - pass + """ + 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) # Add swappable like this to not break django 1.4 compatibility AccessToken._meta.swappable = 'OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL' @@ -226,6 +228,19 @@ class AccessToken(AbstractAccessToken): @python_2_unicode_compatible class AbstractRefreshToken(models.Model): + user = models.ForeignKey(AUTH_USER_MODEL) + application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL) + access_token = models.OneToOneField(oauth2_settings.ACCESS_TOKEN_MODEL, + related_name='refresh_token') + + class Meta: + abstract = True + + def __str__(self): + return self.token + + +class RefreshToken(AbstractRefreshToken): """ A RefreshToken instance represents a token that can be swapped for a new access token when it expires. @@ -238,18 +253,7 @@ class AbstractRefreshToken(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(oauth2_settings.ACCESS_TOKEN_MODEL, - related_name='refresh_token') - - def __str__(self): - return self.token - - -class RefreshToken(AbstractRefreshToken): - pass # Add swappable like this to not break django 1.4 compatibility RefreshToken._meta.swappable = 'OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL' From 025db21f5c87f88206da9b17bd2995350f527656 Mon Sep 17 00:00:00 2001 From: Dirk Moors Date: Fri, 22 May 2015 14:20:31 +0200 Subject: [PATCH 03/12] Migrated __str__ from abstract classes to concrete classes --- oauth2_provider/models.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/oauth2_provider/models.py b/oauth2_provider/models.py index 5b5599d0d..400d79464 100644 --- a/oauth2_provider/models.py +++ b/oauth2_provider/models.py @@ -202,9 +202,6 @@ def allow_scopes(self, scopes): return resource_scopes.issubset(provided_scopes) - def __str__(self): - return self.token - class AccessToken(AbstractAccessToken): """ @@ -222,6 +219,9 @@ class AccessToken(AbstractAccessToken): """ 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' @@ -236,9 +236,6 @@ class AbstractRefreshToken(models.Model): class Meta: abstract = True - def __str__(self): - return self.token - class RefreshToken(AbstractRefreshToken): """ @@ -255,6 +252,9 @@ class RefreshToken(AbstractRefreshToken): """ 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 RefreshToken._meta.swappable = 'OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL' From 417575b665a2a653a0ec606e4f81ee14517ae701 Mon Sep 17 00:00:00 2001 From: Dirk Moors Date: Fri, 22 May 2015 14:38:06 +0200 Subject: [PATCH 04/12] Moved python_2_unicode_compatible to concrete models --- oauth2_provider/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/oauth2_provider/models.py b/oauth2_provider/models.py index 400d79464..2299c6747 100644 --- a/oauth2_provider/models.py +++ b/oauth2_provider/models.py @@ -164,7 +164,6 @@ def __str__(self): return self.code -@python_2_unicode_compatible class AbstractAccessToken(models.Model): user = models.ForeignKey(AUTH_USER_MODEL, blank=True, null=True) application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL) @@ -203,6 +202,7 @@ def allow_scopes(self, scopes): return resource_scopes.issubset(provided_scopes) +@python_2_unicode_compatible class AccessToken(AbstractAccessToken): """ An AccessToken instance represents the actual access token to @@ -226,7 +226,6 @@ def __str__(self): AccessToken._meta.swappable = 'OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL' -@python_2_unicode_compatible class AbstractRefreshToken(models.Model): user = models.ForeignKey(AUTH_USER_MODEL) application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL) @@ -237,6 +236,7 @@ class Meta: abstract = True +@python_2_unicode_compatible class RefreshToken(AbstractRefreshToken): """ A RefreshToken instance represents a token that can be swapped for a new From 57645932f69e1d357ebd75fa1298d2b0b0fe0272 Mon Sep 17 00:00:00 2001 From: Dirk Moors Date: Fri, 22 May 2015 14:40:14 +0200 Subject: [PATCH 05/12] Added migration for RefreshToken to be able to point to a custom AccessToken --- .../migrations/0002_auto_20150522_1231.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 oauth2_provider/migrations/0002_auto_20150522_1231.py diff --git a/oauth2_provider/migrations/0002_auto_20150522_1231.py b/oauth2_provider/migrations/0002_auto_20150522_1231.py new file mode 100644 index 000000000..4a623db5c --- /dev/null +++ b/oauth2_provider/migrations/0002_auto_20150522_1231.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +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='refreshtoken', + name='access_token', + field=models.OneToOneField(to=settings.OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL, related_name='refresh_token'), + ), + ] From 264d3077a64eff51ba6304a64be5b275e6cb3efa Mon Sep 17 00:00:00 2001 From: Dirk Moors Date: Fri, 22 May 2015 14:43:27 +0200 Subject: [PATCH 06/12] Fixed bug in migration --- oauth2_provider/migrations/0002_auto_20150522_1231.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/oauth2_provider/migrations/0002_auto_20150522_1231.py b/oauth2_provider/migrations/0002_auto_20150522_1231.py index 4a623db5c..39b586ad6 100644 --- a/oauth2_provider/migrations/0002_auto_20150522_1231.py +++ b/oauth2_provider/migrations/0002_auto_20150522_1231.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from django.db import models, migrations -from django.conf import settings +from oauth2_provider.settings import oauth2_settings class Migration(migrations.Migration): @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='refreshtoken', name='access_token', - field=models.OneToOneField(to=settings.OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL, related_name='refresh_token'), + field=models.OneToOneField(to=oauth2_settings.ACCESS_TOKEN_MODEL, related_name='refresh_token'), ), ] From ad739db86203df4c0e5558051d9ad7aedca75dd7 Mon Sep 17 00:00:00 2001 From: Dirk Moors Date: Mon, 25 May 2015 12:24:57 +0200 Subject: [PATCH 07/12] Added related_name to ForeignKey fields --- oauth2_provider/models.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/oauth2_provider/models.py b/oauth2_provider/models.py index 2299c6747..1fbcfaa54 100644 --- a/oauth2_provider/models.py +++ b/oauth2_provider/models.py @@ -165,8 +165,8 @@ def __str__(self): class AbstractAccessToken(models.Model): - user = models.ForeignKey(AUTH_USER_MODEL, blank=True, null=True) - application = models.ForeignKey(oauth2_settings.APPLICATION_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) @@ -227,8 +227,8 @@ def __str__(self): class AbstractRefreshToken(models.Model): - user = models.ForeignKey(AUTH_USER_MODEL) - application = models.ForeignKey(oauth2_settings.APPLICATION_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') From d973813d9848d9715a57b64aea09f5144bd2f9b8 Mon Sep 17 00:00:00 2001 From: Dirk Moors Date: Mon, 25 May 2015 13:52:26 +0200 Subject: [PATCH 08/12] Moved revoke functionality to abstract base classes for RefreshToken and AccessToken --- oauth2_provider/models.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/oauth2_provider/models.py b/oauth2_provider/models.py index 1140aa3db..fbc359232 100644 --- a/oauth2_provider/models.py +++ b/oauth2_provider/models.py @@ -201,6 +201,13 @@ def allow_scopes(self, scopes): return resource_scopes.issubset(provided_scopes) + def revoke(self): + """ + Convenience method to uniform tokens' interface, for now + simply remove this token from the database in order to revoke it. + """ + self.delete() + @python_2_unicode_compatible class AccessToken(AbstractAccessToken): @@ -219,13 +226,6 @@ class AccessToken(AbstractAccessToken): """ token = models.CharField(max_length=255, db_index=True) - def revoke(self): - """ - Convenience method to uniform tokens' interface, for now - simply remove this token from the database in order to revoke it. - """ - self.delete() - def __str__(self): return self.token @@ -242,6 +242,13 @@ class AbstractRefreshToken(models.Model): class Meta: abstract = True + def revoke(self): + """ + Delete this refresh token along with related access token + """ + AccessToken.objects.get(id=self.access_token.id).revoke() + self.delete() + @python_2_unicode_compatible class RefreshToken(AbstractRefreshToken): @@ -259,13 +266,6 @@ class RefreshToken(AbstractRefreshToken): """ token = models.CharField(max_length=255, db_index=True) - 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 From 87446b3e76995d4e4a8333658c7b03e13c555d25 Mon Sep 17 00:00:00 2001 From: Dirk Moors Date: Mon, 25 May 2015 13:53:43 +0200 Subject: [PATCH 09/12] Bugfix --- oauth2_provider/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oauth2_provider/models.py b/oauth2_provider/models.py index fbc359232..beb972099 100644 --- a/oauth2_provider/models.py +++ b/oauth2_provider/models.py @@ -246,7 +246,7 @@ def revoke(self): """ Delete this refresh token along with related access token """ - AccessToken.objects.get(id=self.access_token.id).revoke() + get_access_token_model().objects.get(id=self.access_token.id).revoke() self.delete() From f75ea40cd1459d73f144eaa88e5b6e430410cf60 Mon Sep 17 00:00:00 2001 From: Dirk Moors Date: Tue, 23 Jun 2015 09:58:55 +0200 Subject: [PATCH 10/12] Added new migration --- .../migrations/0002_auto_20150623_0630.py | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 oauth2_provider/migrations/0002_auto_20150623_0630.py diff --git a/oauth2_provider/migrations/0002_auto_20150623_0630.py b/oauth2_provider/migrations/0002_auto_20150623_0630.py new file mode 100644 index 000000000..3f8037cfd --- /dev/null +++ b/oauth2_provider/migrations/0002_auto_20150623_0630.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +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=settings.OAUTH2_PROVIDER_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=settings.OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL), + ), + migrations.AlterField( + model_name='refreshtoken', + name='application', + field=models.ForeignKey(related_name='refreshtoken_set', to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL), + ), + migrations.AlterField( + model_name='refreshtoken', + name='user', + field=models.ForeignKey(related_name='refreshtoken_set', to=settings.AUTH_USER_MODEL), + ), + ] From 6131885ef0fc8e7a6fbfdb0c0dde793186cecb1d Mon Sep 17 00:00:00 2001 From: Dirk Moors Date: Tue, 23 Jun 2015 10:06:58 +0200 Subject: [PATCH 11/12] Fixed migration --- oauth2_provider/migrations/0002_auto_20150623_0630.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/oauth2_provider/migrations/0002_auto_20150623_0630.py b/oauth2_provider/migrations/0002_auto_20150623_0630.py index 3f8037cfd..b290a9bde 100644 --- a/oauth2_provider/migrations/0002_auto_20150623_0630.py +++ b/oauth2_provider/migrations/0002_auto_20150623_0630.py @@ -1,6 +1,7 @@ # -*- 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 @@ -15,7 +16,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='accesstoken', name='application', - field=models.ForeignKey(related_name='accesstoken_set', to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL), + field=models.ForeignKey(related_name='accesstoken_set', to=oauth2_settings.APPLICATION_MODEL), ), migrations.AlterField( model_name='accesstoken', @@ -25,12 +26,12 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='refreshtoken', name='access_token', - field=models.OneToOneField(related_name='refresh_token', to=settings.OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL), + 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=settings.OAUTH2_PROVIDER_APPLICATION_MODEL), + field=models.ForeignKey(related_name='refreshtoken_set', to=oauth2_settings.APPLICATION_MODEL), ), migrations.AlterField( model_name='refreshtoken', From c386f70e47ccbcc54a71399f2f1920cfbf41cf88 Mon Sep 17 00:00:00 2001 From: Dirk Moors Date: Wed, 9 Sep 2015 13:31:55 +0200 Subject: [PATCH 12/12] Fixed migration --- ...to_20150623_0630.py => 0003_auto_20150909_1131.py} | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) rename oauth2_provider/migrations/{0002_auto_20150623_0630.py => 0003_auto_20150909_1131.py} (70%) diff --git a/oauth2_provider/migrations/0002_auto_20150623_0630.py b/oauth2_provider/migrations/0003_auto_20150909_1131.py similarity index 70% rename from oauth2_provider/migrations/0002_auto_20150623_0630.py rename to oauth2_provider/migrations/0003_auto_20150909_1131.py index b290a9bde..75a2db3e1 100644 --- a/oauth2_provider/migrations/0002_auto_20150623_0630.py +++ b/oauth2_provider/migrations/0003_auto_20150909_1131.py @@ -1,7 +1,6 @@ # -*- 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 @@ -9,29 +8,29 @@ class Migration(migrations.Migration): dependencies = [ - ('oauth2_provider', '0001_initial'), + ('oauth2_provider', '0002_08_updates'), ] operations = [ migrations.AlterField( model_name='accesstoken', name='application', - field=models.ForeignKey(related_name='accesstoken_set', to=oauth2_settings.APPLICATION_MODEL), + field=models.ForeignKey(related_name='accesstoken_set', to=settings.OAUTH2_PROVIDER_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'), + field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=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), + field=models.OneToOneField(to=settings.OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL, related_name='refresh_token'), ), migrations.AlterField( model_name='refreshtoken', name='application', - field=models.ForeignKey(related_name='refreshtoken_set', to=oauth2_settings.APPLICATION_MODEL), + field=models.ForeignKey(related_name='refreshtoken_set', to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL), ), migrations.AlterField( model_name='refreshtoken',