File Coverage

blib/lib/Captcha/reCAPTCHA/Mailhide.pm
Criterion Covered Total %
statement 54 54 100.0
branch 11 12 91.6
condition 3 3 100.0
subroutine 13 13 100.0
pod 3 3 100.0
total 84 85 98.8


line stmt bran cond sub pod time code
1             package Captcha::reCAPTCHA::Mailhide;
2              
3 3     3   82263 use warnings;
  3         8  
  3         104  
4 3     3   17 use strict;
  3         6  
  3         104  
5 3     3   18 use Carp;
  3         11  
  3         304  
6 3     3   2717 use Crypt::Rijndael;
  3         2626  
  3         89  
7 3     3   2739 use MIME::Base64;
  3         2815  
  3         211  
8 3     3   2857 use HTML::Tiny;
  3         14241  
  3         210  
9              
10             our $VERSION = '0.94';
11              
12 3         2841 use constant API_MAILHIDE_SERVER =>
13 3     3   30 'http://www.google.com/recaptcha/mailhide';
  3         7  
14              
15             sub new {
16 5     5 1 2030 my $class = shift;
17 5         17 my $self = bless {}, $class;
18 5 100       144 croak "new takes no parameters" if @_;
19 4         26 return $self;
20             }
21              
22             sub _aes_encrypt {
23 5     5   7 my ( $val, $ky ) = @_;
24              
25 5         14 my $val_len = length( $val );
26 5         15 my $pad_len = int( ( $val_len + 15 ) / 16 ) * 16;
27              
28             # Pad value
29 5 50       22 $val .= chr( 16 - $val_len % 16 ) x ( $pad_len - $val_len )
30             if $val_len < $pad_len;
31              
32 5         51 my $cipher = Crypt::Rijndael->new( $ky, Crypt::Rijndael::MODE_CBC );
33 5         17 $cipher->set_iv( "\0" x 16 );
34              
35 5         41 return $cipher->encrypt( $val );
36             }
37              
38             sub _urlbase64 {
39 5     5   8 my $str = shift;
40 5         24 chomp( my $enc = encode_base64( $str ) );
41 5         9 $enc =~ tr{+/}{-_};
42 5         25 return $enc;
43             }
44              
45             sub mailhide_url {
46 8     8 1 12 my $self = shift;
47 8         16 my ( $pubkey, $privkey, $email ) = @_;
48              
49 8 100 100     357 croak
50             "To use reCAPTCHA::Mailhide, you have to sign up for a public and "
51             . "private key. You can do so at http://www.google.com/recaptcha/mailhide/apikey."
52             unless $pubkey && $privkey;
53              
54 6 100       135 croak "You must supply an email address"
55             unless $email;
56              
57 5         20 my $h = HTML::Tiny->new();
58              
59             return
60 5         256 API_MAILHIDE_SERVER . '/d?'
61             . $h->query_encode(
62             {
63             k => $pubkey,
64             c => _urlbase64( _aes_encrypt( $email, pack( 'H*', $privkey ) ) )
65             }
66             );
67             }
68              
69             sub _email_parts {
70 11     11   4509 my ( $user, $dom ) = split( /\@/, shift, 2 );
71 11         19 my $ul = length( $user );
72 11 100       54 return ( substr( $user, 0, $ul <= 4 ? 1 : $ul <= 6 ? 3 : 4 ),
    100          
73             '...', '@', $dom );
74             }
75              
76             sub mailhide_html {
77 7     7 1 2665 my $self = shift;
78 7         16 my ( $pubkey, $privkey, $email ) = @_;
79              
80 7         29 my $h = HTML::Tiny->new();
81              
82 7         399 my $url = $self->mailhide_url( $pubkey, $privkey, $email );
83 4         252 my ( $user, $dots, $at, $dom ) = _email_parts( $email );
84              
85 4         26 my %window_options = (
86             toolbar => 0,
87             scrollbars => 0,
88             location => 0,
89             statusbar => 0,
90             menubar => 0,
91             resizable => 0,
92             width => 500,
93             height => 300
94             );
95              
96 32         68 my $options = join ',',
97 4         20 map { "$_=$window_options{$_}" } sort keys %window_options;
98              
99 4         18 return join(
100             '',
101             $h->entity_encode( $user ),
102             $h->a(
103             {
104             href => $url,
105             onclick => "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              
115             1;
116             __END__