Punk-Challenge

 view release on metacpan or  search on metacpan

t/14-proxy.t  view on Meta::CPAN

    use Punk;
    use Punk::Plugin::Challenge;
    plugin 'Challenge' => { secret => 'k', bits => 8 };
    challenge for => '/x', always => 1;
    get '/x' => sub { $_[0]->text('x') };
}

my $T = Punk::Challenge::Token::;
my %cfg = ( secret => 'k', bits => 8 );
my $PROXY = { REMOTE_ADDR => '10.0.0.1' };
my $ALICE = { 'X-Forwarded-For' => '192.0.2.7' };
my $BOB   = { 'X-Forwarded-For' => '198.51.100.7' };

# ---- under proxy: the subject is the forwarded client -------------------------------

{
    my $t = Punk::Test->new('Proxied');
    local $SIG{__WARN__} = sub { };    # the after-rule boot warning, not this test's subject
    $t->get_ok('/whoami', env => $PROXY, headers => $ALICE)->content_is('192.0.2.7',
        'proxy resolved the client');

    $t->get_ok('/x', env => $PROXY, headers => $ALICE)->status_is(403);

t/14-proxy.t  view on Meta::CPAN


    my $alice = $T->clear(\%cfg, $T->subject('192.0.2.7'));
    $t->get_ok('/x', env => $PROXY, headers => { %$ALICE, 'X-Clearance' => $alice })
      ->status_is(200)->content_is('x', "Alice's clearance clears Alice");
    $t->get_ok('/x', env => $PROXY, headers => { %$BOB, 'X-Clearance' => $alice })
      ->status_is(403, '  and not Bob, behind the same proxy');
    my $bob = $T->clear(\%cfg, $T->subject('198.51.100.7'));
    $t->get_ok('/x', env => $PROXY, headers => { %$BOB, 'X-Clearance' => $bob })
      ->status_is(200)->content_is('x', "  Bob's clears Bob");

    # a client that writes its own X-Forwarded-For does not choose its subject:
    # with one proxy trusted, the client is the rightmost entry
    $t->get_ok('/x', env => $PROXY, headers => { 'X-Forwarded-For' => '192.0.2.7, 198.51.100.7',
                                                  'X-Clearance' => $alice })
      ->status_is(403, 'a spoofed leftmost entry does not borrow a clearance');
}

# ---- the after counter is keyed by the client too -------------------------------------

{
    my @keys;
    no warnings 'redefine';
    local *Punk::Context::rate_hit = sub { push @keys, $_[1]; return (1, 0, time + 60) };

t/14-proxy.t  view on Meta::CPAN

    $t->get_ok('/x', env => $PROXY, headers => $ALICE)->status_is(403);
    my $sol = Punk::Challenge::Solver::solve($t->header('X-Challenge'));
    is(scalar $T->verify(\%cfg, $T->subject('10.0.0.1'), $sol), 8,
        "without proxy, the puzzle is bound to the proxy's /24");

    my $proxy_clr = $T->clear(\%cfg, $T->subject('10.0.0.1'));
    $t->get_ok('/x', env => $PROXY, headers => { %$ALICE, 'X-Clearance' => $proxy_clr })
      ->status_is(200, "  so one visitor's clearance clears Alice");
    $t->get_ok('/x', env => $PROXY, headers => { %$BOB, 'X-Clearance' => $proxy_clr })
      ->status_is(200, '  and Bob');
    $t->get_ok('/x', env => $PROXY, headers => { 'X-Forwarded-For' => '203.0.113.9', 'X-Clearance' => $proxy_clr })
      ->status_is(200, '  and everybody else: the shared-subject case the POD warns about');
}

done_testing;



( run in 2.643 seconds using v1.01-cache-2.11-cpan-54e63673c56 )