|
|
|
package AN::Tools::Validate;
|
|
|
|
#
|
|
|
|
# This module contains methods used to validate types of data.
|
|
|
|
#
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
use Data::Dumper;
|
|
|
|
use Scalar::Util qw(weaken isweak);
|
|
|
|
|
|
|
|
our $VERSION = "3.0.0";
|
|
|
|
my $THIS_FILE = "Validate.pm";
|
|
|
|
|
|
|
|
### Methods;
|
|
|
|
# is_alphanumeric
|
|
|
|
# is_domain_name
|
|
|
|
# is_ipv4
|
|
|
|
# is_positive_integer
|
|
|
|
# is_uuid
|
|
|
|
|
|
|
|
=pod
|
|
|
|
|
|
|
|
=encoding utf8
|
|
|
|
|
|
|
|
=head1 NAME
|
|
|
|
|
|
|
|
AN::Tools::Validate
|
|
|
|
|
|
|
|
Provides all methods related to data validation.
|
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
|
|
|
|
use AN::Tools;
|
|
|
|
|
|
|
|
# Validate a common object handle on all AN::Tools modules.
|
|
|
|
my $an = AN::Tools->new();
|
|
|
|
|
|
|
|
# Access to methods using '$an->Validate->X'.
|
|
|
|
#
|
|
|
|
# Example using 'is_uuid()';
|
|
|
|
if ($an->Validate->is_uuid({uuid => $string}))
|
|
|
|
{
|
|
|
|
print "The UUID: [$string] is valid!\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
=head1 METHODS
|
|
|
|
|
|
|
|
Methods in this module;
|
|
|
|
|
|
|
|
=cut
|
|
|
|
sub new
|
|
|
|
{
|
|
|
|
my $class = shift;
|
|
|
|
my $self = {};
|
|
|
|
|
|
|
|
bless $self, $class;
|
|
|
|
|
|
|
|
return ($self);
|
|
|
|
}
|
|
|
|
|
|
|
|
# Get a handle on the AN::Tools object. I know that technically that is a sibling module, but it makes more
|
|
|
|
# sense in this case to think of it as a parent.
|
|
|
|
sub parent
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
my $parent = shift;
|
|
|
|
|
|
|
|
$self->{HANDLE}{TOOLS} = $parent if $parent;
|
|
|
|
|
|
|
|
# Defend against memory leads. See Scalar::Util'.
|
|
|
|
if (not isweak($self->{HANDLE}{TOOLS}))
|
|
|
|
{
|
|
|
|
weaken($self->{HANDLE}{TOOLS});;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ($self->{HANDLE}{TOOLS});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#############################################################################################################
|
|
|
|
# Public methods #
|
|
|
|
#############################################################################################################
|
|
|
|
|
|
|
|
=head2 is_alphanumeric
|
|
|
|
|
|
|
|
This verifies that the passed-in string contains only alpha-numeric characters. This is strict and will return invalid if spaces, hyphens or other characters are found.
|
|
|
|
|
|
|
|
NOTE: An empty string is considered invalid.
|
|
|
|
|
|
|
|
$string = "4words";
|
|
|
|
if ($an->Validate->is_alphanumeric({string => $string}))
|
|
|
|
{
|
|
|
|
print "The string: [$string] is valid!\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
=head2 Parameters;
|
|
|
|
|
|
|
|
=head3 string (required)
|
|
|
|
|
|
|
|
This is the string name to validate.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
sub is_alphanumeric
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
my $parameter = shift;
|
|
|
|
my $an = $self->parent;
|
|
|
|
|
|
|
|
my $valid = 1;
|
|
|
|
my $debug = 3;
|
|
|
|
my $string = defined $parameter->{string} ? $parameter->{string} : "";
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { string => $string }});
|
|
|
|
|
|
|
|
if (not $string)
|
|
|
|
{
|
|
|
|
$valid = 0;
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }});
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($string !~ /^[a-zA-Z0-9]+$/)
|
|
|
|
{
|
|
|
|
$valid = 0;
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }});
|
|
|
|
}
|
|
|
|
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }});
|
|
|
|
return($valid);
|
|
|
|
}
|
|
|
|
|
|
|
|
=head2 is_domain_name
|
|
|
|
|
|
|
|
Checks if the passed-in string is a valid domain name. Returns 'C<< 1 >>' if OK, 'C<< 0 >>' if not.
|
|
|
|
|
|
|
|
$name = "alteeve.com";
|
|
|
|
if ($an->Validate->is_domain_name({name => $name}))
|
|
|
|
{
|
|
|
|
print "The domain name: [$name] is valid!\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
=head2 Parameters;
|
|
|
|
|
|
|
|
=head3 name (required)
|
|
|
|
|
|
|
|
This is the domain name to validate.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
sub is_domain_name
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
my $parameter = shift;
|
|
|
|
my $an = $self->parent;
|
|
|
|
|
|
|
|
my $valid = 1;
|
|
|
|
my $debug = 3;
|
|
|
|
my $name = $parameter->{name} ? $parameter->{name} : "";
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { name => $name }});
|
|
|
|
|
|
|
|
if (not $name)
|
|
|
|
{
|
|
|
|
$valid = 0;
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }});
|
|
|
|
}
|
|
|
|
elsif (($name !~ /^((([a-z]|[0-9]|\-)+)\.)+([a-z])+$/i) && (($name !~ /^\w+$/) && ($name !~ /-/)))
|
|
|
|
{
|
|
|
|
# Doesn't appear to be valid.
|
|
|
|
$valid = 0;
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }});
|
|
|
|
}
|
|
|
|
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }});
|
|
|
|
return($valid);
|
|
|
|
}
|
|
|
|
|
|
|
|
=head2 is_ipv4
|
|
|
|
|
|
|
|
Checks if the passed-in string is an IPv4 address. Returns 'C<< 1 >>' if OK, 'C<< 0 >>' if not.
|
|
|
|
|
|
|
|
$ip = "111.222.33.44";
|
|
|
|
if ($an->Validate->is_ipv4({ip => $ip}))
|
|
|
|
{
|
|
|
|
print "The IP address: [$ip] is valid!\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
=head2 Parameters;
|
|
|
|
|
|
|
|
=head3 ip (required)
|
|
|
|
|
|
|
|
This is the IP address to verify.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
sub is_ipv4
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
my $parameter = shift;
|
|
|
|
my $an = $self->parent;
|
|
|
|
|
|
|
|
my $debug = 3;
|
|
|
|
my $ip = defined $parameter->{ip} ? $parameter->{ip} : "";
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ip => $ip }});
|
|
|
|
|
|
|
|
my $valid = 1;
|
|
|
|
if ($ip =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)
|
|
|
|
{
|
|
|
|
# It is in the right format.
|
|
|
|
my $first_octet = $1;
|
|
|
|
my $second_octet = $2;
|
|
|
|
my $third_octet = $3;
|
|
|
|
my $fourth_octet = $4;
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
|
|
|
|
first_octet => $first_octet,
|
|
|
|
second_octet => $second_octet,
|
|
|
|
third_octet => $third_octet,
|
|
|
|
fourth_octet => $fourth_octet,
|
|
|
|
}});
|
|
|
|
|
|
|
|
if (($first_octet < 0) or ($first_octet > 255) or
|
|
|
|
($second_octet < 0) or ($second_octet > 255) or
|
|
|
|
($third_octet < 0) or ($third_octet > 255) or
|
|
|
|
($fourth_octet < 0) or ($fourth_octet > 255))
|
|
|
|
{
|
|
|
|
# One of the octets is out of range.
|
|
|
|
$valid = 0;
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
# Not in the right format.
|
|
|
|
$valid = 0;
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }});
|
|
|
|
}
|
|
|
|
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }});
|
|
|
|
return($valid);
|
|
|
|
}
|
|
|
|
|
|
|
|
=head2 is_positive_integer
|
|
|
|
|
|
|
|
This method verifies that the passed in value is a positive integer.
|
|
|
|
|
|
|
|
NOTE: This method is strict and will only validate numbers without decimal places and that have no sign or a positive sign only (ie: C<< +3 >>, or C<< 3 >> are valid, but C<< -3 >> or C<< 3.0 >> are not).
|
|
|
|
|
|
|
|
my $number = 3;
|
|
|
|
if ($an->Validate->is_positive_integer({number => $number}))
|
|
|
|
{
|
|
|
|
print "The number: [$number] is valid!\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
=head2 Parameters;
|
|
|
|
|
|
|
|
=head3 number (required)
|
|
|
|
|
|
|
|
This is the number to verify.
|
|
|
|
|
|
|
|
=head3 zero (optional)
|
|
|
|
|
|
|
|
If set, the number C<< 0 >> will be considered valid. By default, c<< 0 >> is not considered "positive".
|
|
|
|
|
|
|
|
=cut
|
|
|
|
sub is_positive_integer
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
my $parameter = shift;
|
|
|
|
my $an = $self->parent;
|
|
|
|
|
|
|
|
my $debug = 3;
|
|
|
|
my $valid = 1;
|
|
|
|
my $number = defined $parameter->{number} ? $parameter->{number} : "";
|
|
|
|
my $zero = defined $parameter->{zero} ? $parameter->{zero} : 0;
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
|
|
|
|
number => $number,
|
|
|
|
zero => $zero,
|
|
|
|
}});
|
|
|
|
|
|
|
|
# We'll strip a positive leading character as that is allowed.
|
|
|
|
$number =~ s/^\+//;
|
|
|
|
|
|
|
|
# Now anything
|
|
|
|
if ($number !~ /^\d+$/)
|
|
|
|
{
|
|
|
|
$valid = 0;
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }});
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((not $zero) && (not $number))
|
|
|
|
{
|
|
|
|
$valid = 0;
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }});
|
|
|
|
}
|
|
|
|
|
|
|
|
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }});
|
|
|
|
return($valid);
|
|
|
|
}
|
|
|
|
|
|
|
|
=head2 is_uuid
|
|
|
|
|
|
|
|
This method takes a UUID string and returns 'C<< 1 >>' if it is a valid UUID string. Otherwise it returns 'C<< 0 >>'.
|
|
|
|
|
|
|
|
NOTE: This method is strict and will only validate UUIDs that are lower case!
|
|
|
|
|
|
|
|
if ($an->Validate->is_uuid({uuid => $string}))
|
|
|
|
{
|
|
|
|
print "The UUID: [$string] is valid!\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
=head2 Parameters;
|
|
|
|
|
|
|
|
=head3 uuid (required)
|
|
|
|
|
|
|
|
This is the UUID to verify.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
sub is_uuid
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
my $parameter = shift;
|
|
|
|
my $an = $self->parent;
|
|
|
|
|
|
|
|
my $uuid = defined $parameter->{uuid} ? $parameter->{uuid} : 0;
|
|
|
|
my $valid = 0;
|
|
|
|
|
|
|
|
if (($uuid) && ($uuid =~ /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/))
|
|
|
|
{
|
|
|
|
$valid = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return($valid);
|
|
|
|
}
|