1CGI::Application::PlugiUns:e:rAuCtohnetnrtiibcuatCteGidIo:nP:(eA3rp)lplDioccautmieonnt:a:tPiloungin::Authentication(3)
2
3
4
6 CGI::Application::Plugin::Authentication - Authentication framework for
7 CGI::Application
8
10 package MyCGIApp;
11
12 use base qw(CGI::Application); # make sure this occurs before you load the plugin
13
14 use CGI::Application::Plugin::Authentication;
15
16 MyCGIApp->authen->config(
17 DRIVER => [ 'Generic', { user1 => '123' } ],
18 );
19 MyCGIApp->authen->protected_runmodes('myrunmode');
20
21 sub myrunmode {
22 my $self = shift;
23
24 # The user should be logged in if we got here
25 my $username = $self->authen->username;
26
27 }
28
30 CGI::Application::Plugin::Authentication adds the ability to
31 authenticate users in your CGI::Application modules. It imports one
32 method called 'authen' into your CGI::Application module. Through the
33 authen method you can call all the methods of the
34 CGI::Application::Plugin::Authentication plugin.
35
36 There are two main decisions that you need to make when using this
37 module. How will the usernames and password be verified (i.e. from a
38 database, LDAP, etc...), and how can we keep the knowledge that a user
39 has already logged in persistent, so that they will not have to enter
40 their credentials again on the next request (i.e. how do we 'Store' the
41 authentication information across requests).
42
43 Choosing a Driver
44 There are three drivers that are included with the distribution. Also,
45 there is built in support for all of the Authen::Simple modules (search
46 CPAN for Authen::Simple for more information). This should be enough
47 to cover everyone's needs.
48
49 If you need to authenticate against a source that is not provided, you
50 can use the Generic driver which will accept either a hash of
51 username/password pairs, or an array of arrays of credentials, or a
52 subroutine reference that can verify the credentials. So through the
53 Generic driver you should be able to write your own verification
54 system. There is also a Dummy driver, which blindly accepts any
55 credentials (useful for testing). See the
56 CGI::Application::Plugin::Authentication::Driver::Generic,
57 CGI::Application::Plugin::Authentication::Driver::DBI and,
58 CGI::Application::Plugin::Authentication::Driver::Dummy docs for more
59 information on how to use these drivers. And see the Authen::Simple
60 suite of modules for information on those drivers.
61
62 Choosing a Store
63 The Store modules keep information about the authentication status of
64 the user persistent across multiple requests. The information that is
65 stored in the store include the username, and the expiry time of the
66 login. There are two Store modules included with this distribution. A
67 Session based store, and a Cookie based store. If your application is
68 already using Sessions (through the CGI::Application::Plugin::Session
69 module), then I would recommend that you use the Session store for
70 authentication. If you are not using the Session plugin, then you can
71 use the Cookie store. The Cookie store keeps all the authentication in
72 a cookie, which contains a checksum to ensure that users can not change
73 the information.
74
75 If you do not specify which Store module you wish to use, the plugin
76 will try to determine the best one for you.
77
78 Login page
79 The Authentication plugin comes with a default login page that can be
80 used if you do not want to create a custom login page. This login form
81 will automatically be used if you do not provide either a LOGIN_URL or
82 LOGIN_RUNMODE parameter in the configuration. If you plan to create
83 your own login page, I would recommend that you start with the HTML
84 code for the default login page, so that your login page will contain
85 the correct form fields and hidden fields.
86
87 TODO: The login page is designed using CSS style-sheets. I plan to
88 make this more flexible, so that you can easily create your own style-
89 sheets to make this login form more re-usable. Also, the default CSS
90 has only really been tested on Mozilla based browser, so if there are
91 any CSS gurus out there, I would appreciate some help in getting the
92 default login page to work nicely in most browsers. Currently it
93 should degrade gracefully, but it might not be pretty...
94
95 Ticket based authentication
96 This Authentication plugin can handle ticket based authentication
97 systems as well. All that is required of you is to write a Store
98 module that can understand the contents of the ticket. The
99 Authentication plugin will require at least the 'username' to be
100 retrieved from the ticket. A Ticket based authentication scheme will
101 not need a Driver module at all, since the actual verification of
102 credentials is done by an external authentication system, possibly even
103 on a different host. You will need to specify the location of the
104 login page using the LOGIN_URL configuration variable, and
105 unauthenticated users will automatically be redirected to your ticket
106 authentication login page.
107
109 authen
110 This is the only method exported from this module. Everything is
111 controlled through this method call, which will return a
112 CGI::Application::Plugin::Authentication object, or just the class name
113 if called as a class method. When using the plugin, you will always
114 first call $self->authen or __PACKAGE__->authen and then the method you
115 wish to invoke. For example:
116
117 __PACKAGE__->authen->config(
118 LOGIN_RUNMODE => 'login',
119 );
120
121 - or -
122
123 $self->authen->protected_runmodes(qw(one two));
124
126 config
127 This method is used to configure the
128 CGI::Application::Plugin::Authentication module. It can be called as
129 an object method, or as a class method. Calling this function, will not
130 itself generate cookies or session ids.
131
132 The following parameters are accepted:
133
134 DRIVER
135 Here you can choose which authentication module(s) you want to use
136 to perform the authentication. For simplicity, you can leave off
137 the CGI::Application::Plugin::Authentication::Driver:: part when
138 specifying the DRIVER name If this module requires extra
139 parameters, you can pass an array reference that contains as the
140 first parameter the name of the module, and the rest of the values
141 in the array will be considered options for the driver. You can
142 provide multiple drivers which will be used, in order, to check the
143 credentials until a valid response is received.
144
145 DRIVER => 'Dummy' # let anyone in regardless of the password
146
147 - or -
148
149 DRIVER => [ 'DBI',
150 DBH => $self->dbh,
151 TABLE => 'user',
152 CONSTRAINTS => {
153 'user.name' => '__CREDENTIAL_1__',
154 'MD5:user.password' => '__CREDENTIAL_2__'
155 },
156 ],
157
158 - or -
159
160 DRIVER => [
161 [ 'Generic', { user1 => '123' } ],
162 [ 'Generic', sub { my ($u, $p) = @_; is_prime($p) ? 1 : 0 } ]
163 ],
164
165 - or -
166
167 DRIVER => [ 'Authen::Simple::LDAP',
168 host => 'ldap.company.com',
169 basedn => 'ou=People,dc=company,dc=net'
170 ],
171
172 STORE
173 Here you can choose how we store the authenticated information
174 after a use has successfully logged in. We need to store the
175 username so that on the next request we can tell the user has
176 already logged in, and we do not have to present them with another
177 login form. If you do not provide the STORE option, then the
178 plugin will look to see if you are using the
179 CGI::Application::Plugin::Session module and based on that info use
180 wither the Session module, or fall back on the Cookie module. If
181 the module requires extra parameters, you can pass an array
182 reference that contains as the first parameter the name of the
183 module, and the rest of the array should contain key value pairs of
184 options for this module. These storage modules generally live
185 under the CGI::Application::Plugin::Authentication::Store:: name-
186 space, and this part of the package name can be left off when
187 specifying the STORE parameter.
188
189 STORE => 'Session'
190
191 - or -
192
193 STORE => ['Cookie',
194 NAME => 'MYAuthCookie',
195 SECRET => 'FortyTwo',
196 EXPIRY => '1d',
197 ]
198
199 POST_LOGIN_RUNMODE
200 Here you can specify a runmode that the user will be redirected to
201 if they successfully login.
202
203 POST_LOGIN_RUNMODE => 'welcome'
204
205 POST_LOGIN_URL
206 Here you can specify a URL that the user will be redirected to if
207 they successfully login. If both POST_LOGIN_URL and
208 POST_LOGIN_RUNMODE are specified, then the latter will take
209 precedence.
210
211 POST_LOGIN_URL => 'http://example.com/start.cgi'
212
213 POST_LOGIN_CALLBACK
214 A code reference that is executed after login processing but before
215 POST_LOGIN_RUNMODE or redirecting to POST_LOGIN_URL. This is
216 normally a method in your CGI::Application application and as such
217 the CGI::Application object is passed as a parameter.
218
219 POST_LOGIN_CALLBACK => \&update_login_date
220
221 and later in your code:
222
223 sub update_login_date {
224 my $self = shift;
225
226 return unless($self->authen->is_authenticated);
227
228 ...
229 }
230
231 LOGIN_RUNMODE
232 Here you can specify a runmode that the user will be redirected to
233 if they need to login.
234
235 LOGIN_RUNMODE => 'login'
236
237 LOGIN_URL
238 If your login page is external to this module, then you can use
239 this option to specify a URL that the user will be redirected to
240 when they need to login. If both LOGIN_URL and LOGIN_RUNMODE are
241 specified, then the latter will take precedence.
242
243 LOGIN_URL => 'http://example.com/login.cgi'
244
245 LOGOUT_RUNMODE
246 Here you can specify a runmode that the user will be redirected to
247 if they ask to logout.
248
249 LOGOUT_RUNMODE => 'logout'
250
251 LOGOUT_URL
252 If your logout page is external to this module, then you can use
253 this option to specify a URL that the user will be redirected to
254 when they ask to logout. If both LOGOUT_URL and LOGOUT_RUNMODE are
255 specified, then the latter will take precedence.
256
257 LOGIN_URL => 'http://example.com/logout.html'
258
259 CREDENTIALS
260 Set this to the list of form fields where the user will type in
261 their username and password. By default this is set to
262 ['authen_username', 'authen_password']. The form field names
263 should be set to a value that you are not likely to use in any
264 other forms. This is important because this plugin will
265 automatically look for query parameters that match these values on
266 every request to see if a user is trying to log in. So if you use
267 the same parameter names on a user management page, you may
268 inadvertently perform a login when that was not intended. Most of
269 the Driver modules will return the first CREDENTIAL as the
270 username, so make sure that you list the username field first.
271 This option can be ignored if you use the built in login box
272
273 CREDENTIALS => 'authen_password'
274
275 - or -
276
277 CREDENTIALS => [ 'authen_username', 'authen_domain', 'authen_password' ]
278
279 LOGIN_SESSION_TIMEOUT
280 This option can be used to tell the system when to force the user
281 to re-authenticate. There are a few different possibilities that
282 can all be used concurrently:
283
284 IDLE_FOR
285 If this value is set, a re-authentication will be forced if the
286 user was idle for more then x amount of time.
287
288 EVERY
289 If this value is set, a re-authentication will be forced every
290 x amount of time.
291
292 CUSTOM
293 This value can be set to a subroutine reference that returns
294 true if the session should be timed out, and false if it is
295 still active. This can allow you to be very selective about
296 how the timeout system works. The authen object will be passed
297 in as the only parameter.
298
299 Time values are specified in seconds. You can also specify the time
300 by using a number with the following suffixes (m h d w), which
301 represent minutes, hours, days and weeks. The default is 0 which
302 means the login will never timeout.
303
304 Note that the login is also dependant on the type of STORE that is
305 used. If the Session store is used, and the session expires, then
306 the login will also automatically expire. The same goes for the
307 Cookie store.
308
309 For backwards compatibility, if you set LOGIN_SESSION_TIMEOUT to a
310 time value instead of a hashref, it will be treated as an IDLE_FOR
311 time out.
312
313 # force re-authentication if idle for more than 15 minutes
314 LOGIN_SESSION_TIMEOUT => '15m'
315
316 # Everyone must re-authentication if idle for more than 30 minutes
317 # also, everyone must re-authentication at least once a day
318 # and root must re-authentication if idle for more than 5 minutes
319 LOGIN_SESSION_TIMEOUT => {
320 IDLE_FOR => '30m',
321 EVERY => '1d',
322 CUSTOM => sub {
323 my $authen = shift;
324 return ($authen->username eq 'root' && (time() - $authen->last_access) > 300) ? 1 : 0;
325 }
326 }
327
328 RENDER_LOGIN
329 This value can be set to a subroutine reference that returns the
330 HTML of a login form. The subroutine reference overrides the
331 default call to login_box. The subroutine is normally a method in
332 your CGI::Application application and as such the CGI::Application
333 object is passed as the first parameter.
334
335 RENDER_LOGIN => \&login_form
336
337 and later in your code:
338
339 sub login_form {
340 my $self = shift;
341
342 ...
343 return $html
344 }
345
346 LOGIN_FORM
347 You can set this option to customize the login form that is created
348 when a user needs to be authenticated. If you wish to replace the
349 entire login form with a completely custom version, then just set
350 LOGIN_RUNMODE to point to your custom runmode.
351
352 All of the parameters listed below are optional, and a reasonable
353 default will be used if left blank:
354
355 TITLE (default: Sign In)
356 the heading at the top of the login box
357
358 USERNAME_LABEL (default: User Name)
359 the label for the user name input
360
361 PASSWORD_LABEL (default: Password)
362 the label for the password input
363
364 SUBMIT_LABEL (default: Sign In)
365 the label for the submit button
366
367 COMMENT (default: Please enter your username and password in the
368 fields below.)
369 a message provided on the first login attempt
370
371 REMEMBERUSER_OPTION (default: 1)
372 provide a checkbox to offer to remember the users name in a
373 cookie so that their user name will be pre-filled the next time
374 they log in
375
376 REMEMBERUSER_LABEL (default: Remember User Name)
377 the label for the remember user name checkbox
378
379 REMEMBERUSER_COOKIENAME (default: CAPAUTHTOKEN)
380 the name of the cookie where the user name will be saved
381
382 REGISTER_URL (default: <none>)
383 the URL for the register new account link
384
385 REGISTER_LABEL (default: Register Now!)
386 the label for the register new account link
387
388 FORGOTPASSWORD_URL (default: <none>)
389 the URL for the forgot password link
390
391 FORGOTPASSWORD_LABEL (default: Forgot Password?)
392 the label for the forgot password link
393
394 INVALIDPASSWORD_MESSAGE (default: Invalid username or password<br
395 />(login attempt %d)
396 a message given when a login failed
397
398 INCLUDE_STYLESHEET (default: 1)
399 use this to disable the built in style-sheet for the login box
400 so you can provide your own custom styles
401
402 FORM_SUBMIT_METHOD (default: post)
403 use this to get the form to submit using 'get' instead of
404 'post'
405
406 FOCUS_FORM_ONLOAD (default: 1)
407 use this to automatically focus the login form when the page
408 loads so a user can start typing right away.
409
410 BASE_COLOUR (default: #445588)
411 This is the base colour that will be used in the included login
412 box. All other colours are automatically calculated based on
413 this colour (unless you hardcode the colour values). In order
414 to calculate other colours, you will need the Color::Calc
415 module. If you do not have the Color::Calc module, then you
416 will need to use fixed values for all of the colour options.
417 All colour values besides the BASE_COLOUR can be simple
418 percentage values (including the % sign). For example if you
419 set the LIGHTER_COLOUR option to 80%, then the calculated
420 colour will be 80% lighter than the BASE_COLOUR.
421
422 LIGHT_COLOUR (default: 50% or #a2aac4)
423 A colour that is lighter than the base colour.
424
425 LIGHTER_COLOUR (default: 75% or #d0d5e1)
426 A colour that is another step lighter than the light colour.
427
428 DARK_COLOUR (default: 30% or #303c5f)
429 A colour that is darker than the base colour.
430
431 DARKER_COLOUR (default: 60% or #1b2236)
432 A colour that is another step darker than the dark colour.
433
434 GREY_COLOUR (default: #565656)
435 A grey colour that is calculated by desaturating the base
436 colour.
437
438 LOGIN_FORM => {
439 TITLE => 'Login',
440 SUBMIT_LABEL => 'Login',
441 REMEMBERUSER_LABEL => 1,
442 BASE_COLOUR => '#0099FF',
443 LIGHTER_COLOUR => '#AAFFFF',
444 DARK_COLOUR => '50%',
445 }
446
447 protected_runmodes
448 This method takes a list of runmodes that are to be protected by
449 authentication. If a user tries to access one of these runmodes, then
450 they will be redirected to a login page unless they are properly logged
451 in. The runmode names can be a list of simple strings, regular
452 expressions, or special directives that start with a colon. This
453 method is cumulative, so if it is called multiple times, the new values
454 are added to existing entries. It returns a list of all entries that
455 have been saved so far. Calling this function, will not itself
456 generate cookies or session ids.
457
458 :all - All runmodes in this module will require authentication
459
460 # match all runmodes
461 __PACKAGE__->authen->protected_runmodes(':all');
462
463 # only protect runmodes one two and three
464 __PACKAGE__->authen->protected_runmodes(qw(one two three));
465
466 # protect only runmodes that start with auth_
467 __PACKAGE__->authen->protected_runmodes(qr/^auth_/);
468
469 # protect all runmodes that *do not* start with public_
470 __PACKAGE__->authen->protected_runmodes(qr/^(?!public_)/);
471
472 is_protected_runmode
473 This method accepts the name of a runmode, and will tell you if that
474 runmode is a protected runmode (i.e. does a user need to be
475 authenticated to access this runmode). Calling this function, will not
476 itself generate cookies or session ids.
477
478 redirect_after_login
479 This method is be called during the prerun stage to redirect the user
480 to the page that has been configured as the destination after a
481 successful login. The location is based on the values of the
482 POST_LOGIN_RUNMODE or POST_LOGIN_URL config parameter, or in their
483 absence, the page will be redirected to the page that was originally
484 requested when the login page was triggered.
485
486 redirect_to_login
487 This method is be called during the prerun stage if the current user is
488 not logged in, and they are trying to access a protected runmode. It
489 will redirect to the page that has been configured as the login page,
490 based on the value of LOGIN_RUNMODE or LOGIN_URL If nothing is
491 configured a simple login page will be automatically provided.
492
493 redirect_to_logout
494 This method is called during the prerun stage if the user has requested
495 to be logged out. It will redirect to the page that has been
496 configured as the logout page, based on the value of LOGOUT_RUNMODE or
497 LOGOUT_URL If nothing is configured, the page will redirect to the
498 website homepage.
499
500 setup_runmodes
501 This method is called during the prerun stage to register some custom
502 runmodes that the Authentication plugin requires in order to function.
503 Calling this function, will not itself generate cookies or session ids.
504
505 last_login
506 This will return return the time of the last login for this user
507
508 my $last_login = $self->authen->last_login;
509
510 This function will initiate a session or cookie if one has not been
511 created already.
512
513 last_access
514 This will return return the time of the last access for this user
515
516 my $last_access = $self->authen->last_access;
517
518 This function will initiate a session or cookie if one has not been
519 created already.
520
521 is_login_timeout
522 This will return true or false depending on whether the users login
523 status just timed out
524
525 $self->add_message('login session timed out') if $self->authen->is_login_timeout;
526
527 This function will initiate a session or cookie if one has not been
528 created already.
529
530 is_authenticated
531 This will return true or false depending on the login status of this
532 user
533
534 assert($self->authen->is_authenticated); # The user should be logged in if we got here
535
536 This function will initiate a session or cookie if one has not been
537 created already.
538
539 login_attempts
540 This method will return the number of failed login attempts have been
541 made by this user since the last successful login. This is not a
542 number that can be trusted, as it is dependant on the underlying store
543 to be able to return the correct value for this user. For example, if
544 the store uses a cookie based session, the user trying to login could
545 delete their cookies, and hence get a new session which will not have
546 any login attempts listed. The number will be cleared upon a
547 successful login. This function will initiate a session or cookie if
548 one has not been created already.
549
550 username
551 This will return the username of the currently logged in user, or undef
552 if no user is currently logged in.
553
554 my $username = $self->authen->username;
555
556 This function will initiate a session or cookie if one has not been
557 created already.
558
559 is_new_login
560 This will return true or false depending on if this is a fresh login
561
562 $self->log->info("New Login") if $self->authen->is_new_login;
563
564 This function will initiate a session or cookie if one has not been
565 created already.
566
567 credentials
568 This method will return the names of the form parameters that will be
569 looked for during a login. By default they are authen_username and
570 authen_password, but these values can be changed by supplying the
571 CREDENTIALS parameters in the configuration. Calling this function,
572 will not itself generate cookies or session ids.
573
574 logout
575 This will attempt to logout the user. If during a request the
576 Authentication module sees a parameter called 'authen_logout', it will
577 automatically call this method to log out the user.
578
579 $self->authen->logout();
580
581 This function will initiate a session or cookie if one has not been
582 created already.
583
584 drivers
585 This method will return a list of driver objects that are used for
586 verifying the login credentials. Calling this function, will not itself
587 generate cookies or session ids.
588
589 store
590 This method will return a store object that is used to store
591 information about the status of the authentication across multiple
592 requests. This function will initiate a session or cookie if one has
593 not been created already.
594
595 initialize
596 This does most of the heavy lifting for the Authentication plugin. It
597 will check to see if the user is currently attempting to login by
598 looking for the credential form fields in the query object. It will
599 load the required driver objects and authenticate the user. It is OK
600 to call this method multiple times as it checks to see if it has
601 already been executed and will just return without doing anything if
602 called multiple times. This allows us to call initialize as late as
603 possible in the request so that no unnecessary work is done.
604
605 The user will be logged out by calling the "logout()" method if the
606 login session has been idle for too long, if it has been too long since
607 the last login, or if the login has timed out. If you need to know if
608 a user was logged out because of a time out, you can call the
609 "is_login_timeout" method.
610
611 If all goes well, a true value will be returned, although it is usually
612 not necessary to check.
613
614 This function will initiate a session or cookie if one has not been
615 created already.
616
617 login_box
618 This method will return the HTML for a login box that can be embedded
619 into another page. This is the same login box that is used in the
620 default authen_login runmode that the plugin provides.
621
622 This function will initiate a session or cookie if one has not been
623 created already.
624
625 login_styles
626 This method returns a style-sheet that can be used for the login box
627 that the plugin provides. The login box automatically includes these
628 default styles in the page unless you set the LOGIN_FORM =>
629 INCLUDE_STYLESHEET option to 0. The colours used in the returned
630 styles can be customized by providing colour options to LOGIN_FORM
631 configuration parameter.
632
633 Calling this function, will not itself generate cookies or session ids.
634
635 new
636 This method creates a new CGI::Application::Plugin::Authentication
637 object. It requires as it's only parameter a CGI::Application object.
638 This method should never be called directly, since the 'authen' method
639 that is imported into the CGI::Application module will take care of
640 creating the CGI::Application::Plugin::Authentication object when it is
641 required. Calling this function, will not itself generate cookies or
642 session ids.
643
644 instance
645 This method works the same way as 'new', except that it returns the
646 same Authentication object for the duration of the request. This
647 method should never be called directly, since the 'authen' method that
648 is imported into the CGI::Application module will take care of creating
649 the CGI::Application::Plugin::Authentication object when it is
650 required. Calling this function, will not itself generate cookies or
651 session ids.
652
654 prerun_callback
655 This method is a CGI::Application prerun callback that will be
656 automatically registered for you if you are using CGI::Application 4.0
657 or greater. If you are using an older version of CGI::Application you
658 will have to create your own cgiapp_prerun method and make sure you
659 call this method from there.
660
661 sub cgiapp_prerun {
662 my $self = shift;
663
664 $self->CGI::Application::Plugin::Authentication::prerun_callback();
665 }
666
668 authen_login_runmode
669 This runmode is provided if you do not want to create your own login
670 runmode. It will display a simple login form for the user, which can
671 be replaced by assigning RENDER_LOGIN a coderef that returns the HTML.
672
673 authen_dummy_redirect
674 This runmode is provided for convenience when an external redirect
675 needs to be done. It just returns an empty string.
676
678 In a CGI::Application module:
679
680 use base qw(CGI::Application);
681 use CGI::Application::Plugin::AutoRunmode;
682 use CGI::Application::Plugin::Session;
683 use CGI::Application::Plugin::Authentication;
684
685 __PACKAGE__->authen->config(
686 DRIVER => [ 'Generic', { user1 => '123' } ],
687 STORE => 'Session',
688 LOGOUT_RUNMODE => 'start',
689 );
690 __PACKAGE__->authen->protected_runmodes(qr/^auth_/, 'one');
691
692 sub start : RunMode {
693 my $self = shift;
694
695 }
696
697 sub one : RunMode {
698 my $self = shift;
699
700 # The user will only get here if they are logged in
701 }
702
703 sub auth_two : RunMode {
704 my $self = shift;
705
706 # This is also protected because of the
707 # regexp call to protected_runmodes above
708 }
709
711 There are lots of things that can still be done to improve this plugin.
712 If anyone else is interested in helping out feel free to dig right in.
713 Many of these things don't need my input, but if you want to avoid
714 duplicated efforts, send me a note, and I'll let you know of anyone
715 else is working in the same area.
716
717 write a tutorial
718 build more Drivers (Class::DBI, LDAP, Radius, etc...)
719 Add support for method attributes to identify runmodes that require
720 authentication
721 finish the test suite
722 provide more example code
723 clean up the documentation
724 build a DB driver that builds it's own table structure. This can be
725 used by people that don't have their own user database to work with,
726 and could include a simple user management application.
727
729 This is alpha software and as such, the features and interface are
730 subject to change. So please check the Changes file when upgrading.
731
733 CGI::Application, perl(1)
734
736 Author: Cees Hek <ceeshek@gmail.com>; Co-maintainer: Nicholas Bamber
737 <nicholas@periapt.co.uk>.
738
740 Thanks to SiteSuite (http://www.sitesuite.com.au) for funding the
741 development of this plugin and for releasing it to the world.
742
744 Copyright (c) 2005, SiteSuite. All rights reserved.
745
746 This module is free software; you can redistribute it and/or modify it
747 under the same terms as Perl itself.
748
750 BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
751 FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT
752 WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
753 PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND,
754 EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
755 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
756 ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
757 YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
758 NECESSARY SERVICING, REPAIR, OR CORRECTION.
759
760 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
761 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
762 REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE
763 TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR
764 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
765 SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
766 RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
767 FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
768 SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
769 DAMAGES.
770
771
772
773perl v5.12.0 20C1G0I-:0:4A-p3p0lication::Plugin::Authentication(3)