File Coverage

blib/lib/Mojolicious/Plugin/ReCAPTCHAv2Async.pm
Criterion Covered Total %
statement 30 40 75.0
branch 3 8 37.5
condition 2 4 50.0
subroutine 5 5 100.0
pod 1 1 100.0
total 41 58 70.6


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::ReCAPTCHAv2Async;
2             # ABSTRACT: Adds async recaptcha_verify_p helper to Mojolicious ReCAPTCHAv2 plugin.
3             $Mojolicious::Plugin::ReCAPTCHAv2Async::VERSION = '0.001';
4 2     2   1457 use Mojo::Base 'Mojolicious::Plugin::ReCAPTCHAv2';
  2         4  
  2         18  
5 2     2   4814 use Mojo::UserAgent;
  2         4  
  2         24  
6 2     2   61 use Mojo::Promise;
  2         4  
  2         20  
7              
8             has ua => sub { Mojo::UserAgent->new->max_redirects(0); };
9              
10             sub register {
11 1     1 1 41 my $plugin = shift;
12 1         3 my ($app, $conf) = @_;
13              
14 1         7 $plugin->next::method(@_);
15              
16 1         363 $plugin->ua->request_timeout($plugin->conf->{'api_timeout'});
17              
18             $app->helper(recaptcha_verify_p => sub {
19 2     2   26307 my $c = shift;
20              
21             my %verify_params = (
22             remote_ip => $c->tx->remote_address,
23             response => ( $c->req->param('g-recaptcha-response') || '' ),
24 2   50     9 secret => $plugin->conf->{'secret'},
25             );
26              
27 2         583 my $url = $plugin->conf->{'api_url'};
28 2         13 my $timeout = $plugin->conf->{'api_timeout'};
29              
30 2         27 my $p = Mojo::Promise->new();
31             $plugin->ua->post( $url => form => \%verify_params, sub {
32 2         97225 my ($ua, $tx) = @_;
33              
34 2 50       20 if (my $err = $tx->error) {
35 0         0 my $txt = 'Retrieving captcha verification failed';
36 0 0       0 $txt .= ' (HTTP ' . $err->{'code'} . ')' if $err->{'code'};
37              
38 0         0 $c->app->log->error( $txt . ': ' . $err->{'message'} );
39 0         0 $c->app->log->error( 'Request was: ' . $tx->req->to_string );
40 0         0 return $p->reject( 'x-http-communication-failed' );
41             }
42              
43 2         43 my $res = $tx->res;
44 2         10 my $json = eval { $res->json };
  2         13  
45            
46 2 50       621 if (not defined $json) {
47 0         0 $c->app->log->error( 'Decoding JSON response failed: ' . $@ );
48 0         0 $c->app->log->error( 'Request was: ' . $tx->req->to_string );
49 0         0 $c->app->log->error( 'Response was: ' . $tx->res->to_string );
50 0         0 return $p->reject( 'x-unparseable-data-received' );
51             }
52              
53 2 50       42 if (not $json->{'success'}) {
54 2   50     22 return $p->reject( @{ $json->{'error-codes'} // [] } );
  2         18  
55             }
56              
57 0         0 return $p->resolve;
58              
59 2         85 });
60              
61 2         3574 return $p;
62 1         30 });
63             }
64              
65             1;
66              
67             __END__