=encoding utf8

=head1 NAME

GD::SecurityImage::AC - A drop-in replacement for Authen::Captcha.

=head1 SYNOPSIS

  use GD::SecurityImage::AC;

  # create a new object
  my $captcha = Authen::Captcha->new();

  # set the data_folder. contains flatfile db to maintain state
  $captcha->data_folder('/some/folder');

  # set directory to hold publicly accessable images
  $captcha->output_folder('/some/http/folder');

  # Alternatively, any of the methods to set variables may also be
  # used directly in the constructor

  my $captcha = Authen::Captcha->new(
    data_folder   => '/some/folder',
    output_folder => '/some/http/folder',
    );

  # create a captcha. Image filename is "$md5sum.png"
  my $md5sum = $captcha->generate_code($number_of_characters);

  # check for a valid submitted captcha
  #   $code is the submitted letter combination guess from the user
  #   $md5sum is the submitted md5sum from the user (that we gave them)
  my $results = $captcha->check_code($code,$md5sum);
  # $results will be one of:
  #          1 : Passed
  #          0 : Code not checked (file error)
  #         -1 : Failed: code expired
  #         -2 : Failed: invalid code (not in database)
  #         -3 : Failed: invalid code (code does not match crypt)
  ##############

=head1 DESCRIPTION

This module is a drop-in GD::SecurityImage replacement for Authen::Captcha. 
Module is mostly compatible with Authen::Captcha. You can just replace

   use Authen::Captcha;

line in your programs with

   use GD::SecurityImage::AC;

to enable GD::SecurityImage interface. Alternatively, you can use

   use GD::SecurityImage backend => 'AC';

Regular GD::SecurityImage interface is supported with an extra method: 
C<gdsi>. Also see the C<CAVEATS> section for incompatibilities.

This module uses: C<GD::SecurityImage>, C<Digest::MD5>, C<File::Spec> and 
C<Fcntl> modules.

If you are writing a captcha handler from scratch, this module is 
B<not recommended>. You must use C<GD::SecurityImage> directly. This 
module can be used for older Authen::Captcha applications only. And 
features are (and will be) limited with Authen::Captcha capabilities.

B<Do not use this module if you have any doubt>.

=head1 METHODS

See L<Authen::Captcha> for the methods and usage.

=head2 gdsi

This method is used to set L<GD::SecurityImage> parameters. Three
methods are supported: C<new>, C<create> and C<particle>. Parameter
types and names are identical to GD::SecurityImage parameters:

   $captcha->gdsi(new      => {name => value},
                  create   => [param1, param2, ...],
                  particle => [param1, param2]);

C<new> is a hashref while the other two are arrayrefs. 
See L<GD::SecurityImage> for information about these parameters.

C<gdsi> method must be called just after creating the object:

   my $captcha = Authen::Captcha->new;
   $captcha->gdsi(
      new => {
               width    => 350,
               height   => 100,
               lines    => 10,
               font     => "/absolute/path/to/your.ttf",
               scramble => 1,
               ptsize   => 24,
      },
      create   => [ttf => 'box', '#80C0F0', '#0F644B'],
      particle => [115, 250],
   );

If you don't use this method, the captcha image will be generated with
default options.

C<gdsi> returns the object itself. So, you can create your object like this:

   my $captcha = Authen::Captcha->new( ... )->gdsi( ... );

=head1 CAVEATS

=over 4

=item *

width and height parameters are *not* character's width and height,
but they define the image dimensions. 

=item *

No outside images. Captchas are generated with the GD::SecurityImage
interface, not with third party "letter" graphics (but you can use true 
type fonts, see C<gdsi> method). As a side effect, captcha size is not 
(actually "can not be") determined automatically. so, you have to specify 
a width and height value at the beginning.

=item *

Setting C<images_folder> has no effect.

=item *

No background images. Backgrounds are drawn with GD::SecurityImage styles.

=item *

You have to specify a TTF font, if you want to use another font (other than GD
built-in C<GD::Font-E<gt>Giant>).

=item *

Setting C<debug> has no effect. You can still set C<debug>, but it is not used 
inside this module.

=item *

The code is compatible with taint, but only so long as your C<data_folder> and
C<output_folder> paths are not tainted. This is deliberate. If your C<data_folder>
or C<output_folder> paths are tainted, you are probably doing something wrong and
definitely doing something that bears close examination.

=back

=head1 CHANGES

1.13 Mon Oct 05 06:40:00 2020
    * Fixed tests with improper file path handling
    * Parameterized lock timeout
    * Fixed problem with unlocking on Win32 caused by using LOCK_NB with LOCK_UN
    * Changed licence to MIT License

1.12 Sun Sep 27 07:02:00 2020
    * Changed license to MIT
    * Fixed encoding issue in POD
    * Updated build tooling
    * Updated maintainer info
    * Made POD tests optional
    * Added 'use warnings'

1.11 Sun May 02 07:29:00 2008
    * Seperated POD into .pod file
    * Fixed taint compatibility and added documentation note on it
    * Fixed locking
    * Removed pointless AUTOLOAD (and consequent DESTROY) subs
    * Replaced use of 'base' module with direct setting of @Authen::Captcha::ISA 
    * Added build test for taint compatibility
    * Benjamin Franz took over as maintainer

1.10 Sun Feb 19 23:33:56 2006
    * First release after separation from GD::SecurityImage distribution.
    * Fixed a bug in setting attributes in new() and AUTOLOAD().
    * (Hopefully) fixed a bug related to unlink()ing images. Reported by GribUser.

=head1 SEE ALSO

L<GD::SecurityImage>, L<Authen::Captcha>.

=head1 AUTHOR

Burak Gürsoy, E<lt>burakE<64>cpan.orgE<gt>, Jerilyn Franz E<lt>cpanE<64>jerilyn.infoE<gt>

=head1 COPYRIGHT

Copyright 2005-2006 Burak Gürsoy, 2020 Jerilyn Franz. All rights reserved.

Some portions of this module adapted from L<Authen::Captcha>. 
L<Authen::Captcha> Copyright 2003 by First Productions, Inc. & Seth Jackson.

=head1 LICENSE

MIT License

Copyright (c) 2006 Burak Gürsoy, 2020 Jerilyn Franz

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

=cut