plone.app.discussion/plone/app/discussion/browser/validator.py

61 lines
2.0 KiB
Python

"""Captcha validator, see captcha.txt for design notes.
"""
from Acquisition import aq_inner
from plone.app.discussion.interfaces import ICaptcha
from plone.app.discussion.interfaces import IDiscussionLayer
from plone.app.discussion.interfaces import IDiscussionSettings
from plone.registry.interfaces import IRegistry
from z3c.form import validator
from z3c.form.interfaces import IValidator
from zope.component import adapter
from zope.component import getMultiAdapter
from zope.component import queryUtility
from zope.interface import implementer
from zope.interface import Interface
from zope.schema.interfaces import IField
try:
from collective.z3cform.norobots.validator import WrongNorobotsAnswer
except ImportError:
pass
try:
from plone.formwidget.captcha.validator import WrongCaptchaCode
except ImportError:
pass
try:
from plone.formwidget.recaptcha.validator import WrongCaptchaCode # noqa
except ImportError:
pass
@implementer(IValidator)
@adapter(Interface, IDiscussionLayer, Interface, IField, Interface)
class CaptchaValidator(validator.SimpleFieldValidator):
# Object, Request, Form, Field, Widget,
# We adapt the CaptchaValidator class to all form fields (IField)
def validate(self, value):
super().validate(value)
registry = queryUtility(IRegistry)
settings = registry.forInterface(IDiscussionSettings, check=False)
if settings.captcha in ("captcha", "recaptcha", "norobots"):
captcha = getMultiAdapter(
(aq_inner(self.context), self.request), name=settings.captcha
)
if not captcha.verify(input=value):
if settings.captcha == "norobots":
raise WrongNorobotsAnswer
else:
raise WrongCaptchaCode
else:
return True
# Register Captcha validator for the Captcha field in the ICaptcha Form
validator.WidgetValidatorDiscriminators(CaptchaValidator, field=ICaptcha["captcha"])