line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Catalyst::TraitFor::Controller::CAPTCHA; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
13086
|
use Moose::Role; |
|
1
|
|
|
|
|
291317
|
|
|
1
|
|
|
|
|
3
|
|
4
|
1
|
|
|
1
|
|
4401
|
use MooseX::MethodAttributes::Role; |
|
1
|
|
|
|
|
84832
|
|
|
1
|
|
|
|
|
7
|
|
5
|
1
|
|
|
1
|
|
41788
|
use namespace::autoclean; |
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
4
|
|
6
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
|
637
|
use GD::SecurityImage; |
|
1
|
|
|
|
|
3489
|
|
|
1
|
|
|
|
|
3
|
|
8
|
|
|
|
|
|
|
use HTTP::Date; |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $VERSION = '1.0'; |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
use MRO::Compat; |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
sub generate_captcha : Private { |
15
|
|
|
|
|
|
|
my ($self,$c) = @_; |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
my $conf = $c->config->{captcha}; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
my $new = $conf->{gd_config} ||= {}; |
20
|
|
|
|
|
|
|
my $create = $conf->{create} ||= []; |
21
|
|
|
|
|
|
|
my $particle = $conf->{particle} ||= []; |
22
|
|
|
|
|
|
|
my $out = $conf->{out} ||= {}; |
23
|
|
|
|
|
|
|
my $sname = $conf->{session_name} ||= 'captcha_string'; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
my $image = GD::SecurityImage->new( %{ $new } ); |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
$image->random(); |
28
|
|
|
|
|
|
|
$image->create( @{ $create } ); |
29
|
|
|
|
|
|
|
$image->particle( @{ $particle } ); |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
my ( $image_data, $mime_type, $random_string ) = $image->out( %{ $out } ); |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
#Store the captcha string to session for validation |
34
|
|
|
|
|
|
|
$c->session->{ $sname } = $random_string; |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
$c->res->headers->expires( time() ); |
37
|
|
|
|
|
|
|
$c->res->headers->header( 'Last-Modified' => HTTP::Date::time2str ); |
38
|
|
|
|
|
|
|
$c->res->headers->header( 'Pragma' => 'no-cache' ); |
39
|
|
|
|
|
|
|
$c->res->headers->header( 'Cache-Control' => 'no-cache' ); |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
$c->res->content_type("image/$mime_type"); |
42
|
|
|
|
|
|
|
$c->res->output($image_data); |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub validate_captcha : Private { |
47
|
|
|
|
|
|
|
my ($self, $c , $posted_string ) = @_; |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
my $conf = $c->config->{captcha}; |
50
|
|
|
|
|
|
|
my $sname = $conf->{session_name} ||= 'captcha_string'; |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
my $string = $c->session->{ $sname }; |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
#Clear the Captcha |
55
|
|
|
|
|
|
|
$c->session->{ $sname } = undef; |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
return ( $posted_string && $string && $posted_string eq $string ); |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
1; |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
__END__ |
64
|
|
|
|
|
|
|
=pod |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=head1 NAME |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
Catalyst::TraitFor::Controller::CAPTCHA - authenticate human by create and validate captcha |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=head1 VERSION |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
version 1.0 |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=head1 SYNOPSIS |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
In your controller |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
package MyApp::Controller::MyController; |
79
|
|
|
|
|
|
|
use Moose; |
80
|
|
|
|
|
|
|
use namespace::autoclean; |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
BEGIN { extends 'Catalyst::Controller' } |
83
|
|
|
|
|
|
|
with 'Catalyst::TraitFor::Controller::CAPTCHA'; |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
sub captcha_image : Local :Args(0) { |
86
|
|
|
|
|
|
|
my ( $self, $c ) = @_; |
87
|
|
|
|
|
|
|
$c->forward('generate_captcha'); |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
#Now <img src="/captcha_image" /> will have captcha and |
91
|
|
|
|
|
|
|
#<input name="captcha_text" type="text"> will prompt user to enter captcha text |
92
|
|
|
|
|
|
|
#and this should be embed into your form that needs to be validated. |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub form_post : Local { |
95
|
|
|
|
|
|
|
my ($self,$c) = @_; |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
my $posted_string = $c->req->body_params('captcha_text'); |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
if ( $c->forward('validate_captcha',[$posted_string]) ) { |
100
|
|
|
|
|
|
|
#Allowed |
101
|
|
|
|
|
|
|
}else { |
102
|
|
|
|
|
|
|
#Not Allowed |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
1; |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=head1 SUMMARY |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
This Catalyst::Controller role provides C<Private> methods that deal with the generation and validation of captcha. |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=head2 CONFIGURATION |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
In MyApp.pm (or equivalent in config file): |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
__PACKAGE__->config->{captcha} = { |
117
|
|
|
|
|
|
|
session_name => 'captcha_string', |
118
|
|
|
|
|
|
|
#Refer GD::SecurityImage for additonal configuration |
119
|
|
|
|
|
|
|
gd_config => { |
120
|
|
|
|
|
|
|
width => 100, |
121
|
|
|
|
|
|
|
height => 50, |
122
|
|
|
|
|
|
|
lines => 5, |
123
|
|
|
|
|
|
|
gd_font => 'giant', |
124
|
|
|
|
|
|
|
}, |
125
|
|
|
|
|
|
|
create => [qw/normal rect/], |
126
|
|
|
|
|
|
|
particle => [10], |
127
|
|
|
|
|
|
|
out => {force => 'jpeg'} |
128
|
|
|
|
|
|
|
}; |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
=head2 DESCRIPTION |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
This controller's private methods will create and validate captcha.This module is based/altered from L<Catalyst::Plugin::Captcha> because that shouldn't be a Catalyst::Plugin.Now it is a base controller like L<Catalyst::TraitFor::Controller::reCAPTCHA>.It uses L<GD::SecurityImage> and requires a session plugins like L<Catalyst::Plugin::Session>. |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
=head2 METHODS |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
=head3 generate_captcha : Private |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
This will create and respond the captcha. |
139
|
|
|
|
|
|
|
$c->forward('generate_captcha'); |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=head3 validate_captcha : Private |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
This will validate the given string against the Captcha image that has been generated earlier. |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
if ( $c->forward('validate_captcha',[$posted_string]) ) { |
146
|
|
|
|
|
|
|
#do something based on the CAPTCHA passing |
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
=head1 SEE ALSO |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=over 4 |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
=item * |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
L<Catalyst::TraitFor::Controller::reCAPTCHA> |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
=item * |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
L<Catalyst::Controller> |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
=item * |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
L<Catalyst> |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
=item * |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
L<GD::SecurityImage> |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=back |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
This module is almost copied from Diego Kuperman L<Catalyst::Plugin::Captcha>. |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
=head1 AUTHOR |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
Baskar Nallathambi <baskarmusiri@gmail.com>,<baskar@exceleron.com> |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
182
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=cut |