Do not expose secret keys in global settings

This commit is contained in:
Raphael Michel
2020-04-29 11:25:22 +02:00
parent 5c62f2b852
commit ee1928aeed
3 changed files with 43 additions and 4 deletions

View File

@@ -48,6 +48,9 @@ class I18nInlineFormSet(i18nfield.forms.I18nInlineFormSet):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
SECRET_REDACTED = '*****'
class SettingsForm(i18nfield.forms.I18nFormMixin, HierarkeyForm): class SettingsForm(i18nfield.forms.I18nFormMixin, HierarkeyForm):
auto_fields = [] auto_fields = []
@@ -73,6 +76,12 @@ class SettingsForm(i18nfield.forms.I18nFormMixin, HierarkeyForm):
if isinstance(f, (RelativeDateTimeField, RelativeDateField)): if isinstance(f, (RelativeDateTimeField, RelativeDateField)):
f.set_event(self.obj) f.set_event(self.obj)
def save(self):
for k, v in self.cleaned_data.items():
if isinstance(self.fields[k], SecretKeySettingsField) and self.cleaned_data[k] == SECRET_REDACTED:
self.cleaned_data[k] = self.initial[k]
return super().save()
def get_new_filename(self, name: str) -> str: def get_new_filename(self, name: str) -> str:
from pretix.base.models import Event from pretix.base.models import Event
@@ -111,3 +120,32 @@ class SafeSessionWizardView(SessionWizardView):
} }
) )
return context return context
class SecretKeySettingsWidget(forms.TextInput):
def __init__(self, attrs=None):
if attrs is None:
attrs = {}
attrs.update({
'autocomplete': 'new-password' # see https://bugs.chromium.org/p/chromium/issues/detail?id=370363#c7
})
super().__init__(attrs)
def get_context(self, name, value, attrs):
if value:
value = SECRET_REDACTED
return super().get_context(name, value, attrs)
class SecretKeySettingsField(forms.CharField):
widget = SecretKeySettingsWidget
def has_changed(self, initial, data):
if data == SECRET_REDACTED:
return False
return super().has_changed(initial, data)
def run_validators(self, value):
if value == SECRET_REDACTED:
return
return super().run_validators(value)

View File

@@ -4,7 +4,7 @@ from django import forms
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from i18nfield.forms import I18nFormField, I18nTextarea, I18nTextInput from i18nfield.forms import I18nFormField, I18nTextarea, I18nTextInput
from pretix.base.forms import SettingsForm from pretix.base.forms import SecretKeySettingsField, SettingsForm
from pretix.base.settings import GlobalSettingsObject from pretix.base.settings import GlobalSettingsObject
from pretix.base.signals import register_global_settings from pretix.base.signals import register_global_settings
@@ -37,7 +37,7 @@ class GlobalSettingsForm(SettingsForm):
required=False, required=False,
label=_("Global message banner detail text"), label=_("Global message banner detail text"),
)), )),
('opencagedata_apikey', forms.CharField( ('opencagedata_apikey', SecretKeySettingsField(
required=False, required=False,
label=_("OpenCage API key for geocoding"), label=_("OpenCage API key for geocoding"),
)), )),

View File

@@ -7,6 +7,7 @@ from django.template.loader import get_template
from django.urls import resolve, reverse from django.urls import resolve, reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from pretix.base.forms import SecretKeySettingsField
from pretix.base.settings import settings_hierarkey from pretix.base.settings import settings_hierarkey
from pretix.base.signals import ( from pretix.base.signals import (
logentry_display, register_global_settings, register_payment_providers, logentry_display, register_global_settings, register_payment_providers,
@@ -98,7 +99,7 @@ def register_global_settings(sender, **kwargs):
StripeKeyValidator('ca_'), StripeKeyValidator('ca_'),
), ),
)), )),
('payment_stripe_connect_secret_key', forms.CharField( ('payment_stripe_connect_secret_key', SecretKeySettingsField(
label=_('Stripe Connect: Secret key'), label=_('Stripe Connect: Secret key'),
required=False, required=False,
validators=( validators=(
@@ -112,7 +113,7 @@ def register_global_settings(sender, **kwargs):
StripeKeyValidator('pk_live_'), StripeKeyValidator('pk_live_'),
), ),
)), )),
('payment_stripe_connect_test_secret_key', forms.CharField( ('payment_stripe_connect_test_secret_key', SecretKeySettingsField(
label=_('Stripe Connect: Secret key (test)'), label=_('Stripe Connect: Secret key (test)'),
required=False, required=False,
validators=( validators=(