File Coverage

blib/lib/Catalyst/TraitFor/Controller/reCAPTCHA.pm
Criterion Covered Total %
statement 40 44 90.9
branch 6 10 60.0
condition 6 12 50.0
subroutine 9 9 100.0
pod 2 2 100.0
total 63 77 81.8


line stmt bran cond sub pod time code
1             package Catalyst::TraitFor::Controller::reCAPTCHA;
2             # ABSTRACT: authenticate people and read books!
3             $Catalyst::TraitFor::Controller::reCAPTCHA::VERSION = '2.00';
4 2     2   1897057 use Moose::Role;
  2         404615  
  2         17  
5 2     2   9553 use MooseX::MethodAttributes::Role;
  2         118843  
  2         12  
6 2     2   103469 use namespace::autoclean;
  2         10  
  2         16  
7              
8 2     2   991 use Captcha::reCAPTCHA;
  2         40095  
  2         56  
9 2     2   14 use Carp 'croak';
  2         4  
  2         347  
10              
11             has recaptcha => ( is => 'ro', default => sub { Captcha::reCAPTCHA->new } );
12              
13             sub captcha_get :Private {
14 2     2 1 51517 my ( $self, $c ) = @_;
15 2         4 my $recaptcha;
16              
17 2 100 100     8 if (lc($c->config->{recaptcha}{version} || '') eq 'v2') {
18             $recaptcha = $self->recaptcha->get_html_v2(
19             $c->config->{recaptcha}{pub_key},
20             $c->config->{recaptcha}{options}
21 1         108 );
22             }
23             else {
24             $recaptcha = $self->recaptcha->get_html(
25             $c->config->{recaptcha}{pub_key},
26             $c->stash->{recaptcha_error},
27             $c->req->secure,
28             $c->config->{recaptcha}{options}
29 1         118 );
30             }
31              
32 2         1136 $c->stash( recaptcha => $recaptcha );
33 2     2   403 }
  2         940  
  2         18  
34              
35             sub captcha_check :Private {
36 1     1 1 32159 my ( $self, $c ) = @_;
37              
38 1         4 my $challenge = $c->req->param('recaptcha_challenge_field');
39 1         145 my $response = $c->req->param('recaptcha_response_field');
40 1         132 my $response_v2 = $c->req->param('g-recaptcha-response');
41              
42 1 50 33     75 unless ( ($response && $challenge || $response_v2)) {
      33        
43 0         0 $c->stash->{recaptcha_error} = 'User appears not to have submitted a recaptcha';
44 0         0 return;
45             }
46              
47 1         3 my $res;
48 1 50 50     9 if (lc($c->config->{recaptcha}{version} || '') eq 'v2') {
49 0         0 $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = $c->req->secure;
50             $res = $self->recaptcha->check_answer_v2(
51             $c->config->{recaptcha}{priv_key},
52 0         0 $response_v2,
53             $c->req->address
54             );
55             }
56             else {
57             $res = $self->recaptcha->check_answer(
58             $c->config->{recaptcha}{priv_key},
59 1         113 $c->req->address,
60             $challenge,
61             $response
62             );
63             }
64              
65 1 50       55334 croak 'Failed to get valid result from reCaptcha'
66             unless ref $res eq 'HASH';
67              
68 1 50       4 unless ( $res->{is_valid} ) {
69 1   50     7 $c->stash( recaptcha_error => $res->{error} || 'Invalid recaptcha' );
70             }
71              
72 1         90 $c->stash( recaptcha_ok => $res->{is_valid} );
73 1         63 return $res->{is_valid};
74 2     2   1078 }
  2         5  
  2         7  
75              
76             1;
77              
78             __END__
79              
80             =pod
81              
82             =encoding UTF-8
83              
84             =head1 NAME
85              
86             Catalyst::TraitFor::Controller::reCAPTCHA - authenticate people and read books!
87              
88             =head1 VERSION
89              
90             version 2.00
91              
92             =head1 SYNOPSIS
93              
94             In your controller
95              
96             package MyApp::Controller::Comment;
97             use Moose;
98             use namespace::autoclean;
99              
100             BEGIN { extends 'Catalyst::Controller' }
101             with 'Catalyst::TraitFor::Controller::reCAPTCHA';
102              
103             sub example : Local {
104             my ( $self, $c ) = @;
105              
106             # validate received form
107             if ( $c->forward('captcha_check') ) {
108             $c->detach('my_form_is_ok');
109             }
110              
111             # Set reCAPTCHA html code
112             $c->forward('captcha_get');
113             }
114              
115             1;
116              
117             =head1 SUMMARY
118              
119             Catalyst::Controller role around L<Captcha::reCAPTCHA>. Provides
120             a number of C<Private> methods that deal with the recaptcha.
121              
122             This module is based/copied from L<Catalyst::Controller::reCAPTCHA>,
123             it just adds support for option passing and automatically sets ssl
124             when used on a secure request.
125              
126             If you are using L<Catalyst::Controller::reCAPTCHA> and want to move
127             to this role, you only need to stop extending L<Catalyst::Controller>
128             and apply this role as shown in the SYNOPSIS.
129              
130             =head2 CONFIGURATION
131              
132             In MyApp.pm (or equivalent in config file):
133              
134             __PACKAGE__->config->{recaptcha} = {
135             pub_key => '6LcsbAAAAAAAAPDSlBaVGXjMo1kJHwUiHzO2TDze',
136             priv_key => '6LcsbAAAAAAAANQQGqwsnkrTd7QTGRBKQQZwBH-L',
137             options => { theme => 'white' },
138             version => 'v2' ## reCaptcha version default (v1)
139             };
140              
141             (the two keys above work for http://localhost unless someone hammers the
142             reCAPTCHA server with failures, in which case the API keys get a temporary
143             ban).
144              
145             =head2 METHODS
146              
147             =head3 captcha_get : Private
148              
149             Sets $c->stash->{recaptcha} to be the html form for the L<http://recaptcha.net/> reCAPTCHA service which can be included in your HTML form.
150              
151             =head3 captcha_check : Private
152              
153             Validates the reCaptcha using L<Captcha::reCAPTCHA>. sets
154             $c->stash->{recaptcha_ok} which will be 1 on success. The action also returns
155             true if there is success. This means you can do:
156              
157             if ( $c->forward(captcha_check) ) {
158             # do something based on the reCAPTCHA passing
159             }
160              
161             or alternatively:
162              
163             $c->forward(captcha_check);
164             if ( $c->stash->{recaptcha_ok} ) {
165             # do something based on the reCAPTCHA passing
166             }
167              
168             If there's an error, $c->stash->{recaptcha_error} is
169             set with the error string provided by L<Captcha::reCAPTCHA>.
170              
171             =head1 SEE ALSO
172              
173             =over 4
174              
175             =item *
176              
177             L<Captcha::reCAPTCHA>
178              
179             =item *
180              
181             L<Catalyst::Controller>
182              
183             =item *
184              
185             L<Catalyst>
186              
187             =back
188              
189             =head1 ACKNOWLEDGEMENTS
190              
191             This module is almost copied from Kieren Diment L<Catalyst::Controller::reCAPTCHA>.
192              
193             =head1 AUTHOR
194              
195             Diego Kuperman <diego@freekeylabs.com>
196              
197             =head1 COPYRIGHT AND LICENSE
198              
199             This software is copyright (c) 2017 by Diego Kuperman.
200              
201             This is free software; you can redistribute it and/or modify it under
202             the same terms as the Perl 5 programming language system itself.
203              
204             =cut