Commit | Line | Data |
47a916e2 |
1 | #!/usr/bin/perl |
2 | use strict; |
3 | use warnings; |
4 | use FindBin qw/$Bin/; |
5 | use lib "$Bin/lib"; |
6 | use Test::More; |
7 | BEGIN { |
8 | do { |
9 | eval { require Test::WWW::Mechanize::Catalyst } |
10 | and |
11 | Test::WWW::Mechanize::Catalyst->VERSION('0.51') |
12 | } |
13 | or plan skip_all => |
14 | "Test::WWW::Mechanize::Catalyst is needed for this test"; |
15 | eval { require Catalyst::Plugin::Cache } |
16 | or plan skip_all => |
17 | "Catalyst::Plugin::Cache is needed for this test"; |
18 | eval { require Cache::FileCache } |
19 | or plan skip_all => |
20 | "Cache::FileCache is needed for this test"; |
21 | plan tests => 19; |
22 | } |
23 | use Digest::MD5; |
24 | use HTTP::Request; |
25 | use Test::More; |
26 | use Test::WWW::Mechanize::Catalyst; |
27 | |
28 | sub do_test { |
29 | my ($username, $uri, $emulate_dotnet, $fail) = @_; |
30 | my $app = $fail ? 'AuthDigestTestApp' : 'AuthDigestDotnetTestApp'; |
31 | my $mech = Test::WWW::Mechanize::Catalyst->new(catalyst_app => $app); |
32 | $mech->get("http://localhost/moose"); |
33 | is( $mech->status, 401, "status is 401" ); |
34 | my $www_auth = $mech->res->headers->header('WWW-Authenticate'); |
35 | my %www_auth_params = map { |
36 | my @key_val = split /=/, $_, 2; |
37 | $key_val[0] = lc $key_val[0]; |
38 | $key_val[1] =~ s{"}{}g; # remove the quotes |
39 | @key_val; |
40 | } split /, /, substr( $www_auth, 7 ); #7 == length "Digest " |
41 | $mech->content_lacks( "foo", "no output" ); |
42 | my $response = ''; |
43 | { |
44 | my $password = 'Circle Of Life'; |
45 | my $realm = $www_auth_params{realm}; |
46 | my $nonce = $www_auth_params{nonce}; |
47 | my $cnonce = '0a4f113b'; |
48 | my $opaque = $www_auth_params{opaque}; |
49 | my $nc = '00000001'; |
50 | my $method = 'GET'; |
51 | my $qop = 'auth'; |
52 | $uri ||= '/moose'; |
53 | my $auth_uri = $uri; |
54 | if ($emulate_dotnet) { |
55 | $auth_uri =~ s/\?.*//; |
56 | } |
57 | my $ctx = Digest::MD5->new; |
58 | $ctx->add( join( ':', $username, $realm, $password ) ); |
59 | my $A1_digest = $ctx->hexdigest; |
60 | $ctx = Digest::MD5->new; |
61 | $ctx->add( join( ':', $method, $auth_uri ) ); |
62 | my $A2_digest = $ctx->hexdigest; |
63 | my $digest = Digest::MD5::md5_hex( |
64 | join( ':', |
65 | $A1_digest, $nonce, $qop ? ( $nc, $cnonce, $qop ) : (), $A2_digest ) |
66 | ); |
67 | |
68 | $response = qq{Digest username="$username", realm="$realm", nonce="$nonce", uri="$auth_uri", qop=$qop, nc=$nc, cnonce="$cnonce", response="$digest", opaque="$opaque"}; |
69 | } |
70 | my $r = HTTP::Request->new( GET => "http://localhost" . $uri ); |
71 | $mech->request($r); |
72 | $r->headers->push_header( Authorization => $response ); |
73 | $mech->request($r); |
74 | if ($fail) { |
75 | is( $mech->status, 400, "status is 400" ); |
76 | } else { |
77 | is( $mech->status, 200, "status is 200" ); |
78 | $mech->content_contains( $username, "Mufasa output" ); |
79 | } |
80 | } |
81 | |
82 | do_test('Mufasa'); |
83 | do_test('Mufasa2'); |
84 | # Test with query string |
85 | do_test('Mufasa2', '/moose?moose_id=1'); |
86 | # Test with query string, emulating .NET, which omits the query string |
87 | # from the Authorization header |
88 | do_test('Mufasa2', '/moose?moose_id=1', 1); |
89 | |
90 | # Test with query string, emulating .NET, against app without .NET setting; |
91 | # authorization should fail |
92 | do_test('Mufasa2', '/moose?moose_id=1', 1, 1); |