diff --git a/auth_signup_verify_email/controllers/main.py b/auth_signup_verify_email/controllers/main.py index 3c1564b5dc..aa8de15813 100644 --- a/auth_signup_verify_email/controllers/main.py +++ b/auth_signup_verify_email/controllers/main.py @@ -6,6 +6,7 @@ from email_validator import EmailSyntaxError, EmailUndeliverableError, validate_email from odoo import _ +from odoo.exceptions import UserError, ValidationError from odoo.http import request, route from odoo.addons.auth_signup.controllers.main import AuthSignupHome @@ -21,9 +22,23 @@ def web_auth_signup(self, *args, **kw): return super().web_auth_signup(*args, **kw) def passwordless_signup(self): - values = request.params + values = dict(request.params) qcontext = self.get_auth_signup_qcontext() + verify_captcha = getattr( + request.env["ir.http"], "_verify_request_recaptcha_token", None + ) + if verify_captcha: + try: + if not verify_captcha("signup"): + qcontext["error"] = _( + "Suspicious activity detected by human verification." + ) + return request.render("auth_signup.signup", qcontext) + except (UserError, ValidationError) as error: + qcontext["error"] = str(error) + return request.render("auth_signup.signup", qcontext) + # Check good format of e-mail try: validate_email(values.get("login", "")) @@ -44,8 +59,16 @@ def passwordless_signup(self): values["email"] = values.get("login") # remove values that could raise "Invalid field '*' on model 'res.users'" - values.pop("redirect", "") - values.pop("token", "") + for key in ( + "redirect", + "token", + "csrf_token", + "confirm_password", + "turnstile_captcha", + "recaptcha_token_response", + "g-recaptcha-response", + ): + values.pop(key, "") # Remove password values["password"] = "" diff --git a/auth_signup_verify_email/tests/test_verify_email.py b/auth_signup_verify_email/tests/test_verify_email.py index 39a82073c0..754dd2370e 100644 --- a/auth_signup_verify_email/tests/test_verify_email.py +++ b/auth_signup_verify_email/tests/test_verify_email.py @@ -8,6 +8,7 @@ except ImportError: from unittest.mock import patch +from odoo.exceptions import UserError from odoo.tests.common import HttpCase from odoo.tools.misc import mute_logger @@ -51,3 +52,38 @@ def test_good_email(self): self.data["login"] = "contributors@odoo-community.org" doc = self.html_doc(data=self.data) self.assertTrue(doc.xpath('//p[@class="alert alert-success"]')) + + @mute_logger("odoo.addons.auth_signup_verify_email.controllers.main") + def test_good_email_with_captcha_fields(self): + """Test acceptance when captcha fields are present in POST data.""" + self.data["login"] = "contributors@odoo-community.org" + self.data["turnstile_captcha"] = "dummy-turnstile-token" + self.data["recaptcha_token_response"] = "dummy-recaptcha-token" + doc = self.html_doc(data=self.data) + self.assertTrue(doc.xpath('//p[@class="alert alert-success"]')) + + @mute_logger("odoo.addons.auth_signup_verify_email.controllers.main") + def test_captcha_verification_error(self): + """Test rejection when captcha verification raises an error.""" + self.data["login"] = "contributors@odoo-community.org" + with patch.object( + type(self.env["ir.http"]), + "_verify_request_recaptcha_token", + side_effect=UserError("Captcha failed"), + create=True, + ): + doc = self.html_doc(data=self.data) + self.assertTrue(doc.xpath('//p[@class="alert alert-danger"]')) + + @mute_logger("odoo.addons.auth_signup_verify_email.controllers.main") + def test_captcha_verification_false(self): + """Test rejection when captcha verification returns False.""" + self.data["login"] = "contributors@odoo-community.org" + with patch.object( + type(self.env["ir.http"]), + "_verify_request_recaptcha_token", + return_value=False, + create=True, + ): + doc = self.html_doc(data=self.data) + self.assertTrue(doc.xpath('//p[@class="alert alert-danger"]'))