diff --git a/common/djangoapps/third_party_auth/admin.py b/common/djangoapps/third_party_auth/admin.py index 3491be6eee..5d29c08246 100644 --- a/common/djangoapps/third_party_auth/admin.py +++ b/common/djangoapps/third_party_auth/admin.py @@ -13,14 +13,23 @@ from .models import ( SAMLConfiguration, SAMLProviderData, LTIProviderConfig, - ProviderApiPermissions + ProviderApiPermissions, + _PSA_OAUTH2_BACKENDS, + _PSA_SAML_BACKENDS ) from .tasks import fetch_saml_metadata from third_party_auth.provider import Registry +class OAuth2ProviderConfigForm(forms.ModelForm): + """ Django Admin form class for OAuth2ProviderConfig """ + backend_name = forms.ChoiceField(choices=((name, name) for name in _PSA_OAUTH2_BACKENDS)) + + class OAuth2ProviderConfigAdmin(KeyedConfigurationModelAdmin): """ Django Admin class for OAuth2ProviderConfig """ + form = OAuth2ProviderConfigForm + def get_list_display(self, request): """ Don't show every single field in the admin change list """ return ( @@ -31,8 +40,15 @@ class OAuth2ProviderConfigAdmin(KeyedConfigurationModelAdmin): admin.site.register(OAuth2ProviderConfig, OAuth2ProviderConfigAdmin) +class SAMLProviderConfigForm(forms.ModelForm): + """ Django Admin form class for SAMLProviderConfig """ + backend_name = forms.ChoiceField(choices=((name, name) for name in _PSA_SAML_BACKENDS)) + + class SAMLProviderConfigAdmin(KeyedConfigurationModelAdmin): """ Django Admin class for SAMLProviderConfig """ + form = SAMLProviderConfigForm + def get_list_display(self, request): """ Don't show every single field in the admin change list """ return ( diff --git a/common/djangoapps/third_party_auth/models.py b/common/djangoapps/third_party_auth/models.py index 5200a92b71..ce76ef20c5 100644 --- a/common/djangoapps/third_party_auth/models.py +++ b/common/djangoapps/third_party_auth/models.py @@ -212,7 +212,7 @@ class OAuth2ProviderConfig(ProviderConfig): prefix = 'oa2' KEY_FIELDS = ('backend_name', ) # Backend name is unique backend_name = models.CharField( - max_length=50, choices=[(name, name) for name in _PSA_OAUTH2_BACKENDS], blank=False, db_index=True, + max_length=50, blank=False, db_index=True, help_text=( "Which python-social-auth OAuth2 provider backend to use. " "The list of backend choices is determined by the THIRD_PARTY_AUTH_BACKENDS setting." @@ -265,7 +265,7 @@ class SAMLProviderConfig(ProviderConfig): prefix = 'saml' KEY_FIELDS = ('idp_slug', ) backend_name = models.CharField( - max_length=50, default='tpa-saml', choices=[(name, name) for name in _PSA_SAML_BACKENDS], blank=False, + max_length=50, default='tpa-saml', blank=False, help_text="Which python-social-auth provider backend to use. 'tpa-saml' is the standard edX SAML backend.") idp_slug = models.SlugField( max_length=30, db_index=True, diff --git a/common/djangoapps/util/tests/test_db.py b/common/djangoapps/util/tests/test_db.py index 603eecd9bb..75895e5e48 100644 --- a/common/djangoapps/util/tests/test_db.py +++ b/common/djangoapps/util/tests/test_db.py @@ -4,13 +4,16 @@ import ddt import threading import time import unittest +from unittest import skipIf from django.contrib.auth.models import User +from django.core.management import call_command +from django.conf import settings from django.db import connection, IntegrityError from django.db.transaction import atomic, TransactionManagementError from django.test import TestCase, TransactionTestCase -from util.db import commit_on_success, generate_int_id, outer_atomic +from util.db import commit_on_success, generate_int_id, outer_atomic, NoOpMigrationModules @ddt.ddt @@ -161,3 +164,17 @@ class GenerateIntIdTestCase(TestCase): for i in range(times): int_id = generate_int_id(minimum, maximum, used_ids) self.assertIn(int_id, list(set(range(minimum, maximum + 1)) - used_ids)) + + +class MigrationTests(TestCase): + """ + Tests for migrations. + """ + @skipIf(isinstance(settings.MIGRATION_MODULES, NoOpMigrationModules), 'Skip in case of NoOpMigrationModules') + def test_migrations_are_in_sync(self): + """ + Tests that the migration files are in sync with the models. + If this fails, you needs to run the Django command makemigrations. + """ + with self.assertRaises(SystemExit): + call_command('makemigrations', '-e') diff --git a/lms/djangoapps/commerce/migrations/0003_auto_20160329_0709.py b/lms/djangoapps/commerce/migrations/0003_auto_20160329_0709.py new file mode 100644 index 0000000000..814d57450f --- /dev/null +++ b/lms/djangoapps/commerce/migrations/0003_auto_20160329_0709.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('commerce', '0002_commerceconfiguration'), + ] + + operations = [ + migrations.AlterModelOptions( + name='commerceconfiguration', + options={}, + ), + ] diff --git a/lms/djangoapps/lti_provider/migrations/0002_auto_20160325_0407.py b/lms/djangoapps/lti_provider/migrations/0002_auto_20160325_0407.py new file mode 100644 index 0000000000..232a1e6c00 --- /dev/null +++ b/lms/djangoapps/lti_provider/migrations/0002_auto_20160325_0407.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import provider.utils + + +class Migration(migrations.Migration): + + dependencies = [ + ('lti_provider', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='lticonsumer', + name='consumer_secret', + field=models.CharField(default=provider.utils.short_token, unique=True, max_length=32), + ), + ] diff --git a/openedx/core/djangoapps/ccxcon/migrations/0002_auto_20160325_0407.py b/openedx/core/djangoapps/ccxcon/migrations/0002_auto_20160325_0407.py new file mode 100644 index 0000000000..ffb6ee7d68 --- /dev/null +++ b/openedx/core/djangoapps/ccxcon/migrations/0002_auto_20160325_0407.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ccxcon', '0001_initial_ccxcon_model'), + ] + + operations = [ + migrations.AlterModelOptions( + name='ccxcon', + options={'verbose_name': 'CCX Connector', 'verbose_name_plural': 'CCX Connectors'}, + ), + ] diff --git a/openedx/core/djangoapps/coursetalk/migrations/0002_auto_20160325_0631.py b/openedx/core/djangoapps/coursetalk/migrations/0002_auto_20160325_0631.py new file mode 100644 index 0000000000..73f04f9065 --- /dev/null +++ b/openedx/core/djangoapps/coursetalk/migrations/0002_auto_20160325_0631.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('coursetalk', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='coursetalkwidgetconfiguration', + name='platform_key', + field=models.CharField(help_text='The platform key associates CourseTalk widgets with your platform. Generally, it is the domain name for your platform. For example, if your platform is http://edx.org, the platform key is "edx".', max_length=50), + ), + ] diff --git a/openedx/core/djangoapps/credentials/migrations/0002_auto_20160325_0631.py b/openedx/core/djangoapps/credentials/migrations/0002_auto_20160325_0631.py new file mode 100644 index 0000000000..5cafeda4e1 --- /dev/null +++ b/openedx/core/djangoapps/credentials/migrations/0002_auto_20160325_0631.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('credentials', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='credentialsapiconfig', + options={}, + ), + ] diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index ca346fed43..bfa8fe06bc 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -39,7 +39,7 @@ djangorestframework-oauth==1.1.0 edx-ccx-keys==0.1.2 edx-lint==0.4.3 edx-management-commands==0.0.1 -edx-django-oauth2-provider==1.0.1 +edx-django-oauth2-provider==1.0.2 edx-oauth2-provider==1.0.0 edx-opaque-keys==0.2.1 edx-organizations==0.4.0