diff --git a/CHANGELOG b/CHANGELOG index e25e8a531c51aff9cdc1ea889aef62ceccdd9007..d0f989e70d11eff1a4ebb31f0035e3811f07818b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,8 @@ smasch (1.0.0~alpha.1-0) unstable; urgency=low * small improvement: all configuration options that are not obligatory are moved to configuration panel (#343) * small improvement: 2FA can be configured to be required option (#358) + * small improvement: redcap API token is not visible in configuration panel + (#359) -- Piotr Gawron <piotr.gawron@uni.lu> Tue, 10 Nov 2020 14:00:00 +0200 diff --git a/smash/web/api_views/configuration.py b/smash/web/api_views/configuration.py index 12c420dc66c6bed578984b5929b3a3cbf59beba9..d351af3459cc54555a6210fb8d092c3df3f5d27d 100644 --- a/smash/web/api_views/configuration.py +++ b/smash/web/api_views/configuration.py @@ -1,6 +1,7 @@ from django.http import JsonResponse from web.models import ConfigurationItem +from web.models.constants import VALUE_TYPE_PASSWORD def configuration_items(request): @@ -18,10 +19,14 @@ def configuration_items(request): data = [] for configuration_item in sliced_items: + value = configuration_item.value + if configuration_item.value_type == VALUE_TYPE_PASSWORD: + value = '' data.append({ "id": configuration_item.id, "name": configuration_item.name, - "value": configuration_item.value + "value": value, + "value_type": configuration_item.value_type, }) return JsonResponse({ "draw": draw, diff --git a/smash/web/migrations/0182_auto_20201126_1042.py b/smash/web/migrations/0182_auto_20201126_1042.py new file mode 100644 index 0000000000000000000000000000000000000000..6260bec1fd0e60270202d30b62c1955c04ed7b7c --- /dev/null +++ b/smash/web/migrations/0182_auto_20201126_1042.py @@ -0,0 +1,42 @@ +# Generated by Django 2.0.13 on 2020-11-26 10:42 + +import django.core.files.storage +from django.db import migrations, models + +from web.models.constants import REDCAP_TOKEN_CONFIGURATION_TYPE, VALUE_TYPE_PASSWORD, NEXMO_API_KEY, NEXMO_API_SECRET + + +def configuration_items(apps, item_type): + # We can't import the ConfigurationItem model directly as it may be a newer + # version than this migration expects. We use the historical version. + + # noinspection PyPep8Naming + ConfigurationItem = apps.get_model("web", "ConfigurationItem") + items = ConfigurationItem.objects.filter( + type__in=[REDCAP_TOKEN_CONFIGURATION_TYPE, NEXMO_API_KEY, NEXMO_API_SECRET]).all() + for item in items: + item.value_type = VALUE_TYPE_PASSWORD + item.save() + + +class Migration(migrations.Migration): + dependencies = [ + ('web', '0181_worker_privacy_notice_accepted'), + ] + + operations = [ + migrations.AddField( + model_name='configurationitem', + name='value_type', + field=models.CharField(choices=[('PASSWORD', 'Password'), ('TEXT', 'Text')], default='TEXT', max_length=32, + verbose_name='Value type'), + ), + migrations.AlterField( + model_name='studysubject', + name='referral_letter', + field=models.FileField(blank=True, null=True, + storage=django.core.files.storage.FileSystemStorage(location='~/tmp/upload'), + upload_to='referral_letters', verbose_name='Referral letter'), + ), + migrations.RunPython(configuration_items), + ] diff --git a/smash/web/migrations/0182_auto_20201126_1154.py b/smash/web/migrations/0183_auto_20201126_1154.py similarity index 97% rename from smash/web/migrations/0182_auto_20201126_1154.py rename to smash/web/migrations/0183_auto_20201126_1154.py index 3c7e93752fa5a3e1da48bf20888ce871c967c238..2e2670d0eb8e394244cba25128b47b456299a45f 100644 --- a/smash/web/migrations/0182_auto_20201126_1154.py +++ b/smash/web/migrations/0183_auto_20201126_1154.py @@ -7,7 +7,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('web', '0181_worker_privacy_notice_accepted'), + ('web', '0182_auto_20201126_1042'), ] operations = [ diff --git a/smash/web/models/configuration_item.py b/smash/web/models/configuration_item.py index 9879847cb62413f0914aa0de43160abef2210fd4..f873981e05d017326c26818d2e171c2b67dc101b 100644 --- a/smash/web/models/configuration_item.py +++ b/smash/web/models/configuration_item.py @@ -5,7 +5,8 @@ from django.db import models from web.models.constants import CANCELLED_APPOINTMENT_COLOR_CONFIGURATION_TYPE, \ NO_SHOW_APPOINTMENT_COLOR_CONFIGURATION_TYPE, KIT_EMAIL_HOUR_CONFIGURATION_TYPE, \ - KIT_EMAIL_DAY_OF_WEEK_CONFIGURATION_TYPE, KIT_DAILY_EMAIL_TIME_FORMAT_TYPE, KIT_DAILY_EMAIL_DAYS_PERIOD_TYPE + KIT_EMAIL_DAY_OF_WEEK_CONFIGURATION_TYPE, KIT_DAILY_EMAIL_TIME_FORMAT_TYPE, KIT_DAILY_EMAIL_DAYS_PERIOD_TYPE, \ + VALUE_TYPE_CHOICES, VALUE_TYPE_TEXT class ConfigurationItem(models.Model): @@ -24,6 +25,11 @@ class ConfigurationItem(models.Model): value = models.CharField(max_length=1024, verbose_name='Value', ) + value_type = models.CharField(max_length=32, + choices=VALUE_TYPE_CHOICES, + verbose_name='Value type', + default=VALUE_TYPE_TEXT + ) def __str__(self): return "%s %s" % (self.name, self.value) diff --git a/smash/web/models/constants.py b/smash/web/models/constants.py index 34f44a4886090fcfb416ce73e20e7ab3ecb06970..664604bbfe67215ed080c10bdde526a52a701e05 100644 --- a/smash/web/models/constants.py +++ b/smash/web/models/constants.py @@ -16,6 +16,15 @@ BOOL_CHOICES_WITH_NONE = ( (False, 'No'), (None, 'N/A'), ) + +VALUE_TYPE_PASSWORD = 'PASSWORD' +VALUE_TYPE_TEXT = 'TEXT' +VALUE_TYPE_CHOICES = ( + (VALUE_TYPE_PASSWORD, 'Password'), + (VALUE_TYPE_TEXT, 'Text'), +) + + SUBJECT_TYPE_CHOICES_CONTROL = 'C' SUBJECT_TYPE_CHOICES_PATIENT = 'P' SUBJECT_TYPE_CHOICES = { diff --git a/smash/web/tests/api_views/test_configuration_item.py b/smash/web/tests/api_views/test_configuration_item.py index 0628c1715d1d65cba82b1676ff4f7e33b1584484..e0a88dbfa405aad25d02c187aed7db344bf8ed70 100644 --- a/smash/web/tests/api_views/test_configuration_item.py +++ b/smash/web/tests/api_views/test_configuration_item.py @@ -4,7 +4,7 @@ from django.urls import reverse from web.models import ConfigurationItem -from web.models.constants import CANCELLED_APPOINTMENT_COLOR_CONFIGURATION_TYPE +from web.models.constants import CANCELLED_APPOINTMENT_COLOR_CONFIGURATION_TYPE, VALUE_TYPE_PASSWORD from web.tests import LoggedInTestCase from web.tests.functions import create_configuration_item @@ -15,6 +15,18 @@ class TestConfigurationItemApi(LoggedInTestCase): response = self.client.get(reverse('web.api.configuration_items')) self.assertEqual(response.status_code, 200) + def test_password_item(self): + item = ConfigurationItem.objects.create() + item.type = "TEST" + item.value = "secret_password" + item.name = "yyy" + item.value_type = VALUE_TYPE_PASSWORD + item.save() + response = self.client.get(reverse('web.api.configuration_items'), {'length': "100"}) + self.assertFalse(item.value in response.content.decode("utf-8")) + self.assertTrue(item.value_type in response.content.decode("utf-8")) + self.assertEqual(response.status_code, 200) + def test_configuration_modify_invalid(self): response = self.client.get(reverse('web.api.update_configuration_item')) self.assertEqual(response.status_code, 200)