diff options
Diffstat (limited to 'recaptcha/client/mailhide.py')
-rw-r--r-- | recaptcha/client/mailhide.py | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/recaptcha/client/mailhide.py b/recaptcha/client/mailhide.py new file mode 100644 index 00000000..437b2c25 --- /dev/null +++ b/recaptcha/client/mailhide.py @@ -0,0 +1,68 @@ +import base64 +import cgi + +try: + from Crypto.Cipher import AES +except: + raise Exception ("You need the pycrpyto library: http://cheeseshop.python.org/pypi/pycrypto/") + +MAIL_HIDE_BASE="http://www.google.com/recaptcha/mailhide" + +def asurl (email, + public_key, + private_key): + """Wraps an email address with reCAPTCHA mailhide and + returns the url. public_key is the public key from reCAPTCHA + (in the base 64 encoded format). Private key is the AES key, and should + be 32 hex chars.""" + + cryptmail = _encrypt_string (email, base64.b16decode (private_key, casefold=True), '\0' * 16) + base64crypt = base64.urlsafe_b64encode (cryptmail) + + return "%s/d?k=%s&c=%s" % (MAIL_HIDE_BASE, public_key, base64crypt) + +def ashtml (email, + public_key, + private_key): + """Wraps an email address with reCAPTCHA Mailhide and + returns html that displays the email""" + + url = asurl (email, public_key, private_key) + (userpart, domainpart) = _doterizeemail (email) + + return """%(user)s<a href='%(url)s' onclick="window.open('%(url)s', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;" title="Reveal this e-mail address">...</a>@%(domain)s""" % { + 'user' : cgi.escape (userpart), + 'domain' : cgi.escape (domainpart), + 'url' : cgi.escape (url), + } + + +def _pad_string (str, block_size): + numpad = block_size - (len (str) % block_size) + return str + numpad * chr (numpad) + +def _encrypt_string (str, aes_key, aes_iv): + if len (aes_key) != 16: + raise Exception ("expecting key of length 16") + if len (aes_iv) != 16: + raise Exception ("expecting iv of length 16") + return AES.new (aes_key, AES.MODE_CBC, aes_iv).encrypt (_pad_string (str, 16)) + +def _doterizeemail (email): + """replaces part of the username with dots""" + + try: + [user, domain] = email.split ('@') + except: + # handle invalid emails... sorta + user = email + domain = "" + + if len(user) <= 4: + user_prefix = user[:1] + elif len(user) <= 6: + user_prefix = user[:3] + else: + user_prefix = user[:4] + + return (user_prefix, domain) |