From 8c005af24a138debc3d81cd8890e5ca0c75b0125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20M=C3=A9taireau?= Date: Mon, 22 Nov 2021 22:05:13 +0100 Subject: [PATCH] Do not require a captcha when using the API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was trickier than expected, due to some side effects : when the captcha is set to `True` via configuration, it doesn't change the behavior directly of the ProjectForm class, but does so only when the project form is used in the `web.py` module. So, when just using the API (and not using the web.py module, for instance during tests — manual or functional), no problem was shown, and everything was working properly. But at soon as somebody sees the "/" endpoint, the captcha was required, by both the API and the `web.py` module. This fixes it by adding a way to bypass the captcha with a new `bypass_captcha` property on the form. --- ihatemoney/api/common.py | 4 ++-- ihatemoney/forms.py | 7 +++++-- ihatemoney/tests/main_test.py | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ihatemoney/api/common.py b/ihatemoney/api/common.py index 923a5391..f9f20165 100644 --- a/ihatemoney/api/common.py +++ b/ihatemoney/api/common.py @@ -50,7 +50,7 @@ def need_auth(f): class ProjectsHandler(Resource): def post(self): - form = ProjectForm(meta={"csrf": False}) + form = ProjectForm(meta={"csrf": False}, bypass_captcha=True) 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}) + form = EditProjectForm(id=project.id, meta={"csrf": False}, bypass_captcha=True) if form.validate() and current_app.config.get("ALLOW_PUBLIC_PROJECT_CREATION"): form.update(project) db.session.commit() diff --git a/ihatemoney/forms.py b/ihatemoney/forms.py index a55166e8..f7b748f1 100644 --- a/ihatemoney/forms.py +++ b/ihatemoney/forms.py @@ -197,6 +197,10 @@ 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,12 +236,11 @@ class ProjectForm(EditProjectForm): def enable_captcha(cls): captchaField = StringField( _("Which is a real currency: Euro or Petro dollar?"), - validators=[DataRequired()], ) setattr(cls, "captcha", captchaField) def validate_captcha(form, field): - if not field.data.lower() == _("euro"): + if not field.data.lower() == _("euro") and not form.bypass_captcha: message = _("Please, validate the captcha to proceed.") raise ValidationError(Markup(message)) diff --git a/ihatemoney/tests/main_test.py b/ihatemoney/tests/main_test.py index 3efc4bf2..cbcc4742 100644 --- a/ihatemoney/tests/main_test.py +++ b/ihatemoney/tests/main_test.py @@ -286,6 +286,7 @@ class CaptchaTestCase(IhatemoneyTestCase): assert len(models.Project.query.all()) == 1 def test_api_project_creation_does_not_need_captcha(self): + self.client.get('/') resp = self.client.post( "/api/projects", data={