PageRenderTime 64ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/recaptcha-plugins/perl/Captcha-reCAPTCHA-Mailhide/branches/pure_perl/lib/Captcha/reCAPTCHA/Mailhide.pm

http://recaptcha.googlecode.com/
Perl | 303 lines | 212 code | 87 blank | 4 comment | 6 complexity | 1dfa04684ed20a986bda2030451d3192 MD5 | raw file
  1. package Captcha::reCAPTCHA::Mailhide;
  2. use warnings;
  3. use strict;
  4. use Carp;
  5. # use Best qw/Crypt::Rijndael2 Crypt::Rijndael_PP/;
  6. use MIME::Base64;
  7. use HTML::Tiny;
  8. our $VERSION = '0.94';
  9. use constant API_MAILHIDE_SERVER => 'http://mailhide.recaptcha.net';
  10. my $crypt_class;
  11. BEGIN {
  12. my @crypt_opt = qw( Crypt::Rijndael2 Crypt::Rijndael_PP );
  13. for my $class ( @crypt_opt ) {
  14. warn "# ### $class ###";
  15. eval "use $class";
  16. unless ( $@ ) {
  17. $crypt_class = $class;
  18. last;
  19. }
  20. }
  21. $crypt_class ||= shift @crypt_opt;
  22. warn "# $crypt_class\n";
  23. }
  24. sub new {
  25. my $class = shift;
  26. my $self = bless {}, $class;
  27. $self->_initialize( @_ );
  28. return $self;
  29. }
  30. sub _initialize {
  31. my $self = shift;
  32. my $args = shift || {};
  33. croak "new must be called with a reference to a hash of parameters"
  34. unless 'HASH' eq ref $args;
  35. }
  36. sub _aes_encrypt {
  37. my ( $val, $ky ) = @_;
  38. my $val_len = length( $val );
  39. my $pad_len = int( ( $val_len + 15 ) / 16 ) * 16;
  40. # Pad value
  41. $val .= chr( 16 - $val_len % 16 ) x ( $pad_len - $val_len )
  42. if $val_len < $pad_len;
  43. my $cipher = $crypt_class->new( $ky, $crypt_class->MODE_CBC );
  44. $cipher->set_iv( "\0" x 16 );
  45. return $cipher->encrypt( $val );
  46. }
  47. sub _urlbase64 {
  48. my $str = shift;
  49. chomp( my $enc = encode_base64( $str ) );
  50. $enc =~ tr{+/}{-_};
  51. return $enc;
  52. }
  53. sub mailhide_url {
  54. my $self = shift;
  55. my ( $pubkey, $privkey, $email ) = @_;
  56. croak
  57. "To use reCAPTCHA::Mailhide, you have to sign up for a public and "
  58. . "private key. You can do so at http://mailhide.recaptcha.net/apikey."
  59. unless $pubkey && $privkey;
  60. croak "You must supply an email address"
  61. unless $email;
  62. my $h = HTML::Tiny->new();
  63. return
  64. API_MAILHIDE_SERVER . '/d?'
  65. . $h->query_encode(
  66. {
  67. k => $pubkey,
  68. c => _urlbase64(
  69. _aes_encrypt( $email, pack( 'H*', $privkey ) )
  70. )
  71. }
  72. );
  73. }
  74. sub _email_parts {
  75. my ( $user, $dom ) = split( /\@/, shift, 2 );
  76. my $ul = length( $user );
  77. return ( substr( $user, 0, $ul <= 4 ? 1 : $ul <= 6 ? 3 : 4 ),
  78. '...', '@', $dom );
  79. }
  80. sub mailhide_html {
  81. my $self = shift;
  82. my ( $pubkey, $privkey, $email ) = @_;
  83. my $h = HTML::Tiny->new();
  84. my $url = $self->mailhide_url( $pubkey, $privkey, $email );
  85. my ( $user, $dots, $at, $dom ) = _email_parts( $email );
  86. my %window_options = (
  87. toolbar => 0,
  88. scrollbars => 0,
  89. location => 0,
  90. statusbar => 0,
  91. menubar => 0,
  92. resizable => 0,
  93. width => 500,
  94. height => 300
  95. );
  96. my $options = join ',',
  97. map { "$_=$window_options{$_}" } sort keys %window_options;
  98. return join(
  99. '',
  100. $h->entity_encode( $user ),
  101. $h->a(
  102. {
  103. href => $url,
  104. onclick =>
  105. "window.open('$url', '', '$options'); return false;",
  106. title => 'Reveal this e-mail address'
  107. },
  108. $dots
  109. ),
  110. $at,
  111. $h->entity_encode( $dom )
  112. );
  113. }
  114. 1;
  115. __END__
  116. =head1 NAME
  117. Captcha::reCAPTCHA::Mailhide - A Perl implementation of the reCAPTCHA Mailhide API
  118. =head1 VERSION
  119. This document describes Captcha::reCAPTCHA::Mailhide version 0.94
  120. =head1 SYNOPSIS
  121. use Captcha::reCAPTCHA::Mailhide;
  122. my $m = Captcha::reCAPTCHA::Mailhide->new;
  123. # Get the URL that reveals the email
  124. my $url = $m->mailhide_url( MAIL_PUBLIC_KEY, MAIL_PRIVATE_KEY, 'someone@example.com' );
  125. # Or - even easier - get the formatted HTML for an email link
  126. print $m->mailhide_html( MAIL_PUBLIC_KEY, MAIL_PRIVATE_KEY, 'someone@example.com' );
  127. For complete examples see the /examples subdirectory
  128. =head1 DESCRIPTION
  129. reCAPTCHA is a hybrid mechanical turk and captcha that allows visitors
  130. who complete the captcha to assist in the digitization of books.
  131. From L<http://recaptcha.net/learnmore.html>:
  132. reCAPTCHA improves the process of digitizing books by sending words that
  133. cannot be read by computers to the Web in the form of CAPTCHAs for
  134. humans to decipher. More specifically, each word that cannot be read
  135. correctly by OCR is placed on an image and used as a CAPTCHA. This is
  136. possible because most OCR programs alert you when a word cannot be read
  137. correctly.
  138. This Perl implementation is modelled on the PHP interface that can be
  139. found here:
  140. L<http://recaptcha.net/plugins/php/>
  141. =head1 INTERFACE
  142. To use reCAPTCHA Mailhide you need to get a public, private key pair
  143. from this page:
  144. L<http://mailhide.recaptcha.net/apikey>
  145. The Mailhide API consists of two methods C<< mailhide_html >>
  146. and C<< mailhide_url >>. The methods have the same parameters.
  147. The _html version returns HTML that can be directly put on your web
  148. page. The username portion of the email that is passed in is
  149. truncated and replaced with a link that calls Mailhide. The _url
  150. version gives you the url to decode the email and leaves it up to you
  151. to place the email in HTML.
  152. =over
  153. =item C<< new >>
  154. Create a new C<< Captcha::reCAPTCHA::Mailhide >>.
  155. =item C<< mailhide_url( $pubkey, $privkey, $email ) >>
  156. Generate a link that will decode the specified email address.
  157. =over
  158. =item C<< $pubkey >>
  159. The Mailhide public key from the signup page
  160. =item C<< $privkey >>
  161. The Mailhide private key from the signup page
  162. =item C<< $email >>
  163. The email address you want to hide.
  164. =back
  165. Returns a URL that when clicked will allow the user to decode the hidden
  166. email address.
  167. =item C<< mailhide_html( $pubkey, $privkey, $email ) >>
  168. Generates HTML markup to embed a Mailhide protected email address
  169. on a page.
  170. The arguments are the same as for C<mailhide_url>.
  171. Returns a string containing HTML that may be embedded directly in
  172. a web page.
  173. =back
  174. =head1 CONFIGURATION AND ENVIRONMENT
  175. Captcha::reCAPTCHA::Mailhide requires no configuration files or environment
  176. variables.
  177. To use Mailhide get a public/private key pair here:
  178. L<http://mailhide.recaptcha.net/apikey>
  179. =head1 DEPENDENCIES
  180. Crypt::Rijndael or Crypt::Rijndael_PP (Crypt::Rijndael being preferable),
  181. MIME::Base64,
  182. HTML::Tiny,
  183. Best
  184. =head1 INCOMPATIBILITIES
  185. None reported .
  186. =head1 BUGS AND LIMITATIONS
  187. No bugs have been reported.
  188. Please report any bugs or feature requests to
  189. C<bug-captcha-recaptcha@rt.cpan.org>, or through the web interface at
  190. L<http://rt.cpan.org>.
  191. =head1 AUTHOR
  192. Andy Armstrong C<< <andy@hexten.net> >>
  193. =head1 LICENCE AND COPYRIGHT
  194. Copyright (c) 2007, Andy Armstrong C<< <andy@hexten.net> >>. All rights reserved.
  195. This module is free software; you can redistribute it and/or
  196. modify it under the same terms as Perl itself. See L<perlartistic>.
  197. =head1 DISCLAIMER OF WARRANTY
  198. BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
  199. FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
  200. OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
  201. PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
  202. EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  203. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
  204. ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
  205. YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
  206. NECESSARY SERVICING, REPAIR, OR CORRECTION.
  207. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  208. WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
  209. REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
  210. LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
  211. OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
  212. THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
  213. RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
  214. FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
  215. SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
  216. SUCH DAMAGES.