browser.captcha - Captcha Components

Components to add captcha functionality in views/pages.

This is currently a playground, stuff still to be worked out more properly.

class waeup.kofa.browser.captcha.CaptchaManager[source]

Bases: grokcore.component.components.GlobalUtility

__doc__ = None
__implemented__ = <implementedBy waeup.kofa.browser.captcha.CaptchaManager>
__module__ = 'waeup.kofa.browser.captcha'
__provides__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
getAvailCaptchas()[source]

Get all available captchas registered as utils for ICaptcha.

The default captcha (as it most probably is a copy of another registered captcha) is left out of the result.

Result will be a dict with registration names as keys and the specific captcha instances as values.

getCaptcha()[source]

Get captcha chosen to be used.

Sites can activate a specific captcha by setting site['configuration'].captcha. The attribute should be a string under which the specific captcha is registered.

If this attribute is not set or we are not ‘in a site’, the default captcha is returned.

class waeup.kofa.browser.captcha.CaptchaRequest(solution=None, challenge=None)[source]

Bases: object

__dict__ = dict_proxy({'__providedBy__': <_interface_coptimizations.ObjectSpecificationDescriptor object at 0x7f402dea22c0>, '__module__': 'waeup.kofa.browser.captcha', '__provides__': <zope.interface.declarations.ClassProvides object at 0x7f40276fd950>, '__init__': <function __init__ at 0x7f4024d9a8c0>, '__dict__': <attribute '__dict__' of 'CaptchaRequest' objects>, '__implemented__': <implementedBy waeup.kofa.browser.captcha.CaptchaRequest>, '__weakref__': <attribute '__weakref__' of 'CaptchaRequest' objects>, '__doc__': None})
__doc__ = None
__implemented__ = <implementedBy waeup.kofa.browser.captcha.CaptchaRequest>
__init__(solution=None, challenge=None)[source]
__module__ = 'waeup.kofa.browser.captcha'
__providedBy__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
__provides__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
__weakref__

list of weak references to the object (if defined)

class waeup.kofa.browser.captcha.CaptchaResponse(is_valid, error_code=None)[source]

Bases: object

__dict__ = dict_proxy({'__providedBy__': <_interface_coptimizations.ObjectSpecificationDescriptor object at 0x7f402dea22c0>, '__module__': 'waeup.kofa.browser.captcha', '__provides__': <zope.interface.declarations.ClassProvides object at 0x7f40276fdf50>, '__init__': <function __init__ at 0x7f4024d80b90>, '__dict__': <attribute '__dict__' of 'CaptchaResponse' objects>, '__implemented__': <implementedBy waeup.kofa.browser.captcha.CaptchaResponse>, '__weakref__': <attribute '__weakref__' of 'CaptchaResponse' objects>, '__doc__': None})
__doc__ = None
__implemented__ = <implementedBy waeup.kofa.browser.captcha.CaptchaResponse>
__init__(is_valid, error_code=None)[source]
__module__ = 'waeup.kofa.browser.captcha'
__providedBy__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
__provides__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
__weakref__

list of weak references to the object (if defined)

class waeup.kofa.browser.captcha.CaptchaTestPage(context, request)[source]

Bases: waeup.kofa.browser.layout.KofaPage

__doc__ = None
__module__ = 'waeup.kofa.browser.captcha'
label = 'Captcha Test'
render()[source]
title = 'Captcha Test'
update(recaptcha_challenge_field=None, recaptcha_response_field=None)[source]
class waeup.kofa.browser.captcha.NullCaptcha[source]

Bases: object

A captcha that does not expect any input.

Meant as a placeholder for sites that do not want captchas at all.

NullCaptchas do not render any HTML/JavaScript and accept any request when asked for verification.

They can be used in pages prepared for captchas where the site maintainer decides not to use it at all.

