From 2f3fc6ea736cee1b4648b6a5f2122d2ee3ac4f73 Mon Sep 17 00:00:00 2001 From: Olivier Sels Date: Fri, 20 Dec 2013 12:26:45 +0100 Subject: [PATCH 1/2] tests for broken related objects with custom Application See issue #90 --- oauth2_provider/tests/models.py | 6 ++++++ oauth2_provider/tests/settings.py | 1 + oauth2_provider/tests/test_models.py | 26 ++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 oauth2_provider/tests/models.py diff --git a/oauth2_provider/tests/models.py b/oauth2_provider/tests/models.py new file mode 100644 index 000000000..27b01d66f --- /dev/null +++ b/oauth2_provider/tests/models.py @@ -0,0 +1,6 @@ +from django.db import models +from oauth2_provider.models import AbstractApplication + + +class TestApplication(AbstractApplication): + custom_field = models.CharField(max_length=255) diff --git a/oauth2_provider/tests/settings.py b/oauth2_provider/tests/settings.py index 19dfa2560..0622090c9 100644 --- a/oauth2_provider/tests/settings.py +++ b/oauth2_provider/tests/settings.py @@ -68,6 +68,7 @@ 'django.contrib.admin', 'oauth2_provider', + 'oauth2_provider.tests', ) LOGGING = { diff --git a/oauth2_provider/tests/test_models.py b/oauth2_provider/tests/test_models.py index 4e5c1a515..0c75211dd 100644 --- a/oauth2_provider/tests/test_models.py +++ b/oauth2_provider/tests/test_models.py @@ -1,6 +1,13 @@ from __future__ import unicode_literals +try: + from unittest import skipIf +except ImportError: + from django.utils.unittest.case import skipIf + +import django from django.test import TestCase +from django.test.utils import override_settings from django.core.exceptions import ValidationError from ..models import AccessToken, get_application_model @@ -60,3 +67,22 @@ def test_grant_implicit_redirect_uris(self): ) self.assertRaises(ValidationError, app.full_clean) + +@skipIf(django.VERSION < (1, 5), "Behavior is broken on 1.4 and there is no solution") +@override_settings(OAUTH2_PROVIDER_APPLICATION_MODEL='tests.TestApplication') +class TestCustomApplicationModel(TestCase): + def setUp(self): + self.user = UserModel.objects.create_user("test_user", "test@user.com", "123456") + + def test_related_objects(self): + """ + If a custom application model is installed, it should be present in + the related objects and not the swapped out one. + + See issue #90 (https://github.com/evonove/django-oauth-toolkit/issues/90) + """ + # Django internals caches the related objects. + del UserModel._meta._related_objects_cache + related_object_names = [ro.name for ro in UserModel._meta.get_all_related_objects()] + self.assertNotIn('oauth2_provider:application', related_object_names) + self.assertIn('tests:testapplication', related_object_names) From a83f19a5d97a979bf29ac1d2cd164001657a7d9d Mon Sep 17 00:00:00 2001 From: Olivier Sels Date: Fri, 20 Dec 2013 12:39:22 +0100 Subject: [PATCH 2/2] Make Application model truly 'swappable' This also introduces a new non-namespaced setting OAUTH2_PROVIDER_APPLICATION_MODEL. --- oauth2_provider/models.py | 3 +++ oauth2_provider/settings.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/oauth2_provider/models.py b/oauth2_provider/models.py index b9d9a3e07..9fbe54f5a 100644 --- a/oauth2_provider/models.py +++ b/oauth2_provider/models.py @@ -109,6 +109,9 @@ def __str__(self): class Application(AbstractApplication): pass +# Add swappable like this to not break django 1.4 compatibility +Application._meta.swappable = 'OAUTH2_PROVIDER_APPLICATION_MODEL' + @python_2_unicode_compatible class Grant(models.Model): diff --git a/oauth2_provider/settings.py b/oauth2_provider/settings.py index eb8c8701a..8e01ec575 100644 --- a/oauth2_provider/settings.py +++ b/oauth2_provider/settings.py @@ -34,7 +34,7 @@ 'WRITE_SCOPE': 'write', 'AUTHORIZATION_CODE_EXPIRE_SECONDS': 60, 'ACCESS_TOKEN_EXPIRE_SECONDS': 36000, - 'APPLICATION_MODEL': 'oauth2_provider.Application', + 'APPLICATION_MODEL': getattr(settings, 'OAUTH2_PROVIDER_APPLICATION_MODEL', 'oauth2_provider.Application'), # Special settings that will be evaluated at runtime '_SCOPES': [],