root/branches/boomer/t/41-atom.t @ 1098

Revision 1098, 8.4 kB (checked in by hachi, 2 years ago)

Branching for boomer from release-19, rev 62318

  • Property svn:mime-type set to text/plain
  • Property svn:keywords set to Author Date Id Revision
Line 
1use strict;
2use POSIX;
3
4use Test::More tests => 11;
5
6# To keep away from being under FastCGI
7$ENV{HTTP_HOST} = 'localhost';
8
9use MT::Atom;
10
11use MT;
12
13use vars qw( $DB_DIR $T_CFG );
14my $mt = MT->new( Config => $T_CFG ) or die MT->errstr;
15isa_ok($mt, 'MT');
16
17use lib 't/lib', 'extlib', 'lib', '../lib', '../extlib';
18use MT::Test qw(:db :data);
19
20my $username = 'Chuck D';
21my $chuck = MT::Author->load({name => $username})
22    or die "Couldn't load $username";
23my $chuck_token = $chuck->api_password;
24
25# not a good nonce-maker
26my @hexch = ('0' .. '9', 'a' .. 'f');
27sub make_nonce {
28    join '', map { $hexch[rand() * @hexch] } (0..7);
29}
30sub make_wsse {
31    my ($password) = @_;
32    my $timestamp = strftime("%Y-%m-%dT%H:%M:%SZ", gmtime(time));
33    my $nonce = make_nonce();
34    my $PasswordDigest = sha1_base64($nonce . $timestamp . $chuck_token);
35    # print "# PasswordDigest is sha1('$nonce$timestamp$chuck_token')\n";
36    $nonce = MIME::Base64::encode_base64($nonce, '');
37    return "UserNameToken Username=\"$username\", "
38                 . "PasswordDigest=\"$PasswordDigest\", Nonce=\"$nonce\", "
39                 . "Created=\"$timestamp\"";
40}
41
42require LWP::UserAgent::Local;
43my $ua = new LWP::UserAgent::Local({ ScriptAlias => '/' });
44
45{
46# # # # First try a req with baloney auth, make sure it fails
47    # TBD: Try more bogus auth varieties
48    my $nonce = make_nonce();
49    $nonce = MIME::Base64::encode_base64($nonce, '');
50
51    my $uri = new URI();
52    $uri->path('/mt-atom.cgi/weblog/blog_id=1');
53    my $req = new HTTP::Request(GET => $uri);
54    $req->header(Authentication => 'Atom');
55    $req->header('X-WSSE' => "UserNameToken Username=\"Melody\", PasswordDigest=\"Oj12fART+XZvBZBe39vVvkirg4w\", Nonce=\"" . $nonce . "\", Created=\"2004-05-19T20:08:57Z\"");
56    print "# requesting: " . $req->uri . "\n";
57    my $resp = $ua->request($req);
58
59    print "# response code was: " . $resp->code . "\n";
60    print "# content was: " . $resp->content . "\n";# if !$resp->code();
61    ok($resp->is_error());
62}
63
64
65my $entry_id;
66
67use constant USE_DIGEST => 0;
68
69if (USE_DIGEST)
70{
71# # # # # # # use this to do a Digest auth with MD5 as the algorithm.
72    my $realm = 'movabletype';
73#     $username = shift;
74#     $hashed_pwd = shift;
75    require Digest::MD5;
76    my $hashed_pwd = Digest::MD5::md5(join ':', $username, $realm, $chuck_token);
77    my $method = 'POST';
78
79    my $uri = new URI;
80    $uri->path('/mt-atom.cgi/weblog/blog_id=1');
81    my $req = new HTTP::Request(POST => $uri);
82
83    my $resp = $ua->simple_request($req);
84    ok($resp->is_error());
85    my $auth_header = $resp->header('WWW-Authenticate');
86    my ($nonce) = $auth_header =~ /nonce=(\S*)/;
87
88    my $A1 = pack('H*', $hashed_pwd);
89    my $A2 = $method . ':' . $uri;
90   
91    require Digest::MD5;
92    my $hash = \&Digest::MD5::md5;
93    my $kd = sub { $hash->($_[0].':'.$_[1]) };
94
95    print STDERR "Signing ", join(':',
96                                  $nonce,
97                                  '',
98                                  '',
99                                  'auth',
100                                  $hash->($A2)), "\n";
101    print STDERR "with key ", $hash->($A1), "\n";
102
103    my $response = $kd->($hash->($A1), join(':',
104                                            $nonce,
105                                            '',
106                                            '',
107                                            'auth',
108                                            $hash->($A2)));
109    print "# ", ($response = unpack('H*', $response)), "\n";
110
111    $uri = new URI;
112    $uri->path('/mt-atom.cgi/weblog/blog_id=1');
113    $req = new HTTP::Request(POST => $uri);
114
115    $req->header('X-Atom-Authorization', "Digest nonce=$nonce, username=$username, realm=movabletype, uri=$uri, qop=auth, response=$response");
116    print "# sending: ", $req->header('X-Atom-Authorization');
117
118    $req->content(<<XML);
119<?xml version="1.0" encoding="utf-8"?>
120    <entry xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
121    <title>Fight the Power</title>
122    <content>Elvis was a hero to most but he never meant shit to me</content>
123    </entry>
124XML
125
126    $resp = $ua->simple_request($req);
127
128    print "# " . $resp->code . " " . $resp->message . "\n";
129    print "# " . $resp->content . "\n";
130    ok($resp->is_success());
131
132    print "##\n". $resp->header('Location')  . "\n##\n";
133    my $location = $resp->header('Location')
134        || die "No Location: header. Did get\n"
135                . $resp->code() . $resp->message() . "\n"
136                . $resp->headers_as_string() . "\n"
137                . $resp->content();
138    ($entry_id) = ($location =~ /entry_id=(\d+)/);
139
140    $entry_id || die "Couldn't get entry ID from header Location: "
141        . $location;
142
143    print "# entry ID is $entry_id\n";
144
145    ok($entry_id);
146}
147
148unless (USE_DIGEST)
149{
150    print "# Doing Digest auth\n";
151# # # # Now try posting an entry with authentication
152    my $nonce = make_nonce();
153    my $timestamp = strftime("%Y-%m-%dT%H:%M:%SZ", gmtime(time));
154    use Digest::SHA1 qw(sha1_base64);
155    my $PasswordDigest = sha1_base64($nonce . $timestamp . $chuck_token);
156
157#     print STDERR ("Client hashing (",
158#                 unpack('H*', $nonce . $timestamp . $chuck_token), ")\n");
159#     print STDERR "      produces: $PasswordDigest\n";
160
161    $nonce = MIME::Base64::encode_base64($nonce, '');
162
163    print "# nonce: $nonce\n";
164
165    my $dir = `pwd`; chomp $dir;
166    while (! -x ($dir . "/mt-atom.cgi")) {
167        $dir =~ s!(/[^/]*)$!!;
168        last if $dir =~ m!^/?$!;
169    }   
170
171    my $uri = new URI;
172    $uri->path('/mt-atom.cgi/weblog/blog_id=1');
173    my $req = new HTTP::Request(POST => $uri);
174    $req->header('Authorization' => 'Atom');
175    $req->header('X-WSSE' => "UserNameToken Username=\"$username\", "
176                 . "PasswordDigest=\"$PasswordDigest\", Nonce=\"$nonce\", "
177                 . "Created=\"$timestamp\"");
178
179    $req->content(<<XML);
180<?xml version="1.0" encoding="utf-8"?>
181    <entry xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
182    <title>Fight the Power</title>
183    <content>Elvis was a hero to most but he never meant shit to me</content>
184    <issued>2004-08-06T00:43:34+01:00</issued>
185    </entry>
186XML
187
188    my $resp = $ua->simple_request($req);
189
190    print "######### RESPONSE #########\n";
191    print "# " . $resp->code . " " . $resp->message . "\n";
192    my $content =  $resp->content;
193    $content =~ s/^/# /gm;
194    print $content;
195    print "#########~RESPONSE #########\n";
196    ok($resp->is_success());
197
198    #print "##\n". $resp->header('Location')  . "\n##\n";
199    my $location = $resp->header('Location')
200        || die "No Location: header. Did get\n"
201                . $resp->headers_as_string() . "\n"
202                . $resp->content();
203    ($entry_id) = ($location =~ /entry_id=(\d+)/);
204
205    $entry_id || die "Couldn't get entry ID from header Location: "
206        . $location;
207
208    print "# entry ID is $entry_id\n";
209
210    ok($entry_id);
211    require XML::Atom;
212    my $atom_obj = XML::Atom::Entry->new(\$resp->content());
213    require Date::Parse;
214    print "# ", $atom_obj->issued(), "\n";
215    is(Date::Parse::str2time($atom_obj->issued()),
216       Date::Parse::str2time('2004-08-06T00:43:34+01:00'), $atom_obj->issued());
217}
218
219{
220    my $wsse_header = make_wsse($chuck_token);
221    my $uri = new URI;
222    $uri->path("/mt-atom.cgi/weblog/blog_id=1/entry_id=$entry_id");
223    my $req = new HTTP::Request(GET => $uri);
224    $req->header('Authorization' => 'Atom');
225    $req->header('X-WSSE' => $wsse_header);
226
227    print "# X-WSSSE: $wsse_header\n";
228
229    my $resp = $ua->request($req);
230
231    require XML::LibXML;
232    my $atom_entry = XML::Atom::Entry->new(Stream => \$resp->content());
233
234    is($atom_entry->title(), "Fight the Power");
235    is($atom_entry->author()->name(), $chuck->nickname);
236    is($atom_entry->content()->body(),
237       "Elvis was a hero to most but he never meant shit to me");
238
239    $wsse_header = make_wsse($chuck_token);
240    $uri = new URI;
241    $uri->path("/mt-atom.cgi/weblog/blog_id=1/entry_id=$entry_id");
242    $req = new HTTP::Request(PUT => $uri);
243    $req->header('Authorization' => 'Atom');
244    $req->header('X-WSSE' => $wsse_header);
245    my $body = $atom_entry->as_xml();
246    $req->content($body);
247   
248    $resp = $ua->request($req);
249
250    if (ok($resp->is_success)) {
251        $atom_entry = XML::Atom::Entry->new(Stream => \$resp->content());
252        is($atom_entry->title, "Fight the Power");
253        is(Date::Parse::str2time($atom_entry->issued),
254           Date::Parse::str2time("2004-08-05T21:13:34-0230"));
255    } else {
256        print STDERR "# PUT request returned ", $resp->status_line(), "\n";
257        skip(1);
258        skip(1);
259    }
260}
261
262END {
263    #my $melody = MT::Author->load({ name => $username });
264    #$melody->delete() if $melody;
265}
Note: See TracBrowser for help on using the browser.