From 2e0b52889d5d566db510eead5ba9e00987443be6 Mon Sep 17 00:00:00 2001 From: Timo Stollenwerk Date: Tue, 1 Jun 2010 16:38:29 +0000 Subject: [PATCH] Clean up (Re)Captcha code. Register Captcha field/validator only if a package is installed that provides the "plone.app.discussion-captcha" feature (currently plone.formwidget.captcha and plone.formwidget.recaptcha trunk only). svn path=/plone.app.discussion/trunk/; revision=36877 --- plone/app/discussion/browser/captcha.py | 80 ++++++++------------- plone/app/discussion/browser/configure.zcml | 32 +++++---- plone/app/discussion/browser/validator.py | 44 ++++++------ 3 files changed, 70 insertions(+), 86 deletions(-) diff --git a/plone/app/discussion/browser/captcha.py b/plone/app/discussion/browser/captcha.py index 6baa87b..bc32fc2 100644 --- a/plone/app/discussion/browser/captcha.py +++ b/plone/app/discussion/browser/captcha.py @@ -25,69 +25,45 @@ from plone.app.discussion.interfaces import IDiscussionSettings, ICaptcha from plone.app.discussion.browser.validator import CaptchaValidator -HAS_CAPTCHA = False -try: - from plone.formwidget.captcha import CaptchaFieldWidget - HAS_CAPTCHA = True -except ImportError: - pass - -HAS_RECAPTCHA = False -try: - from plone.formwidget.recaptcha import ReCaptchaFieldWidget - HAS_RECAPTCHA = True -except ImportError: - pass class Captcha(Persistent): + """Captcha input field. + """ interface.implements(ICaptcha) adapts(Comment) captcha = u"" Captcha = factory(Captcha) -if HAS_CAPTCHA or HAS_RECAPTCHA: - # Extend the comment form with captcha, if a captcha solution is installed. - class CaptchaExtender(extensible.FormExtender): - adapts(Interface, IDefaultBrowserLayer, CommentForm) # context, request, form - fields = Fields(ICaptcha) +class CaptchaExtender(extensible.FormExtender): + """Extends the comment form with a Captcha. This Captcha extender is only + registered when a plugin is installed that provides the + "plone.app.discussion-captcha" feature. + """ + adapts(Interface, IDefaultBrowserLayer, CommentForm) # context, request, form - def __init__(self, context, request, form): - self.context = context - self.request = request - self.form = form + fields = Fields(ICaptcha) - registry = queryUtility(IRegistry) - settings = registry.forInterface(IDiscussionSettings) - self.captcha = settings.captcha - portal_membership = getToolByName(self.context, 'portal_membership') - self.isAnon = portal_membership.isAnonymousUser() + def __init__(self, context, request, form): + self.context = context + self.request = request + self.form = form - def update(self): - if self.captcha != 'disabled' and self.isAnon: - # Add captcha field if captcha is enabled in the registry - self.add(ICaptcha, prefix="") - if HAS_CAPTCHA and self.captcha == 'captcha': - # If Captcha is installed and Captcha is enabled, - # use the CaptchaFieldWidget - self.form.fields['captcha'].widgetFactory = CaptchaFieldWidget - elif HAS_RECAPTCHA and self.captcha == 'recaptcha': - # If ReCaptcha is installed and ReCaptcha is enabled, - # use the ReCaptchaFieldWidget - self.form.fields['captcha'].widgetFactory = ReCaptchaFieldWidget + registry = queryUtility(IRegistry) + settings = registry.forInterface(IDiscussionSettings) + self.captcha = settings.captcha + portal_membership = getToolByName(self.context, 'portal_membership') + self.isAnon = portal_membership.isAnonymousUser() - # Register Captcha validator for the Captcha field in the ICaptcha Form - validator.WidgetValidatorDiscriminators(CaptchaValidator, field=ICaptcha['captcha']) + def update(self): + if self.captcha != 'disabled' and self.isAnon: + # Add a captcha field if captcha is enabled in the registry + self.add(ICaptcha, prefix="") + if self.captcha == 'captcha': + from plone.formwidget.captcha import CaptchaFieldWidget + self.form.fields['captcha'].widgetFactory = CaptchaFieldWidget + elif self.captcha == 'recaptcha': + from plone.formwidget.recaptcha import ReCaptchaFieldWidget + self.form.fields['captcha'].widgetFactory = ReCaptchaFieldWidget -else: - # This is necessary, otherwise the zcml registration of the CaptchaExtender - # would fail if no captcha solution is installed. - class CaptchaExtender(extensible.FormExtender): - adapts(Interface, IDefaultBrowserLayer, CommentForm) - - def __init__(self, context, request, form): - pass - - def update(self): - pass \ No newline at end of file diff --git a/plone/app/discussion/browser/configure.zcml b/plone/app/discussion/browser/configure.zcml index e22aed8..02e8bb5 100644 --- a/plone/app/discussion/browser/configure.zcml +++ b/plone/app/discussion/browser/configure.zcml @@ -1,6 +1,7 @@ @@ -81,18 +82,23 @@ /> - - - - - - + + + + + + - + \ No newline at end of file diff --git a/plone/app/discussion/browser/validator.py b/plone/app/discussion/browser/validator.py index 65a5408..7e775ee 100644 --- a/plone/app/discussion/browser/validator.py +++ b/plone/app/discussion/browser/validator.py @@ -1,8 +1,4 @@ -# Captcha/ReCaptcha validators. We override the standard validators from -# plone.formwidget.captcha and plone.formwidget.recaptcha, in order to -# switch between the two. This is necessary, because the zcml registration -# of the CaptchaValidator has to be there, no matter which captcha solution -# is installed, or even when no captcha solution is installed. +# -*- coding: utf-8 -*- from Acquisition import aq_inner @@ -14,25 +10,24 @@ from zope.component import getMultiAdapter, provideAdapter, queryUtility from zope.schema import ValidationError +from zope.interface import implements, Interface +from zope.schema.interfaces import IField +from zope.component import adapts + from plone.registry.interfaces import IRegistry -from plone.app.discussion.interfaces import IDiscussionSettings, IDiscussionLayer, MessageFactory as _ - -from zope.interface import implements, Interface -from zope.schema.interfaces import IField -from zope.component import adapts +from plone.app.discussion.interfaces import ICaptcha +from plone.app.discussion.interfaces import IDiscussionSettings +from plone.app.discussion.interfaces import IDiscussionLayer +from plone.app.discussion.interfaces import MessageFactory as _ try: - from plone.formwidget.captcha import CaptchaMessageFactory as _ - class WrongCaptchaCode(ValidationError): - __doc__ = _("""The code you entered was wrong, please enter the new one.""") + from plone.formwidget.captcha.validator import WrongCaptchaCode except: pass try: - from plone.formwidget.recaptcha import ReCaptchaMessageFactory as _ - class WrongReCaptchaCode(ValidationError): - __doc__ = _("""The code you entered was wrong, please enter the new one.""") + from plone.formwidget.recaptcha.validator import WrongCaptchaCode except: pass @@ -40,6 +35,7 @@ from zope.interface import implements, Interface from zope.schema.interfaces import IField from zope.component import adapts + class CaptchaValidator(validator.SimpleFieldValidator): implements(IValidator) adapts(Interface,IDiscussionLayer,Interface,IField,Interface) @@ -53,7 +49,8 @@ class CaptchaValidator(validator.SimpleFieldValidator): if settings.captcha == 'captcha': # Fetch captcha view - captcha = getMultiAdapter((aq_inner(self.context), self.request), name='captcha') + captcha = getMultiAdapter((aq_inner(self.context), self.request), + name='captcha') if value: if not captcha.verify(value): raise WrongCaptchaCode @@ -61,9 +58,14 @@ class CaptchaValidator(validator.SimpleFieldValidator): return True raise WrongCaptchaCode elif settings.captcha == 'recaptcha': - # Fetch recatpcha view - captcha = getMultiAdapter((aq_inner(self.context), self.request), name='recaptcha') + # Fetch recaptcha view + captcha = getMultiAdapter((aq_inner(self.context), self.request), + name='recaptcha') if not captcha.verify(): - raise WrongReCaptchaCode + raise WrongCaptchaCode else: - return True \ No newline at end of file + return True + +# Register Captcha validator for the Captcha field in the ICaptcha Form +validator.WidgetValidatorDiscriminators(CaptchaValidator, + field=ICaptcha['captcha']) \ No newline at end of file