| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Captcha::reCAPTCHA::V3; | 
| 2 | 3 |  |  | 3 |  | 147850 | use 5.008001; | 
|  | 3 |  |  |  |  | 32 |  | 
| 3 | 3 |  |  | 3 |  | 19 | use strict; | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 75 |  | 
| 4 | 3 |  |  | 3 |  | 15 | use warnings; | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 198 |  | 
| 5 |  |  |  |  |  |  |  | 
| 6 |  |  |  |  |  |  | our $VERSION = "0.03"; | 
| 7 |  |  |  |  |  |  |  | 
| 8 | 3 |  |  | 3 |  | 28 | use Carp; | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 182 |  | 
| 9 | 3 |  |  | 3 |  | 2450 | use JSON qw(decode_json); | 
|  | 3 |  |  |  |  | 36268 |  | 
|  | 3 |  |  |  |  | 16 |  | 
| 10 | 3 |  |  | 3 |  | 2738 | use LWP::UserAgent; | 
|  | 3 |  |  |  |  | 139610 |  | 
|  | 3 |  |  |  |  | 1757 |  | 
| 11 |  |  |  |  |  |  | my $ua = LWP::UserAgent->new(); | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | sub new { | 
| 14 | 3 |  |  | 3 | 1 | 807 | my $class = shift; | 
| 15 | 3 |  |  |  |  | 9 | my $self  = bless {}, $class; | 
| 16 | 3 |  |  |  |  | 16 | my %attr  = @_; | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | # Initialize the values for API | 
| 19 | 3 |  | 33 |  |  | 26 | $self->{'secret'}     = $attr{'secret'}     || croak "missing param 'secret'"; | 
| 20 | 3 |  | 33 |  |  | 13 | $self->{'sitekey'}    = $attr{'sitekey'}    || croak "missing param 'sitekey'"; | 
| 21 | 3 |  | 50 |  |  | 28 | $self->{'query_name'} = $attr{'query_name'} || 'g-recaptcha-response'; | 
| 22 |  |  |  |  |  |  |  | 
| 23 | 3 |  |  |  |  | 14 | $self->{'widget_api'} = 'https://www.google.com/recaptcha/api.js?render=' . $attr{'sitekey'}; | 
| 24 | 3 |  |  |  |  | 7 | $self->{'verify_api'} = 'https://www.google.com/recaptcha/api/siteverify'; | 
| 25 | 3 |  |  |  |  | 13 | return $self; | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | #my $res = $ua->get( $self->{'widget_api'} ); | 
| 28 |  |  |  |  |  |  | #croak "something wrong to post by " . $ua->agent(), "\n" unless $res->is_success(); | 
| 29 |  |  |  |  |  |  | #return $self if $res->decoded_content() | 
| 30 |  |  |  |  |  |  | #    =~ m|^\Q/* PLEASE DO NOT COPY AND PASTE THIS CODE. */(function(){|; | 
| 31 |  |  |  |  |  |  | # )| this line is required to fix syntax highlights :) | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | } | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | # verifiers ======================================================================= | 
| 36 |  |  |  |  |  |  | sub verify { | 
| 37 | 1 |  |  | 1 | 1 | 6 | my $self     = shift; | 
| 38 | 1 |  |  |  |  | 2 | my $response = shift; | 
| 39 | 1 | 50 |  |  |  | 4 | croak "Extra arguments have been set." if @_; | 
| 40 |  |  |  |  |  |  |  | 
| 41 |  |  |  |  |  |  | my $params = { | 
| 42 | 1 |  | 33 |  |  | 5 | secret   => $self->{'secret'}, | 
| 43 |  |  |  |  |  |  | response => $response || croak "missing response token", | 
| 44 |  |  |  |  |  |  | }; | 
| 45 |  |  |  |  |  |  |  | 
| 46 | 1 |  |  |  |  | 6 | my $res = $ua->post( $self->{'verify_api'}, $params ); | 
| 47 | 1 | 50 |  |  |  | 273364 | return decode_json $res->decoded_content() if $res->is_success(); | 
| 48 |  |  |  |  |  |  |  | 
| 49 | 0 |  |  |  |  | 0 | croak "something wrong to POST by " . $ua->agent(), "\n"; | 
| 50 |  |  |  |  |  |  | } | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | sub deny_by_score { | 
| 53 | 0 |  |  | 0 | 1 | 0 | my $self     = shift; | 
| 54 | 0 |  |  |  |  | 0 | my %attr     = @_; | 
| 55 | 0 |  | 0 |  |  | 0 | my $response = $attr{'response'} || croak "missing response token"; | 
| 56 | 0 |  | 0 |  |  | 0 | my $score    = $attr{'score'}    || 0.5; | 
| 57 | 0 | 0 | 0 |  |  | 0 | croak "invalid score was set: $score" if $score < 0 or 1 < $score; | 
| 58 |  |  |  |  |  |  |  | 
| 59 | 0 |  |  |  |  | 0 | my $content = $self->verify($response); | 
| 60 | 0 | 0 | 0 |  |  | 0 | if ( $content->{'success'} and $content->{'score'} == 1 || $content->{'score'} < $score ) { | 
|  |  |  | 0 |  |  |  |  | 
| 61 | 0 |  |  |  |  | 0 | unshift @{ $content->{'error-codes'} }, 'too-low-score'; | 
|  | 0 |  |  |  |  | 0 |  | 
| 62 | 0 |  |  |  |  | 0 | $content->{'success'} = 0; | 
| 63 |  |  |  |  |  |  | } | 
| 64 | 0 |  |  |  |  | 0 | return $content; | 
| 65 |  |  |  |  |  |  | } | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | sub verify_or_die { | 
| 68 | 0 |  |  | 0 | 1 | 0 | my $self    = shift; | 
| 69 | 0 |  |  |  |  | 0 | my $content = $self->deny_by_score(@_); | 
| 70 | 0 | 0 |  |  |  | 0 | return $content if $content->{'success'}; | 
| 71 | 0 |  |  |  |  | 0 | die 'fail to verify reCAPTCHA: ', $content->{'error-codes'}[0], "\n"; | 
| 72 |  |  |  |  |  |  | } | 
| 73 |  |  |  |  |  |  |  | 
| 74 |  |  |  |  |  |  | # extra routines ======================================================================= | 
| 75 |  |  |  |  |  |  | sub scripts { | 
| 76 | 1 |  |  | 1 | 1 | 8 | my $self   = shift; | 
| 77 | 1 |  |  |  |  | 4 | my %attr   = @_; | 
| 78 | 1 | 50 |  |  |  | 5 | my $id     = $attr{'id'} or croak "missing the id for Form tag"; | 
| 79 | 1 |  | 50 |  |  | 7 | my $action = $attr{'action'} || 'homepage'; | 
| 80 | 1 |  |  |  |  | 8 | return <<"EOL"; | 
| 81 |  |  |  |  |  |  |  | 
| 82 |  |  |  |  |  |  |  | 
| 96 |  |  |  |  |  |  | EOL | 
| 97 |  |  |  |  |  |  | } | 
| 98 |  |  |  |  |  |  |  | 
| 99 |  |  |  |  |  |  | 1; | 
| 100 |  |  |  |  |  |  | __END__ |