Rework how captcha is handled in the form.

Prior to this commit, things were done by activating or deactivating a
"captcha" property on the class on-the-fly, which caused side-effects.

This is now using subclasses, which makes the code simpler to
understand, and less prone to side-effects.

Thanks @zorun for the idea.
This commit is contained in:
Alexis Métaireau 2021-11-23 19:20:38 +01:00
parent a6bf81a707
commit 7072fb33b9
3 changed files with 10 additions and 15 deletions

View file

@ -50,7 +50,7 @@ def need_auth(f):
class ProjectsHandler(Resource):
def post(self):
form = ProjectForm(meta={"csrf": False}, bypass_captcha=True)
form = ProjectForm(meta={"csrf": False})
if form.validate() and current_app.config.get("ALLOW_PUBLIC_PROJECT_CREATION"):
project = form.save()
db.session.add(project)
@ -71,7 +71,7 @@ class ProjectHandler(Resource):
return "DELETED"
def put(self, project):
form = EditProjectForm(id=project.id, meta={"csrf": False}, bypass_captcha=True)
form = EditProjectForm(id=project.id, meta={"csrf": False})
if form.validate() and current_app.config.get("ALLOW_PUBLIC_PROJECT_CREATION"):
form.update(project)
db.session.commit()

View file

@ -197,10 +197,6 @@ class ProjectForm(EditProjectForm):
password = PasswordField(_("Private code"), validators=[DataRequired()])
submit = SubmitField(_("Create the project"))
def __init__(self, *args, **kwargs):
self.bypass_captcha = kwargs.get("bypass_captcha", False)
super().__init__(*args, **kwargs)
def save(self):
"""Create a new project with the information given by this form.
@ -232,15 +228,14 @@ class ProjectForm(EditProjectForm):
)
raise ValidationError(Markup(message))
@classmethod
def enable_captcha(cls):
captchaField = StringField(
_("Which is a real currency: Euro or Petro dollar?"),
)
setattr(cls, "captcha", captchaField)
class ProjectFormWithCaptcha(ProjectForm):
captcha = StringField(
_("Which is a real currency: Euro or Petro dollar?"),
)
def validate_captcha(form, field):
if not field.data.lower() == _("euro") and not form.bypass_captcha:
if not field.data.lower() == _("euro"):
message = _("Please, validate the captcha to proceed.")
raise ValidationError(Markup(message))

View file

@ -47,6 +47,7 @@ from ihatemoney.forms import (
MemberForm,
PasswordReminder,
ProjectForm,
ProjectFormWithCaptcha,
ResetPasswordForm,
UploadForm,
get_billform_for,
@ -263,8 +264,7 @@ def authenticate(project_id=None):
def get_project_form():
if current_app.config.get("ENABLE_CAPTCHA", False):
ProjectForm.enable_captcha()
return ProjectFormWithCaptcha()
return ProjectForm()