From 42de91fbc1402f916ce03a6ba52b9c61c74f02ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 18:57:15 +0000 Subject: [PATCH 01/23] build(deps): bump actions/setup-python from 2 to 5 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2 to 5. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v2...v5) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 4 ++-- .github/workflows/mysql8-migrations-check.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2c9630fa..b9fc17ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: django-version: ["pinned"] steps: - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} architecture: x64 @@ -41,7 +41,7 @@ jobs: python-version: ["3.12"] steps: - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} architecture: x64 diff --git a/.github/workflows/mysql8-migrations-check.yml b/.github/workflows/mysql8-migrations-check.yml index 914456b1..e3880fc1 100644 --- a/.github/workflows/mysql8-migrations-check.yml +++ b/.github/workflows/mysql8-migrations-check.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@v2 - name: Setup Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} From 853f7c2babc39a74f3423fd455bdc9649a934450 Mon Sep 17 00:00:00 2001 From: edX requirements bot Date: Sun, 22 Sep 2024 22:28:49 -0400 Subject: [PATCH 02/23] chore: Upgrade Python requirements --- requirements/base.txt | 14 ++++++++------ requirements/dev.txt | 19 ++++++++++--------- requirements/doc.txt | 19 ++++++++++--------- requirements/pip.txt | 2 +- requirements/production.txt | 13 +++++++------ requirements/quality.txt | 17 +++++++++-------- requirements/test.txt | 19 ++++++++++--------- requirements/validation.txt | 19 ++++++++++--------- 8 files changed, 65 insertions(+), 57 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index d3e83fd7..58052fb3 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -20,11 +20,11 @@ backoff==1.10.0 # via # -r requirements/base.in # analytics-python -billiard==4.2.0 +billiard==4.2.1 # via celery -boto3==1.35.19 +boto3==1.35.24 # via django-ses -botocore==1.35.19 +botocore==1.35.24 # via # boto3 # s3transfer @@ -187,7 +187,7 @@ jsonschema==4.23.0 # via drf-spectacular jsonschema-specifications==2023.12.1 # via jsonschema -kombu==5.4.1 +kombu==5.4.2 # via celery markupsafe==2.1.5 # via jinja2 @@ -218,7 +218,7 @@ pyjwt[crypto]==2.9.0 # edx-drf-extensions # edx-rest-api-client # social-auth-core -pymongo==4.8.0 +pymongo==4.9.1 # via edx-opaque-keys pynacl==1.5.0 # via edx-django-utils @@ -288,7 +288,9 @@ text-unidecode==1.3 typing-extensions==4.12.2 # via edx-opaque-keys tzdata==2024.1 - # via celery + # via + # celery + # kombu uritemplate==4.1.1 # via drf-spectacular urllib3==2.2.3 diff --git a/requirements/dev.txt b/requirements/dev.txt index 48f397d6..957d8ce7 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -15,7 +15,7 @@ asgiref==3.8.1 # -r requirements/validation.txt # django # django-cors-headers -astroid==3.2.4 +astroid==3.3.3 # via # -r requirements/validation.txt # pylint @@ -29,15 +29,15 @@ backoff==1.10.0 # via # -r requirements/validation.txt # analytics-python -billiard==4.2.0 +billiard==4.2.1 # via # -r requirements/validation.txt # celery -boto3==1.35.19 +boto3==1.35.24 # via # -r requirements/validation.txt # django-ses -botocore==1.35.19 +botocore==1.35.24 # via # -r requirements/validation.txt # boto3 @@ -251,7 +251,7 @@ edx-toggles==5.2.0 # via -r requirements/validation.txt factory-boy==3.3.1 # via -r requirements/validation.txt -faker==28.4.1 +faker==29.0.0 # via # -r requirements/validation.txt # factory-boy @@ -304,7 +304,7 @@ jsonschema-specifications==2023.12.1 # via # -r requirements/validation.txt # jsonschema -kombu==5.4.1 +kombu==5.4.2 # via # -r requirements/validation.txt # celery @@ -362,7 +362,7 @@ pbr==6.1.0 # stevedore pip-tools==7.4.1 # via -r requirements/pip-tools.txt -platformdirs==4.3.3 +platformdirs==4.3.6 # via # -r requirements/validation.txt # pylint @@ -405,7 +405,7 @@ pyjwt[crypto]==2.9.0 # edx-drf-extensions # edx-rest-api-client # social-auth-core -pylint==3.2.7 +pylint==3.3.0 # via # -r requirements/validation.txt # edx-lint @@ -425,7 +425,7 @@ pylint-plugin-utils==0.8.2 # -r requirements/validation.txt # pylint-celery # pylint-django -pymongo==4.8.0 +pymongo==4.9.1 # via # -r requirements/validation.txt # edx-opaque-keys @@ -561,6 +561,7 @@ tzdata==2024.1 # via # -r requirements/validation.txt # celery + # kombu uritemplate==4.1.1 # via # -r requirements/validation.txt diff --git a/requirements/doc.txt b/requirements/doc.txt index f7756a80..61325b85 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -19,7 +19,7 @@ asgiref==3.8.1 # -r requirements/test.txt # django # django-cors-headers -astroid==3.2.4 +astroid==3.3.3 # via # -r requirements/test.txt # pylint @@ -39,15 +39,15 @@ backoff==1.10.0 # analytics-python beautifulsoup4==4.12.3 # via pydata-sphinx-theme -billiard==4.2.0 +billiard==4.2.1 # via # -r requirements/test.txt # celery -boto3==1.35.19 +boto3==1.35.24 # via # -r requirements/test.txt # django-ses -botocore==1.35.19 +botocore==1.35.24 # via # -r requirements/test.txt # boto3 @@ -250,7 +250,7 @@ edx-toggles==5.2.0 # via -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==28.4.1 +faker==29.0.0 # via # -r requirements/test.txt # factory-boy @@ -296,7 +296,7 @@ jsonschema-specifications==2023.12.1 # via # -r requirements/test.txt # jsonschema -kombu==5.4.1 +kombu==5.4.2 # via # -r requirements/test.txt # celery @@ -335,7 +335,7 @@ pbr==6.1.0 # via # -r requirements/test.txt # stevedore -platformdirs==4.3.3 +platformdirs==4.3.6 # via # -r requirements/test.txt # pylint @@ -376,7 +376,7 @@ pyjwt[crypto]==2.9.0 # edx-drf-extensions # edx-rest-api-client # social-auth-core -pylint==3.2.7 +pylint==3.3.0 # via # -r requirements/test.txt # edx-lint @@ -396,7 +396,7 @@ pylint-plugin-utils==0.8.2 # -r requirements/test.txt # pylint-celery # pylint-django -pymongo==4.8.0 +pymongo==4.9.1 # via # -r requirements/test.txt # edx-opaque-keys @@ -545,6 +545,7 @@ tzdata==2024.1 # via # -r requirements/test.txt # celery + # kombu uritemplate==4.1.1 # via # -r requirements/test.txt diff --git a/requirements/pip.txt b/requirements/pip.txt index 15fc7c28..488d41f8 100644 --- a/requirements/pip.txt +++ b/requirements/pip.txt @@ -10,5 +10,5 @@ wheel==0.44.0 # The following packages are considered to be unsafe in a requirements file: pip==24.2 # via -r requirements/pip.in -setuptools==75.0.0 +setuptools==75.1.0 # via -r requirements/pip.in diff --git a/requirements/production.txt b/requirements/production.txt index 81fcb3ec..74132710 100644 --- a/requirements/production.txt +++ b/requirements/production.txt @@ -24,15 +24,15 @@ backoff==1.10.0 # via # -r requirements/base.txt # analytics-python -billiard==4.2.0 +billiard==4.2.1 # via # -r requirements/base.txt # celery -boto3==1.35.19 +boto3==1.35.24 # via # -r requirements/base.txt # django-ses -botocore==1.35.19 +botocore==1.35.24 # via # -r requirements/base.txt # boto3 @@ -205,7 +205,7 @@ edx-toggles==5.2.0 # via -r requirements/base.txt gevent==24.2.1 # via -r requirements/production.in -greenlet==3.1.0 +greenlet==3.1.1 # via gevent gunicorn==23.0.0 # via -r requirements/production.in @@ -238,7 +238,7 @@ jsonschema-specifications==2023.12.1 # via # -r requirements/base.txt # jsonschema -kombu==5.4.1 +kombu==5.4.2 # via # -r requirements/base.txt # celery @@ -293,7 +293,7 @@ pyjwt[crypto]==2.9.0 # social-auth-core pymemcache==4.0.0 # via -r requirements/production.in -pymongo==4.8.0 +pymongo==4.9.1 # via # -r requirements/base.txt # edx-opaque-keys @@ -399,6 +399,7 @@ tzdata==2024.1 # via # -r requirements/base.txt # celery + # kombu uritemplate==4.1.1 # via # -r requirements/base.txt diff --git a/requirements/quality.txt b/requirements/quality.txt index f3db7f88..49954a73 100644 --- a/requirements/quality.txt +++ b/requirements/quality.txt @@ -15,7 +15,7 @@ asgiref==3.8.1 # -r requirements/base.txt # django # django-cors-headers -astroid==3.2.4 +astroid==3.3.3 # via # pylint # pylint-celery @@ -28,15 +28,15 @@ backoff==1.10.0 # via # -r requirements/base.txt # analytics-python -billiard==4.2.0 +billiard==4.2.1 # via # -r requirements/base.txt # celery -boto3==1.35.19 +boto3==1.35.24 # via # -r requirements/base.txt # django-ses -botocore==1.35.19 +botocore==1.35.24 # via # -r requirements/base.txt # boto3 @@ -249,7 +249,7 @@ jsonschema-specifications==2023.12.1 # via # -r requirements/base.txt # jsonschema -kombu==5.4.1 +kombu==5.4.2 # via # -r requirements/base.txt # celery @@ -278,7 +278,7 @@ pbr==6.1.0 # via # -r requirements/base.txt # stevedore -platformdirs==4.3.3 +platformdirs==4.3.6 # via pylint ply==3.11 # via @@ -308,7 +308,7 @@ pyjwt[crypto]==2.9.0 # edx-drf-extensions # edx-rest-api-client # social-auth-core -pylint==3.2.7 +pylint==3.3.0 # via # edx-lint # pylint-celery @@ -322,7 +322,7 @@ pylint-plugin-utils==0.8.2 # via # pylint-celery # pylint-django -pymongo==4.8.0 +pymongo==4.9.1 # via # -r requirements/base.txt # edx-opaque-keys @@ -430,6 +430,7 @@ tzdata==2024.1 # via # -r requirements/base.txt # celery + # kombu uritemplate==4.1.1 # via # -r requirements/base.txt diff --git a/requirements/test.txt b/requirements/test.txt index fb49889f..7b4fda80 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -15,7 +15,7 @@ asgiref==3.8.1 # -r requirements/base.txt # django # django-cors-headers -astroid==3.2.4 +astroid==3.3.3 # via # pylint # pylint-celery @@ -28,15 +28,15 @@ backoff==1.10.0 # via # -r requirements/base.txt # analytics-python -billiard==4.2.0 +billiard==4.2.1 # via # -r requirements/base.txt # celery -boto3==1.35.19 +boto3==1.35.24 # via # -r requirements/base.txt # django-ses -botocore==1.35.19 +botocore==1.35.24 # via # -r requirements/base.txt # boto3 @@ -227,7 +227,7 @@ edx-toggles==5.2.0 # via -r requirements/base.txt factory-boy==3.3.1 # via -r requirements/test.in -faker==28.4.1 +faker==29.0.0 # via factory-boy freezegun==1.5.1 # via -r requirements/test.in @@ -264,7 +264,7 @@ jsonschema-specifications==2023.12.1 # via # -r requirements/base.txt # jsonschema -kombu==5.4.1 +kombu==5.4.2 # via # -r requirements/base.txt # celery @@ -295,7 +295,7 @@ pbr==6.1.0 # via # -r requirements/base.txt # stevedore -platformdirs==4.3.3 +platformdirs==4.3.6 # via pylint pluggy==1.5.0 # via pytest @@ -323,7 +323,7 @@ pyjwt[crypto]==2.9.0 # edx-drf-extensions # edx-rest-api-client # social-auth-core -pylint==3.2.7 +pylint==3.3.0 # via # edx-lint # pylint-celery @@ -337,7 +337,7 @@ pylint-plugin-utils==0.8.2 # via # pylint-celery # pylint-django -pymongo==4.8.0 +pymongo==4.9.1 # via # -r requirements/base.txt # edx-opaque-keys @@ -453,6 +453,7 @@ tzdata==2024.1 # via # -r requirements/base.txt # celery + # kombu uritemplate==4.1.1 # via # -r requirements/base.txt diff --git a/requirements/validation.txt b/requirements/validation.txt index b30b4b4e..e5ebaaec 100644 --- a/requirements/validation.txt +++ b/requirements/validation.txt @@ -19,7 +19,7 @@ asgiref==3.8.1 # -r requirements/test.txt # django # django-cors-headers -astroid==3.2.4 +astroid==3.3.3 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -36,17 +36,17 @@ backoff==1.10.0 # -r requirements/quality.txt # -r requirements/test.txt # analytics-python -billiard==4.2.0 +billiard==4.2.1 # via # -r requirements/quality.txt # -r requirements/test.txt # celery -boto3==1.35.19 +boto3==1.35.24 # via # -r requirements/quality.txt # -r requirements/test.txt # django-ses -botocore==1.35.19 +botocore==1.35.24 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -307,7 +307,7 @@ edx-toggles==5.2.0 # -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==28.4.1 +faker==29.0.0 # via # -r requirements/test.txt # factory-boy @@ -358,7 +358,7 @@ jsonschema-specifications==2023.12.1 # -r requirements/quality.txt # -r requirements/test.txt # jsonschema -kombu==5.4.1 +kombu==5.4.2 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -414,7 +414,7 @@ pbr==6.1.0 # -r requirements/quality.txt # -r requirements/test.txt # stevedore -platformdirs==4.3.3 +platformdirs==4.3.6 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -458,7 +458,7 @@ pyjwt[crypto]==2.9.0 # edx-drf-extensions # edx-rest-api-client # social-auth-core -pylint==3.2.7 +pylint==3.3.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -482,7 +482,7 @@ pylint-plugin-utils==0.8.2 # -r requirements/test.txt # pylint-celery # pylint-django -pymongo==4.8.0 +pymongo==4.9.1 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -636,6 +636,7 @@ tzdata==2024.1 # -r requirements/quality.txt # -r requirements/test.txt # celery + # kombu uritemplate==4.1.1 # via # -r requirements/quality.txt From 3b39ff818888813a9ed75e788098ab4871d5a761 Mon Sep 17 00:00:00 2001 From: muhammad-ammar Date: Fri, 27 Sep 2024 15:23:51 +0500 Subject: [PATCH 03/23] chore: disable too-many-positional-arguments pylint rule --- pylintrc | 3 ++- pylintrc_tweaks | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pylintrc b/pylintrc index d857e0e4..fe450ac8 100644 --- a/pylintrc +++ b/pylintrc @@ -304,6 +304,7 @@ disable = no-member, useless-option-value, unknown-option-value, + too-many-positional-arguments, [REPORTS] output-format = text @@ -400,4 +401,4 @@ int-import-graph = [EXCEPTIONS] overgeneral-exceptions = builtins.Exception -# 2fe5a71dc9c880b7985a7eefc288cd0ada05602f +# fe60e0fc0935adda7e448a1daaa3ef3547352d92 diff --git a/pylintrc_tweaks b/pylintrc_tweaks index b3b778e4..514d4015 100644 --- a/pylintrc_tweaks +++ b/pylintrc_tweaks @@ -23,3 +23,4 @@ disable+ = no-member, useless-option-value, unknown-option-value, + too-many-positional-arguments, From 500cdf851c69a12b029d1e76fb2fe15b28d54853 Mon Sep 17 00:00:00 2001 From: jajjibhai008 Date: Thu, 19 Sep 2024 16:06:01 +0500 Subject: [PATCH 04/23] feat: Add fields related to custom expiration messaging to CustomerAgreement --- license_manager/apps/api/serializers.py | 4 + license_manager/apps/subscriptions/admin.py | 6 +- ...d_subscription_modal_messaging_and_more.py | 53 +++++++++++ license_manager/apps/subscriptions/models.py | 91 +++++++++++++++++-- 4 files changed, 145 insertions(+), 9 deletions(-) create mode 100644 license_manager/apps/subscriptions/migrations/0070_customeragreement_expired_subscription_modal_messaging_and_more.py diff --git a/license_manager/apps/api/serializers.py b/license_manager/apps/api/serializers.py index 2215e073..029036be 100644 --- a/license_manager/apps/api/serializers.py +++ b/license_manager/apps/api/serializers.py @@ -371,6 +371,10 @@ class Meta: model = CustomerAgreement fields = MinimalCustomerAgreementSerializer.Meta.fields + [ 'subscriptions', + 'has_custom_license_expiration_messaging', + 'expired_subscription_modal_messaging', + 'hyper_link_text_for_expired_modal', + 'url_for_expired_modal', ] @property diff --git a/license_manager/apps/subscriptions/admin.py b/license_manager/apps/subscriptions/admin.py index 0879002c..e2924184 100644 --- a/license_manager/apps/subscriptions/admin.py +++ b/license_manager/apps/subscriptions/admin.py @@ -416,7 +416,11 @@ class CustomerAgreementAdmin(admin.ModelAdmin): 'default_enterprise_catalog_uuid', 'disable_expiration_notifications', 'license_duration_before_purge', - 'disable_onboarding_notifications' + 'disable_onboarding_notifications', + 'has_custom_license_expiration_messaging', + 'expired_subscription_modal_messaging', + 'hyper_link_text_for_expired_modal', + 'url_for_expired_modal', ) custom_fields = ('subscription_for_auto_applied_licenses',) diff --git a/license_manager/apps/subscriptions/migrations/0070_customeragreement_expired_subscription_modal_messaging_and_more.py b/license_manager/apps/subscriptions/migrations/0070_customeragreement_expired_subscription_modal_messaging_and_more.py new file mode 100644 index 00000000..d0691e7e --- /dev/null +++ b/license_manager/apps/subscriptions/migrations/0070_customeragreement_expired_subscription_modal_messaging_and_more.py @@ -0,0 +1,53 @@ +# Generated by Django 4.2.16 on 2024-09-27 13:55 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('subscriptions', '0069_alter_customeragreement_disable_expiration_notifications_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='customeragreement', + name='expired_subscription_modal_messaging', + field=models.CharField(blank=True, help_text='The content of a modal that will appear to learners upon subscription expiration. This text can be used for custom guidance per customer.', max_length=512, null=True), + ), + migrations.AddField( + model_name='customeragreement', + name='has_custom_license_expiration_messaging', + field=models.BooleanField(default=False, help_text='Indicates if the customer has a unique license expiration experience, instead of the standard one.'), + ), + migrations.AddField( + model_name='customeragreement', + name='hyper_link_text_for_expired_modal', + field=models.CharField(blank=True, help_text='The display text for the link that will be embedded at the end of the custom expiration modal.', max_length=255, null=True), + ), + migrations.AddField( + model_name='customeragreement', + name='url_for_expired_modal', + field=models.CharField(blank=True, help_text='The underlying url that will be embedded as a hyperlink at the end of the custom expiration modal.', max_length=512, null=True), + ), + migrations.AddField( + model_name='historicalcustomeragreement', + name='expired_subscription_modal_messaging', + field=models.CharField(blank=True, help_text='The content of a modal that will appear to learners upon subscription expiration. This text can be used for custom guidance per customer.', max_length=512, null=True), + ), + migrations.AddField( + model_name='historicalcustomeragreement', + name='has_custom_license_expiration_messaging', + field=models.BooleanField(default=False, help_text='Indicates if the customer has a unique license expiration experience, instead of the standard one.'), + ), + migrations.AddField( + model_name='historicalcustomeragreement', + name='hyper_link_text_for_expired_modal', + field=models.CharField(blank=True, help_text='The display text for the link that will be embedded at the end of the custom expiration modal.', max_length=255, null=True), + ), + migrations.AddField( + model_name='historicalcustomeragreement', + name='url_for_expired_modal', + field=models.CharField(blank=True, help_text='The underlying url that will be embedded as a hyperlink at the end of the custom expiration modal.', max_length=512, null=True), + ), + ] diff --git a/license_manager/apps/subscriptions/models.py b/license_manager/apps/subscriptions/models.py index 933e9aba..355f7913 100644 --- a/license_manager/apps/subscriptions/models.py +++ b/license_manager/apps/subscriptions/models.py @@ -143,6 +143,41 @@ class CustomerAgreement(TimeStampedModel): ), ) + has_custom_license_expiration_messaging = models.BooleanField( + default=False, + help_text=_( + "Indicates if the customer has a unique license expiration experience, instead of the standard one." + ) + ) + + expired_subscription_modal_messaging = models.CharField( + max_length=512, + blank=True, + null=True, + help_text=_( + "The content of a modal that will appear to learners upon subscription expiration. This text can be used " + "for custom guidance per customer." + ) + ) + + hyper_link_text_for_expired_modal = models.CharField( + max_length=255, + blank=True, + null=True, + help_text=_( + "The display text for the link that will be embedded at the end of the custom expiration modal." + ) + ) + + url_for_expired_modal = models.CharField( + max_length=512, + blank=True, + null=True, + help_text=_( + "The underlying url that will be embedded as a hyperlink at the end of the custom expiration modal." + ) + ) + history = HistoricalRecords() @property @@ -192,15 +227,55 @@ class Meta: verbose_name = _("Customer Agreement") verbose_name_plural = _("Customer Agreements") - def __str__(self): - """ - Return human-readable string representation. - """ - return ( - "".format( - self.enterprise_customer_slug or self.enterprise_customer_name + def clean(self): + # Check if custom messaging is enabled and messaging field is blank + if self.has_custom_license_expiration_messaging: + if not self.expired_subscription_modal_messaging: + raise ValidationError({ + "expired_subscription_modal_messaging": ( + "This field cannot be blank if 'Has Custom License Expiration Messaging' is checked." + ) + }) + + # Validate that URL field is not blank if hyperlink text is provided + if self.hyper_link_text_for_expired_modal and not self.url_for_expired_modal: + raise ValidationError({ + "url_for_expired_modal": ( + "This field cannot be blank if 'Hyper Link Text for Expired Modal' has values." + ) + }) + + # Validate that hyperlink text is not blank if URL is provided + if self.url_for_expired_modal and not self.hyper_link_text_for_expired_modal: + raise ValidationError({ + "hyper_link_text_for_expired_modal": ( + "This field cannot be blank if 'URL for Expired Modal' has values." + ) + }) + + # Ensure all fields are blank if custom messaging is disabled + if not self.has_custom_license_expiration_messaging: + if any([ + self.expired_subscription_modal_messaging, + self.hyper_link_text_for_expired_modal, + self.url_for_expired_modal + ]): + error_msg = "This field must be blank if 'Has Custom License Expiration Messaging' is unchecked." + raise ValidationError({ + "expired_subscription_modal_messaging": error_msg, + "hyper_link_text_for_expired_modal": error_msg, + "url_for_expired_modal": error_msg, + }) + + def __str__(self): + """ + Return human-readable string representation. + """ + return ( + "".format( + self.enterprise_customer_slug or self.enterprise_customer_name + ) ) - ) class PlanType(models.Model): From c95878e455cdd37936306d62edbec653f89fa72b Mon Sep 17 00:00:00 2001 From: edX requirements bot Date: Sun, 29 Sep 2024 22:31:17 -0400 Subject: [PATCH 05/23] chore: Upgrade Python requirements --- requirements/base.txt | 12 ++++++------ requirements/dev.txt | 22 +++++++++++----------- requirements/doc.txt | 20 ++++++++++---------- requirements/pip-tools.txt | 2 +- requirements/production.txt | 12 ++++++------ requirements/quality.txt | 18 +++++++++--------- requirements/test.txt | 20 ++++++++++---------- requirements/validation.txt | 20 ++++++++++---------- 8 files changed, 63 insertions(+), 63 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 58052fb3..c1a58f8e 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -22,9 +22,9 @@ backoff==1.10.0 # analytics-python billiard==4.2.1 # via celery -boto3==1.35.24 +boto3==1.35.29 # via django-ses -botocore==1.35.24 +botocore==1.35.29 # via # boto3 # s3transfer @@ -195,7 +195,7 @@ monotonic==1.6 # via analytics-python mysqlclient==2.2.4 # via -r requirements/base.in -newrelic==9.13.0 +newrelic==10.0.0 # via edx-django-utils oauthlib==3.2.2 # via @@ -205,7 +205,7 @@ pbr==6.1.0 # via stevedore ply==3.11 # via djangoql -prompt-toolkit==3.0.47 +prompt-toolkit==3.0.48 # via click-repl psutil==6.0.0 # via edx-django-utils @@ -237,7 +237,7 @@ pyyaml==6.0.2 # via # code-annotations # drf-spectacular -redis==5.0.8 +redis==5.1.0 # via -r requirements/base.in referencing==0.35.1 # via @@ -287,7 +287,7 @@ text-unidecode==1.3 # via python-slugify typing-extensions==4.12.2 # via edx-opaque-keys -tzdata==2024.1 +tzdata==2024.2 # via # celery # kombu diff --git a/requirements/dev.txt b/requirements/dev.txt index 957d8ce7..ab85f868 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -15,7 +15,7 @@ asgiref==3.8.1 # -r requirements/validation.txt # django # django-cors-headers -astroid==3.3.3 +astroid==3.3.4 # via # -r requirements/validation.txt # pylint @@ -33,11 +33,11 @@ billiard==4.2.1 # via # -r requirements/validation.txt # celery -boto3==1.35.24 +boto3==1.35.29 # via # -r requirements/validation.txt # django-ses -botocore==1.35.24 +botocore==1.35.29 # via # -r requirements/validation.txt # boto3 @@ -120,7 +120,7 @@ diff-cover==4.0.0 # via # -c requirements/constraints.txt # -r requirements/dev.in -dill==0.3.8 +dill==0.3.9 # via # -r requirements/validation.txt # pylint @@ -251,7 +251,7 @@ edx-toggles==5.2.0 # via -r requirements/validation.txt factory-boy==3.3.1 # via -r requirements/validation.txt -faker==29.0.0 +faker==30.0.0 # via # -r requirements/validation.txt # factory-boy @@ -333,7 +333,7 @@ more-itertools==10.5.0 # via inflect mysqlclient==2.2.4 # via -r requirements/validation.txt -newrelic==9.13.0 +newrelic==10.0.0 # via # -r requirements/validation.txt # edx-django-utils @@ -379,7 +379,7 @@ polib==1.2.0 # via # -r requirements/validation.txt # edx-i18n-tools -prompt-toolkit==3.0.47 +prompt-toolkit==3.0.48 # via # -r requirements/validation.txt # click-repl @@ -405,7 +405,7 @@ pyjwt[crypto]==2.9.0 # edx-drf-extensions # edx-rest-api-client # social-auth-core -pylint==3.3.0 +pylint==3.3.1 # via # -r requirements/validation.txt # edx-lint @@ -433,7 +433,7 @@ pynacl==1.5.0 # via # -r requirements/validation.txt # edx-django-utils -pyproject-hooks==1.1.0 +pyproject-hooks==1.2.0 # via # -r requirements/pip-tools.txt # build @@ -473,7 +473,7 @@ pyyaml==6.0.2 # code-annotations # drf-spectacular # edx-i18n-tools -redis==5.0.8 +redis==5.1.0 # via -r requirements/validation.txt referencing==0.35.1 # via @@ -557,7 +557,7 @@ typing-extensions==4.12.2 # -r requirements/validation.txt # edx-opaque-keys # typeguard -tzdata==2024.1 +tzdata==2024.2 # via # -r requirements/validation.txt # celery diff --git a/requirements/doc.txt b/requirements/doc.txt index 61325b85..14d2ddaa 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -19,7 +19,7 @@ asgiref==3.8.1 # -r requirements/test.txt # django # django-cors-headers -astroid==3.3.3 +astroid==3.3.4 # via # -r requirements/test.txt # pylint @@ -43,11 +43,11 @@ billiard==4.2.1 # via # -r requirements/test.txt # celery -boto3==1.35.24 +boto3==1.35.29 # via # -r requirements/test.txt # django-ses -botocore==1.35.24 +botocore==1.35.29 # via # -r requirements/test.txt # boto3 @@ -118,7 +118,7 @@ defusedxml==0.8.0rc2 # -r requirements/test.txt # python3-openid # social-auth-core -dill==0.3.8 +dill==0.3.9 # via # -r requirements/test.txt # pylint @@ -250,7 +250,7 @@ edx-toggles==5.2.0 # via -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==29.0.0 +faker==30.0.0 # via # -r requirements/test.txt # factory-boy @@ -314,7 +314,7 @@ monotonic==1.6 # analytics-python mysqlclient==2.2.4 # via -r requirements/test.txt -newrelic==9.13.0 +newrelic==10.0.0 # via # -r requirements/test.txt # edx-django-utils @@ -347,7 +347,7 @@ ply==3.11 # via # -r requirements/test.txt # djangoql -prompt-toolkit==3.0.47 +prompt-toolkit==3.0.48 # via # -r requirements/test.txt # click-repl @@ -376,7 +376,7 @@ pyjwt[crypto]==2.9.0 # edx-drf-extensions # edx-rest-api-client # social-auth-core -pylint==3.3.0 +pylint==3.3.1 # via # -r requirements/test.txt # edx-lint @@ -438,7 +438,7 @@ pyyaml==6.0.2 # drf-spectacular readme-renderer==44.0 # via -r requirements/doc.in -redis==5.0.8 +redis==5.1.0 # via -r requirements/test.txt referencing==0.35.1 # via @@ -541,7 +541,7 @@ typing-extensions==4.12.2 # -r requirements/test.txt # edx-opaque-keys # pydata-sphinx-theme -tzdata==2024.1 +tzdata==2024.2 # via # -r requirements/test.txt # celery diff --git a/requirements/pip-tools.txt b/requirements/pip-tools.txt index e6268ff6..8c9fbc8d 100644 --- a/requirements/pip-tools.txt +++ b/requirements/pip-tools.txt @@ -12,7 +12,7 @@ packaging==24.1 # via build pip-tools==7.4.1 # via -r requirements/pip-tools.in -pyproject-hooks==1.1.0 +pyproject-hooks==1.2.0 # via # build # pip-tools diff --git a/requirements/production.txt b/requirements/production.txt index 74132710..8469d71b 100644 --- a/requirements/production.txt +++ b/requirements/production.txt @@ -28,11 +28,11 @@ billiard==4.2.1 # via # -r requirements/base.txt # celery -boto3==1.35.24 +boto3==1.35.29 # via # -r requirements/base.txt # django-ses -botocore==1.35.24 +botocore==1.35.29 # via # -r requirements/base.txt # boto3 @@ -252,7 +252,7 @@ monotonic==1.6 # analytics-python mysqlclient==2.2.4 # via -r requirements/base.txt -newrelic==9.13.0 +newrelic==10.0.0 # via # -r requirements/base.txt # edx-django-utils @@ -271,7 +271,7 @@ ply==3.11 # via # -r requirements/base.txt # djangoql -prompt-toolkit==3.0.47 +prompt-toolkit==3.0.48 # via # -r requirements/base.txt # click-repl @@ -325,7 +325,7 @@ pyyaml==6.0.2 # -r requirements/production.in # code-annotations # drf-spectacular -redis==5.0.8 +redis==5.1.0 # via -r requirements/base.txt referencing==0.35.1 # via @@ -395,7 +395,7 @@ typing-extensions==4.12.2 # via # -r requirements/base.txt # edx-opaque-keys -tzdata==2024.1 +tzdata==2024.2 # via # -r requirements/base.txt # celery diff --git a/requirements/quality.txt b/requirements/quality.txt index 49954a73..0c317cf8 100644 --- a/requirements/quality.txt +++ b/requirements/quality.txt @@ -15,7 +15,7 @@ asgiref==3.8.1 # -r requirements/base.txt # django # django-cors-headers -astroid==3.3.3 +astroid==3.3.4 # via # pylint # pylint-celery @@ -32,11 +32,11 @@ billiard==4.2.1 # via # -r requirements/base.txt # celery -boto3==1.35.24 +boto3==1.35.29 # via # -r requirements/base.txt # django-ses -botocore==1.35.24 +botocore==1.35.29 # via # -r requirements/base.txt # boto3 @@ -99,7 +99,7 @@ defusedxml==0.8.0rc2 # -r requirements/base.txt # python3-openid # social-auth-core -dill==0.3.8 +dill==0.3.9 # via pylint django==4.2.16 # via @@ -265,7 +265,7 @@ monotonic==1.6 # analytics-python mysqlclient==2.2.4 # via -r requirements/base.txt -newrelic==9.13.0 +newrelic==10.0.0 # via # -r requirements/base.txt # edx-django-utils @@ -284,7 +284,7 @@ ply==3.11 # via # -r requirements/base.txt # djangoql -prompt-toolkit==3.0.47 +prompt-toolkit==3.0.48 # via # -r requirements/base.txt # click-repl @@ -308,7 +308,7 @@ pyjwt[crypto]==2.9.0 # edx-drf-extensions # edx-rest-api-client # social-auth-core -pylint==3.3.0 +pylint==3.3.1 # via # edx-lint # pylint-celery @@ -351,7 +351,7 @@ pyyaml==6.0.2 # -r requirements/base.txt # code-annotations # drf-spectacular -redis==5.0.8 +redis==5.1.0 # via -r requirements/base.txt referencing==0.35.1 # via @@ -426,7 +426,7 @@ typing-extensions==4.12.2 # via # -r requirements/base.txt # edx-opaque-keys -tzdata==2024.1 +tzdata==2024.2 # via # -r requirements/base.txt # celery diff --git a/requirements/test.txt b/requirements/test.txt index 7b4fda80..8beeb5b2 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -15,7 +15,7 @@ asgiref==3.8.1 # -r requirements/base.txt # django # django-cors-headers -astroid==3.3.3 +astroid==3.3.4 # via # pylint # pylint-celery @@ -32,11 +32,11 @@ billiard==4.2.1 # via # -r requirements/base.txt # celery -boto3==1.35.24 +boto3==1.35.29 # via # -r requirements/base.txt # django-ses -botocore==1.35.24 +botocore==1.35.29 # via # -r requirements/base.txt # boto3 @@ -106,7 +106,7 @@ defusedxml==0.8.0rc2 # -r requirements/base.txt # python3-openid # social-auth-core -dill==0.3.8 +dill==0.3.9 # via pylint django==4.2.16 # via @@ -227,7 +227,7 @@ edx-toggles==5.2.0 # via -r requirements/base.txt factory-boy==3.3.1 # via -r requirements/test.in -faker==29.0.0 +faker==30.0.0 # via factory-boy freezegun==1.5.1 # via -r requirements/test.in @@ -280,7 +280,7 @@ monotonic==1.6 # analytics-python mysqlclient==2.2.4 # via -r requirements/base.txt -newrelic==9.13.0 +newrelic==10.0.0 # via # -r requirements/base.txt # edx-django-utils @@ -303,7 +303,7 @@ ply==3.11 # via # -r requirements/base.txt # djangoql -prompt-toolkit==3.0.47 +prompt-toolkit==3.0.48 # via # -r requirements/base.txt # click-repl @@ -323,7 +323,7 @@ pyjwt[crypto]==2.9.0 # edx-drf-extensions # edx-rest-api-client # social-auth-core -pylint==3.3.0 +pylint==3.3.1 # via # edx-lint # pylint-celery @@ -376,7 +376,7 @@ pyyaml==6.0.2 # -r requirements/base.txt # code-annotations # drf-spectacular -redis==5.0.8 +redis==5.1.0 # via -r requirements/base.txt referencing==0.35.1 # via @@ -449,7 +449,7 @@ typing-extensions==4.12.2 # via # -r requirements/base.txt # edx-opaque-keys -tzdata==2024.1 +tzdata==2024.2 # via # -r requirements/base.txt # celery diff --git a/requirements/validation.txt b/requirements/validation.txt index e5ebaaec..b1023d6d 100644 --- a/requirements/validation.txt +++ b/requirements/validation.txt @@ -19,7 +19,7 @@ asgiref==3.8.1 # -r requirements/test.txt # django # django-cors-headers -astroid==3.3.3 +astroid==3.3.4 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -41,12 +41,12 @@ billiard==4.2.1 # -r requirements/quality.txt # -r requirements/test.txt # celery -boto3==1.35.24 +boto3==1.35.29 # via # -r requirements/quality.txt # -r requirements/test.txt # django-ses -botocore==1.35.24 +botocore==1.35.29 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -130,7 +130,7 @@ defusedxml==0.8.0rc2 # -r requirements/test.txt # python3-openid # social-auth-core -dill==0.3.8 +dill==0.3.9 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -307,7 +307,7 @@ edx-toggles==5.2.0 # -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==29.0.0 +faker==30.0.0 # via # -r requirements/test.txt # factory-boy @@ -388,7 +388,7 @@ mysqlclient==2.2.4 # via # -r requirements/quality.txt # -r requirements/test.txt -newrelic==9.13.0 +newrelic==10.0.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -430,7 +430,7 @@ ply==3.11 # djangoql polib==1.2.0 # via edx-i18n-tools -prompt-toolkit==3.0.47 +prompt-toolkit==3.0.48 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -458,7 +458,7 @@ pyjwt[crypto]==2.9.0 # edx-drf-extensions # edx-rest-api-client # social-auth-core -pylint==3.3.0 +pylint==3.3.1 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -531,7 +531,7 @@ pyyaml==6.0.2 # code-annotations # drf-spectacular # edx-i18n-tools -redis==5.0.8 +redis==5.1.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -631,7 +631,7 @@ typing-extensions==4.12.2 # -r requirements/quality.txt # -r requirements/test.txt # edx-opaque-keys -tzdata==2024.1 +tzdata==2024.2 # via # -r requirements/quality.txt # -r requirements/test.txt From 87b88f3c4043067c340910912deca11893a8120c Mon Sep 17 00:00:00 2001 From: jajjibhai008 Date: Tue, 1 Oct 2024 12:10:45 +0500 Subject: [PATCH 06/23] feat: make customer agreements fields available in learner license endpoint --- license_manager/apps/api/serializers.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/license_manager/apps/api/serializers.py b/license_manager/apps/api/serializers.py index 029036be..10d7d1a5 100644 --- a/license_manager/apps/api/serializers.py +++ b/license_manager/apps/api/serializers.py @@ -354,6 +354,10 @@ class Meta: 'net_days_until_expiration', 'subscription_for_auto_applied_licenses', 'available_subscription_catalogs', + 'has_custom_license_expiration_messaging', + 'expired_subscription_modal_messaging', + 'hyper_link_text_for_expired_modal', + 'url_for_expired_modal', ] def get_subscription_for_auto_applied_licenses(self, obj): @@ -371,10 +375,6 @@ class Meta: model = CustomerAgreement fields = MinimalCustomerAgreementSerializer.Meta.fields + [ 'subscriptions', - 'has_custom_license_expiration_messaging', - 'expired_subscription_modal_messaging', - 'hyper_link_text_for_expired_modal', - 'url_for_expired_modal', ] @property From 05e3b605748c5c9bab2da046652652bcbed5b2f3 Mon Sep 17 00:00:00 2001 From: MueezKhan246 Date: Mon, 30 Sep 2024 12:23:32 +0500 Subject: [PATCH 07/23] feat: added 423 status in api yaml file --- api.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api.yaml b/api.yaml index 10cc98a0..2127d01c 100644 --- a/api.yaml +++ b/api.yaml @@ -224,6 +224,8 @@ endpoints: description: Forbidden "404": description: Not Found + "423": + description: Locked "429": description: Too Many Requests "500": @@ -240,6 +242,8 @@ endpoints: statusCode: "403" "404": statusCode: "404" + "423": + statusCode: "423" "429": statusCode: "429" "500": From 0ab5fdc0a585b8ab8907b212c584247581a3a3b3 Mon Sep 17 00:00:00 2001 From: MueezKhan246 Date: Mon, 30 Sep 2024 17:54:28 +0500 Subject: [PATCH 08/23] feat: added 423 status for assign endpoint in api-compact for proper generation of api.yaml --- api-compact.yaml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/api-compact.yaml b/api-compact.yaml index df0eaa6c..0e87b16f 100644 --- a/api-compact.yaml +++ b/api-compact.yaml @@ -237,9 +237,15 @@ endpoints: notify_users: description: "Send license assignment email or not." type: "boolean" - responses: *responses + responses: + <<: *responses + 423: + description: "Locked" x-amazon-apigateway-integration: - responses: *apigateway_responses + responses: + <<: *apigateway_responses + 423: + statusCode: "423" httpMethod: "POST" type: "http" requestParameters: From ae79fc7b7a6a4f45689c4a886e95a3c0a2a8022d Mon Sep 17 00:00:00 2001 From: MueezKhan246 Date: Mon, 30 Sep 2024 20:01:56 +0500 Subject: [PATCH 09/23] feat: defined 423 at apigateway_responses and response level --- api-compact.yaml | 14 ++++++-------- api.yaml | 8 ++++++++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/api-compact.yaml b/api-compact.yaml index 0e87b16f..fe125309 100644 --- a/api-compact.yaml +++ b/api-compact.yaml @@ -24,6 +24,8 @@ apigateway_responses: &apigateway_responses statusCode: "403" 404: statusCode: "404" + 423: + statusCode: "423" 429: statusCode: "429" 500: @@ -112,6 +114,8 @@ responses: &responses description: "Forbidden" 404: description: "Not Found" + 423: + description: "Locked" 429: description: "Too Many Requests" 500: @@ -237,15 +241,9 @@ endpoints: notify_users: description: "Send license assignment email or not." type: "boolean" - responses: - <<: *responses - 423: - description: "Locked" + responses: *responses x-amazon-apigateway-integration: - responses: - <<: *apigateway_responses - 423: - statusCode: "423" + responses: *apigateway_responses httpMethod: "POST" type: "http" requestParameters: diff --git a/api.yaml b/api.yaml index 2127d01c..f9f65b59 100644 --- a/api.yaml +++ b/api.yaml @@ -13,6 +13,8 @@ apigateway_responses: statusCode: "403" "404": statusCode: "404" + "423": + statusCode: "423" "429": statusCode: "429" "500": @@ -92,6 +94,8 @@ responses: description: Forbidden "404": description: Not Found + "423": + description: Locked "429": description: Too Many Requests "500": @@ -384,6 +388,8 @@ endpoints: description: Forbidden "404": description: Not Found + "423": + description: Locked "429": description: Too Many Requests "500": @@ -400,6 +406,8 @@ endpoints: statusCode: "403" "404": statusCode: "404" + "423": + statusCode: "423" "429": statusCode: "429" "500": From 05a9423ecaccd37cc38578f826e379ac4fdc3eae Mon Sep 17 00:00:00 2001 From: Hamzah Ullah Date: Mon, 7 Oct 2024 12:03:20 -0400 Subject: [PATCH 10/23] feat: Add field to allow auto-apply without SSO (#718) --- license_manager/apps/api/serializers.py | 1 + license_manager/apps/subscriptions/admin.py | 1 + .../apps/subscriptions/constants.py | 8 +++++++ license_manager/apps/subscriptions/forms.py | 15 +++++++++--- ...scriptions_with_universal_link_and_more.py | 23 +++++++++++++++++++ license_manager/apps/subscriptions/models.py | 11 +++++++++ .../apps/subscriptions/tests/factories.py | 1 + .../apps/subscriptions/tests/test_admin.py | 5 +++- .../apps/subscriptions/tests/test_forms.py | 3 ++- pylintrc | 4 ++-- 10 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 license_manager/apps/subscriptions/migrations/0071_customeragreement_enable_auto_applied_subscriptions_with_universal_link_and_more.py diff --git a/license_manager/apps/api/serializers.py b/license_manager/apps/api/serializers.py index 10d7d1a5..38a56e78 100644 --- a/license_manager/apps/api/serializers.py +++ b/license_manager/apps/api/serializers.py @@ -358,6 +358,7 @@ class Meta: 'expired_subscription_modal_messaging', 'hyper_link_text_for_expired_modal', 'url_for_expired_modal', + 'enable_auto_applied_subscriptions_with_universal_link' ] def get_subscription_for_auto_applied_licenses(self, obj): diff --git a/license_manager/apps/subscriptions/admin.py b/license_manager/apps/subscriptions/admin.py index e2924184..0697816a 100644 --- a/license_manager/apps/subscriptions/admin.py +++ b/license_manager/apps/subscriptions/admin.py @@ -421,6 +421,7 @@ class CustomerAgreementAdmin(admin.ModelAdmin): 'expired_subscription_modal_messaging', 'hyper_link_text_for_expired_modal', 'url_for_expired_modal', + 'enable_auto_applied_subscriptions_with_universal_link' ) custom_fields = ('subscription_for_auto_applied_licenses',) diff --git a/license_manager/apps/subscriptions/constants.py b/license_manager/apps/subscriptions/constants.py index 492e3501..8782e9c7 100644 --- a/license_manager/apps/subscriptions/constants.py +++ b/license_manager/apps/subscriptions/constants.py @@ -25,6 +25,14 @@ class LicenseTypesToRenew: ) +class SubscriptionPlanShouldAutoApplyLicensesChoices: + CHOICES = ( + (None, "----------"), + (True, "Yes"), + (False, "No") + ) + + class SubscriptionPlanChangeReasonChoices: NONE = None NEW = "new" diff --git a/license_manager/apps/subscriptions/forms.py b/license_manager/apps/subscriptions/forms.py index e6324795..4e96753e 100644 --- a/license_manager/apps/subscriptions/forms.py +++ b/license_manager/apps/subscriptions/forms.py @@ -19,6 +19,7 @@ MAX_NUM_LICENSES, MIN_NUM_LICENSES, SubscriptionPlanChangeReasonChoices, + SubscriptionPlanShouldAutoApplyLicensesChoices, ) from license_manager.apps.subscriptions.models import ( CustomerAgreement, @@ -40,6 +41,14 @@ class SubscriptionPlanForm(forms.ModelForm): """ Form used for the SubscriptionPlan admin class. """ + + should_auto_apply_licenses = forms.ChoiceField( + choices=SubscriptionPlanShouldAutoApplyLicensesChoices.CHOICES, + required=False, + label="Should auto apply licenses", + help_text="Whether licenses from this Subscription Plan should be auto applied." + ) + # Extra form field to specify the number of licenses to be associated with the subscription plan num_licenses = forms.IntegerField( label="Number of Licenses", @@ -276,15 +285,15 @@ def populate_subscription_for_auto_applied_licenses_choices(self, instance): start_date__lte=now, expiration_date__gte=now ) - current_plan = instance.auto_applicable_subscription - empty_choice = ('', '------') choices = [empty_choice] + [(plan.uuid, plan.title) for plan in active_plans] choice_field = forms.ChoiceField( choices=choices, required=False, - initial=empty_choice if not current_plan else (current_plan.uuid, current_plan.title) + initial=empty_choice if not current_plan else (current_plan.uuid, current_plan.title), + help_text="The subscription plan to be associated with auto apply licenses. Selecting a license" + " will automatically enable the \"Should auto apply licenses\" field on the subscription plan" ) self.fields['subscription_for_auto_applied_licenses'] = choice_field diff --git a/license_manager/apps/subscriptions/migrations/0071_customeragreement_enable_auto_applied_subscriptions_with_universal_link_and_more.py b/license_manager/apps/subscriptions/migrations/0071_customeragreement_enable_auto_applied_subscriptions_with_universal_link_and_more.py new file mode 100644 index 00000000..67d12885 --- /dev/null +++ b/license_manager/apps/subscriptions/migrations/0071_customeragreement_enable_auto_applied_subscriptions_with_universal_link_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.16 on 2024-10-07 15:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('subscriptions', '0070_customeragreement_expired_subscription_modal_messaging_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='customeragreement', + name='enable_auto_applied_subscriptions_with_universal_link', + field=models.BooleanField(default=False, help_text='By default, auto-applied subscriptions are only granted when learners join their enterprise via SSO, checking this box will enable subscription licenses to be applied when a learner joins the enterprise via Universal link as well'), + ), + migrations.AddField( + model_name='historicalcustomeragreement', + name='enable_auto_applied_subscriptions_with_universal_link', + field=models.BooleanField(default=False, help_text='By default, auto-applied subscriptions are only granted when learners join their enterprise via SSO, checking this box will enable subscription licenses to be applied when a learner joins the enterprise via Universal link as well'), + ), + ] diff --git a/license_manager/apps/subscriptions/models.py b/license_manager/apps/subscriptions/models.py index 355f7913..edffda87 100644 --- a/license_manager/apps/subscriptions/models.py +++ b/license_manager/apps/subscriptions/models.py @@ -178,6 +178,15 @@ class CustomerAgreement(TimeStampedModel): ) ) + enable_auto_applied_subscriptions_with_universal_link = models.BooleanField( + default=False, + help_text=_( + "By default, auto-applied subscriptions are only granted when learners join their enterprise via SSO, " + "checking this box will enable subscription licenses to be applied when a learner joins the enterprise via " + "Universal link as well" + ) + ) + history = HistoricalRecords() @property @@ -596,6 +605,7 @@ def num_revocations_remaining(self): num_revocations_allowed = ceil(self.num_licenses * (self.revoke_max_percentage / 100)) return num_revocations_allowed - self.num_revocations_applied + num_revocations_remaining.fget.short_description = "Number of Revocations Remaining" @property @@ -1036,6 +1046,7 @@ class License(TimeStampedModel): .. pii_types: id,email_address .. pii_retirement: local_api """ + class Meta: indexes = [ models.Index(fields=["subscription_plan", "status"], name="subscription_plan_status_idx"), diff --git a/license_manager/apps/subscriptions/tests/factories.py b/license_manager/apps/subscriptions/tests/factories.py index 96db577c..02aa39a7 100644 --- a/license_manager/apps/subscriptions/tests/factories.py +++ b/license_manager/apps/subscriptions/tests/factories.py @@ -54,6 +54,7 @@ class Meta: default_enterprise_catalog_uuid = factory.LazyFunction(uuid4) enterprise_customer_name = factory.LazyAttribute(lambda x: FAKER.company()) disable_onboarding_notifications = False + enable_auto_applied_subscriptions_with_universal_link = False class PlanTypeFactory(factory.django.DjangoModelFactory): diff --git a/license_manager/apps/subscriptions/tests/test_admin.py b/license_manager/apps/subscriptions/tests/test_admin.py index e2bab224..019db949 100644 --- a/license_manager/apps/subscriptions/tests/test_admin.py +++ b/license_manager/apps/subscriptions/tests/test_admin.py @@ -114,7 +114,10 @@ def test_select_subscription_for_auto_applied_licenses(mock_toggle_auto_apply_li request = RequestFactory() request.user = UserFactory() customer_agreement = CustomerAgreementFactory() - subscription_plan = SubscriptionPlanFactory(customer_agreement=customer_agreement) + subscription_plan = SubscriptionPlanFactory( + customer_agreement=customer_agreement, + ) + customer_agreement_uuid = str(customer_agreement.uuid) subscription_uuid = str(subscription_plan.uuid) request.resolver_match = mock.Mock(kwargs={'object_id': customer_agreement_uuid}) diff --git a/license_manager/apps/subscriptions/tests/test_forms.py b/license_manager/apps/subscriptions/tests/test_forms.py index c7154ba8..6563e871 100644 --- a/license_manager/apps/subscriptions/tests/test_forms.py +++ b/license_manager/apps/subscriptions/tests/test_forms.py @@ -241,10 +241,11 @@ def test_populate_subscription_for_auto_applied_licenses_choices(self): field = form.fields['subscription_for_auto_applied_licenses'] choices = field.choices + initial = field.initial self.assertEqual(len(choices), 2) self.assertEqual(choices[0], ('', '------')) self.assertEqual(choices[1], (active_subscription_plan.uuid, active_subscription_plan.title)) - self.assertEqual(field.initial, ('', '------')) + self.assertEqual(initial, ('', '------')) def test_populate_subscription_for_auto_applied_licenses_choices_initial_choice(self): customer_agreement = CustomerAgreementFactory() diff --git a/pylintrc b/pylintrc index fe450ac8..6edf14d3 100644 --- a/pylintrc +++ b/pylintrc @@ -64,7 +64,7 @@ # SERIOUSLY. # # ------------------------------ -# Generated by edx-lint version: 5.3.6 +# Generated by edx-lint version: 5.4.0 # ------------------------------ [MASTER] ignore = ,migrations, settings, wsgi.py @@ -401,4 +401,4 @@ int-import-graph = [EXCEPTIONS] overgeneral-exceptions = builtins.Exception -# fe60e0fc0935adda7e448a1daaa3ef3547352d92 +# ea586deca5871e992466c748232382f9dfadff18 From 358908ee5504200b9834f29742f39c65636f541c Mon Sep 17 00:00:00 2001 From: edX requirements bot Date: Sun, 6 Oct 2024 22:30:22 -0400 Subject: [PATCH 11/23] chore: Upgrade Python requirements --- requirements/base.txt | 14 +++++++------- requirements/dev.txt | 21 +++++++++++---------- requirements/doc.txt | 19 ++++++++++--------- requirements/pip-tools.txt | 2 +- requirements/production.txt | 14 +++++++------- requirements/quality.txt | 16 ++++++++-------- requirements/test.txt | 19 ++++++++++--------- requirements/validation.txt | 19 ++++++++++--------- 8 files changed, 64 insertions(+), 60 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index c1a58f8e..8c3f77b4 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -22,9 +22,9 @@ backoff==1.10.0 # analytics-python billiard==4.2.1 # via celery -boto3==1.35.29 +boto3==1.35.34 # via django-ses -botocore==1.35.29 +botocore==1.35.34 # via # boto3 # s3transfer @@ -117,7 +117,7 @@ django-model-utils==5.0.0 # -r requirements/base.in # edx-celeryutils # edx-rbac -django-ses==4.1.1 +django-ses==4.2.0 # via -r requirements/base.in django-simple-history==3.7.0 # via -r requirements/base.in @@ -139,7 +139,7 @@ djangorestframework==3.15.2 # edx-drf-extensions djangorestframework-csv==3.0.2 # via -r requirements/base.in -dnspython==2.6.1 +dnspython==2.7.0 # via pymongo drf-jwt==1.19.2 # via edx-drf-extensions @@ -153,7 +153,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.in edx-celeryutils==1.3.0 # via -r requirements/base.in -edx-django-utils==5.15.0 +edx-django-utils==5.16.0 # via # -r requirements/base.in # edx-drf-extensions @@ -218,7 +218,7 @@ pyjwt[crypto]==2.9.0 # edx-drf-extensions # edx-rest-api-client # social-auth-core -pymongo==4.9.1 +pymongo==4.10.1 # via edx-opaque-keys pynacl==1.5.0 # via edx-django-utils @@ -237,7 +237,7 @@ pyyaml==6.0.2 # via # code-annotations # drf-spectacular -redis==5.1.0 +redis==5.1.1 # via -r requirements/base.in referencing==0.35.1 # via diff --git a/requirements/dev.txt b/requirements/dev.txt index ab85f868..6101d291 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -15,7 +15,7 @@ asgiref==3.8.1 # -r requirements/validation.txt # django # django-cors-headers -astroid==3.3.4 +astroid==3.3.5 # via # -r requirements/validation.txt # pylint @@ -33,16 +33,16 @@ billiard==4.2.1 # via # -r requirements/validation.txt # celery -boto3==1.35.29 +boto3==1.35.34 # via # -r requirements/validation.txt # django-ses -botocore==1.35.29 +botocore==1.35.34 # via # -r requirements/validation.txt # boto3 # s3transfer -build==1.2.2 +build==1.2.2.post1 # via # -r requirements/pip-tools.txt # pip-tools @@ -185,7 +185,7 @@ django-model-utils==5.0.0 # -r requirements/validation.txt # edx-celeryutils # edx-rbac -django-ses==4.1.1 +django-ses==4.2.0 # via -r requirements/validation.txt django-simple-history==3.7.0 # via -r requirements/validation.txt @@ -207,7 +207,7 @@ djangorestframework==3.15.2 # edx-drf-extensions djangorestframework-csv==3.0.2 # via -r requirements/validation.txt -dnspython==2.6.1 +dnspython==2.7.0 # via # -r requirements/validation.txt # pymongo @@ -225,7 +225,7 @@ edx-braze-client==0.2.5 # via -r requirements/validation.txt edx-celeryutils==1.3.0 # via -r requirements/validation.txt -edx-django-utils==5.15.0 +edx-django-utils==5.16.0 # via # -r requirements/validation.txt # edx-drf-extensions @@ -251,7 +251,7 @@ edx-toggles==5.2.0 # via -r requirements/validation.txt factory-boy==3.3.1 # via -r requirements/validation.txt -faker==30.0.0 +faker==30.1.0 # via # -r requirements/validation.txt # factory-boy @@ -425,7 +425,7 @@ pylint-plugin-utils==0.8.2 # -r requirements/validation.txt # pylint-celery # pylint-django -pymongo==4.9.1 +pymongo==4.10.1 # via # -r requirements/validation.txt # edx-opaque-keys @@ -473,7 +473,7 @@ pyyaml==6.0.2 # code-annotations # drf-spectacular # edx-i18n-tools -redis==5.1.0 +redis==5.1.1 # via -r requirements/validation.txt referencing==0.35.1 # via @@ -556,6 +556,7 @@ typing-extensions==4.12.2 # via # -r requirements/validation.txt # edx-opaque-keys + # faker # typeguard tzdata==2024.2 # via diff --git a/requirements/doc.txt b/requirements/doc.txt index 14d2ddaa..662ea20b 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -19,7 +19,7 @@ asgiref==3.8.1 # -r requirements/test.txt # django # django-cors-headers -astroid==3.3.4 +astroid==3.3.5 # via # -r requirements/test.txt # pylint @@ -43,11 +43,11 @@ billiard==4.2.1 # via # -r requirements/test.txt # celery -boto3==1.35.29 +boto3==1.35.34 # via # -r requirements/test.txt # django-ses -botocore==1.35.29 +botocore==1.35.34 # via # -r requirements/test.txt # boto3 @@ -177,7 +177,7 @@ django-model-utils==5.0.0 # -r requirements/test.txt # edx-celeryutils # edx-rbac -django-ses==4.1.1 +django-ses==4.2.0 # via -r requirements/test.txt django-simple-history==3.7.0 # via -r requirements/test.txt @@ -199,7 +199,7 @@ djangorestframework==3.15.2 # edx-drf-extensions djangorestframework-csv==3.0.2 # via -r requirements/test.txt -dnspython==2.6.1 +dnspython==2.7.0 # via # -r requirements/test.txt # pymongo @@ -226,7 +226,7 @@ edx-braze-client==0.2.5 # via -r requirements/test.txt edx-celeryutils==1.3.0 # via -r requirements/test.txt -edx-django-utils==5.15.0 +edx-django-utils==5.16.0 # via # -r requirements/test.txt # edx-drf-extensions @@ -250,7 +250,7 @@ edx-toggles==5.2.0 # via -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==30.0.0 +faker==30.1.0 # via # -r requirements/test.txt # factory-boy @@ -396,7 +396,7 @@ pylint-plugin-utils==0.8.2 # -r requirements/test.txt # pylint-celery # pylint-django -pymongo==4.9.1 +pymongo==4.10.1 # via # -r requirements/test.txt # edx-opaque-keys @@ -438,7 +438,7 @@ pyyaml==6.0.2 # drf-spectacular readme-renderer==44.0 # via -r requirements/doc.in -redis==5.1.0 +redis==5.1.1 # via -r requirements/test.txt referencing==0.35.1 # via @@ -540,6 +540,7 @@ typing-extensions==4.12.2 # via # -r requirements/test.txt # edx-opaque-keys + # faker # pydata-sphinx-theme tzdata==2024.2 # via diff --git a/requirements/pip-tools.txt b/requirements/pip-tools.txt index 8c9fbc8d..cf4131e2 100644 --- a/requirements/pip-tools.txt +++ b/requirements/pip-tools.txt @@ -4,7 +4,7 @@ # # make upgrade # -build==1.2.2 +build==1.2.2.post1 # via pip-tools click==8.1.7 # via pip-tools diff --git a/requirements/production.txt b/requirements/production.txt index 8469d71b..1a3d85d0 100644 --- a/requirements/production.txt +++ b/requirements/production.txt @@ -28,11 +28,11 @@ billiard==4.2.1 # via # -r requirements/base.txt # celery -boto3==1.35.29 +boto3==1.35.34 # via # -r requirements/base.txt # django-ses -botocore==1.35.29 +botocore==1.35.34 # via # -r requirements/base.txt # boto3 @@ -143,7 +143,7 @@ django-model-utils==5.0.0 # -r requirements/base.txt # edx-celeryutils # edx-rbac -django-ses==4.1.1 +django-ses==4.2.0 # via -r requirements/base.txt django-simple-history==3.7.0 # via -r requirements/base.txt @@ -165,7 +165,7 @@ djangorestframework==3.15.2 # edx-drf-extensions djangorestframework-csv==3.0.2 # via -r requirements/base.txt -dnspython==2.6.1 +dnspython==2.7.0 # via # -r requirements/base.txt # pymongo @@ -183,7 +183,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.txt edx-celeryutils==1.3.0 # via -r requirements/base.txt -edx-django-utils==5.15.0 +edx-django-utils==5.16.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -293,7 +293,7 @@ pyjwt[crypto]==2.9.0 # social-auth-core pymemcache==4.0.0 # via -r requirements/production.in -pymongo==4.9.1 +pymongo==4.10.1 # via # -r requirements/base.txt # edx-opaque-keys @@ -325,7 +325,7 @@ pyyaml==6.0.2 # -r requirements/production.in # code-annotations # drf-spectacular -redis==5.1.0 +redis==5.1.1 # via -r requirements/base.txt referencing==0.35.1 # via diff --git a/requirements/quality.txt b/requirements/quality.txt index 0c317cf8..7f267c8a 100644 --- a/requirements/quality.txt +++ b/requirements/quality.txt @@ -15,7 +15,7 @@ asgiref==3.8.1 # -r requirements/base.txt # django # django-cors-headers -astroid==3.3.4 +astroid==3.3.5 # via # pylint # pylint-celery @@ -32,11 +32,11 @@ billiard==4.2.1 # via # -r requirements/base.txt # celery -boto3==1.35.29 +boto3==1.35.34 # via # -r requirements/base.txt # django-ses -botocore==1.35.29 +botocore==1.35.34 # via # -r requirements/base.txt # boto3 @@ -154,7 +154,7 @@ django-model-utils==5.0.0 # -r requirements/base.txt # edx-celeryutils # edx-rbac -django-ses==4.1.1 +django-ses==4.2.0 # via -r requirements/base.txt django-simple-history==3.7.0 # via -r requirements/base.txt @@ -176,7 +176,7 @@ djangorestframework==3.15.2 # edx-drf-extensions djangorestframework-csv==3.0.2 # via -r requirements/base.txt -dnspython==2.6.1 +dnspython==2.7.0 # via # -r requirements/base.txt # pymongo @@ -194,7 +194,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.txt edx-celeryutils==1.3.0 # via -r requirements/base.txt -edx-django-utils==5.15.0 +edx-django-utils==5.16.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -322,7 +322,7 @@ pylint-plugin-utils==0.8.2 # via # pylint-celery # pylint-django -pymongo==4.9.1 +pymongo==4.10.1 # via # -r requirements/base.txt # edx-opaque-keys @@ -351,7 +351,7 @@ pyyaml==6.0.2 # -r requirements/base.txt # code-annotations # drf-spectacular -redis==5.1.0 +redis==5.1.1 # via -r requirements/base.txt referencing==0.35.1 # via diff --git a/requirements/test.txt b/requirements/test.txt index 8beeb5b2..ec8e86c9 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -15,7 +15,7 @@ asgiref==3.8.1 # -r requirements/base.txt # django # django-cors-headers -astroid==3.3.4 +astroid==3.3.5 # via # pylint # pylint-celery @@ -32,11 +32,11 @@ billiard==4.2.1 # via # -r requirements/base.txt # celery -boto3==1.35.29 +boto3==1.35.34 # via # -r requirements/base.txt # django-ses -botocore==1.35.29 +botocore==1.35.34 # via # -r requirements/base.txt # boto3 @@ -163,7 +163,7 @@ django-model-utils==5.0.0 # -r requirements/base.txt # edx-celeryutils # edx-rbac -django-ses==4.1.1 +django-ses==4.2.0 # via -r requirements/base.txt django-simple-history==3.7.0 # via -r requirements/base.txt @@ -185,7 +185,7 @@ djangorestframework==3.15.2 # edx-drf-extensions djangorestframework-csv==3.0.2 # via -r requirements/base.txt -dnspython==2.6.1 +dnspython==2.7.0 # via # -r requirements/base.txt # pymongo @@ -203,7 +203,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.txt edx-celeryutils==1.3.0 # via -r requirements/base.txt -edx-django-utils==5.15.0 +edx-django-utils==5.16.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -227,7 +227,7 @@ edx-toggles==5.2.0 # via -r requirements/base.txt factory-boy==3.3.1 # via -r requirements/test.in -faker==30.0.0 +faker==30.1.0 # via factory-boy freezegun==1.5.1 # via -r requirements/test.in @@ -337,7 +337,7 @@ pylint-plugin-utils==0.8.2 # via # pylint-celery # pylint-django -pymongo==4.9.1 +pymongo==4.10.1 # via # -r requirements/base.txt # edx-opaque-keys @@ -376,7 +376,7 @@ pyyaml==6.0.2 # -r requirements/base.txt # code-annotations # drf-spectacular -redis==5.1.0 +redis==5.1.1 # via -r requirements/base.txt referencing==0.35.1 # via @@ -449,6 +449,7 @@ typing-extensions==4.12.2 # via # -r requirements/base.txt # edx-opaque-keys + # faker tzdata==2024.2 # via # -r requirements/base.txt diff --git a/requirements/validation.txt b/requirements/validation.txt index b1023d6d..9d79f3ef 100644 --- a/requirements/validation.txt +++ b/requirements/validation.txt @@ -19,7 +19,7 @@ asgiref==3.8.1 # -r requirements/test.txt # django # django-cors-headers -astroid==3.3.4 +astroid==3.3.5 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -41,12 +41,12 @@ billiard==4.2.1 # -r requirements/quality.txt # -r requirements/test.txt # celery -boto3==1.35.29 +boto3==1.35.34 # via # -r requirements/quality.txt # -r requirements/test.txt # django-ses -botocore==1.35.29 +botocore==1.35.34 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -208,7 +208,7 @@ django-model-utils==5.0.0 # -r requirements/test.txt # edx-celeryutils # edx-rbac -django-ses==4.1.1 +django-ses==4.2.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -240,7 +240,7 @@ djangorestframework-csv==3.0.2 # via # -r requirements/quality.txt # -r requirements/test.txt -dnspython==2.6.1 +dnspython==2.7.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -270,7 +270,7 @@ edx-celeryutils==1.3.0 # via # -r requirements/quality.txt # -r requirements/test.txt -edx-django-utils==5.15.0 +edx-django-utils==5.16.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -307,7 +307,7 @@ edx-toggles==5.2.0 # -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==30.0.0 +faker==30.1.0 # via # -r requirements/test.txt # factory-boy @@ -482,7 +482,7 @@ pylint-plugin-utils==0.8.2 # -r requirements/test.txt # pylint-celery # pylint-django -pymongo==4.9.1 +pymongo==4.10.1 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -531,7 +531,7 @@ pyyaml==6.0.2 # code-annotations # drf-spectacular # edx-i18n-tools -redis==5.1.0 +redis==5.1.1 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -631,6 +631,7 @@ typing-extensions==4.12.2 # -r requirements/quality.txt # -r requirements/test.txt # edx-opaque-keys + # faker tzdata==2024.2 # via # -r requirements/quality.txt From 53bf5cf2a2a11b0e9f9d151f33efee07d8191571 Mon Sep 17 00:00:00 2001 From: edX requirements bot <49161187+edx-requirements-bot@users.noreply.github.com> Date: Wed, 16 Oct 2024 10:16:31 -0400 Subject: [PATCH 12/23] chore: Upgrade Python requirements (#720) --- requirements/base.txt | 18 +++++++++--------- requirements/dev.txt | 26 +++++++++++++------------- requirements/doc.txt | 26 +++++++++++++------------- requirements/production.txt | 22 +++++++++++----------- requirements/quality.txt | 20 ++++++++++---------- requirements/test.txt | 24 ++++++++++++------------ requirements/validation.txt | 26 +++++++++++++------------- 7 files changed, 81 insertions(+), 81 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 8c3f77b4..17585d69 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -22,9 +22,9 @@ backoff==1.10.0 # analytics-python billiard==4.2.1 # via celery -boto3==1.35.34 +boto3==1.35.39 # via django-ses -botocore==1.35.34 +botocore==1.35.39 # via # boto3 # s3transfer @@ -39,7 +39,7 @@ cffi==1.17.1 # via # cryptography # pynacl -charset-normalizer==3.3.2 +charset-normalizer==3.4.0 # via requests click==8.1.7 # via @@ -97,7 +97,7 @@ django-autocomplete-light==3.11.0 # via -r requirements/base.in django-celery-results==2.5.1 # via -r requirements/base.in -django-cors-headers==4.4.0 +django-cors-headers==4.5.0 # via -r requirements/base.in django-crum==0.7.9 # via @@ -153,7 +153,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.in edx-celeryutils==1.3.0 # via -r requirements/base.in -edx-django-utils==5.16.0 +edx-django-utils==6.0.0 # via # -r requirements/base.in # edx-drf-extensions @@ -185,17 +185,17 @@ jsonfield==3.1.0 # via edx-celeryutils jsonschema==4.23.0 # via drf-spectacular -jsonschema-specifications==2023.12.1 +jsonschema-specifications==2024.10.1 # via jsonschema kombu==5.4.2 # via celery -markupsafe==2.1.5 +markupsafe==3.0.1 # via jinja2 monotonic==1.6 # via analytics-python mysqlclient==2.2.4 # via -r requirements/base.in -newrelic==10.0.0 +newrelic==10.1.0 # via edx-django-utils oauthlib==3.2.2 # via @@ -258,7 +258,7 @@ rpds-py==0.20.0 # referencing rules==3.5 # via -r requirements/base.in -s3transfer==0.10.2 +s3transfer==0.10.3 # via boto3 semantic-version==2.10.0 # via edx-drf-extensions diff --git a/requirements/dev.txt b/requirements/dev.txt index 6101d291..6aea12d8 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -33,11 +33,11 @@ billiard==4.2.1 # via # -r requirements/validation.txt # celery -boto3==1.35.34 +boto3==1.35.39 # via # -r requirements/validation.txt # django-ses -botocore==1.35.34 +botocore==1.35.39 # via # -r requirements/validation.txt # boto3 @@ -60,7 +60,7 @@ cffi==1.17.1 # -r requirements/validation.txt # cryptography # pynacl -charset-normalizer==3.3.2 +charset-normalizer==3.4.0 # via # -r requirements/validation.txt # requests @@ -98,7 +98,7 @@ code-annotations==1.8.0 # -r requirements/validation.txt # edx-lint # edx-toggles -coverage[toml]==7.6.1 +coverage[toml]==7.6.3 # via # -r requirements/validation.txt # pytest-cov @@ -158,7 +158,7 @@ django-autocomplete-light==3.11.0 # via -r requirements/validation.txt django-celery-results==2.5.1 # via -r requirements/validation.txt -django-cors-headers==4.4.0 +django-cors-headers==4.5.0 # via -r requirements/validation.txt django-crum==0.7.9 # via @@ -225,7 +225,7 @@ edx-braze-client==0.2.5 # via -r requirements/validation.txt edx-celeryutils==1.3.0 # via -r requirements/validation.txt -edx-django-utils==5.16.0 +edx-django-utils==6.0.0 # via # -r requirements/validation.txt # edx-drf-extensions @@ -251,7 +251,7 @@ edx-toggles==5.2.0 # via -r requirements/validation.txt factory-boy==3.3.1 # via -r requirements/validation.txt -faker==30.1.0 +faker==30.3.0 # via # -r requirements/validation.txt # factory-boy @@ -300,7 +300,7 @@ jsonschema==4.23.0 # via # -r requirements/validation.txt # drf-spectacular -jsonschema-specifications==2023.12.1 +jsonschema-specifications==2024.10.1 # via # -r requirements/validation.txt # jsonschema @@ -313,11 +313,11 @@ lxml[html-clean]==5.3.0 # -r requirements/validation.txt # edx-i18n-tools # lxml-html-clean -lxml-html-clean==0.2.2 +lxml-html-clean==0.3.1 # via # -r requirements/validation.txt # lxml -markupsafe==2.1.5 +markupsafe==3.0.1 # via # -r requirements/validation.txt # jinja2 @@ -333,7 +333,7 @@ more-itertools==10.5.0 # via inflect mysqlclient==2.2.4 # via -r requirements/validation.txt -newrelic==10.0.0 +newrelic==10.1.0 # via # -r requirements/validation.txt # edx-django-utils @@ -416,7 +416,7 @@ pylint-celery==0.3 # via # -r requirements/validation.txt # edx-lint -pylint-django==2.5.5 +pylint-django==2.6.1 # via # -r requirements/validation.txt # edx-lint @@ -499,7 +499,7 @@ rpds-py==0.20.0 # referencing rules==3.5 # via -r requirements/validation.txt -s3transfer==0.10.2 +s3transfer==0.10.3 # via # -r requirements/validation.txt # boto3 diff --git a/requirements/doc.txt b/requirements/doc.txt index 662ea20b..11f2e46e 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -43,11 +43,11 @@ billiard==4.2.1 # via # -r requirements/test.txt # celery -boto3==1.35.34 +boto3==1.35.39 # via # -r requirements/test.txt # django-ses -botocore==1.35.34 +botocore==1.35.39 # via # -r requirements/test.txt # boto3 @@ -66,7 +66,7 @@ cffi==1.17.1 # -r requirements/test.txt # cryptography # pynacl -charset-normalizer==3.3.2 +charset-normalizer==3.4.0 # via # -r requirements/test.txt # requests @@ -102,7 +102,7 @@ code-annotations==1.8.0 # -r requirements/test.txt # edx-lint # edx-toggles -coverage[toml]==7.6.1 +coverage[toml]==7.6.3 # via # -r requirements/test.txt # pytest-cov @@ -154,7 +154,7 @@ django-autocomplete-light==3.11.0 # via -r requirements/test.txt django-celery-results==2.5.1 # via -r requirements/test.txt -django-cors-headers==4.4.0 +django-cors-headers==4.5.0 # via -r requirements/test.txt django-crum==0.7.9 # via @@ -226,7 +226,7 @@ edx-braze-client==0.2.5 # via -r requirements/test.txt edx-celeryutils==1.3.0 # via -r requirements/test.txt -edx-django-utils==5.16.0 +edx-django-utils==6.0.0 # via # -r requirements/test.txt # edx-drf-extensions @@ -250,7 +250,7 @@ edx-toggles==5.2.0 # via -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==30.1.0 +faker==30.3.0 # via # -r requirements/test.txt # factory-boy @@ -292,7 +292,7 @@ jsonschema==4.23.0 # via # -r requirements/test.txt # drf-spectacular -jsonschema-specifications==2023.12.1 +jsonschema-specifications==2024.10.1 # via # -r requirements/test.txt # jsonschema @@ -300,7 +300,7 @@ kombu==5.4.2 # via # -r requirements/test.txt # celery -markupsafe==2.1.5 +markupsafe==3.0.1 # via # -r requirements/test.txt # jinja2 @@ -314,7 +314,7 @@ monotonic==1.6 # analytics-python mysqlclient==2.2.4 # via -r requirements/test.txt -newrelic==10.0.0 +newrelic==10.1.0 # via # -r requirements/test.txt # edx-django-utils @@ -387,7 +387,7 @@ pylint-celery==0.3 # via # -r requirements/test.txt # edx-lint -pylint-django==2.5.5 +pylint-django==2.6.1 # via # -r requirements/test.txt # edx-lint @@ -467,7 +467,7 @@ rpds-py==0.20.0 # referencing rules==3.5 # via -r requirements/test.txt -s3transfer==0.10.2 +s3transfer==0.10.3 # via # -r requirements/test.txt # boto3 @@ -498,7 +498,7 @@ social-auth-core==4.5.4 # social-auth-app-django soupsieve==2.6 # via beautifulsoup4 -sphinx==8.0.2 +sphinx==8.1.3 # via # -r requirements/doc.in # pydata-sphinx-theme diff --git a/requirements/production.txt b/requirements/production.txt index 1a3d85d0..e06bc8a5 100644 --- a/requirements/production.txt +++ b/requirements/production.txt @@ -28,11 +28,11 @@ billiard==4.2.1 # via # -r requirements/base.txt # celery -boto3==1.35.34 +boto3==1.35.39 # via # -r requirements/base.txt # django-ses -botocore==1.35.34 +botocore==1.35.39 # via # -r requirements/base.txt # boto3 @@ -51,7 +51,7 @@ cffi==1.17.1 # -r requirements/base.txt # cryptography # pynacl -charset-normalizer==3.3.2 +charset-normalizer==3.4.0 # via # -r requirements/base.txt # requests @@ -122,7 +122,7 @@ django-autocomplete-light==3.11.0 # via -r requirements/base.txt django-celery-results==2.5.1 # via -r requirements/base.txt -django-cors-headers==4.4.0 +django-cors-headers==4.5.0 # via -r requirements/base.txt django-crum==0.7.9 # via @@ -183,7 +183,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.txt edx-celeryutils==1.3.0 # via -r requirements/base.txt -edx-django-utils==5.16.0 +edx-django-utils==6.0.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -203,7 +203,7 @@ edx-rest-api-client==6.0.0 # via -r requirements/base.txt edx-toggles==5.2.0 # via -r requirements/base.txt -gevent==24.2.1 +gevent==24.10.2 # via -r requirements/production.in greenlet==3.1.1 # via gevent @@ -234,7 +234,7 @@ jsonschema==4.23.0 # via # -r requirements/base.txt # drf-spectacular -jsonschema-specifications==2023.12.1 +jsonschema-specifications==2024.10.1 # via # -r requirements/base.txt # jsonschema @@ -242,7 +242,7 @@ kombu==5.4.2 # via # -r requirements/base.txt # celery -markupsafe==2.1.5 +markupsafe==3.0.1 # via # -r requirements/base.txt # jinja2 @@ -252,7 +252,7 @@ monotonic==1.6 # analytics-python mysqlclient==2.2.4 # via -r requirements/base.txt -newrelic==10.0.0 +newrelic==10.1.0 # via # -r requirements/base.txt # edx-django-utils @@ -351,7 +351,7 @@ rpds-py==0.20.0 # referencing rules==3.5 # via -r requirements/base.txt -s3transfer==0.10.2 +s3transfer==0.10.3 # via # -r requirements/base.txt # boto3 @@ -423,7 +423,7 @@ zipp==3.20.2 # via -r requirements/base.txt zope-event==5.0 # via gevent -zope-interface==7.0.3 +zope-interface==7.1.0 # via gevent # The following packages are considered to be unsafe in a requirements file: diff --git a/requirements/quality.txt b/requirements/quality.txt index 7f267c8a..75979165 100644 --- a/requirements/quality.txt +++ b/requirements/quality.txt @@ -32,11 +32,11 @@ billiard==4.2.1 # via # -r requirements/base.txt # celery -boto3==1.35.34 +boto3==1.35.39 # via # -r requirements/base.txt # django-ses -botocore==1.35.34 +botocore==1.35.39 # via # -r requirements/base.txt # boto3 @@ -55,7 +55,7 @@ cffi==1.17.1 # -r requirements/base.txt # cryptography # pynacl -charset-normalizer==3.3.2 +charset-normalizer==3.4.0 # via # -r requirements/base.txt # requests @@ -133,7 +133,7 @@ django-autocomplete-light==3.11.0 # via -r requirements/base.txt django-celery-results==2.5.1 # via -r requirements/base.txt -django-cors-headers==4.4.0 +django-cors-headers==4.5.0 # via -r requirements/base.txt django-crum==0.7.9 # via @@ -194,7 +194,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.txt edx-celeryutils==1.3.0 # via -r requirements/base.txt -edx-django-utils==5.16.0 +edx-django-utils==6.0.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -245,7 +245,7 @@ jsonschema==4.23.0 # via # -r requirements/base.txt # drf-spectacular -jsonschema-specifications==2023.12.1 +jsonschema-specifications==2024.10.1 # via # -r requirements/base.txt # jsonschema @@ -253,7 +253,7 @@ kombu==5.4.2 # via # -r requirements/base.txt # celery -markupsafe==2.1.5 +markupsafe==3.0.1 # via # -r requirements/base.txt # jinja2 @@ -265,7 +265,7 @@ monotonic==1.6 # analytics-python mysqlclient==2.2.4 # via -r requirements/base.txt -newrelic==10.0.0 +newrelic==10.1.0 # via # -r requirements/base.txt # edx-django-utils @@ -316,7 +316,7 @@ pylint==3.3.1 # pylint-plugin-utils pylint-celery==0.3 # via edx-lint -pylint-django==2.5.5 +pylint-django==2.6.1 # via edx-lint pylint-plugin-utils==0.8.2 # via @@ -377,7 +377,7 @@ rpds-py==0.20.0 # referencing rules==3.5 # via -r requirements/base.txt -s3transfer==0.10.2 +s3transfer==0.10.3 # via # -r requirements/base.txt # boto3 diff --git a/requirements/test.txt b/requirements/test.txt index ec8e86c9..00efff69 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -32,11 +32,11 @@ billiard==4.2.1 # via # -r requirements/base.txt # celery -boto3==1.35.34 +boto3==1.35.39 # via # -r requirements/base.txt # django-ses -botocore==1.35.34 +botocore==1.35.39 # via # -r requirements/base.txt # boto3 @@ -55,7 +55,7 @@ cffi==1.17.1 # -r requirements/base.txt # cryptography # pynacl -charset-normalizer==3.3.2 +charset-normalizer==3.4.0 # via # -r requirements/base.txt # requests @@ -90,7 +90,7 @@ code-annotations==1.8.0 # -r requirements/test.in # edx-lint # edx-toggles -coverage[toml]==7.6.1 +coverage[toml]==7.6.3 # via # -r requirements/test.in # pytest-cov @@ -140,7 +140,7 @@ django-autocomplete-light==3.11.0 # via -r requirements/base.txt django-celery-results==2.5.1 # via -r requirements/base.txt -django-cors-headers==4.4.0 +django-cors-headers==4.5.0 # via -r requirements/base.txt django-crum==0.7.9 # via @@ -203,7 +203,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.txt edx-celeryutils==1.3.0 # via -r requirements/base.txt -edx-django-utils==5.16.0 +edx-django-utils==6.0.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -227,7 +227,7 @@ edx-toggles==5.2.0 # via -r requirements/base.txt factory-boy==3.3.1 # via -r requirements/test.in -faker==30.1.0 +faker==30.3.0 # via factory-boy freezegun==1.5.1 # via -r requirements/test.in @@ -260,7 +260,7 @@ jsonschema==4.23.0 # via # -r requirements/base.txt # drf-spectacular -jsonschema-specifications==2023.12.1 +jsonschema-specifications==2024.10.1 # via # -r requirements/base.txt # jsonschema @@ -268,7 +268,7 @@ kombu==5.4.2 # via # -r requirements/base.txt # celery -markupsafe==2.1.5 +markupsafe==3.0.1 # via # -r requirements/base.txt # jinja2 @@ -280,7 +280,7 @@ monotonic==1.6 # analytics-python mysqlclient==2.2.4 # via -r requirements/base.txt -newrelic==10.0.0 +newrelic==10.1.0 # via # -r requirements/base.txt # edx-django-utils @@ -331,7 +331,7 @@ pylint==3.3.1 # pylint-plugin-utils pylint-celery==0.3 # via edx-lint -pylint-django==2.5.5 +pylint-django==2.6.1 # via edx-lint pylint-plugin-utils==0.8.2 # via @@ -402,7 +402,7 @@ rpds-py==0.20.0 # referencing rules==3.5 # via -r requirements/base.txt -s3transfer==0.10.2 +s3transfer==0.10.3 # via # -r requirements/base.txt # boto3 diff --git a/requirements/validation.txt b/requirements/validation.txt index 9d79f3ef..2ec1a3e8 100644 --- a/requirements/validation.txt +++ b/requirements/validation.txt @@ -41,12 +41,12 @@ billiard==4.2.1 # -r requirements/quality.txt # -r requirements/test.txt # celery -boto3==1.35.34 +boto3==1.35.39 # via # -r requirements/quality.txt # -r requirements/test.txt # django-ses -botocore==1.35.34 +botocore==1.35.39 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -69,7 +69,7 @@ cffi==1.17.1 # -r requirements/test.txt # cryptography # pynacl -charset-normalizer==3.3.2 +charset-normalizer==3.4.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -112,7 +112,7 @@ code-annotations==1.8.0 # -r requirements/test.txt # edx-lint # edx-toggles -coverage[toml]==7.6.1 +coverage[toml]==7.6.3 # via # -r requirements/test.txt # pytest-cov @@ -173,7 +173,7 @@ django-celery-results==2.5.1 # via # -r requirements/quality.txt # -r requirements/test.txt -django-cors-headers==4.4.0 +django-cors-headers==4.5.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -270,7 +270,7 @@ edx-celeryutils==1.3.0 # via # -r requirements/quality.txt # -r requirements/test.txt -edx-django-utils==5.16.0 +edx-django-utils==6.0.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -307,7 +307,7 @@ edx-toggles==5.2.0 # -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==30.1.0 +faker==30.3.0 # via # -r requirements/test.txt # factory-boy @@ -353,7 +353,7 @@ jsonschema==4.23.0 # -r requirements/quality.txt # -r requirements/test.txt # drf-spectacular -jsonschema-specifications==2023.12.1 +jsonschema-specifications==2024.10.1 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -367,9 +367,9 @@ lxml[html-clean,html_clean]==5.3.0 # via # edx-i18n-tools # lxml-html-clean -lxml-html-clean==0.2.2 +lxml-html-clean==0.3.1 # via lxml -markupsafe==2.1.5 +markupsafe==3.0.1 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -388,7 +388,7 @@ mysqlclient==2.2.4 # via # -r requirements/quality.txt # -r requirements/test.txt -newrelic==10.0.0 +newrelic==10.1.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -471,7 +471,7 @@ pylint-celery==0.3 # -r requirements/quality.txt # -r requirements/test.txt # edx-lint -pylint-django==2.5.5 +pylint-django==2.6.1 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -565,7 +565,7 @@ rules==3.5 # via # -r requirements/quality.txt # -r requirements/test.txt -s3transfer==0.10.2 +s3transfer==0.10.3 # via # -r requirements/quality.txt # -r requirements/test.txt From 5f7ba4fcfb965d45227c03ac4031576f39b01583 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 17 Oct 2024 11:14:38 -0400 Subject: [PATCH 13/23] feat: return serialized subs license in license-activation POST (#722) --- .../apps/api/v1/tests/test_api_eventing.py | 2 +- .../v1/tests/test_license_activation_view.py | 44 ++++++++++++++++--- license_manager/apps/api/v1/views.py | 7 +-- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/license_manager/apps/api/v1/tests/test_api_eventing.py b/license_manager/apps/api/v1/tests/test_api_eventing.py index 7f962c0d..e1038e09 100644 --- a/license_manager/apps/api/v1/tests/test_api_eventing.py +++ b/license_manager/apps/api/v1/tests/test_api_eventing.py @@ -246,7 +246,7 @@ def test_activate_an_assigned_license(self, _): url = reverse('api:v1:license-activation') + '/?' + query_params.urlencode() response = self.api_client.post(url) - assert status.HTTP_204_NO_CONTENT == response.status_code + assert status.HTTP_200_OK == response.status_code license_to_be_activated.refresh_from_db() assert mock_activated_track_event.call_count == 1 diff --git a/license_manager/apps/api/v1/tests/test_license_activation_view.py b/license_manager/apps/api/v1/tests/test_license_activation_view.py index aeab03a3..7adf1f76 100644 --- a/license_manager/apps/api/v1/tests/test_license_activation_view.py +++ b/license_manager/apps/api/v1/tests/test_license_activation_view.py @@ -145,8 +145,18 @@ def test_activate_an_assigned_license(self, mock_send_post_activation_email_task with freeze_time(self.now): response = self._post_request(str(self.activation_key)) - assert status.HTTP_204_NO_CONTENT == response.status_code + # Verify that the response contains activated subscription license. + assert status.HTTP_200_OK == response.status_code + activated_license = response.json() + assert activated_license['uuid'] == str(license_to_be_activated.uuid) + assert activated_license['status'] == constants.ACTIVATED + expected_activation_date = self.now.strftime('%Y-%m-%dT%H:%M:%S.%fZ') + assert activated_license['activation_date'] == expected_activation_date + + # Refresh license from the database license_to_be_activated.refresh_from_db() + + # Verify that the license has been activated in the DB assert constants.ACTIVATED == license_to_be_activated.status assert self.lms_user_id == license_to_be_activated.lms_user_id assert self.now == license_to_be_activated.activation_date @@ -159,7 +169,7 @@ def test_activate_an_assigned_license(self, mock_send_post_activation_email_task self.user.email, ) - def test_license_already_activated_returns_204(self): + def test_license_already_activated_returns_200(self): self._assign_learner_roles( jwt_payload_extra={ 'user_id': self.lms_user_id, @@ -174,7 +184,13 @@ def test_license_already_activated_returns_204(self): response = self._post_request(str(self.activation_key)) - assert status.HTTP_204_NO_CONTENT == response.status_code + assert status.HTTP_200_OK == response.status_code + activated_license = response.json() + assert activated_license['uuid'] == str(already_activated_license.uuid) + assert activated_license['status'] == constants.ACTIVATED + expected_activation_date = self.now.strftime('%Y-%m-%dT%H:%M:%S.%fZ') + assert activated_license['activation_date'] == expected_activation_date + already_activated_license.refresh_from_db() assert constants.ACTIVATED == already_activated_license.status assert self.lms_user_id == already_activated_license.lms_user_id @@ -217,7 +233,12 @@ def test_duplicate_licenses_are_cleaned_up(self, mock_license_clean, mock_email_ with freeze_time(self.now): response = self._post_request(str(self.activation_key)) - assert status.HTTP_204_NO_CONTENT == response.status_code + assert status.HTTP_200_OK == response.status_code + activated_license = response.json() + assert activated_license['uuid'] == str(license_b.uuid) + assert activated_license['status'] == constants.ACTIVATED + expected_activation_date = self.now.strftime('%Y-%m-%dT%H:%M:%S.%fZ') + assert activated_license['activation_date'] == expected_activation_date license_b.refresh_from_db() assert constants.ACTIVATED == license_b.status @@ -268,7 +289,12 @@ def test_activated_license_exists_with_duplicates(self, mock_license_clean, mock with freeze_time(self.now): response = self._post_request(str(license_a_activation_key)) - assert status.HTTP_204_NO_CONTENT == response.status_code + assert status.HTTP_200_OK == response.status_code + activated_license = response.json() + assert activated_license['uuid'] == str(license_b.uuid) + assert activated_license['status'] == constants.ACTIVATED + expected_activation_date = self.now.strftime('%Y-%m-%dT%H:%M:%S.%fZ') + assert activated_license['activation_date'] == expected_activation_date license_b.refresh_from_db() assert constants.ACTIVATED == license_b.status @@ -341,7 +367,13 @@ def test_activating_renewed_assigned_license(self, mock_send_post_activation_ema with freeze_time(self.now): response = self._post_request(str(self.activation_key)) - assert status.HTTP_204_NO_CONTENT == response.status_code + assert status.HTTP_200_OK == response.status_code + activated_license = response.json() + assert activated_license['uuid'] == str(current_assigned_license.uuid) + assert activated_license['status'] == constants.ACTIVATED + expected_activation_date = self.now.strftime('%Y-%m-%dT%H:%M:%S.%fZ') + assert activated_license['activation_date'] == expected_activation_date + current_assigned_license.refresh_from_db() prior_assigned_license.refresh_from_db() assert prior_assigned_license.activation_date != self.now diff --git a/license_manager/apps/api/v1/views.py b/license_manager/apps/api/v1/views.py index 24c99388..5757b862 100644 --- a/license_manager/apps/api/v1/views.py +++ b/license_manager/apps/api/v1/views.py @@ -1779,10 +1779,10 @@ def post(self, request): license's subscription plan. * 404 Not Found - if the email found in the request's JWT and the provided ``activation_key`` do not match those of any existing license in an activate subscription plan. - * 204 No Content - if such a license was found, and if the license is currently ``assigned``, + * 200 OK - if such a license was found, and if the license is currently ``assigned``, it is updated with a status of ``activated``, its ``activation_date`` is set, and its ``lms_user_id`` is updated to the value found in the request's JWT. If the license is already ``activated``, - no update is made to it. + no update is made to it. The activated license is then returned in the response. * 422 Unprocessable Entity - if we find a license, but it's status is not currently ``assigned`` or ``activated``, we do nothing and return a 422 with a message indicating that the license cannot be activated. @@ -1801,7 +1801,8 @@ def post(self, request): # There's an implied logical branch where the license is already activated # in which case we also return as if the activation action was successful. - return Response(status=status.HTTP_204_NO_CONTENT) + serialized_license = serializers.LicenseSerializer(user_license) + return Response(serialized_license.data, status=status.HTTP_200_OK) def _track_and_notify(self, user_license): """ From 11ae7f3de35db50108f92dc0b20d9eeffc552fa6 Mon Sep 17 00:00:00 2001 From: jajjibhai008 Date: Mon, 14 Oct 2024 16:54:59 +0500 Subject: [PATCH 14/23] feat: update some fields in customer agreemnet model --- license_manager/apps/api/serializers.py | 5 +- license_manager/apps/subscriptions/admin.py | 7 +- ...greement_button_label_in_modal_and_more.py | 53 ++++++++ license_manager/apps/subscriptions/models.py | 116 +++++++++++------- .../apps/subscriptions/sanitize.py | 30 +++++ requirements/base.in | 1 + requirements/base.txt | 13 +- requirements/dev.txt | 17 ++- requirements/doc.txt | 17 ++- requirements/pip.txt | 2 +- requirements/production.txt | 15 ++- requirements/quality.txt | 15 ++- requirements/test.txt | 17 ++- requirements/validation.txt | 20 ++- 14 files changed, 250 insertions(+), 78 deletions(-) create mode 100644 license_manager/apps/subscriptions/migrations/0072_customeragreement_button_label_in_modal_and_more.py create mode 100644 license_manager/apps/subscriptions/sanitize.py diff --git a/license_manager/apps/api/serializers.py b/license_manager/apps/api/serializers.py index 38a56e78..5123f0bf 100644 --- a/license_manager/apps/api/serializers.py +++ b/license_manager/apps/api/serializers.py @@ -354,11 +354,14 @@ class Meta: 'net_days_until_expiration', 'subscription_for_auto_applied_licenses', 'available_subscription_catalogs', + 'enable_auto_applied_subscriptions_with_universal_link', 'has_custom_license_expiration_messaging', + 'modal_header_text', 'expired_subscription_modal_messaging', + 'button_label_in_modal', + 'url_for_button_in_modal', 'hyper_link_text_for_expired_modal', 'url_for_expired_modal', - 'enable_auto_applied_subscriptions_with_universal_link' ] def get_subscription_for_auto_applied_licenses(self, obj): diff --git a/license_manager/apps/subscriptions/admin.py b/license_manager/apps/subscriptions/admin.py index 0697816a..522a28a1 100644 --- a/license_manager/apps/subscriptions/admin.py +++ b/license_manager/apps/subscriptions/admin.py @@ -417,11 +417,14 @@ class CustomerAgreementAdmin(admin.ModelAdmin): 'disable_expiration_notifications', 'license_duration_before_purge', 'disable_onboarding_notifications', + 'enable_auto_applied_subscriptions_with_universal_link', 'has_custom_license_expiration_messaging', + 'modal_header_text', 'expired_subscription_modal_messaging', + 'button_label_in_modal', + 'url_for_button_in_modal', 'hyper_link_text_for_expired_modal', - 'url_for_expired_modal', - 'enable_auto_applied_subscriptions_with_universal_link' + 'url_for_expired_modal' ) custom_fields = ('subscription_for_auto_applied_licenses',) diff --git a/license_manager/apps/subscriptions/migrations/0072_customeragreement_button_label_in_modal_and_more.py b/license_manager/apps/subscriptions/migrations/0072_customeragreement_button_label_in_modal_and_more.py new file mode 100644 index 00000000..623c0f4f --- /dev/null +++ b/license_manager/apps/subscriptions/migrations/0072_customeragreement_button_label_in_modal_and_more.py @@ -0,0 +1,53 @@ +# Generated by Django 4.2.16 on 2024-10-18 09:53 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('subscriptions', '0071_customeragreement_enable_auto_applied_subscriptions_with_universal_link_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='customeragreement', + name='button_label_in_modal', + field=models.CharField(blank=True, help_text='The text that will appear as on the button in the expiration modal', max_length=255, null=True), + ), + migrations.AddField( + model_name='customeragreement', + name='modal_header_text', + field=models.CharField(blank=True, help_text='The bold text that will appear as the header in the expiration modal.', max_length=512, null=True), + ), + migrations.AddField( + model_name='customeragreement', + name='url_for_button_in_modal', + field=models.CharField(blank=True, help_text='The URL that should underly the sole button in the expiration modal', max_length=512, null=True), + ), + migrations.AddField( + model_name='historicalcustomeragreement', + name='button_label_in_modal', + field=models.CharField(blank=True, help_text='The text that will appear as on the button in the expiration modal', max_length=255, null=True), + ), + migrations.AddField( + model_name='historicalcustomeragreement', + name='modal_header_text', + field=models.CharField(blank=True, help_text='The bold text that will appear as the header in the expiration modal.', max_length=512, null=True), + ), + migrations.AddField( + model_name='historicalcustomeragreement', + name='url_for_button_in_modal', + field=models.CharField(blank=True, help_text='The URL that should underly the sole button in the expiration modal', max_length=512, null=True), + ), + migrations.AlterField( + model_name='customeragreement', + name='expired_subscription_modal_messaging', + field=models.TextField(blank=True, help_text='The content of a modal that will appear to learners upon subscription expiration. This text can be used for custom guidance per customer.', null=True), + ), + migrations.AlterField( + model_name='historicalcustomeragreement', + name='expired_subscription_modal_messaging', + field=models.TextField(blank=True, help_text='The content of a modal that will appear to learners upon subscription expiration. This text can be used for custom guidance per customer.', null=True), + ), + ] diff --git a/license_manager/apps/subscriptions/models.py b/license_manager/apps/subscriptions/models.py index edffda87..e786e8af 100644 --- a/license_manager/apps/subscriptions/models.py +++ b/license_manager/apps/subscriptions/models.py @@ -48,6 +48,7 @@ track_event, track_license_changes, ) +from license_manager.apps.subscriptions.sanitize import sanitize_html from license_manager.apps.subscriptions.utils import ( days_until, get_license_activation_link, @@ -150,8 +151,16 @@ class CustomerAgreement(TimeStampedModel): ) ) - expired_subscription_modal_messaging = models.CharField( + modal_header_text = models.CharField( max_length=512, + blank=True, + null=True, + help_text=_( + "The bold text that will appear as the header in the expiration modal." + ) + ) + + expired_subscription_modal_messaging = models.TextField( blank=True, null=True, help_text=_( @@ -178,6 +187,24 @@ class CustomerAgreement(TimeStampedModel): ) ) + button_label_in_modal = models.CharField( + max_length=255, + blank=True, + null=True, + help_text=_( + "The text that will appear as on the button in the expiration modal" + ) + ) + + url_for_button_in_modal = models.CharField( + max_length=512, + blank=True, + null=True, + help_text=_( + "The URL that should underly the sole button in the expiration modal" + ) + ) + enable_auto_applied_subscriptions_with_universal_link = models.BooleanField( default=False, help_text=_( @@ -237,54 +264,59 @@ class Meta: verbose_name_plural = _("Customer Agreements") def clean(self): - # Check if custom messaging is enabled and messaging field is blank + """ + Custom clean method to validate fields based on the 'Has Custom License Expiration Messaging' flag. + """ + errors = {} + + # Sanitize the expired_subscription_modal_messaging field + if self.expired_subscription_modal_messaging: + self.expired_subscription_modal_messaging = sanitize_html(self.expired_subscription_modal_messaging) + + error_message = "This field cannot be blank if 'Has Custom License Expiration Messaging' is checked." + # Validate fields when custom messaging is enabled if self.has_custom_license_expiration_messaging: - if not self.expired_subscription_modal_messaging: - raise ValidationError({ - "expired_subscription_modal_messaging": ( - "This field cannot be blank if 'Has Custom License Expiration Messaging' is checked." - ) - }) - - # Validate that URL field is not blank if hyperlink text is provided - if self.hyper_link_text_for_expired_modal and not self.url_for_expired_modal: - raise ValidationError({ - "url_for_expired_modal": ( - "This field cannot be blank if 'Hyper Link Text for Expired Modal' has values." - ) - }) + required_fields = { + "modal_header_text": error_message, + "expired_subscription_modal_messaging": error_message, + "button_label_in_modal": error_message, + "url_for_button_in_modal": error_message, + "hyper_link_text_for_expired_modal": error_message, + "url_for_expired_modal": error_message + } - # Validate that hyperlink text is not blank if URL is provided - if self.url_for_expired_modal and not self.hyper_link_text_for_expired_modal: - raise ValidationError({ - "hyper_link_text_for_expired_modal": ( - "This field cannot be blank if 'URL for Expired Modal' has values." - ) - }) + # Check if any required fields are missing + for field, error_message in required_fields.items(): + if not getattr(self, field): + errors[field] = error_message # Ensure all fields are blank if custom messaging is disabled if not self.has_custom_license_expiration_messaging: - if any([ - self.expired_subscription_modal_messaging, - self.hyper_link_text_for_expired_modal, - self.url_for_expired_modal - ]): + fields_to_check = [ + "modal_header_text", + "expired_subscription_modal_messaging", + "button_label_in_modal", + "url_for_button_in_modal", + "hyper_link_text_for_expired_modal", + "url_for_expired_modal", + ] + if any(getattr(self, field) for field in fields_to_check): error_msg = "This field must be blank if 'Has Custom License Expiration Messaging' is unchecked." - raise ValidationError({ - "expired_subscription_modal_messaging": error_msg, - "hyper_link_text_for_expired_modal": error_msg, - "url_for_expired_modal": error_msg, - }) - - def __str__(self): - """ - Return human-readable string representation. - """ - return ( - "".format( - self.enterprise_customer_slug or self.enterprise_customer_name - ) + errors = {field: error_msg for field in fields_to_check} + + # Raise ValidationError if there are any errors + if errors: + raise ValidationError(errors) + + def __str__(self): + """ + Return human-readable string representation. + """ + return ( + "".format( + self.enterprise_customer_slug or self.enterprise_customer_name ) + ) class PlanType(models.Model): diff --git a/license_manager/apps/subscriptions/sanitize.py b/license_manager/apps/subscriptions/sanitize.py new file mode 100644 index 00000000..c2da423b --- /dev/null +++ b/license_manager/apps/subscriptions/sanitize.py @@ -0,0 +1,30 @@ +import bleach + + +def sanitize_html(html_content): + """ + Sanitize HTML content to allow only safe tags and attributes, + while disallowing JavaScript and unsafe protocols. + """ + # Define allowed tags and attributes + allowed_tags = bleach.ALLOWED_TAGS # Allow all standard HTML tags + allowed_attrs = {"*": ["className", "class", "style", "id"]} + + # Clean the HTML content + sanitized_content = bleach.clean( + html_content, + tags=allowed_tags, + attributes=allowed_attrs, + strip=True, # Strip disallowed tags completely + protocols=["http", "https"], # Only allow http and https URLs + ) + + # Use bleach.linkify to ensure no javascript: links in tags + sanitized_content = bleach.linkify( + sanitized_content, + callbacks=[ + bleach.callbacks.nofollow + ], # Apply 'nofollow' to external links for safety + ) + + return sanitized_content diff --git a/requirements/base.in b/requirements/base.in index e7bdd14f..6de2a2d5 100644 --- a/requirements/base.in +++ b/requirements/base.in @@ -40,3 +40,4 @@ rules simplejson zipp django-log-request-id +bleach diff --git a/requirements/base.txt b/requirements/base.txt index 17585d69..7800d2c1 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -22,9 +22,11 @@ backoff==1.10.0 # analytics-python billiard==4.2.1 # via celery -boto3==1.35.39 +bleach==6.1.0 + # via -r requirements/base.in +boto3==1.35.42 # via django-ses -botocore==1.35.39 +botocore==1.35.42 # via # boto3 # s3transfer @@ -153,7 +155,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.in edx-celeryutils==1.3.0 # via -r requirements/base.in -edx-django-utils==6.0.0 +edx-django-utils==6.1.0 # via # -r requirements/base.in # edx-drf-extensions @@ -195,7 +197,7 @@ monotonic==1.6 # via analytics-python mysqlclient==2.2.4 # via -r requirements/base.in -newrelic==10.1.0 +newrelic==10.2.0 # via edx-django-utils oauthlib==3.2.2 # via @@ -267,6 +269,7 @@ simplejson==3.19.3 six==1.16.0 # via # analytics-python + # bleach # edx-auth-backends # edx-rbac # python-dateutil @@ -304,6 +307,8 @@ vine==5.1.0 # kombu wcwidth==0.2.13 # via prompt-toolkit +webencodings==0.5.1 + # via bleach zipp==3.20.2 # via -r requirements/base.in diff --git a/requirements/dev.txt b/requirements/dev.txt index 6aea12d8..84f5cc3d 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -33,11 +33,13 @@ billiard==4.2.1 # via # -r requirements/validation.txt # celery -boto3==1.35.39 +bleach==6.1.0 + # via -r requirements/validation.txt +boto3==1.35.42 # via # -r requirements/validation.txt # django-ses -botocore==1.35.39 +botocore==1.35.42 # via # -r requirements/validation.txt # boto3 @@ -225,7 +227,7 @@ edx-braze-client==0.2.5 # via -r requirements/validation.txt edx-celeryutils==1.3.0 # via -r requirements/validation.txt -edx-django-utils==6.0.0 +edx-django-utils==6.1.0 # via # -r requirements/validation.txt # edx-drf-extensions @@ -251,7 +253,7 @@ edx-toggles==5.2.0 # via -r requirements/validation.txt factory-boy==3.3.1 # via -r requirements/validation.txt -faker==30.3.0 +faker==30.6.0 # via # -r requirements/validation.txt # factory-boy @@ -333,7 +335,7 @@ more-itertools==10.5.0 # via inflect mysqlclient==2.2.4 # via -r requirements/validation.txt -newrelic==10.1.0 +newrelic==10.2.0 # via # -r requirements/validation.txt # edx-django-utils @@ -513,6 +515,7 @@ six==1.16.0 # via # -r requirements/validation.txt # analytics-python + # bleach # edx-auth-backends # edx-lint # edx-rbac @@ -582,6 +585,10 @@ wcwidth==0.2.13 # via # -r requirements/validation.txt # prompt-toolkit +webencodings==0.5.1 + # via + # -r requirements/validation.txt + # bleach wheel==0.44.0 # via # -r requirements/pip-tools.txt diff --git a/requirements/doc.txt b/requirements/doc.txt index 11f2e46e..54859157 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -43,11 +43,13 @@ billiard==4.2.1 # via # -r requirements/test.txt # celery -boto3==1.35.39 +bleach==6.1.0 + # via -r requirements/test.txt +boto3==1.35.42 # via # -r requirements/test.txt # django-ses -botocore==1.35.39 +botocore==1.35.42 # via # -r requirements/test.txt # boto3 @@ -226,7 +228,7 @@ edx-braze-client==0.2.5 # via -r requirements/test.txt edx-celeryutils==1.3.0 # via -r requirements/test.txt -edx-django-utils==6.0.0 +edx-django-utils==6.1.0 # via # -r requirements/test.txt # edx-drf-extensions @@ -250,7 +252,7 @@ edx-toggles==5.2.0 # via -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==30.3.0 +faker==30.6.0 # via # -r requirements/test.txt # factory-boy @@ -314,7 +316,7 @@ monotonic==1.6 # analytics-python mysqlclient==2.2.4 # via -r requirements/test.txt -newrelic==10.1.0 +newrelic==10.2.0 # via # -r requirements/test.txt # edx-django-utils @@ -481,6 +483,7 @@ six==1.16.0 # via # -r requirements/test.txt # analytics-python + # bleach # edx-auth-backends # edx-lint # edx-rbac @@ -566,6 +569,10 @@ wcwidth==0.2.13 # via # -r requirements/test.txt # prompt-toolkit +webencodings==0.5.1 + # via + # -r requirements/test.txt + # bleach zipp==3.20.2 # via -r requirements/test.txt diff --git a/requirements/pip.txt b/requirements/pip.txt index 488d41f8..35655630 100644 --- a/requirements/pip.txt +++ b/requirements/pip.txt @@ -10,5 +10,5 @@ wheel==0.44.0 # The following packages are considered to be unsafe in a requirements file: pip==24.2 # via -r requirements/pip.in -setuptools==75.1.0 +setuptools==75.2.0 # via -r requirements/pip.in diff --git a/requirements/production.txt b/requirements/production.txt index e06bc8a5..08ca91b5 100644 --- a/requirements/production.txt +++ b/requirements/production.txt @@ -28,11 +28,13 @@ billiard==4.2.1 # via # -r requirements/base.txt # celery -boto3==1.35.39 +bleach==6.1.0 + # via -r requirements/base.txt +boto3==1.35.42 # via # -r requirements/base.txt # django-ses -botocore==1.35.39 +botocore==1.35.42 # via # -r requirements/base.txt # boto3 @@ -183,7 +185,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.txt edx-celeryutils==1.3.0 # via -r requirements/base.txt -edx-django-utils==6.0.0 +edx-django-utils==6.1.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -252,7 +254,7 @@ monotonic==1.6 # analytics-python mysqlclient==2.2.4 # via -r requirements/base.txt -newrelic==10.1.0 +newrelic==10.2.0 # via # -r requirements/base.txt # edx-django-utils @@ -365,6 +367,7 @@ six==1.16.0 # via # -r requirements/base.txt # analytics-python + # bleach # edx-auth-backends # edx-rbac # python-dateutil @@ -419,6 +422,10 @@ wcwidth==0.2.13 # via # -r requirements/base.txt # prompt-toolkit +webencodings==0.5.1 + # via + # -r requirements/base.txt + # bleach zipp==3.20.2 # via -r requirements/base.txt zope-event==5.0 diff --git a/requirements/quality.txt b/requirements/quality.txt index 75979165..bbad69ae 100644 --- a/requirements/quality.txt +++ b/requirements/quality.txt @@ -32,11 +32,13 @@ billiard==4.2.1 # via # -r requirements/base.txt # celery -boto3==1.35.39 +bleach==6.1.0 + # via -r requirements/base.txt +boto3==1.35.42 # via # -r requirements/base.txt # django-ses -botocore==1.35.39 +botocore==1.35.42 # via # -r requirements/base.txt # boto3 @@ -194,7 +196,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.txt edx-celeryutils==1.3.0 # via -r requirements/base.txt -edx-django-utils==6.0.0 +edx-django-utils==6.1.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -265,7 +267,7 @@ monotonic==1.6 # analytics-python mysqlclient==2.2.4 # via -r requirements/base.txt -newrelic==10.1.0 +newrelic==10.2.0 # via # -r requirements/base.txt # edx-django-utils @@ -391,6 +393,7 @@ six==1.16.0 # via # -r requirements/base.txt # analytics-python + # bleach # edx-auth-backends # edx-lint # edx-rbac @@ -450,6 +453,10 @@ wcwidth==0.2.13 # via # -r requirements/base.txt # prompt-toolkit +webencodings==0.5.1 + # via + # -r requirements/base.txt + # bleach zipp==3.20.2 # via -r requirements/base.txt diff --git a/requirements/test.txt b/requirements/test.txt index 00efff69..ed139657 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -32,11 +32,13 @@ billiard==4.2.1 # via # -r requirements/base.txt # celery -boto3==1.35.39 +bleach==6.1.0 + # via -r requirements/base.txt +boto3==1.35.42 # via # -r requirements/base.txt # django-ses -botocore==1.35.39 +botocore==1.35.42 # via # -r requirements/base.txt # boto3 @@ -203,7 +205,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.txt edx-celeryutils==1.3.0 # via -r requirements/base.txt -edx-django-utils==6.0.0 +edx-django-utils==6.1.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -227,7 +229,7 @@ edx-toggles==5.2.0 # via -r requirements/base.txt factory-boy==3.3.1 # via -r requirements/test.in -faker==30.3.0 +faker==30.6.0 # via factory-boy freezegun==1.5.1 # via -r requirements/test.in @@ -280,7 +282,7 @@ monotonic==1.6 # analytics-python mysqlclient==2.2.4 # via -r requirements/base.txt -newrelic==10.1.0 +newrelic==10.2.0 # via # -r requirements/base.txt # edx-django-utils @@ -416,6 +418,7 @@ six==1.16.0 # via # -r requirements/base.txt # analytics-python + # bleach # edx-auth-backends # edx-lint # edx-rbac @@ -474,6 +477,10 @@ wcwidth==0.2.13 # via # -r requirements/base.txt # prompt-toolkit +webencodings==0.5.1 + # via + # -r requirements/base.txt + # bleach zipp==3.20.2 # via -r requirements/base.txt diff --git a/requirements/validation.txt b/requirements/validation.txt index 2ec1a3e8..d49c6103 100644 --- a/requirements/validation.txt +++ b/requirements/validation.txt @@ -41,12 +41,16 @@ billiard==4.2.1 # -r requirements/quality.txt # -r requirements/test.txt # celery -boto3==1.35.39 +bleach==6.1.0 + # via + # -r requirements/quality.txt + # -r requirements/test.txt +boto3==1.35.42 # via # -r requirements/quality.txt # -r requirements/test.txt # django-ses -botocore==1.35.39 +botocore==1.35.42 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -270,7 +274,7 @@ edx-celeryutils==1.3.0 # via # -r requirements/quality.txt # -r requirements/test.txt -edx-django-utils==6.0.0 +edx-django-utils==6.1.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -307,7 +311,7 @@ edx-toggles==5.2.0 # -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==30.3.0 +faker==30.6.0 # via # -r requirements/test.txt # factory-boy @@ -388,7 +392,7 @@ mysqlclient==2.2.4 # via # -r requirements/quality.txt # -r requirements/test.txt -newrelic==10.1.0 +newrelic==10.2.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -584,6 +588,7 @@ six==1.16.0 # -r requirements/quality.txt # -r requirements/test.txt # analytics-python + # bleach # edx-auth-backends # edx-lint # edx-rbac @@ -661,6 +666,11 @@ wcwidth==0.2.13 # -r requirements/quality.txt # -r requirements/test.txt # prompt-toolkit +webencodings==0.5.1 + # via + # -r requirements/quality.txt + # -r requirements/test.txt + # bleach zipp==3.20.2 # via # -r requirements/quality.txt From 9071d8346ceabb13249dd92b5cd44ea979774f7f Mon Sep 17 00:00:00 2001 From: edX requirements bot Date: Tue, 22 Oct 2024 05:14:16 -0400 Subject: [PATCH 15/23] chore: Upgrade Python requirements --- requirements/base.txt | 14 +++++++------- requirements/dev.txt | 18 +++++++++--------- requirements/doc.txt | 18 +++++++++--------- requirements/production.txt | 16 ++++++++-------- requirements/quality.txt | 14 +++++++------- requirements/test.txt | 18 +++++++++--------- requirements/validation.txt | 18 +++++++++--------- 7 files changed, 58 insertions(+), 58 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 7800d2c1..80254895 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -24,9 +24,9 @@ billiard==4.2.1 # via celery bleach==6.1.0 # via -r requirements/base.in -boto3==1.35.42 +boto3==1.35.45 # via django-ses -botocore==1.35.42 +botocore==1.35.45 # via # boto3 # s3transfer @@ -59,7 +59,7 @@ click-repl==0.3.0 # via celery code-annotations==1.8.0 # via edx-toggles -cryptography==43.0.1 +cryptography==43.0.3 # via # pyjwt # social-auth-core @@ -155,7 +155,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.in edx-celeryutils==1.3.0 # via -r requirements/base.in -edx-django-utils==6.1.0 +edx-django-utils==7.0.0 # via # -r requirements/base.in # edx-drf-extensions @@ -191,11 +191,11 @@ jsonschema-specifications==2024.10.1 # via jsonschema kombu==5.4.2 # via celery -markupsafe==3.0.1 +markupsafe==3.0.2 # via jinja2 monotonic==1.6 # via analytics-python -mysqlclient==2.2.4 +mysqlclient==2.2.5 # via -r requirements/base.in newrelic==10.2.0 # via edx-django-utils @@ -209,7 +209,7 @@ ply==3.11 # via djangoql prompt-toolkit==3.0.48 # via click-repl -psutil==6.0.0 +psutil==6.1.0 # via edx-django-utils pycparser==2.22 # via cffi diff --git a/requirements/dev.txt b/requirements/dev.txt index 84f5cc3d..5c1580ef 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -35,11 +35,11 @@ billiard==4.2.1 # celery bleach==6.1.0 # via -r requirements/validation.txt -boto3==1.35.42 +boto3==1.35.45 # via # -r requirements/validation.txt # django-ses -botocore==1.35.42 +botocore==1.35.45 # via # -r requirements/validation.txt # boto3 @@ -100,11 +100,11 @@ code-annotations==1.8.0 # -r requirements/validation.txt # edx-lint # edx-toggles -coverage[toml]==7.6.3 +coverage[toml]==7.6.4 # via # -r requirements/validation.txt # pytest-cov -cryptography==43.0.1 +cryptography==43.0.3 # via # -r requirements/validation.txt # pyjwt @@ -227,7 +227,7 @@ edx-braze-client==0.2.5 # via -r requirements/validation.txt edx-celeryutils==1.3.0 # via -r requirements/validation.txt -edx-django-utils==6.1.0 +edx-django-utils==7.0.0 # via # -r requirements/validation.txt # edx-drf-extensions @@ -253,7 +253,7 @@ edx-toggles==5.2.0 # via -r requirements/validation.txt factory-boy==3.3.1 # via -r requirements/validation.txt -faker==30.6.0 +faker==30.8.0 # via # -r requirements/validation.txt # factory-boy @@ -319,7 +319,7 @@ lxml-html-clean==0.3.1 # via # -r requirements/validation.txt # lxml -markupsafe==3.0.1 +markupsafe==3.0.2 # via # -r requirements/validation.txt # jinja2 @@ -333,7 +333,7 @@ monotonic==1.6 # analytics-python more-itertools==10.5.0 # via inflect -mysqlclient==2.2.4 +mysqlclient==2.2.5 # via -r requirements/validation.txt newrelic==10.2.0 # via @@ -385,7 +385,7 @@ prompt-toolkit==3.0.48 # via # -r requirements/validation.txt # click-repl -psutil==6.0.0 +psutil==6.1.0 # via # -r requirements/validation.txt # edx-django-utils diff --git a/requirements/doc.txt b/requirements/doc.txt index 54859157..6507c14e 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -45,11 +45,11 @@ billiard==4.2.1 # celery bleach==6.1.0 # via -r requirements/test.txt -boto3==1.35.42 +boto3==1.35.45 # via # -r requirements/test.txt # django-ses -botocore==1.35.42 +botocore==1.35.45 # via # -r requirements/test.txt # boto3 @@ -104,11 +104,11 @@ code-annotations==1.8.0 # -r requirements/test.txt # edx-lint # edx-toggles -coverage[toml]==7.6.3 +coverage[toml]==7.6.4 # via # -r requirements/test.txt # pytest-cov -cryptography==43.0.1 +cryptography==43.0.3 # via # -r requirements/test.txt # pyjwt @@ -228,7 +228,7 @@ edx-braze-client==0.2.5 # via -r requirements/test.txt edx-celeryutils==1.3.0 # via -r requirements/test.txt -edx-django-utils==6.1.0 +edx-django-utils==7.0.0 # via # -r requirements/test.txt # edx-drf-extensions @@ -252,7 +252,7 @@ edx-toggles==5.2.0 # via -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==30.6.0 +faker==30.8.0 # via # -r requirements/test.txt # factory-boy @@ -302,7 +302,7 @@ kombu==5.4.2 # via # -r requirements/test.txt # celery -markupsafe==3.0.1 +markupsafe==3.0.2 # via # -r requirements/test.txt # jinja2 @@ -314,7 +314,7 @@ monotonic==1.6 # via # -r requirements/test.txt # analytics-python -mysqlclient==2.2.4 +mysqlclient==2.2.5 # via -r requirements/test.txt newrelic==10.2.0 # via @@ -353,7 +353,7 @@ prompt-toolkit==3.0.48 # via # -r requirements/test.txt # click-repl -psutil==6.0.0 +psutil==6.1.0 # via # -r requirements/test.txt # edx-django-utils diff --git a/requirements/production.txt b/requirements/production.txt index 08ca91b5..c889c267 100644 --- a/requirements/production.txt +++ b/requirements/production.txt @@ -30,11 +30,11 @@ billiard==4.2.1 # celery bleach==6.1.0 # via -r requirements/base.txt -boto3==1.35.42 +boto3==1.35.45 # via # -r requirements/base.txt # django-ses -botocore==1.35.42 +botocore==1.35.45 # via # -r requirements/base.txt # boto3 @@ -82,7 +82,7 @@ code-annotations==1.8.0 # via # -r requirements/base.txt # edx-toggles -cryptography==43.0.1 +cryptography==43.0.3 # via # -r requirements/base.txt # pyjwt @@ -185,7 +185,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.txt edx-celeryutils==1.3.0 # via -r requirements/base.txt -edx-django-utils==6.1.0 +edx-django-utils==7.0.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -205,7 +205,7 @@ edx-rest-api-client==6.0.0 # via -r requirements/base.txt edx-toggles==5.2.0 # via -r requirements/base.txt -gevent==24.10.2 +gevent==24.10.3 # via -r requirements/production.in greenlet==3.1.1 # via gevent @@ -244,7 +244,7 @@ kombu==5.4.2 # via # -r requirements/base.txt # celery -markupsafe==3.0.1 +markupsafe==3.0.2 # via # -r requirements/base.txt # jinja2 @@ -252,7 +252,7 @@ monotonic==1.6 # via # -r requirements/base.txt # analytics-python -mysqlclient==2.2.4 +mysqlclient==2.2.5 # via -r requirements/base.txt newrelic==10.2.0 # via @@ -277,7 +277,7 @@ prompt-toolkit==3.0.48 # via # -r requirements/base.txt # click-repl -psutil==6.0.0 +psutil==6.1.0 # via # -r requirements/base.txt # edx-django-utils diff --git a/requirements/quality.txt b/requirements/quality.txt index bbad69ae..846ae997 100644 --- a/requirements/quality.txt +++ b/requirements/quality.txt @@ -34,11 +34,11 @@ billiard==4.2.1 # celery bleach==6.1.0 # via -r requirements/base.txt -boto3==1.35.42 +boto3==1.35.45 # via # -r requirements/base.txt # django-ses -botocore==1.35.42 +botocore==1.35.45 # via # -r requirements/base.txt # boto3 @@ -91,7 +91,7 @@ code-annotations==1.8.0 # -r requirements/base.txt # edx-lint # edx-toggles -cryptography==43.0.1 +cryptography==43.0.3 # via # -r requirements/base.txt # pyjwt @@ -196,7 +196,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.txt edx-celeryutils==1.3.0 # via -r requirements/base.txt -edx-django-utils==6.1.0 +edx-django-utils==7.0.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -255,7 +255,7 @@ kombu==5.4.2 # via # -r requirements/base.txt # celery -markupsafe==3.0.1 +markupsafe==3.0.2 # via # -r requirements/base.txt # jinja2 @@ -265,7 +265,7 @@ monotonic==1.6 # via # -r requirements/base.txt # analytics-python -mysqlclient==2.2.4 +mysqlclient==2.2.5 # via -r requirements/base.txt newrelic==10.2.0 # via @@ -290,7 +290,7 @@ prompt-toolkit==3.0.48 # via # -r requirements/base.txt # click-repl -psutil==6.0.0 +psutil==6.1.0 # via # -r requirements/base.txt # edx-django-utils diff --git a/requirements/test.txt b/requirements/test.txt index ed139657..17eb45be 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -34,11 +34,11 @@ billiard==4.2.1 # celery bleach==6.1.0 # via -r requirements/base.txt -boto3==1.35.42 +boto3==1.35.45 # via # -r requirements/base.txt # django-ses -botocore==1.35.42 +botocore==1.35.45 # via # -r requirements/base.txt # boto3 @@ -92,11 +92,11 @@ code-annotations==1.8.0 # -r requirements/test.in # edx-lint # edx-toggles -coverage[toml]==7.6.3 +coverage[toml]==7.6.4 # via # -r requirements/test.in # pytest-cov -cryptography==43.0.1 +cryptography==43.0.3 # via # -r requirements/base.txt # pyjwt @@ -205,7 +205,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.txt edx-celeryutils==1.3.0 # via -r requirements/base.txt -edx-django-utils==6.1.0 +edx-django-utils==7.0.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -229,7 +229,7 @@ edx-toggles==5.2.0 # via -r requirements/base.txt factory-boy==3.3.1 # via -r requirements/test.in -faker==30.6.0 +faker==30.8.0 # via factory-boy freezegun==1.5.1 # via -r requirements/test.in @@ -270,7 +270,7 @@ kombu==5.4.2 # via # -r requirements/base.txt # celery -markupsafe==3.0.1 +markupsafe==3.0.2 # via # -r requirements/base.txt # jinja2 @@ -280,7 +280,7 @@ monotonic==1.6 # via # -r requirements/base.txt # analytics-python -mysqlclient==2.2.4 +mysqlclient==2.2.5 # via -r requirements/base.txt newrelic==10.2.0 # via @@ -309,7 +309,7 @@ prompt-toolkit==3.0.48 # via # -r requirements/base.txt # click-repl -psutil==6.0.0 +psutil==6.1.0 # via # -r requirements/base.txt # edx-django-utils diff --git a/requirements/validation.txt b/requirements/validation.txt index d49c6103..06a4b859 100644 --- a/requirements/validation.txt +++ b/requirements/validation.txt @@ -45,12 +45,12 @@ bleach==6.1.0 # via # -r requirements/quality.txt # -r requirements/test.txt -boto3==1.35.42 +boto3==1.35.45 # via # -r requirements/quality.txt # -r requirements/test.txt # django-ses -botocore==1.35.42 +botocore==1.35.45 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -116,11 +116,11 @@ code-annotations==1.8.0 # -r requirements/test.txt # edx-lint # edx-toggles -coverage[toml]==7.6.3 +coverage[toml]==7.6.4 # via # -r requirements/test.txt # pytest-cov -cryptography==43.0.1 +cryptography==43.0.3 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -274,7 +274,7 @@ edx-celeryutils==1.3.0 # via # -r requirements/quality.txt # -r requirements/test.txt -edx-django-utils==6.1.0 +edx-django-utils==7.0.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -311,7 +311,7 @@ edx-toggles==5.2.0 # -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==30.6.0 +faker==30.8.0 # via # -r requirements/test.txt # factory-boy @@ -373,7 +373,7 @@ lxml[html-clean,html_clean]==5.3.0 # lxml-html-clean lxml-html-clean==0.3.1 # via lxml -markupsafe==3.0.1 +markupsafe==3.0.2 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -388,7 +388,7 @@ monotonic==1.6 # -r requirements/quality.txt # -r requirements/test.txt # analytics-python -mysqlclient==2.2.4 +mysqlclient==2.2.5 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -439,7 +439,7 @@ prompt-toolkit==3.0.48 # -r requirements/quality.txt # -r requirements/test.txt # click-repl -psutil==6.0.0 +psutil==6.1.0 # via # -r requirements/quality.txt # -r requirements/test.txt From 8f2b048bf98bb75090eb55b703787ba92bb8150a Mon Sep 17 00:00:00 2001 From: Ejaz Ahmad <86868918+jajjibhai008@users.noreply.github.com> Date: Tue, 22 Oct 2024 17:02:25 +0500 Subject: [PATCH 16/23] Revert "chore: Upgrade Python requirements" --- requirements/base.txt | 14 +++++++------- requirements/dev.txt | 18 +++++++++--------- requirements/doc.txt | 18 +++++++++--------- requirements/production.txt | 16 ++++++++-------- requirements/quality.txt | 14 +++++++------- requirements/test.txt | 18 +++++++++--------- requirements/validation.txt | 18 +++++++++--------- 7 files changed, 58 insertions(+), 58 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 80254895..7800d2c1 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -24,9 +24,9 @@ billiard==4.2.1 # via celery bleach==6.1.0 # via -r requirements/base.in -boto3==1.35.45 +boto3==1.35.42 # via django-ses -botocore==1.35.45 +botocore==1.35.42 # via # boto3 # s3transfer @@ -59,7 +59,7 @@ click-repl==0.3.0 # via celery code-annotations==1.8.0 # via edx-toggles -cryptography==43.0.3 +cryptography==43.0.1 # via # pyjwt # social-auth-core @@ -155,7 +155,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.in edx-celeryutils==1.3.0 # via -r requirements/base.in -edx-django-utils==7.0.0 +edx-django-utils==6.1.0 # via # -r requirements/base.in # edx-drf-extensions @@ -191,11 +191,11 @@ jsonschema-specifications==2024.10.1 # via jsonschema kombu==5.4.2 # via celery -markupsafe==3.0.2 +markupsafe==3.0.1 # via jinja2 monotonic==1.6 # via analytics-python -mysqlclient==2.2.5 +mysqlclient==2.2.4 # via -r requirements/base.in newrelic==10.2.0 # via edx-django-utils @@ -209,7 +209,7 @@ ply==3.11 # via djangoql prompt-toolkit==3.0.48 # via click-repl -psutil==6.1.0 +psutil==6.0.0 # via edx-django-utils pycparser==2.22 # via cffi diff --git a/requirements/dev.txt b/requirements/dev.txt index 5c1580ef..84f5cc3d 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -35,11 +35,11 @@ billiard==4.2.1 # celery bleach==6.1.0 # via -r requirements/validation.txt -boto3==1.35.45 +boto3==1.35.42 # via # -r requirements/validation.txt # django-ses -botocore==1.35.45 +botocore==1.35.42 # via # -r requirements/validation.txt # boto3 @@ -100,11 +100,11 @@ code-annotations==1.8.0 # -r requirements/validation.txt # edx-lint # edx-toggles -coverage[toml]==7.6.4 +coverage[toml]==7.6.3 # via # -r requirements/validation.txt # pytest-cov -cryptography==43.0.3 +cryptography==43.0.1 # via # -r requirements/validation.txt # pyjwt @@ -227,7 +227,7 @@ edx-braze-client==0.2.5 # via -r requirements/validation.txt edx-celeryutils==1.3.0 # via -r requirements/validation.txt -edx-django-utils==7.0.0 +edx-django-utils==6.1.0 # via # -r requirements/validation.txt # edx-drf-extensions @@ -253,7 +253,7 @@ edx-toggles==5.2.0 # via -r requirements/validation.txt factory-boy==3.3.1 # via -r requirements/validation.txt -faker==30.8.0 +faker==30.6.0 # via # -r requirements/validation.txt # factory-boy @@ -319,7 +319,7 @@ lxml-html-clean==0.3.1 # via # -r requirements/validation.txt # lxml -markupsafe==3.0.2 +markupsafe==3.0.1 # via # -r requirements/validation.txt # jinja2 @@ -333,7 +333,7 @@ monotonic==1.6 # analytics-python more-itertools==10.5.0 # via inflect -mysqlclient==2.2.5 +mysqlclient==2.2.4 # via -r requirements/validation.txt newrelic==10.2.0 # via @@ -385,7 +385,7 @@ prompt-toolkit==3.0.48 # via # -r requirements/validation.txt # click-repl -psutil==6.1.0 +psutil==6.0.0 # via # -r requirements/validation.txt # edx-django-utils diff --git a/requirements/doc.txt b/requirements/doc.txt index 6507c14e..54859157 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -45,11 +45,11 @@ billiard==4.2.1 # celery bleach==6.1.0 # via -r requirements/test.txt -boto3==1.35.45 +boto3==1.35.42 # via # -r requirements/test.txt # django-ses -botocore==1.35.45 +botocore==1.35.42 # via # -r requirements/test.txt # boto3 @@ -104,11 +104,11 @@ code-annotations==1.8.0 # -r requirements/test.txt # edx-lint # edx-toggles -coverage[toml]==7.6.4 +coverage[toml]==7.6.3 # via # -r requirements/test.txt # pytest-cov -cryptography==43.0.3 +cryptography==43.0.1 # via # -r requirements/test.txt # pyjwt @@ -228,7 +228,7 @@ edx-braze-client==0.2.5 # via -r requirements/test.txt edx-celeryutils==1.3.0 # via -r requirements/test.txt -edx-django-utils==7.0.0 +edx-django-utils==6.1.0 # via # -r requirements/test.txt # edx-drf-extensions @@ -252,7 +252,7 @@ edx-toggles==5.2.0 # via -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==30.8.0 +faker==30.6.0 # via # -r requirements/test.txt # factory-boy @@ -302,7 +302,7 @@ kombu==5.4.2 # via # -r requirements/test.txt # celery -markupsafe==3.0.2 +markupsafe==3.0.1 # via # -r requirements/test.txt # jinja2 @@ -314,7 +314,7 @@ monotonic==1.6 # via # -r requirements/test.txt # analytics-python -mysqlclient==2.2.5 +mysqlclient==2.2.4 # via -r requirements/test.txt newrelic==10.2.0 # via @@ -353,7 +353,7 @@ prompt-toolkit==3.0.48 # via # -r requirements/test.txt # click-repl -psutil==6.1.0 +psutil==6.0.0 # via # -r requirements/test.txt # edx-django-utils diff --git a/requirements/production.txt b/requirements/production.txt index c889c267..08ca91b5 100644 --- a/requirements/production.txt +++ b/requirements/production.txt @@ -30,11 +30,11 @@ billiard==4.2.1 # celery bleach==6.1.0 # via -r requirements/base.txt -boto3==1.35.45 +boto3==1.35.42 # via # -r requirements/base.txt # django-ses -botocore==1.35.45 +botocore==1.35.42 # via # -r requirements/base.txt # boto3 @@ -82,7 +82,7 @@ code-annotations==1.8.0 # via # -r requirements/base.txt # edx-toggles -cryptography==43.0.3 +cryptography==43.0.1 # via # -r requirements/base.txt # pyjwt @@ -185,7 +185,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.txt edx-celeryutils==1.3.0 # via -r requirements/base.txt -edx-django-utils==7.0.0 +edx-django-utils==6.1.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -205,7 +205,7 @@ edx-rest-api-client==6.0.0 # via -r requirements/base.txt edx-toggles==5.2.0 # via -r requirements/base.txt -gevent==24.10.3 +gevent==24.10.2 # via -r requirements/production.in greenlet==3.1.1 # via gevent @@ -244,7 +244,7 @@ kombu==5.4.2 # via # -r requirements/base.txt # celery -markupsafe==3.0.2 +markupsafe==3.0.1 # via # -r requirements/base.txt # jinja2 @@ -252,7 +252,7 @@ monotonic==1.6 # via # -r requirements/base.txt # analytics-python -mysqlclient==2.2.5 +mysqlclient==2.2.4 # via -r requirements/base.txt newrelic==10.2.0 # via @@ -277,7 +277,7 @@ prompt-toolkit==3.0.48 # via # -r requirements/base.txt # click-repl -psutil==6.1.0 +psutil==6.0.0 # via # -r requirements/base.txt # edx-django-utils diff --git a/requirements/quality.txt b/requirements/quality.txt index 846ae997..bbad69ae 100644 --- a/requirements/quality.txt +++ b/requirements/quality.txt @@ -34,11 +34,11 @@ billiard==4.2.1 # celery bleach==6.1.0 # via -r requirements/base.txt -boto3==1.35.45 +boto3==1.35.42 # via # -r requirements/base.txt # django-ses -botocore==1.35.45 +botocore==1.35.42 # via # -r requirements/base.txt # boto3 @@ -91,7 +91,7 @@ code-annotations==1.8.0 # -r requirements/base.txt # edx-lint # edx-toggles -cryptography==43.0.3 +cryptography==43.0.1 # via # -r requirements/base.txt # pyjwt @@ -196,7 +196,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.txt edx-celeryutils==1.3.0 # via -r requirements/base.txt -edx-django-utils==7.0.0 +edx-django-utils==6.1.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -255,7 +255,7 @@ kombu==5.4.2 # via # -r requirements/base.txt # celery -markupsafe==3.0.2 +markupsafe==3.0.1 # via # -r requirements/base.txt # jinja2 @@ -265,7 +265,7 @@ monotonic==1.6 # via # -r requirements/base.txt # analytics-python -mysqlclient==2.2.5 +mysqlclient==2.2.4 # via -r requirements/base.txt newrelic==10.2.0 # via @@ -290,7 +290,7 @@ prompt-toolkit==3.0.48 # via # -r requirements/base.txt # click-repl -psutil==6.1.0 +psutil==6.0.0 # via # -r requirements/base.txt # edx-django-utils diff --git a/requirements/test.txt b/requirements/test.txt index 17eb45be..ed139657 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -34,11 +34,11 @@ billiard==4.2.1 # celery bleach==6.1.0 # via -r requirements/base.txt -boto3==1.35.45 +boto3==1.35.42 # via # -r requirements/base.txt # django-ses -botocore==1.35.45 +botocore==1.35.42 # via # -r requirements/base.txt # boto3 @@ -92,11 +92,11 @@ code-annotations==1.8.0 # -r requirements/test.in # edx-lint # edx-toggles -coverage[toml]==7.6.4 +coverage[toml]==7.6.3 # via # -r requirements/test.in # pytest-cov -cryptography==43.0.3 +cryptography==43.0.1 # via # -r requirements/base.txt # pyjwt @@ -205,7 +205,7 @@ edx-braze-client==0.2.5 # via -r requirements/base.txt edx-celeryutils==1.3.0 # via -r requirements/base.txt -edx-django-utils==7.0.0 +edx-django-utils==6.1.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -229,7 +229,7 @@ edx-toggles==5.2.0 # via -r requirements/base.txt factory-boy==3.3.1 # via -r requirements/test.in -faker==30.8.0 +faker==30.6.0 # via factory-boy freezegun==1.5.1 # via -r requirements/test.in @@ -270,7 +270,7 @@ kombu==5.4.2 # via # -r requirements/base.txt # celery -markupsafe==3.0.2 +markupsafe==3.0.1 # via # -r requirements/base.txt # jinja2 @@ -280,7 +280,7 @@ monotonic==1.6 # via # -r requirements/base.txt # analytics-python -mysqlclient==2.2.5 +mysqlclient==2.2.4 # via -r requirements/base.txt newrelic==10.2.0 # via @@ -309,7 +309,7 @@ prompt-toolkit==3.0.48 # via # -r requirements/base.txt # click-repl -psutil==6.1.0 +psutil==6.0.0 # via # -r requirements/base.txt # edx-django-utils diff --git a/requirements/validation.txt b/requirements/validation.txt index 06a4b859..d49c6103 100644 --- a/requirements/validation.txt +++ b/requirements/validation.txt @@ -45,12 +45,12 @@ bleach==6.1.0 # via # -r requirements/quality.txt # -r requirements/test.txt -boto3==1.35.45 +boto3==1.35.42 # via # -r requirements/quality.txt # -r requirements/test.txt # django-ses -botocore==1.35.45 +botocore==1.35.42 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -116,11 +116,11 @@ code-annotations==1.8.0 # -r requirements/test.txt # edx-lint # edx-toggles -coverage[toml]==7.6.4 +coverage[toml]==7.6.3 # via # -r requirements/test.txt # pytest-cov -cryptography==43.0.3 +cryptography==43.0.1 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -274,7 +274,7 @@ edx-celeryutils==1.3.0 # via # -r requirements/quality.txt # -r requirements/test.txt -edx-django-utils==7.0.0 +edx-django-utils==6.1.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -311,7 +311,7 @@ edx-toggles==5.2.0 # -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==30.8.0 +faker==30.6.0 # via # -r requirements/test.txt # factory-boy @@ -373,7 +373,7 @@ lxml[html-clean,html_clean]==5.3.0 # lxml-html-clean lxml-html-clean==0.3.1 # via lxml -markupsafe==3.0.2 +markupsafe==3.0.1 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -388,7 +388,7 @@ monotonic==1.6 # -r requirements/quality.txt # -r requirements/test.txt # analytics-python -mysqlclient==2.2.5 +mysqlclient==2.2.4 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -439,7 +439,7 @@ prompt-toolkit==3.0.48 # -r requirements/quality.txt # -r requirements/test.txt # click-repl -psutil==6.1.0 +psutil==6.0.0 # via # -r requirements/quality.txt # -r requirements/test.txt From 194c8c131b02353c95dcadc01a00d28833f3a4c6 Mon Sep 17 00:00:00 2001 From: jajjibhai008 Date: Tue, 22 Oct 2024 15:40:52 +0500 Subject: [PATCH 17/23] refactor: remove the old fields in user agreement model --- license_manager/apps/api/serializers.py | 2 -- license_manager/apps/subscriptions/admin.py | 2 -- license_manager/apps/subscriptions/models.py | 22 -------------------- 3 files changed, 26 deletions(-) diff --git a/license_manager/apps/api/serializers.py b/license_manager/apps/api/serializers.py index 5123f0bf..c6795d21 100644 --- a/license_manager/apps/api/serializers.py +++ b/license_manager/apps/api/serializers.py @@ -360,8 +360,6 @@ class Meta: 'expired_subscription_modal_messaging', 'button_label_in_modal', 'url_for_button_in_modal', - 'hyper_link_text_for_expired_modal', - 'url_for_expired_modal', ] def get_subscription_for_auto_applied_licenses(self, obj): diff --git a/license_manager/apps/subscriptions/admin.py b/license_manager/apps/subscriptions/admin.py index 522a28a1..17d64662 100644 --- a/license_manager/apps/subscriptions/admin.py +++ b/license_manager/apps/subscriptions/admin.py @@ -423,8 +423,6 @@ class CustomerAgreementAdmin(admin.ModelAdmin): 'expired_subscription_modal_messaging', 'button_label_in_modal', 'url_for_button_in_modal', - 'hyper_link_text_for_expired_modal', - 'url_for_expired_modal' ) custom_fields = ('subscription_for_auto_applied_licenses',) diff --git a/license_manager/apps/subscriptions/models.py b/license_manager/apps/subscriptions/models.py index e786e8af..47939af6 100644 --- a/license_manager/apps/subscriptions/models.py +++ b/license_manager/apps/subscriptions/models.py @@ -169,24 +169,6 @@ class CustomerAgreement(TimeStampedModel): ) ) - hyper_link_text_for_expired_modal = models.CharField( - max_length=255, - blank=True, - null=True, - help_text=_( - "The display text for the link that will be embedded at the end of the custom expiration modal." - ) - ) - - url_for_expired_modal = models.CharField( - max_length=512, - blank=True, - null=True, - help_text=_( - "The underlying url that will be embedded as a hyperlink at the end of the custom expiration modal." - ) - ) - button_label_in_modal = models.CharField( max_length=255, blank=True, @@ -281,8 +263,6 @@ def clean(self): "expired_subscription_modal_messaging": error_message, "button_label_in_modal": error_message, "url_for_button_in_modal": error_message, - "hyper_link_text_for_expired_modal": error_message, - "url_for_expired_modal": error_message } # Check if any required fields are missing @@ -297,8 +277,6 @@ def clean(self): "expired_subscription_modal_messaging", "button_label_in_modal", "url_for_button_in_modal", - "hyper_link_text_for_expired_modal", - "url_for_expired_modal", ] if any(getattr(self, field) for field in fields_to_check): error_msg = "This field must be blank if 'Has Custom License Expiration Messaging' is unchecked." From fdf5a764af6f60f8f245f06c106f3f2c1cf5b390 Mon Sep 17 00:00:00 2001 From: jajjibhai008 Date: Wed, 23 Oct 2024 14:31:51 +0500 Subject: [PATCH 18/23] refactor: added migrations for user agreement model --- ...er_link_text_for_expired_modal_and_more.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 license_manager/apps/subscriptions/migrations/0073_remove_customeragreement_hyper_link_text_for_expired_modal_and_more.py diff --git a/license_manager/apps/subscriptions/migrations/0073_remove_customeragreement_hyper_link_text_for_expired_modal_and_more.py b/license_manager/apps/subscriptions/migrations/0073_remove_customeragreement_hyper_link_text_for_expired_modal_and_more.py new file mode 100644 index 00000000..14a31ba8 --- /dev/null +++ b/license_manager/apps/subscriptions/migrations/0073_remove_customeragreement_hyper_link_text_for_expired_modal_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 4.2.16 on 2024-10-23 08:16 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('subscriptions', '0072_customeragreement_button_label_in_modal_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='customeragreement', + name='hyper_link_text_for_expired_modal', + ), + migrations.RemoveField( + model_name='customeragreement', + name='url_for_expired_modal', + ), + migrations.RemoveField( + model_name='historicalcustomeragreement', + name='hyper_link_text_for_expired_modal', + ), + migrations.RemoveField( + model_name='historicalcustomeragreement', + name='url_for_expired_modal', + ), + ] From 144381d52081491250b792a6d1f52168b23c50c0 Mon Sep 17 00:00:00 2001 From: jajjibhai008 Date: Thu, 24 Oct 2024 13:20:07 +0500 Subject: [PATCH 19/23] feat: add validation check on valid url in user agreement model --- license_manager/apps/subscriptions/models.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/license_manager/apps/subscriptions/models.py b/license_manager/apps/subscriptions/models.py index 47939af6..b26071f7 100644 --- a/license_manager/apps/subscriptions/models.py +++ b/license_manager/apps/subscriptions/models.py @@ -282,6 +282,12 @@ def clean(self): error_msg = "This field must be blank if 'Has Custom License Expiration Messaging' is unchecked." errors = {field: error_msg for field in fields_to_check} + # Validate that url_for_button_in_modal is a complete URL + if self.url_for_button_in_modal and not self.url_for_button_in_modal.startswith(("http://", "https://")): + errors["url_for_button_in_modal"] = ( + "The URL must start with 'http://' or 'https://'. Please provide a valid URL." + ) + # Raise ValidationError if there are any errors if errors: raise ValidationError(errors) From b3e210bb1d9f3c20b0822fac37052208d2f9770a Mon Sep 17 00:00:00 2001 From: jajjibhai008 Date: Fri, 25 Oct 2024 17:59:08 +0500 Subject: [PATCH 20/23] chore: Upgrade Python requirements --- requirements/base.txt | 17 +++++++++-------- requirements/constraints.txt | 5 +++++ requirements/dev.txt | 21 +++++++++++---------- requirements/doc.txt | 24 ++++++++++++------------ requirements/production.txt | 21 +++++++++++---------- requirements/quality.txt | 17 +++++++++-------- requirements/test.txt | 21 +++++++++++---------- requirements/validation.txt | 21 +++++++++++---------- 8 files changed, 79 insertions(+), 68 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 7800d2c1..030065c4 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -24,9 +24,9 @@ billiard==4.2.1 # via celery bleach==6.1.0 # via -r requirements/base.in -boto3==1.35.42 +boto3==1.35.48 # via django-ses -botocore==1.35.42 +botocore==1.35.48 # via # boto3 # s3transfer @@ -59,7 +59,7 @@ click-repl==0.3.0 # via celery code-annotations==1.8.0 # via edx-toggles -cryptography==43.0.1 +cryptography==43.0.3 # via # pyjwt # social-auth-core @@ -157,11 +157,12 @@ edx-celeryutils==1.3.0 # via -r requirements/base.in edx-django-utils==6.1.0 # via + # -c requirements/constraints.txt # -r requirements/base.in # edx-drf-extensions # edx-rest-api-client # edx-toggles -edx-drf-extensions==10.4.0 +edx-drf-extensions==10.5.0 # via # -r requirements/base.in # edx-rbac @@ -191,11 +192,11 @@ jsonschema-specifications==2024.10.1 # via jsonschema kombu==5.4.2 # via celery -markupsafe==3.0.1 +markupsafe==3.0.2 # via jinja2 monotonic==1.6 # via analytics-python -mysqlclient==2.2.4 +mysqlclient==2.2.5 # via -r requirements/base.in newrelic==10.2.0 # via edx-django-utils @@ -209,7 +210,7 @@ ply==3.11 # via djangoql prompt-toolkit==3.0.48 # via click-repl -psutil==6.0.0 +psutil==6.1.0 # via edx-django-utils pycparser==2.22 # via cffi @@ -239,7 +240,7 @@ pyyaml==6.0.2 # via # code-annotations # drf-spectacular -redis==5.1.1 +redis==5.2.0 # via -r requirements/base.in referencing==0.35.1 # via diff --git a/requirements/constraints.txt b/requirements/constraints.txt index ba78494f..f4017bc5 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -21,3 +21,8 @@ backports.zoneinfo;python_version<"3.9" # path>16.14.0 has removed the deprecated abspath function, which is breaking the docs build path<16.15.0 + +# The newer version if this package has drop support for background tasks so that why +# when i include that new version (7.0.0) in the requirements upgrade, most of the jobs start failing +# so i have to pin this version to 6.1.0 +edx-django-utils==6.1.0 diff --git a/requirements/dev.txt b/requirements/dev.txt index 84f5cc3d..a14bf087 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -35,11 +35,11 @@ billiard==4.2.1 # celery bleach==6.1.0 # via -r requirements/validation.txt -boto3==1.35.42 +boto3==1.35.48 # via # -r requirements/validation.txt # django-ses -botocore==1.35.42 +botocore==1.35.48 # via # -r requirements/validation.txt # boto3 @@ -100,11 +100,11 @@ code-annotations==1.8.0 # -r requirements/validation.txt # edx-lint # edx-toggles -coverage[toml]==7.6.3 +coverage[toml]==7.6.4 # via # -r requirements/validation.txt # pytest-cov -cryptography==43.0.1 +cryptography==43.0.3 # via # -r requirements/validation.txt # pyjwt @@ -229,11 +229,12 @@ edx-celeryutils==1.3.0 # via -r requirements/validation.txt edx-django-utils==6.1.0 # via + # -c requirements/constraints.txt # -r requirements/validation.txt # edx-drf-extensions # edx-rest-api-client # edx-toggles -edx-drf-extensions==10.4.0 +edx-drf-extensions==10.5.0 # via # -r requirements/validation.txt # edx-rbac @@ -253,7 +254,7 @@ edx-toggles==5.2.0 # via -r requirements/validation.txt factory-boy==3.3.1 # via -r requirements/validation.txt -faker==30.6.0 +faker==30.8.1 # via # -r requirements/validation.txt # factory-boy @@ -319,7 +320,7 @@ lxml-html-clean==0.3.1 # via # -r requirements/validation.txt # lxml -markupsafe==3.0.1 +markupsafe==3.0.2 # via # -r requirements/validation.txt # jinja2 @@ -333,7 +334,7 @@ monotonic==1.6 # analytics-python more-itertools==10.5.0 # via inflect -mysqlclient==2.2.4 +mysqlclient==2.2.5 # via -r requirements/validation.txt newrelic==10.2.0 # via @@ -385,7 +386,7 @@ prompt-toolkit==3.0.48 # via # -r requirements/validation.txt # click-repl -psutil==6.0.0 +psutil==6.1.0 # via # -r requirements/validation.txt # edx-django-utils @@ -475,7 +476,7 @@ pyyaml==6.0.2 # code-annotations # drf-spectacular # edx-i18n-tools -redis==5.1.1 +redis==5.2.0 # via -r requirements/validation.txt referencing==0.35.1 # via diff --git a/requirements/doc.txt b/requirements/doc.txt index 54859157..665a9750 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -45,11 +45,11 @@ billiard==4.2.1 # celery bleach==6.1.0 # via -r requirements/test.txt -boto3==1.35.42 +boto3==1.35.48 # via # -r requirements/test.txt # django-ses -botocore==1.35.42 +botocore==1.35.48 # via # -r requirements/test.txt # boto3 @@ -104,11 +104,11 @@ code-annotations==1.8.0 # -r requirements/test.txt # edx-lint # edx-toggles -coverage[toml]==7.6.3 +coverage[toml]==7.6.4 # via # -r requirements/test.txt # pytest-cov -cryptography==43.0.1 +cryptography==43.0.3 # via # -r requirements/test.txt # pyjwt @@ -230,11 +230,12 @@ edx-celeryutils==1.3.0 # via -r requirements/test.txt edx-django-utils==6.1.0 # via + # -c requirements/constraints.txt # -r requirements/test.txt # edx-drf-extensions # edx-rest-api-client # edx-toggles -edx-drf-extensions==10.4.0 +edx-drf-extensions==10.5.0 # via # -r requirements/test.txt # edx-rbac @@ -252,7 +253,7 @@ edx-toggles==5.2.0 # via -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==30.6.0 +faker==30.8.1 # via # -r requirements/test.txt # factory-boy @@ -302,7 +303,7 @@ kombu==5.4.2 # via # -r requirements/test.txt # celery -markupsafe==3.0.1 +markupsafe==3.0.2 # via # -r requirements/test.txt # jinja2 @@ -314,7 +315,7 @@ monotonic==1.6 # via # -r requirements/test.txt # analytics-python -mysqlclient==2.2.4 +mysqlclient==2.2.5 # via -r requirements/test.txt newrelic==10.2.0 # via @@ -330,7 +331,6 @@ oauthlib==3.2.2 packaging==24.1 # via # -r requirements/test.txt - # pydata-sphinx-theme # pytest # sphinx pbr==6.1.0 @@ -353,7 +353,7 @@ prompt-toolkit==3.0.48 # via # -r requirements/test.txt # click-repl -psutil==6.0.0 +psutil==6.1.0 # via # -r requirements/test.txt # edx-django-utils @@ -361,7 +361,7 @@ pycparser==2.22 # via # -r requirements/test.txt # cffi -pydata-sphinx-theme==0.15.4 +pydata-sphinx-theme==0.16.0 # via sphinx-book-theme pygments==2.18.0 # via @@ -440,7 +440,7 @@ pyyaml==6.0.2 # drf-spectacular readme-renderer==44.0 # via -r requirements/doc.in -redis==5.1.1 +redis==5.2.0 # via -r requirements/test.txt referencing==0.35.1 # via diff --git a/requirements/production.txt b/requirements/production.txt index 08ca91b5..fa9b4d2d 100644 --- a/requirements/production.txt +++ b/requirements/production.txt @@ -30,11 +30,11 @@ billiard==4.2.1 # celery bleach==6.1.0 # via -r requirements/base.txt -boto3==1.35.42 +boto3==1.35.48 # via # -r requirements/base.txt # django-ses -botocore==1.35.42 +botocore==1.35.48 # via # -r requirements/base.txt # boto3 @@ -82,7 +82,7 @@ code-annotations==1.8.0 # via # -r requirements/base.txt # edx-toggles -cryptography==43.0.1 +cryptography==43.0.3 # via # -r requirements/base.txt # pyjwt @@ -187,11 +187,12 @@ edx-celeryutils==1.3.0 # via -r requirements/base.txt edx-django-utils==6.1.0 # via + # -c requirements/constraints.txt # -r requirements/base.txt # edx-drf-extensions # edx-rest-api-client # edx-toggles -edx-drf-extensions==10.4.0 +edx-drf-extensions==10.5.0 # via # -r requirements/base.txt # edx-rbac @@ -205,7 +206,7 @@ edx-rest-api-client==6.0.0 # via -r requirements/base.txt edx-toggles==5.2.0 # via -r requirements/base.txt -gevent==24.10.2 +gevent==24.10.3 # via -r requirements/production.in greenlet==3.1.1 # via gevent @@ -244,7 +245,7 @@ kombu==5.4.2 # via # -r requirements/base.txt # celery -markupsafe==3.0.1 +markupsafe==3.0.2 # via # -r requirements/base.txt # jinja2 @@ -252,7 +253,7 @@ monotonic==1.6 # via # -r requirements/base.txt # analytics-python -mysqlclient==2.2.4 +mysqlclient==2.2.5 # via -r requirements/base.txt newrelic==10.2.0 # via @@ -277,7 +278,7 @@ prompt-toolkit==3.0.48 # via # -r requirements/base.txt # click-repl -psutil==6.0.0 +psutil==6.1.0 # via # -r requirements/base.txt # edx-django-utils @@ -327,7 +328,7 @@ pyyaml==6.0.2 # -r requirements/production.in # code-annotations # drf-spectacular -redis==5.1.1 +redis==5.2.0 # via -r requirements/base.txt referencing==0.35.1 # via @@ -430,7 +431,7 @@ zipp==3.20.2 # via -r requirements/base.txt zope-event==5.0 # via gevent -zope-interface==7.1.0 +zope-interface==7.1.1 # via gevent # The following packages are considered to be unsafe in a requirements file: diff --git a/requirements/quality.txt b/requirements/quality.txt index bbad69ae..a8dc3575 100644 --- a/requirements/quality.txt +++ b/requirements/quality.txt @@ -34,11 +34,11 @@ billiard==4.2.1 # celery bleach==6.1.0 # via -r requirements/base.txt -boto3==1.35.42 +boto3==1.35.48 # via # -r requirements/base.txt # django-ses -botocore==1.35.42 +botocore==1.35.48 # via # -r requirements/base.txt # boto3 @@ -91,7 +91,7 @@ code-annotations==1.8.0 # -r requirements/base.txt # edx-lint # edx-toggles -cryptography==43.0.1 +cryptography==43.0.3 # via # -r requirements/base.txt # pyjwt @@ -198,11 +198,12 @@ edx-celeryutils==1.3.0 # via -r requirements/base.txt edx-django-utils==6.1.0 # via + # -c requirements/constraints.txt # -r requirements/base.txt # edx-drf-extensions # edx-rest-api-client # edx-toggles -edx-drf-extensions==10.4.0 +edx-drf-extensions==10.5.0 # via # -r requirements/base.txt # edx-rbac @@ -255,7 +256,7 @@ kombu==5.4.2 # via # -r requirements/base.txt # celery -markupsafe==3.0.1 +markupsafe==3.0.2 # via # -r requirements/base.txt # jinja2 @@ -265,7 +266,7 @@ monotonic==1.6 # via # -r requirements/base.txt # analytics-python -mysqlclient==2.2.4 +mysqlclient==2.2.5 # via -r requirements/base.txt newrelic==10.2.0 # via @@ -290,7 +291,7 @@ prompt-toolkit==3.0.48 # via # -r requirements/base.txt # click-repl -psutil==6.0.0 +psutil==6.1.0 # via # -r requirements/base.txt # edx-django-utils @@ -353,7 +354,7 @@ pyyaml==6.0.2 # -r requirements/base.txt # code-annotations # drf-spectacular -redis==5.1.1 +redis==5.2.0 # via -r requirements/base.txt referencing==0.35.1 # via diff --git a/requirements/test.txt b/requirements/test.txt index ed139657..e636193c 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -34,11 +34,11 @@ billiard==4.2.1 # celery bleach==6.1.0 # via -r requirements/base.txt -boto3==1.35.42 +boto3==1.35.48 # via # -r requirements/base.txt # django-ses -botocore==1.35.42 +botocore==1.35.48 # via # -r requirements/base.txt # boto3 @@ -92,11 +92,11 @@ code-annotations==1.8.0 # -r requirements/test.in # edx-lint # edx-toggles -coverage[toml]==7.6.3 +coverage[toml]==7.6.4 # via # -r requirements/test.in # pytest-cov -cryptography==43.0.1 +cryptography==43.0.3 # via # -r requirements/base.txt # pyjwt @@ -207,11 +207,12 @@ edx-celeryutils==1.3.0 # via -r requirements/base.txt edx-django-utils==6.1.0 # via + # -c requirements/constraints.txt # -r requirements/base.txt # edx-drf-extensions # edx-rest-api-client # edx-toggles -edx-drf-extensions==10.4.0 +edx-drf-extensions==10.5.0 # via # -r requirements/base.txt # edx-rbac @@ -229,7 +230,7 @@ edx-toggles==5.2.0 # via -r requirements/base.txt factory-boy==3.3.1 # via -r requirements/test.in -faker==30.6.0 +faker==30.8.1 # via factory-boy freezegun==1.5.1 # via -r requirements/test.in @@ -270,7 +271,7 @@ kombu==5.4.2 # via # -r requirements/base.txt # celery -markupsafe==3.0.1 +markupsafe==3.0.2 # via # -r requirements/base.txt # jinja2 @@ -280,7 +281,7 @@ monotonic==1.6 # via # -r requirements/base.txt # analytics-python -mysqlclient==2.2.4 +mysqlclient==2.2.5 # via -r requirements/base.txt newrelic==10.2.0 # via @@ -309,7 +310,7 @@ prompt-toolkit==3.0.48 # via # -r requirements/base.txt # click-repl -psutil==6.0.0 +psutil==6.1.0 # via # -r requirements/base.txt # edx-django-utils @@ -378,7 +379,7 @@ pyyaml==6.0.2 # -r requirements/base.txt # code-annotations # drf-spectacular -redis==5.1.1 +redis==5.2.0 # via -r requirements/base.txt referencing==0.35.1 # via diff --git a/requirements/validation.txt b/requirements/validation.txt index d49c6103..052b6a76 100644 --- a/requirements/validation.txt +++ b/requirements/validation.txt @@ -45,12 +45,12 @@ bleach==6.1.0 # via # -r requirements/quality.txt # -r requirements/test.txt -boto3==1.35.42 +boto3==1.35.48 # via # -r requirements/quality.txt # -r requirements/test.txt # django-ses -botocore==1.35.42 +botocore==1.35.48 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -116,11 +116,11 @@ code-annotations==1.8.0 # -r requirements/test.txt # edx-lint # edx-toggles -coverage[toml]==7.6.3 +coverage[toml]==7.6.4 # via # -r requirements/test.txt # pytest-cov -cryptography==43.0.1 +cryptography==43.0.3 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -276,12 +276,13 @@ edx-celeryutils==1.3.0 # -r requirements/test.txt edx-django-utils==6.1.0 # via + # -c requirements/constraints.txt # -r requirements/quality.txt # -r requirements/test.txt # edx-drf-extensions # edx-rest-api-client # edx-toggles -edx-drf-extensions==10.4.0 +edx-drf-extensions==10.5.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -311,7 +312,7 @@ edx-toggles==5.2.0 # -r requirements/test.txt factory-boy==3.3.1 # via -r requirements/test.txt -faker==30.6.0 +faker==30.8.1 # via # -r requirements/test.txt # factory-boy @@ -373,7 +374,7 @@ lxml[html-clean,html_clean]==5.3.0 # lxml-html-clean lxml-html-clean==0.3.1 # via lxml -markupsafe==3.0.1 +markupsafe==3.0.2 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -388,7 +389,7 @@ monotonic==1.6 # -r requirements/quality.txt # -r requirements/test.txt # analytics-python -mysqlclient==2.2.4 +mysqlclient==2.2.5 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -439,7 +440,7 @@ prompt-toolkit==3.0.48 # -r requirements/quality.txt # -r requirements/test.txt # click-repl -psutil==6.0.0 +psutil==6.1.0 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -535,7 +536,7 @@ pyyaml==6.0.2 # code-annotations # drf-spectacular # edx-i18n-tools -redis==5.1.1 +redis==5.2.0 # via # -r requirements/quality.txt # -r requirements/test.txt From 7fef60cc9207bd3518706cddb04a4c9a1c7e5ffd Mon Sep 17 00:00:00 2001 From: Brian Beggs Date: Mon, 28 Oct 2024 14:50:12 -0400 Subject: [PATCH 21/23] chore: Add CSSSanitizer to sanitize_html --- license_manager/apps/subscriptions/sanitize.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/license_manager/apps/subscriptions/sanitize.py b/license_manager/apps/subscriptions/sanitize.py index c2da423b..3b22dfe8 100644 --- a/license_manager/apps/subscriptions/sanitize.py +++ b/license_manager/apps/subscriptions/sanitize.py @@ -1,5 +1,5 @@ import bleach - +from bleach.css_sanitizer import CSSSanitizer def sanitize_html(html_content): """ @@ -7,8 +7,9 @@ def sanitize_html(html_content): while disallowing JavaScript and unsafe protocols. """ # Define allowed tags and attributes - allowed_tags = bleach.ALLOWED_TAGS # Allow all standard HTML tags + allowed_tags = set.union(bleach.ALLOWED_TAGS, set({"span"})) # Allow all standard HTML tags allowed_attrs = {"*": ["className", "class", "style", "id"]} + css_sanitizer = CSSSanitizer(allowed_css_properties=["color", "font-weight"]) # Clean the HTML content sanitized_content = bleach.clean( @@ -16,7 +17,8 @@ def sanitize_html(html_content): tags=allowed_tags, attributes=allowed_attrs, strip=True, # Strip disallowed tags completely - protocols=["http", "https"], # Only allow http and https URLs + protocols=["http", "https"], # Only allow http and https URLs, + css_sanitizer=css_sanitizer, ) # Use bleach.linkify to ensure no javascript: links in tags From c2b2aabd2f286a121d176b86a1bb4c8ff40846cc Mon Sep 17 00:00:00 2001 From: Brian Beggs Date: Mon, 28 Oct 2024 15:12:28 -0400 Subject: [PATCH 22/23] chore: Update requirements to support bleach[css] --- license_manager/apps/subscriptions/sanitize.py | 1 + requirements/base.in | 1 + requirements/base.txt | 12 ++++++++---- requirements/common_constraints.txt | 4 ++++ requirements/dev.txt | 15 ++++++++++----- requirements/doc.txt | 13 +++++++++---- requirements/pip.txt | 4 +++- requirements/production.txt | 11 ++++++++--- requirements/quality.txt | 13 +++++++++---- requirements/test.txt | 13 +++++++++---- requirements/validation.txt | 14 ++++++++++---- 11 files changed, 72 insertions(+), 29 deletions(-) diff --git a/license_manager/apps/subscriptions/sanitize.py b/license_manager/apps/subscriptions/sanitize.py index 3b22dfe8..a20c53a1 100644 --- a/license_manager/apps/subscriptions/sanitize.py +++ b/license_manager/apps/subscriptions/sanitize.py @@ -1,6 +1,7 @@ import bleach from bleach.css_sanitizer import CSSSanitizer + def sanitize_html(html_content): """ Sanitize HTML content to allow only safe tags and attributes, diff --git a/requirements/base.in b/requirements/base.in index 6de2a2d5..bb7c126d 100644 --- a/requirements/base.in +++ b/requirements/base.in @@ -41,3 +41,4 @@ simplejson zipp django-log-request-id bleach +bleach[css] diff --git a/requirements/base.txt b/requirements/base.txt index 030065c4..1fd509c8 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -22,11 +22,11 @@ backoff==1.10.0 # analytics-python billiard==4.2.1 # via celery -bleach==6.1.0 +bleach[css]==6.1.0 # via -r requirements/base.in -boto3==1.35.48 +boto3==1.35.49 # via django-ses -botocore==1.35.48 +botocore==1.35.49 # via # boto3 # s3transfer @@ -289,6 +289,8 @@ stevedore==5.3.0 # edx-opaque-keys text-unidecode==1.3 # via python-slugify +tinycss2==1.2.1 + # via bleach typing-extensions==4.12.2 # via edx-opaque-keys tzdata==2024.2 @@ -309,7 +311,9 @@ vine==5.1.0 wcwidth==0.2.13 # via prompt-toolkit webencodings==0.5.1 - # via bleach + # via + # bleach + # tinycss2 zipp==3.20.2 # via -r requirements/base.in diff --git a/requirements/common_constraints.txt b/requirements/common_constraints.txt index 1c4a5456..ad46ee15 100644 --- a/requirements/common_constraints.txt +++ b/requirements/common_constraints.txt @@ -34,3 +34,7 @@ elasticsearch<7.14.0 # This can be unpinned once https://github.com/openedx/edx-platform/issues/34586 # has been resolved and edx-platform is running with pymongo>=4.4.0 event-tracking<2.4.1 + +# Cause: https://github.com/openedx/edx-lint/issues/458 +# This can be unpinned once https://github.com/openedx/edx-lint/issues/459 has been resolved. +pip<24.3 diff --git a/requirements/dev.txt b/requirements/dev.txt index a14bf087..0ecd1fd3 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -33,13 +33,13 @@ billiard==4.2.1 # via # -r requirements/validation.txt # celery -bleach==6.1.0 +bleach[css]==6.1.0 # via -r requirements/validation.txt -boto3==1.35.48 +boto3==1.35.49 # via # -r requirements/validation.txt # django-ses -botocore==1.35.48 +botocore==1.35.49 # via # -r requirements/validation.txt # boto3 @@ -240,7 +240,7 @@ edx-drf-extensions==10.5.0 # edx-rbac edx-i18n-tools==1.6.3 # via -r requirements/validation.txt -edx-lint==5.4.0 +edx-lint==5.4.1 # via -r requirements/validation.txt edx-opaque-keys==2.11.0 # via @@ -550,11 +550,15 @@ text-unidecode==1.3 # via # -r requirements/validation.txt # python-slugify +tinycss2==1.2.1 + # via + # -r requirements/validation.txt + # bleach tomlkit==0.13.2 # via # -r requirements/validation.txt # pylint -typeguard==4.3.0 +typeguard==4.4.0 # via inflect typing-extensions==4.12.2 # via @@ -590,6 +594,7 @@ webencodings==0.5.1 # via # -r requirements/validation.txt # bleach + # tinycss2 wheel==0.44.0 # via # -r requirements/pip-tools.txt diff --git a/requirements/doc.txt b/requirements/doc.txt index 665a9750..da33ea57 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -43,13 +43,13 @@ billiard==4.2.1 # via # -r requirements/test.txt # celery -bleach==6.1.0 +bleach[css]==6.1.0 # via -r requirements/test.txt -boto3==1.35.48 +boto3==1.35.49 # via # -r requirements/test.txt # django-ses -botocore==1.35.48 +botocore==1.35.49 # via # -r requirements/test.txt # boto3 @@ -239,7 +239,7 @@ edx-drf-extensions==10.5.0 # via # -r requirements/test.txt # edx-rbac -edx-lint==5.4.0 +edx-lint==5.4.1 # via -r requirements/test.txt edx-opaque-keys==2.11.0 # via @@ -535,6 +535,10 @@ text-unidecode==1.3 # via # -r requirements/test.txt # python-slugify +tinycss2==1.2.1 + # via + # -r requirements/test.txt + # bleach tomlkit==0.13.2 # via # -r requirements/test.txt @@ -573,6 +577,7 @@ webencodings==0.5.1 # via # -r requirements/test.txt # bleach + # tinycss2 zipp==3.20.2 # via -r requirements/test.txt diff --git a/requirements/pip.txt b/requirements/pip.txt index 35655630..a8a601eb 100644 --- a/requirements/pip.txt +++ b/requirements/pip.txt @@ -9,6 +9,8 @@ wheel==0.44.0 # The following packages are considered to be unsafe in a requirements file: pip==24.2 - # via -r requirements/pip.in + # via + # -c requirements/common_constraints.txt + # -r requirements/pip.in setuptools==75.2.0 # via -r requirements/pip.in diff --git a/requirements/production.txt b/requirements/production.txt index fa9b4d2d..a4140c8a 100644 --- a/requirements/production.txt +++ b/requirements/production.txt @@ -28,13 +28,13 @@ billiard==4.2.1 # via # -r requirements/base.txt # celery -bleach==6.1.0 +bleach[css]==6.1.0 # via -r requirements/base.txt -boto3==1.35.48 +boto3==1.35.49 # via # -r requirements/base.txt # django-ses -botocore==1.35.48 +botocore==1.35.49 # via # -r requirements/base.txt # boto3 @@ -395,6 +395,10 @@ text-unidecode==1.3 # via # -r requirements/base.txt # python-slugify +tinycss2==1.2.1 + # via + # -r requirements/base.txt + # bleach typing-extensions==4.12.2 # via # -r requirements/base.txt @@ -427,6 +431,7 @@ webencodings==0.5.1 # via # -r requirements/base.txt # bleach + # tinycss2 zipp==3.20.2 # via -r requirements/base.txt zope-event==5.0 diff --git a/requirements/quality.txt b/requirements/quality.txt index a8dc3575..351fe512 100644 --- a/requirements/quality.txt +++ b/requirements/quality.txt @@ -32,13 +32,13 @@ billiard==4.2.1 # via # -r requirements/base.txt # celery -bleach==6.1.0 +bleach[css]==6.1.0 # via -r requirements/base.txt -boto3==1.35.48 +boto3==1.35.49 # via # -r requirements/base.txt # django-ses -botocore==1.35.48 +botocore==1.35.49 # via # -r requirements/base.txt # boto3 @@ -207,7 +207,7 @@ edx-drf-extensions==10.5.0 # via # -r requirements/base.txt # edx-rbac -edx-lint==5.4.0 +edx-lint==5.4.1 # via -r requirements/quality.in edx-opaque-keys==2.11.0 # via @@ -424,6 +424,10 @@ text-unidecode==1.3 # via # -r requirements/base.txt # python-slugify +tinycss2==1.2.1 + # via + # -r requirements/base.txt + # bleach tomlkit==0.13.2 # via pylint typing-extensions==4.12.2 @@ -458,6 +462,7 @@ webencodings==0.5.1 # via # -r requirements/base.txt # bleach + # tinycss2 zipp==3.20.2 # via -r requirements/base.txt diff --git a/requirements/test.txt b/requirements/test.txt index e636193c..80e4876e 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -32,13 +32,13 @@ billiard==4.2.1 # via # -r requirements/base.txt # celery -bleach==6.1.0 +bleach[css]==6.1.0 # via -r requirements/base.txt -boto3==1.35.48 +boto3==1.35.49 # via # -r requirements/base.txt # django-ses -botocore==1.35.48 +botocore==1.35.49 # via # -r requirements/base.txt # boto3 @@ -216,7 +216,7 @@ edx-drf-extensions==10.5.0 # via # -r requirements/base.txt # edx-rbac -edx-lint==5.4.0 +edx-lint==5.4.1 # via -r requirements/test.in edx-opaque-keys==2.11.0 # via @@ -447,6 +447,10 @@ text-unidecode==1.3 # via # -r requirements/base.txt # python-slugify +tinycss2==1.2.1 + # via + # -r requirements/base.txt + # bleach tomlkit==0.13.2 # via pylint typing-extensions==4.12.2 @@ -482,6 +486,7 @@ webencodings==0.5.1 # via # -r requirements/base.txt # bleach + # tinycss2 zipp==3.20.2 # via -r requirements/base.txt diff --git a/requirements/validation.txt b/requirements/validation.txt index 052b6a76..f16f03d0 100644 --- a/requirements/validation.txt +++ b/requirements/validation.txt @@ -41,16 +41,16 @@ billiard==4.2.1 # -r requirements/quality.txt # -r requirements/test.txt # celery -bleach==6.1.0 +bleach[css]==6.1.0 # via # -r requirements/quality.txt # -r requirements/test.txt -boto3==1.35.48 +boto3==1.35.49 # via # -r requirements/quality.txt # -r requirements/test.txt # django-ses -botocore==1.35.48 +botocore==1.35.49 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -289,7 +289,7 @@ edx-drf-extensions==10.5.0 # edx-rbac edx-i18n-tools==1.6.3 # via -r requirements/validation.in -edx-lint==5.4.0 +edx-lint==5.4.1 # via # -r requirements/quality.txt # -r requirements/test.txt @@ -627,6 +627,11 @@ text-unidecode==1.3 # -r requirements/quality.txt # -r requirements/test.txt # python-slugify +tinycss2==1.2.1 + # via + # -r requirements/quality.txt + # -r requirements/test.txt + # bleach tomlkit==0.13.2 # via # -r requirements/quality.txt @@ -672,6 +677,7 @@ webencodings==0.5.1 # -r requirements/quality.txt # -r requirements/test.txt # bleach + # tinycss2 zipp==3.20.2 # via # -r requirements/quality.txt From f33e70e0056b3c383dcfae490573c2969fea3d25 Mon Sep 17 00:00:00 2001 From: Brian Beggs Date: Mon, 28 Oct 2024 16:13:00 -0400 Subject: [PATCH 23/23] chore: Correctly union sets while sanitizing HTML. --- license_manager/apps/subscriptions/sanitize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/license_manager/apps/subscriptions/sanitize.py b/license_manager/apps/subscriptions/sanitize.py index a20c53a1..27a050ba 100644 --- a/license_manager/apps/subscriptions/sanitize.py +++ b/license_manager/apps/subscriptions/sanitize.py @@ -8,7 +8,7 @@ def sanitize_html(html_content): while disallowing JavaScript and unsafe protocols. """ # Define allowed tags and attributes - allowed_tags = set.union(bleach.ALLOWED_TAGS, set({"span"})) # Allow all standard HTML tags + allowed_tags = set.union(set(bleach.ALLOWED_TAGS), {"span"}) # Allow all standard HTML tags allowed_attrs = {"*": ["className", "class", "style", "id"]} css_sanitizer = CSSSanitizer(allowed_css_properties=["color", "font-weight"])