File Coverage

lib/CGI/Auth/Auto.pm
Criterion Covered Total %
statement 41 130 31.5
branch 5 46 10.8
condition 6 29 20.6
subroutine 9 30 30.0
pod 9 15 60.0
total 70 250 28.0


line stmt bran cond sub pod time code
1             package CGI::Auth::Auto;
2 1     1   18331 use Carp;
  1         2  
  1         94  
3 1     1   5 use strict;
  1         3  
  1         31  
4 1     1   6 use base qw(CGI::Auth);
  1         6  
  1         1072  
5 1     1   5812 use LEOCHARRE::DEBUG;
  1         4553  
  1         7  
6 1     1   979 use CGI::Scriptpaths;
  1         1855  
  1         47  
7 1     1   7 use vars qw($VERSION);
  1         2  
  1         1690  
8             $VERSION = sprintf "%d.%02d", q$Revision: 1.21 $ =~ /(\d+)/g;
9              
10             $CGI::Auth::Auto::CGI_APP_COMPATIBLE = 'rm=logout';
11              
12              
13             sub new {
14 1     1 1 38001 my $proto = shift;
15 1   33     39 my $class = ref($proto) || $proto;
16 1         9 my $self = {};
17 1         11 bless $self, $class;
18              
19 1         5 my $param = shift;
20 1   50     67 $param->{-authfields} ||= [
21             {id => 'user', display => 'User Name', hidden => 0, required => 1},
22             {id => 'pw', display => 'Password', hidden => 1, required => 1},
23             ];
24            
25 1   33     27 $param->{-authdir} ||= _guess_authdir();
26            
27 1   33     35 $param->{-formaction} ||= CGI::Scriptpaths::script_rel_path(); #_guess_formaction();
28 1   33     5682 $param->{-sessdir} ||= $param->{-authdir}.'/sess';
29            
30 1 50 33     32 if (defined $param->{-logintmplpath} or defined $param->{-logintmpl}){
31 0   0     0 $param->{-logintmplpath} ||= $param->{-authdir};
32 0   0     0 $param->{-logintmpl} ||= 'login.html';
33             }
34            
35 1 50       21 if (DEBUG){
36 1         1556 require Data::Dumper;
37 1         11625 printf STDERR __PACKAGE__."::new() params: %s\n", Data::Dumper::Dumper($param);
38             #debug(Data::Dumper::Dumper(\%ENV)."\n");
39             }
40            
41 1 50       257 if (!defined $param->{-authdir}){
42 0         0 carp(__PACKAGE__."::new() missing -authdir param to constructor or setting \$ENV{DOCUMENT_ROOT}");
43 0         0 return;
44             }
45            
46 1 50       31 unless( $self->init($param) ){
47 0         0 warn( sprintf "%s\::init() failed, authdir [%s], userfile expected at:[%s]",__PACKAGE__,$param->{-authdir}, $param->{-authdir}.'/user.dat');
48 0         0 return undef;
49             }
50              
51 1         37972 return $self;
52             }
53              
54              
55              
56             sub authdir {
57 0     0 0 0 my $self = shift;
58 0         0 return $self->{authdir};
59             }
60              
61             sub userdat {
62 0     0 0 0 my $self = shift;
63 0         0 return $self->{userdat};
64             }
65              
66             sub sessdir {
67 0     0 0 0 my $self = shift;
68 0         0 return $self->{sessdir};
69             }
70              
71             sub userfile {
72 0     0 0 0 my $self = shift;
73 0         0 return $self->{userfile};
74             }
75              
76              
77             # override check so that we can do cookie thing
78             sub check {
79 0     0 1 0 my $self = shift;
80 0         0 $self->_pre_check;
81 0         0 $self->SUPER::check; # access overridden method
82 0         0 $self->_post_check;
83 0         0 return;
84             }
85              
86              
87              
88             # this runs before auth check
89             # RATIONALE: pre only tries to load an auth string (unless logout is detected)
90             sub _pre_check {
91 0     0   0 my $self = shift;
92              
93              
94              
95             # 1) first of all see if a prev sess_file id (filename really) can be gotten from cookie
96 0 0       0 my $sess_file = $self->_get_sess_file_from_cookie
97             or # no sess_file on cooie? no harm done.. just return.
98             return;
99              
100              
101              
102              
103              
104             # 2) ok. so the cookie has a sess_file in it...
105             # TODO: had to mess with internals of CGI::Auth ( with $self->{sess_file} ) because that module
106             # does not provide for a set() type of method for the sess_file, it does accept as constructor
107             # but i'd rather leave the constructor to do what it does, which seems to be to assure that
108             # CGI::Auth finds its support files, user db, template, etc.
109            
110 0         0 $self->{sess_file} = $sess_file; # <- had to mess with CGI::Auth internals here.
111 0 0       0 unless( $self->OpenSessionFile ){ # CGI::Auth::OpenSessionFile() checks with $CGI::Auth::OpenSessionFile::sess_file
112             # delete the cookie
113 0 0       0 $self->_ruin_cookie_and_redirect and exit(0);
114             }
115            
116            
117            
118            
119             # 3) cookie was found, sess_file was ok.. now pass it for CGI::Auth::check() to use later.
120             ### $sess_file
121 0         0 $self->{cgi}->param( -name=> $self->sfparam_name, -value=> $sess_file );
122            
123 0         0 return 1;
124             }
125              
126              
127              
128             sub _ruin_cookie_and_redirect {
129 0     0   0 my $self = shift;
130            
131 0         0 print $self->get_cgi->redirect(
132             -uri => $self->{formaction},
133             -cookie =>
134             $self->get_cgi->cookie(
135             -name => $self->sfparam_name,
136             -value => '',
137             -expire => 'now'
138             )
139             );
140              
141 0         0 return 1;
142             }
143              
144             sub _set_cookie_and_redirect {
145 0     0   0 my $self = shift;
146            
147 0         0 print $self->get_cgi->redirect(
148             -uri => $self->{formaction},
149             -cookie =>
150             $self->get_cgi->cookie(
151             -name => $self->sfparam_name,
152             -value => $self->sfparam_value,
153             -expire => $self->get_cookie_expire_time
154             )
155             );
156              
157 0         0 return 1;
158             }
159              
160              
161              
162              
163              
164              
165              
166              
167             # post_check() only runs if user is successfully authenticated.
168             # its task is
169             # a) to assure a cookie is present.
170             # b) check for a logout for this already authenticated user
171             sub _post_check {
172 0     0   0 my $self = shift;
173              
174             # 1) assure cookie is here
175 0 0       0 unless ( $self->_get_sess_file_from_cookie ) { # if no cookie
176 0 0       0 $self->_set_cookie_and_redirect() and exit(0);
177             }
178              
179             # 2) detect logout for authenticated user
180             # ok. so now we found cookie and sess_file id in it- did the user request a logout???
181            
182 0 0       0 if ( $self->_requested_logout ) { # check if logout was requested.
183 0         0 $self->logout; # logout will exit(0). we dont do it here because logout() method could be called directly.
184             };
185            
186 0         0 return 1;
187             }
188              
189              
190              
191              
192              
193              
194             sub logout {
195 0     0 1 0 my $self = shift;
196              
197             # delete auth session
198 0         0 $self->endsession;
199              
200             # ruin cookie and redirects back here
201 0 0       0 $self->_ruin_cookie_and_redirect and exit(0);
202             }
203              
204             # legacy
205             sub run {
206 0     0 0 0 my $self = shift;
207 0         0 $self->check;
208             }
209              
210              
211              
212              
213             # basic get and set methods. useful..
214             # these methods dont do anything major like exit or redirect etc
215              
216             sub get_cgi {
217 0     0 1 0 my $self = shift;
218 0         0 return $self->{cgi};
219             }
220              
221             sub username {
222 0     0 1 0 my $self = shift;
223 0         0 my ($username, undef) = $self->OpenSessionFile;
224 0 0       0 $username or return;
225 0         0 return $username;
226             }
227              
228              
229             sub start_session {
230 0     0 0 0 my $self = shift;
231 0         0 return $self->SUPER::start_session;
232             }
233              
234             sub _get_sess_file_from_cookie {
235             ## _load_cookie()
236 0     0   0 my $self = shift;
237 0         0 my $session_file = $self->get_cgi->cookie($self->sfparam_name);
238 0 0       0 $session_file or return;
239 0         0 return $session_file;
240             }
241              
242             sub _requested_logout {
243 0     0   0 my $self= shift;
244              
245             # does the query string look like we are trying to log out?
246              
247              
248             # for cgi application:
249            
250 0 0       0 if ($CGI::Auth::Auto::CGI_APP_COMPATIBLE){
251 0         0 my($param,$runmode) = split(/\=/, $CGI::Auth::Auto::CGI_APP_COMPATIBLE );
252            
253 0 0 0     0 if ( defined $self->get_cgi->param($param) and $self->get_cgi->param($param) eq $runmode ){
254 0         0 debug("detected $CGI::Auth::Auto::CGI_APP_COMPATIBLE\n");
255 0         0 return 1;
256             }
257             }
258              
259 0 0       0 if ( defined $ENV{QUERY_STRING} ){
260 0         0 debug("\$ENV{QUERY_STRING} $ENV{QUERY_STRING}\n");
261 0 0       0 return 1 if $ENV{QUERY_STRING} eq 'logout';
262             }
263            
264 0         0 my $paramname = $self->get_logout_param_name;
265 0         0 my $paramval = $self->get_cgi->param($self->get_logout_param_name);
266 0 0       0 debug( sprintf " param name: $paramname [$paramval:%s]", ( defined $paramval ? 1 : 0 ));
267              
268 0 0       0 defined $paramval or return 0;
269 0         0 return 1;
270             }
271              
272             sub set_cookie_expire_time {
273 0     0 1 0 my $self= shift;
274 0 0       0 my $val = shift; $val or croak("must have valid arg to set_cookie_expire()");
  0         0  
275 0         0 $self->{cookie_expire_time}= $val;
276 0         0 return $self->{cookie_expire_time};
277             }
278              
279             sub get_cookie_expire_time {
280 0     0 1 0 my $self= shift;
281 0   0     0 $self->{cookie_expire_time} ||= '+1h';
282 0         0 return $self->{cookie_expire_time};
283             }
284              
285             sub get_logout_param_name {
286 0     0 1 0 my $self = shift;
287 0   0     0 $self->{logout_param_name} ||= 'logout';
288 0         0 return $self->{logout_param_name};
289             }
290              
291             sub set_logout_param_name {
292 0     0 1 0 my $self = shift;
293 0 0       0 my $val = shift; $val or croak("must have arg to set_logout_param_name()");
  0         0  
294 0         0 $self->{logout_param_name} = $val;
295 0         0 return $self->{logout_param_name};
296             }
297              
298              
299              
300              
301              
302             # GUESSING SUBS
303              
304              
305             sub _guess_authdir {
306 1     1   5 my $dir = __guess_base().'/auth';
307 1         12 debug("$dir\n");
308 1         47 return $dir;
309             }
310              
311             sub __guess_base {
312 1     1   11 my $cgibin = CGI::Scriptpaths::abs_cgibin();
313              
314 1 50       11192 unless(defined $cgibin){
315 0 0       0 $cgibin = script_abs_loc() or confess("cant get script's absolute location");
316             }
317 1         24 debug($cgibin);
318 1         123 return $cgibin;
319             }
320              
321             sub _guess_sessdir {
322 0     0     my $dir = __guess_authdir().'/sess';
323 0           debug("$dir\n");
324 0           return $dir;
325             }
326              
327              
328             1;
329              
330              
331             __END__