diff --git a/CHANGELOG.rst b/CHANGELOG.rst index abfdc8615b..ea71bd8db3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -17,6 +17,10 @@ Unreleased ---------- * nothing unreleased +[4.23.13] +---------- +* feat: added encrypted columns for user credentials for SAP config + [4.23.12] ---------- * feat: feat: added encrypted client id and secret for canvas integration diff --git a/enterprise/__init__.py b/enterprise/__init__.py index 4a57fd2db7..e308c2e8d0 100644 --- a/enterprise/__init__.py +++ b/enterprise/__init__.py @@ -2,4 +2,4 @@ Your project description goes here. """ -__version__ = "4.23.12" +__version__ = "4.23.13" diff --git a/enterprise/signals.py b/enterprise/signals.py index 7725b72f1d..cb6e277fba 100644 --- a/enterprise/signals.py +++ b/enterprise/signals.py @@ -475,3 +475,14 @@ def mirror_id_and_secret_to_decrypted_fields(sender, instance, **kwargs): # py if COURSE_ENROLLMENT_CHANGED is not None: COURSE_ENROLLMENT_CHANGED.connect(course_enrollment_changed_receiver) + + +@receiver(pre_save, sender=SAPSuccessFactorsEnterpriseCustomerConfiguration) +def update_decrypted_credentials(sender, instance, **kwargs): # pylint: disable=unused-argument + """ + Ensure that the decrypted credentials have same values as unencrypted credentials. + """ + if instance.key != instance.decrypted_key: + instance.decrypted_key = instance.key + if instance.secret != instance.decrypted_secret: + instance.decrypted_secret = instance.secret diff --git a/integrated_channels/sap_success_factors/admin/__init__.py b/integrated_channels/sap_success_factors/admin/__init__.py index be8cb305af..7b5d03b440 100644 --- a/integrated_channels/sap_success_factors/admin/__init__.py +++ b/integrated_channels/sap_success_factors/admin/__init__.py @@ -49,7 +49,9 @@ class SAPSuccessFactorsEnterpriseCustomerConfigurationAdmin(DjangoObjectActions, "sapsf_base_url", "sapsf_company_id", "key", + "decrypted_key", "secret", + "decrypted_secret", "sapsf_user_id", "user_type", "has_access_token", diff --git a/integrated_channels/sap_success_factors/migrations/0017_auto_20240823_0936.py b/integrated_channels/sap_success_factors/migrations/0017_auto_20240823_0936.py new file mode 100644 index 0000000000..09c0e2f620 --- /dev/null +++ b/integrated_channels/sap_success_factors/migrations/0017_auto_20240823_0936.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.23 on 2024-08-23 09:36 + +from django.db import migrations, models +import fernet_fields.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('sap_success_factors', '0016_sapsuccessfactorslearnerdatatransmissionaudit_is_transmitted'), + ] + + operations = [ + migrations.AddField( + model_name='sapsuccessfactorsenterprisecustomerconfiguration', + name='decrypted_key', + field=fernet_fields.fields.EncryptedCharField(blank=True, default='', help_text='The encrypted OAuth client identifier. It will be encrypted when stored in the database.', max_length=255, null=True, verbose_name='Encrypted Client ID'), + ), + migrations.AddField( + model_name='sapsuccessfactorsenterprisecustomerconfiguration', + name='decrypted_secret', + field=models.CharField(blank=True, default='', help_text='The encrypted OAuth client secret. It will be encrypted when stored in the database.', max_length=255, null=True, verbose_name='Encrypted Client Secret'), + ), + ] diff --git a/integrated_channels/sap_success_factors/models.py b/integrated_channels/sap_success_factors/models.py index 79d49d584b..4cf8e7e73b 100644 --- a/integrated_channels/sap_success_factors/models.py +++ b/integrated_channels/sap_success_factors/models.py @@ -6,6 +6,7 @@ from logging import getLogger from config_models.models import ConfigurationModel +from fernet_fields import EncryptedCharField from django.db import models from django.utils.translation import gettext_lazy as _ @@ -80,6 +81,19 @@ class SAPSuccessFactorsEnterpriseCustomerConfiguration(EnterpriseCustomerPluginC verbose_name="Client ID", help_text=_("OAuth client identifier.") ) + + decrypted_key = EncryptedCharField( + max_length=255, + verbose_name="Encrypted Client ID", + blank=True, + default='', + help_text=_( + "The encrypted OAuth client identifier." + " It will be encrypted when stored in the database." + ), + null=True + ) + sapsf_base_url = models.CharField( max_length=255, blank=True, @@ -108,6 +122,19 @@ class SAPSuccessFactorsEnterpriseCustomerConfiguration(EnterpriseCustomerPluginC verbose_name="Client Secret", help_text=_("OAuth client secret.") ) + + decrypted_secret = models.CharField( + max_length=255, + blank=True, + default='', + verbose_name="Encrypted Client Secret", + help_text=_( + "The encrypted OAuth client secret." + " It will be encrypted when stored in the database." + ), + null=True + ) + user_type = models.CharField( max_length=20, choices=USER_TYPE_CHOICES,