__dict__ = dict_proxy({'__providedBy__': <_interface_coptimizations.ObjectSpecificationDescriptor object at 0x7f402dea22c0>, '__module__': 'waeup.kofa.browser.captcha', 'verify': <function verify at 0x7f4024d9a6e0>, '__provides__': <zope.interface.declarations.ClassProvides object at 0x7f40275db890>, '__doc__': 'A captcha that does not expect any input.\n\n Meant as a placeholder for sites that do not want captchas at all.\n\n NullCaptchas do not render any HTML/JavaScript and accept any\n request when asked for verification.\n\n They can be used in pages prepared for captchas where the site\n maintainer decides not to use it at all.\n ', '__dict__': <attribute '__dict__' of 'NullCaptcha' objects>, '__implemented__': <implementedBy waeup.kofa.browser.captcha.NullCaptcha>, '__weakref__': <attribute '__weakref__' of 'NullCaptcha' objects>, 'display': <function display at 0x7f4024d9a758>})
__doc__ = 'A captcha that does not expect any input.\n\n Meant as a placeholder for sites that do not want captchas at all.\n\n NullCaptchas do not render any HTML/JavaScript and accept any\n request when asked for verification.\n\n They can be used in pages prepared for captchas where the site\n maintainer decides not to use it at all.\n '
__implemented__ = <implementedBy waeup.kofa.browser.captcha.NullCaptcha>
__module__ = 'waeup.kofa.browser.captcha'
__providedBy__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
__provides__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
__weakref__

list of weak references to the object (if defined)

display(error_code=None)[source]
verify(request)[source]
class waeup.kofa.browser.captcha.ReCaptcha[source]

Bases: waeup.kofa.browser.captcha.StaticCaptcha

ReCaptcha - strong captchas with images, sound, etc.

This is the Kofa implementation to support captchas as provided by http://www.google.com/recaptcha (v2).

ReCaptcha is widely used and adopted in web applications. See the above web page to learn more about recaptcha.

Basically, it generates a captcha box in a page loaded by a client. The client can then enter a solution for a challenge picture (or audio file) and send the solution back to our server along with the challenge string generated locally on the client.

This component then verifies the entered solution deploying the private key set by asking a verification server. The result (valid or invalid solution) is then returned to any calling component.

As any captcha-component, ReCaptcha can be used by any other component that wants to display/verify captchas.

To incorporate captcha usage in a view, page, or viewlet, the following steps have to be performed:

  • get the currently site-wide selected captcha type by doing:

    mycaptcha = getUtility(ICaptchaManager).getCaptcha()
    
  • if you want a specific captcha type (like ReCaptcha):

    mycaptcha = getUtility(ICaptcha, name='ReCaptcha')
    

Now, as you have a captcha, you can verify sent data by doing:

result = mycaptcha.verify(self.request)

where self.request should be the sent HTTP request and result will be an instance of class:CaptchaResponse. The response will contain an error code (result.error_code) that might be None but can (and should) be passed to the :meth:display method to display error messages in the captcha box. The error code is most probably not a human readable string but some code you shouldn’t rely upon.

All this could be done in the update() method of a view, page, or viewlet.

To render the needed HTML code, you can deploy the display`() method of mycaptcha.

This captcha is available at runtime as a global utility named 'ReCaptcha'.

Shortcomings:
  • no support for selecting theme
  • no support for selecting box layout (normal, compact)
  • no support for non-javascript users
  • Google will get the data of our clients
  • Google will track all activity of our clients
PRIVATE_KEY = '6Lc0y8oSAAAAAMHVbMrGWLLjw2pm8v2Uprwm9AbR'
PUBLIC_KEY = '6Lc0y8oSAAAAAHwdojrqPtcKn7Rww5qGprb0rrSk'
VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify'
__doc__ = "ReCaptcha - strong captchas with images, sound, etc.\n\n This is the Kofa implementation to support captchas as provided by\n http://www.google.com/recaptcha (v2).\n\n ReCaptcha is widely used and adopted in web applications. See the\n above web page to learn more about recaptcha.\n\n Basically, it generates a captcha box in a page loaded by a\n client. The client can then enter a solution for a challenge\n picture (or audio file) and send the solution back to our server\n along with the challenge string generated locally on the client.\n\n This component then verifies the entered solution deploying the\n private key set by asking a verification server. The result (valid\n or invalid solution) is then returned to any calling component.\n\n As any captcha-component, :class:`ReCaptcha` can be used by any\n other component that wants to display/verify captchas.\n\n To incorporate captcha usage in a view, page, or viewlet, the\n following steps have to be performed:\n\n * get the currently site-wide selected captcha type by doing::\n\n mycaptcha = getUtility(ICaptchaManager).getCaptcha()\n\n * if you want a specific captcha type (like ReCaptcha)::\n\n mycaptcha = getUtility(ICaptcha, name='ReCaptcha')\n\n Now, as you have a captcha, you can verify sent data by doing::\n\n result = mycaptcha.verify(self.request)\n\n where ``self.request`` should be the sent HTTP request and\n ``result`` will be an instance of class:``CaptchaResponse``. The\n response will contain an error code (``result.error_code``) that\n might be ``None`` but can (and should) be passed to the\n :meth:``display`` method to display error messages in the captcha\n box. The error code is most probably not a human readable string\n but some code you shouldn't rely upon.\n\n All this could be done in the ``update()`` method of a view, page,\n or viewlet.\n\n To render the needed HTML code, you can deploy the\n :meth:`display`` method of ``mycaptcha``.\n\n This captcha is available at runtime as a global utility named\n ``'ReCaptcha'``.\n\n Shortcomings:\n - no support for selecting theme\n - no support for selecting box layout (normal, compact)\n - no support for non-javascript users\n - Google will get the data of our clients\n - Google will track all activity of our clients\n "
__implemented__ = <implementedBy waeup.kofa.browser.captcha.ReCaptcha>
__module__ = 'waeup.kofa.browser.captcha'
__provides__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
display(error_code=None)[source]

