Ñò
žÅ„Lc           @   s)  d  d k  Z  y d  d k Z e i Z Wn( e j
 o d  d k Z e i Z n Xd  d k Z d  d k Z d  d k	 Z	 d  d k
 l Z d  d k l Z d  d k l Z d  d k l Z d  d k l Z d  d k l Z d  d k l Z d	 e i f d
 „  ƒ  YZ e  i d e  i ƒ Z d d d „  ƒ  YZ d S(   iÿÿÿÿN(   t   randint(   t   render_to_response(   t   RequestContext(   t   forms(   t   ugettext(   t
   simplejson(   t   settingst   MathCaptchaFormc           B   sç   e  Z d  Z e i d ƒ Z e i d d d e d e i	 d h d d 6ƒ d	 d
 ƒ Z
 e i d d d e d e i ƒ  ƒ Z d „  Z d „  Z d „  Z d „  Z d „  Z e d „  ƒ Z e d „  ƒ Z d „  Z d „  Z d „  Z d „  Z RS(   sI  Lightweight mathematical captcha where human is asked to solve
    a simple mathematical calculation like 3+5=?. It don't use database
    and don't require external libraries.

    From concatenation of time, question, answer, settings.SITE_URL and
    settings.SECRET_KEY is built hash that is validated on each form
    submission. It makes impossible to "record" valid captcha form
    submission and "replay" it later - form will not be validated
    because captcha will be expired.

    For more info see:
    http://www.mysoftparade.com/blog/improved-mathematical-captcha/
    s   ^(\d+)$t
   max_lengthi   t   requiredt   widgett   attrst   2t   sizet   labelt    iÈ   c         O   s5   t  t |  ƒ i | | Ž  |  i p |  i ƒ  n d S(   s:   Initalise captcha_question and captcha_token for the form.N(   t   superR   t   __init__t   datat   reset_captcha(   t   selft   argst   kwargs(    (    s,   /var/www/Pootle/pootle/middleware/captcha.pyR   @   s    
c            sÈ   ˆ  i  ƒ  \ } } t i ƒ  t t d d ƒ } ˆ  i | | | ƒ ‰ ˆ ˆ  i d <| ˆ  _ ˆ  i oa ‡  ‡ f d †  } t ˆ  i d ƒ o1 ˆ  i i	 o# t
 ˆ  i _	 | ƒ  t ˆ  i _	 qÄ | ƒ  n d S(   sS   Generate new question and valid token
        for it, reset previous answer if any.t   CAPTCHA_EXPIRES_SECONDSi<   t   captcha_tokenc              s   ˆ ˆ  i  d <d ˆ  i  d <d  S(   NR   R   t   captcha_answer(   R   (    (   R   t   token(    s,   /var/www/Pootle/pootle/middleware/captcha.pyt   _resetR   s    t   _mutableNi  (   t   _generate_captchat   timet   getattrR   t   _make_tokent   initialt   _plain_questionR   t   hasattrR   t   Truet   False(   R   t   qt   at   expiresR   (    (   R   R   s,   /var/www/Pootle/pootle/middleware/captcha.pyR   G   s    		
!c         C   s7   t  d d ƒ t  d d ƒ } } d | | f | | f S(   s:   Generate question and return it along with correct answer.i   i	   s   %s+%s(   R    (   R   R'   t   b(    (    s,   /var/www/Pootle/pootle/middleware/captcha.pyR   \   s    c         C   s=   t  i t i h | d 6| d 6ƒ ƒ } |  i | | | ƒ | S(   NR&   R(   (   t   base64t   urlsafe_b64encodeR   t   dumpst   _sign(   R   R&   R'   R(   R   (    (    s,   /var/www/Pootle/pootle/middleware/captcha.pyR    a   s     c         C   sd   t  t d d ƒ t i | | | g } d i g  } | D] } | t | ƒ q5 ~ ƒ } t | ƒ i ƒ  S(   Nt   SITE_URLR   (   R   R   t
   SECRET_KEYt   joint   strt   sha_ft	   hexdigest(   R   R&   R'   R(   t   plaint   _[1]t   p(    (    s,   /var/www/Pootle/pootle/middleware/captcha.pyR-   f   s    0c         C   s   |  i  S(   N(   R"   (   R   (    (    s,   /var/www/Pootle/pootle/middleware/captcha.pyt   plain_questionl   s    c         C   sM   |  i  i d ƒ } d i g  } | D]  } | d t d d ƒ | f q# ~ ƒ S(   sÉ   Wrap plain_question in some invisibe for humans markup with random
        nonexisted classes, that makes life of spambots a bit harder because
        form of question is vary from request to request.t   +s)   <span class="captcha-random-%s">%s</span>i   i	   (   R"   t   splitR0   R    (   R   t   digitsR5   t   d(    (    s,   /var/www/Pootle/pootle/middleware/captcha.pyt   knotty_questionp   s    c         C   sW   |  i  |  i d ƒ } t i ƒ  | d j o t i t d ƒ ƒ ‚ n | d |  _ | S(   NR   R(   s   Time to answer has expiredR&   (   t   _parse_tokent   cleaned_dataR   R   t   ValidationErrort   _R"   (   R   t   t(    (    s,   /var/www/Pootle/pootle/middleware/captcha.pyt   clean_captcha_tokeny   s
    c      	   C   sš   y^ | d  | d } } t  i t i t | ƒ ƒ ƒ } h | d d 6t | d ƒ d 6| d 6SWn5 t j
 o) } t i d | ƒ t	 i
 d ƒ ‚ n Xd  S(   Ni(   R&   R(   t   signs   Captcha error: %rs   Invalid captcha!(   R   t   loadsR*   t   urlsafe_b64decodeR1   t   floatt	   Exceptiont   loggingt   infoR   R?   (   R   RA   RC   R   t   e(    (    s,   /var/www/Pootle/pootle/middleware/captcha.pyR=   €   s    c         C   sQ   |  i  i |  i i d ƒ ƒ } | p t i t d ƒ ƒ ‚ n t | i d ƒ ƒ S(   NR   s   Enter a numberi    (	   t   A_REt   matchR>   t   getR   R?   R@   t   intt   group(   R   R'   (    (    s,   /var/www/Pootle/pootle/middleware/captcha.pyt   clean_captcha_answer‹   s    c         C   sž   |  i  } d | j o | S| i d ƒ } | oP |  i | d | d | d ƒ } | | d j o t d ƒ g |  i d <q‹ n |  i ƒ  t t |  ƒ i ƒ  S(   s   Check captcha answer.R   R   R&   R(   RC   t	   Incorrect(	   R>   RM   R-   R@   t   _errorsR   R   R   t   clean(   R   t   cdRA   t	   form_sign(    (    s,   /var/www/Pootle/pootle/middleware/captcha.pyRS   ‘   s    	
(   t   __name__t
   __module__t   __doc__t   ret   compileRK   R   t	   CharFieldR$   t	   TextInputR   t   HiddenInputR   R   R   R   R    R-   t   propertyR7   R<   RB   R=   RP   RS   (    (    (    s,   /var/www/Pootle/pootle/middleware/captcha.pyR   +   s"   "									s   http://|https://t   CaptchaMiddlewarec           B   s   e  Z d  Z d „  Z RS(   se   
    Middle ware to display a captcha question to verify POST
    submissions are made by humans
    c         C   s¢  t  i p! | i p | i i d t ƒ o d  S| i i ƒ  o)d | i j o d | i j p  d | i j o d | i j o d  Sy  t t	 i
 | i d ƒ ƒ } Wn t j
 o d } n Xy  t t	 i
 | i d ƒ ƒ } Wn t j
 o d } n Xy  t t	 i
 | i d ƒ ƒ } Wn t j
 o d } n X| d j o | d j p | | j o d  Sn | i i d ƒ p | i i d	 ƒ o d  S| i i d
 ƒ p& | i i d ƒ p | i i d ƒ oE d | i j p d | i j o% d | i j o d | i j o d  Sd | i j o< t | i ƒ } | i ƒ  o t | i d <d  S| i ƒ  n
 t ƒ  } h | d 6| i d 6| i d 6} t d | d t | ƒ ƒS(   Nt   ishumant
   target_f_0t   translator_commentt   submitt   suggesti    t
   source_f_0s   accounts/logins   accounts/login/s
   /translates   /translate/s   /translate.htmlt   backt   skipR   t   formt   urlt	   post_datas   captcha.htmlt   context_instance(   R   t   USE_CAPTCHAt   POSTt   sessionRM   R%   t   usert   is_authenticatedt   lent   URL_REt   findallt   KeyErrort   patht   endswithR   t   is_validR$   R   R   R   (   R   t   requestt   target_urlst   comment_urlst   source_urlsRh   t   ec(    (    s,   /var/www/Pootle/pootle/middleware/captcha.pyt   process_request«   sL    ,     '	&9  	
(   RV   RW   RX   R}   (    (    (    s,   /var/www/Pootle/pootle/middleware/captcha.pyR_   ¦   s   (    (   RY   t   hashlibt   sha1R2   t   ImportErrort   shat   newR*   R   RH   t   randomR    t   django.shortcutsR   t   django.templateR   t   djangoR   t   django.utils.translationR   R@   t   django.utilsR   t   django.confR   t   FormR   RZ   t   IRr   R_   (    (    (    s,   /var/www/Pootle/pootle/middleware/captcha.pyt   <module>   s&   x