CGI-ACL

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN


    # This STILL blocks the IP if it is a cloud host
    my $acl = CGI::ACL->new()
        ->deny_cloud()
        ->allow_ip('198.51.100.5');   # blocked if rDNS says EC2

## Localhost is not automatically allowed

Once any restriction is set, `127.0.0.1` is subject to the same rules
as any other address.  If you need to allow local access (for example,
a health-check endpoint), add it explicitly.

    my $acl = CGI::ACL->new()
        ->allow_ip('127.0.0.1')   # must be explicit
        ->deny_all_countries()
        ->allow_country('US');

## Forgetting the lingua argument

When country restrictions are active and `all_denied()` is called without
a `lingua` argument, the module emits a `carp` warning and denies the

lib/CGI/ACL.pm  view on Meta::CPAN


    # This STILL blocks the IP if it is a cloud host
    my $acl = CGI::ACL->new()
        ->deny_cloud()
        ->allow_ip('198.51.100.5');   # blocked if rDNS says EC2

=head2 Localhost is not automatically allowed

Once any restriction is set, C<127.0.0.1> is subject to the same rules
as any other address.  If you need to allow local access (for example,
a health-check endpoint), add it explicitly.

    my $acl = CGI::ACL->new()
        ->allow_ip('127.0.0.1')   # must be explicit
        ->deny_all_countries()
        ->allow_country('US');

=head2 Forgetting the lingua argument

When country restrictions are active and C<all_denied()> is called without
a C<lingua> argument, the module emits a C<carp> warning and denies the

t/edge_cases.t  view on Meta::CPAN

	# rebuild machinery handles large lists without blowing the stack or OOM.
	my $acl = CGI::ACL->new();

	for my $i (1 .. $STRESS_IP_COUNT) {
		$acl->allow_ip("10.0.0.$i");    # RFC 1918, safe to use in tests
	}

	is(scalar keys %{$acl->{allowed_ips}}, $STRESS_IP_COUNT,
		"$STRESS_IP_COUNT entries stored");

	# Spot-check a few endpoints
	is(denied_at($acl, '10.0.0.1'),   0, 'first entry allowed after large list build');
	is(denied_at($acl, "10.0.0.$STRESS_IP_COUNT"), 0, 'last entry allowed');
	is(denied_at($acl, '10.0.0.' . ($STRESS_IP_COUNT + 1)), 1, 'entry beyond range denied');
	diag "stress list: $STRESS_IP_COUNT entries, CIDR cache holds" if $ENV{TEST_VERBOSE};
};

# ─────────────────────────────────────────────────────────────────────────────
# all_denied(): HOSTILE LINGUA OBJECTS
# ─────────────────────────────────────────────────────────────────────────────
subtest 'all_denied(): lingua->country() that dies is caught, treated as unknown → deny' => sub {



( run in 3.129 seconds using v1.01-cache-2.11-cpan-364913b4093 )