Display captcha widget snippet.

Returns the HTML code to be placed inside an existing <form> of your page. You can add other fields and should add a submit button to send the form.

The error_code can be taken from a previously fetched CaptchaResponse instance (as returned by verify()). If it is not None, it might be displayed inside the generated captcha box (in human readable form).

token_field = 'g-recaptcha-response'

name of response token field in HTTP request

verify(request)[source]

Grab challenge/solution from HTTP request and verify it.

Verification happens against recaptcha remote API servers. It only happens, when a repsonse token was sent with the request.

Returns a CaptchaResponse indicating that the verification failed or succeeded.

class waeup.kofa.browser.captcha.StaticCaptcha[source]

Bases: object

The StaticCaptcha always has the same solution: ‘the-solution’.

It is of no use for real world but for tests. In tests we cannot easily solve really strong captchas. But we can use a captcha that works like a real one but is easy to solve even for machines.

The HTML form piece generated is even prefilled with the correct solution. So in tests it is not necessary to always ‘type’ the solution string in the correct field.

You can, however, fill in a wrong solution and it will be detected as such.

__dict__ = dict_proxy({'__module__': 'waeup.kofa.browser.captcha', '__dict__': <attribute '__dict__' of 'StaticCaptcha' objects>, '__implemented__': <implementedBy waeup.kofa.browser.captcha.StaticCaptcha>, '__weakref__': <attribute '__weakref__' of 'StaticCaptcha' objects>, '__providedBy__': <_interface_coptimizations.ObjectSpecificationDescriptor object at 0x7f402dea22c0>, 'sol_field': 'solution', 'verify': <function verify at 0x7f4024d9a500>, '__provides__': <zope.interface.declarations.ClassProvides object at 0x7f4027726c50>, 'display': <function display at 0x7f4024d9a5f0>, 'chal_field': 'challenge', '__doc__': "The StaticCaptcha always has the same solution: 'the-solution'.\n\n It is of no use for real world but for tests. In tests we cannot\n easily solve really strong captchas. But we can use a captcha that\n works like a real one but is easy to solve even for machines.\n\n The HTML form piece generated is even prefilled with the correct\n solution. So in tests it is not necessary to always 'type' the\n solution string in the correct field.\n\n You can, however, fill in a wrong solution and it will be detected\n as such.\n "})
__doc__ = "The StaticCaptcha always has the same solution: 'the-solution'.\n\n It is of no use for real world but for tests. In tests we cannot\n easily solve really strong captchas. But we can use a captcha that\n works like a real one but is easy to solve even for machines.\n\n The HTML form piece generated is even prefilled with the correct\n solution. So in tests it is not necessary to always 'type' the\n solution string in the correct field.\n\n You can, however, fill in a wrong solution and it will be detected\n as such.\n "
__implemented__ = <implementedBy waeup.kofa.browser.captcha.StaticCaptcha>
__module__ = 'waeup.kofa.browser.captcha'
__providedBy__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
__provides__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
__weakref__

list of weak references to the object (if defined)

chal_field = 'challenge'

name of challenge field in HTTP request

display(error_code=None)[source]

Display challenge and input field for solution as HTML.

sol_field = 'solution'

name of solution field in HTTP request

verify(request)[source]

Verify that a solution sent equals the challenge.