package Google::reCAPTCHA;

use strict;
use warnings;

use Carp;
use LWP::UserAgent;
use JSON qw( decode_json );
use Params::Validate qw( validate SCALAR );

our $VERSION = '0.01';

use constant URL => 'https://www.google.com/recaptcha/api/siteverify';

sub new {
    my $class = shift;
    my $self  = validate( @_, {
        secret => {
            type      => SCALAR,
            callbacks => {
                'is a secret key' =>
                    sub { $_[0] ne '' }
            }
        }
    } );
    
    bless $self, $class;
    
    return $self; 
}

sub siteverify {
    my $self = shift;
    my $pd   = validate( @_, {
        response => {
            type      => SCALAR,
            callbacks => {
                'is a response code' =>
                    sub { $_[0] ne '' }
            }
        },
        remoteip => {
            type      => SCALAR,
            optional  => 1,
            callbacks => {
                'is a remote ipv4 address' =>
                    sub { $_[0] =~ /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ }
            },
        },
    } );
    
    $pd->{secret} = $self->{secret};
    
    my $ua = LWP::UserAgent->new;
    $ua->ssl_opts( verify_hostname => 0 );

    my $response = $ua->post( URL , $pd );
    
    if ( $response->is_success)  {
        my $data = decode_json( $response->decoded_content );
        
        if ( exists ( $data->{'error-codes'} ) ) {
            croak( 'API Error: ' . join( ', ', @{ $data->{'error-codes'} } ) );
        }
        
        return $data->{success} ? 1 : 0;          
    }
    else {      
        my $content = $response->decoded_content ? $response->decoded_content : '';
        my $message = 'HTTP Request failed with status ' . $response->code . ' : ' . $content;

        croak( $message );
    }
}   
    
1;
__END__

=head1 NAME

Google::reCAPTCHA - A simple lightweight implementation of Google's reCAPTCHA for perl

=head1 SYNOPSIS

    use Google::reCAPTCHA;

    my $c = Google::reCAPTCHA->new( secret => 'secret_key' );
    
    # Verifying the user's response 
    my $response = $c->siteverify( response => 'response_key', remoteip => '192.168.0.1' );

=head1 GETTING STARTED

To use reCAPTCHA you need to register your site here:

https://www.google.com/recaptcha/admin/create

=head1 PUBLIC INTERFACE

=head2 Google::reCAPTCHA->new( secret => 'secret_key' )

Our constructor, will croak when invalid parameters are given.

secret

Required. The shared key between your site and ReCAPTCHA.

=head2 siteverify( response => 'response_key', remoteip => '192.168.0.1' )

Request siteverify from Google reCAPTCHA API

response

Required. Form data containing g_captcha_response.

remoteip

Optional. User's ip address.

=head2 Errors

Error code reference:

missing-input-secret    The secret parameter is missing.
invalid-input-secret	The secret parameter is invalid or malformed.
missing-input-response	The response parameter is missing.
invalid-input-response	The response parameter is invalid or malformed.

=head1 Git repo

https://bitbucket.org/tcorkran/google-recaptcha

=head1 VERSION

0.01

=head1 AUTHOR

Thomas Corkran C<< <thomas.corkran@endurance.com> >>

=head1 CONTRIBUTORS

Christopher Mevissen C<< <mev412@gmail.com> >>

=head1 ACKNOWLEDGEMENTS

Matthew Green C<< <green.matt.na@gmail.com> >>

This projects work was sponsored by Hostgator.com.
L<http://www.hostgator.com>
L<http://www.endurance.com>

=head1 COPYRIGHT & LICENSE

Copyright 2015, Thomas Corkran C<< <thomascorkran@gmail.com> >>

This program is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut
