mirror of
https://github.com/lucaspalomodevelop/indico-plugins.git
synced 2026-03-12 23:27:22 +00:00
186 lines
7.2 KiB
Python
186 lines
7.2 KiB
Python
# This file is part of the Indico plugins.
|
|
# Copyright (C) 2017 - 2024 Max Fischer, Martin Claus, CERN
|
|
#
|
|
# The Indico plugins are free software; you can redistribute
|
|
# them and/or modify them under the terms of the MIT License;
|
|
# see the LICENSE file for more details.
|
|
|
|
import re
|
|
|
|
from wtforms.fields import StringField, URLField
|
|
from wtforms.validators import DataRequired, Email, Length, Optional, ValidationError
|
|
|
|
from indico.modules.events.payment import PaymentEventSettingsFormBase, PaymentPluginSettingsFormBase
|
|
from indico.web.forms.fields import IndicoPasswordField
|
|
from indico.web.forms.validators import IndicoRegexp
|
|
|
|
from indico_payment_sixpay import _
|
|
|
|
|
|
# XXX: Maybe this could be refactored to use the standard indico Placeholder system?
|
|
class FormatField:
|
|
"""Validator for format fields, i.e. strings with ``{key}`` placeholders.
|
|
|
|
:param max_length: optional maximum length, checked on a test formatting
|
|
:param field_map: keyword arguments to use for test formatting
|
|
|
|
On validation, a test mapping is applied to the field. This ensures the
|
|
field has a valid ``str.format`` format, and does not use illegal keys
|
|
(as determined by ``default_field_map`` and ``field_map``).
|
|
The ``max_length`` is validated against the test-formatted field, which
|
|
is an estimate for an average sized input.
|
|
"""
|
|
|
|
#: default placeholders to test length after formatting
|
|
default_field_map = {
|
|
'user_id': 12345,
|
|
'user_name': 'Jane Whiteacre',
|
|
'user_firstname': 'Jane',
|
|
'user_lastname': 'Whiteacre',
|
|
'event_id': 12345,
|
|
'event_title': 'Placeholder: The Event',
|
|
'registration_id': 12345,
|
|
'regform_title': 'EarlyBird Registration'
|
|
}
|
|
|
|
#: id-safe placeholders to test length after formatting
|
|
id_safe_field_map = {
|
|
'user_id': 12345,
|
|
'event_id': 12345,
|
|
'registration_id': 12345,
|
|
}
|
|
|
|
def __init__(self, max_length=float('inf'), id_safe=False):
|
|
"""Format field validator, i.e. strings with ``{key}`` placeholders.
|
|
|
|
:param max_length: optional maximum length,
|
|
checked on a test formatting
|
|
:param field_map: keyword arguments to use for test formatting
|
|
:param id_safe: only allow fields safe for a saferpay id argument
|
|
"""
|
|
self.max_length = max_length
|
|
self.id_safe = id_safe
|
|
self.field_map = self.id_safe_field_map if id_safe else self.default_field_map
|
|
|
|
def __call__(self, form, field):
|
|
"""Validate format field data.
|
|
|
|
Returns true on successful validation, else an ValidationError is
|
|
thrown.
|
|
"""
|
|
if not field.data:
|
|
return True
|
|
try:
|
|
test_format = field.data.format(**self.field_map)
|
|
except KeyError as exc:
|
|
raise ValidationError(_('Invalid format string key: {}').format(exc))
|
|
except ValueError as exc:
|
|
raise ValidationError(_('Malformed format string: {}').format(exc))
|
|
if len(test_format) > self.max_length:
|
|
raise ValidationError(
|
|
_('Format string too long: shortest replacement with {len}, expected {max}')
|
|
.format(len=len(test_format), max=self.max_length)
|
|
)
|
|
if self.id_safe and not re.match(r'^[A-Za-z0-9.:_-]+$', test_format):
|
|
raise ValidationError(_('This field may only contain alphanumeric chars, dots, colons, '
|
|
'hyphens and underscores.'))
|
|
return True
|
|
|
|
|
|
class PluginSettingsForm(PaymentPluginSettingsFormBase):
|
|
"""Configuration form for the Plugin across all events."""
|
|
|
|
url = URLField(
|
|
label=_('API URL'),
|
|
validators=[DataRequired()],
|
|
description=_('URL to contact the Saferpay JSON API'),
|
|
)
|
|
username = StringField(
|
|
label=_('API username'),
|
|
validators=[DataRequired()],
|
|
description=_('The username to access the SaferPay JSON API')
|
|
)
|
|
password = IndicoPasswordField(
|
|
label=_('API password'),
|
|
validators=[DataRequired()],
|
|
description=_('The password to access the SaferPay JSON API'),
|
|
toggle=True,
|
|
)
|
|
account_id = StringField(
|
|
label=_('Account ID'),
|
|
validators=[
|
|
Optional(),
|
|
IndicoRegexp(r'^[0-9-]{0,15}$')
|
|
],
|
|
description=_(
|
|
'Default Saferpay account ID, such as "123456-12345678". '
|
|
'Event managers will be able to override this.'
|
|
)
|
|
)
|
|
order_description = StringField(
|
|
label=_('Order Description'),
|
|
validators=[DataRequired(), FormatField(max_length=80)],
|
|
description=_(
|
|
'The default description of each order in a human readable way. '
|
|
'It is presented to the registrant during the transaction with Saferpay. '
|
|
'Event managers will be able to override this. '
|
|
'Supported placeholders: {}'
|
|
).format(', '.join(f'{{{p}}}' for p in FormatField.default_field_map))
|
|
)
|
|
order_identifier = StringField(
|
|
label=_('Order Identifier'),
|
|
validators=[DataRequired(), FormatField(max_length=80, id_safe=True)],
|
|
description=_(
|
|
'The default identifier of each order for further processing. '
|
|
'Event managers will be able to override this. '
|
|
'Supported placeholders: {}'
|
|
).format(', '.join(f'{{{p}}}' for p in FormatField.id_safe_field_map))
|
|
)
|
|
notification_mail = StringField(
|
|
label=_('Notification Email'),
|
|
validators=[Optional(), Email(), Length(0, 50)],
|
|
description=_(
|
|
'Email address to receive notifications of transactions. '
|
|
"This is independent of Indico's own payment notifications. "
|
|
'Event managers will be able to override this.'
|
|
)
|
|
)
|
|
|
|
|
|
class EventSettingsForm(PaymentEventSettingsFormBase):
|
|
"""Configuration form for the plugin for a specific event."""
|
|
|
|
account_id = StringField(
|
|
label=_('Account ID'),
|
|
validators=[
|
|
DataRequired(),
|
|
IndicoRegexp(r'^[0-9-]{0,15}$')
|
|
],
|
|
description=_('The Saferpay account ID, such as "123456-12345678".')
|
|
)
|
|
order_description = StringField(
|
|
label=_('Order Description'),
|
|
validators=[DataRequired(), FormatField(max_length=80)],
|
|
description=_(
|
|
'The description of each order in a human readable way. '
|
|
'It is presented to the registrant during the transaction with Saferpay. '
|
|
'Supported placeholders: {}'
|
|
).format(', '.join(f'{{{p}}}' for p in FormatField.default_field_map))
|
|
)
|
|
order_identifier = StringField(
|
|
label=_('Order Identifier'),
|
|
validators=[DataRequired(), FormatField(max_length=80, id_safe=True)],
|
|
description=_(
|
|
'The default identifier of each order for further processing. '
|
|
'Supported placeholders: {}'
|
|
).format(', '.join(f'{{{p}}}' for p in FormatField.id_safe_field_map))
|
|
)
|
|
notification_mail = StringField(
|
|
label=_('Notification Email'),
|
|
validators=[DataRequired(), Email(), Length(0, 50)],
|
|
description=_(
|
|
'Email address to receive notifications of transactions. '
|
|
"This is independent of Indico's own payment notifications."
|
|
)
|
|
)
|