|
1 | 1 | from collections import OrderedDict
|
| 2 | +from typing import List, Union |
2 | 3 |
|
3 | 4 | from django import forms
|
4 | 5 | from django.conf import settings
|
@@ -142,10 +143,53 @@ def __init__(self, *args, **kwargs):
|
142 | 143 | self.fields['banner_message'].widget.attrs['rows'] = '2'
|
143 | 144 | self.fields['banner_message_detail'].widget.attrs['rows'] = '3'
|
144 | 145 | self.fields = OrderedDict(list(self.fields.items()) + [
|
145 |
| - ('stripe_webhook_secret_key', SecretKeySettingsField( |
146 |
| - label=_('Stripe Webhook: Signing secret'), |
147 |
| - required=False, |
148 |
| - )), |
| 146 | + ( |
| 147 | + 'payment_stripe_connect_secret_key', |
| 148 | + SecretKeySettingsField( |
| 149 | + label=_('Stripe Connect: Secret key'), |
| 150 | + required=False, |
| 151 | + validators=( |
| 152 | + StripeKeyValidator(['sk_live_', 'rk_live_']), |
| 153 | + ), |
| 154 | + ) |
| 155 | + ), |
| 156 | + ( |
| 157 | + 'payment_stripe_connect_publishable_key', |
| 158 | + forms.CharField( |
| 159 | + label=_('Stripe Connect: Publishable key'), |
| 160 | + required=False, |
| 161 | + validators=( |
| 162 | + StripeKeyValidator('pk_live_'), |
| 163 | + ), |
| 164 | + ) |
| 165 | + ), |
| 166 | + ( |
| 167 | + 'payment_stripe_connect_test_secret_key', |
| 168 | + SecretKeySettingsField( |
| 169 | + label=_('Stripe Connect: Secret key (test)'), |
| 170 | + required=False, |
| 171 | + validators=( |
| 172 | + StripeKeyValidator(['sk_test_', 'rk_test_']), |
| 173 | + ), |
| 174 | + ) |
| 175 | + ), |
| 176 | + ( |
| 177 | + 'payment_stripe_connect_test_publishable_key', |
| 178 | + forms.CharField( |
| 179 | + label=_('Stripe Connect: Publishable key (test)'), |
| 180 | + required=False, |
| 181 | + validators=( |
| 182 | + StripeKeyValidator('pk_test_'), |
| 183 | + ), |
| 184 | + ) |
| 185 | + ), |
| 186 | + ( |
| 187 | + 'stripe_webhook_secret_key', |
| 188 | + SecretKeySettingsField( |
| 189 | + label=_('Stripe Webhook: Secret key'), |
| 190 | + required=False, |
| 191 | + ) |
| 192 | + ), |
149 | 193 | (
|
150 | 194 | "ticket_fee_percentage",
|
151 | 195 | forms.DecimalField(
|
@@ -195,3 +239,46 @@ class SSOConfigForm(SettingsForm):
|
195 | 239 | def __init__(self, *args, **kwargs):
|
196 | 240 | self.obj = GlobalSettingsObject()
|
197 | 241 | super().__init__(*args, obj=self.obj, **kwargs)
|
| 242 | + |
| 243 | + |
| 244 | +class StripeKeyValidator: |
| 245 | + """ |
| 246 | + Validates that a given Stripe key starts with the expected prefix(es). |
| 247 | +
|
| 248 | + This validator ensures that Stripe API keys conform to the expected format |
| 249 | + by checking their prefixes. It supports both single prefix validation and |
| 250 | + multiple prefix validation. |
| 251 | + """ |
| 252 | + def __init__(self, prefix: Union[str, List[str]]) -> None: |
| 253 | + if not prefix: |
| 254 | + raise ValueError("Prefix cannot be empty") |
| 255 | + |
| 256 | + if isinstance(prefix, list): |
| 257 | + if not all(isinstance(p, str) and p for p in prefix): |
| 258 | + raise ValueError("All prefixes must be non-empty strings") |
| 259 | + self._prefixes = prefix |
| 260 | + elif isinstance(prefix, str): |
| 261 | + if not prefix.strip(): |
| 262 | + raise ValueError("Prefix cannot be whitespace") |
| 263 | + self._prefixes = [prefix] |
| 264 | + |
| 265 | + def __call__(self, value: str) -> None: |
| 266 | + if not value: |
| 267 | + raise forms.ValidationError( |
| 268 | + _("The Stripe key cannot be empty."), |
| 269 | + code='invalid-stripe-key' |
| 270 | + ) |
| 271 | + |
| 272 | + if not any(value.startswith(p) for p in self._prefixes): |
| 273 | + if len(self._prefixes) == 1: |
| 274 | + message = _('The provided key does not look valid. It should start with "%(prefix)s".') |
| 275 | + params = {'value': value, 'prefix': self._prefixes[0]} |
| 276 | + else: |
| 277 | + message = _('The provided key does not look valid. It should start with one of: %(prefixes)s') |
| 278 | + params = {'value': value, 'prefixes': ', '.join(f'"{p}"' for p in self._prefixes)} |
| 279 | + |
| 280 | + raise forms.ValidationError( |
| 281 | + message, |
| 282 | + code='invalid-stripe-key', |
| 283 | + params=params |
| 284 | + ) |
0 commit comments