[dw-free] Make sure method is GET/POST ( unless the controller handles more )
[commit: http://hg.dwscoalition.org/dw-free/rev/b0d94d3528e4]
http://bugs.dwscoalition.org/show_bug.cgi?id=3539
Limit the methods that can be used for the atom publishing interface (update
to use cleaner method rather than hacking in at the end). Create an
$r->HTTP_OK method, as opposed to $r->OK, for accurate tests.
Patch by
fu.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=3539
Limit the methods that can be used for the atom publishing interface (update
to use cleaner method rather than hacking in at the end). Create an
$r->HTTP_OK method, as opposed to $r->OK, for accurate tests.
Patch by
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Files modified:
- cgi-bin/DW/Controller/Interface/AtomAPI.pm
- cgi-bin/DW/Request/Apache2.pm
- cgi-bin/DW/Request/Standard.pm
- t/atom-post.t
-------------------------------------------------------------------------------- diff -r 37f7a2c8953c -r b0d94d3528e4 cgi-bin/DW/Controller/Interface/AtomAPI.pm --- a/cgi-bin/DW/Controller/Interface/AtomAPI.pm Mon Feb 28 18:44:54 2011 +0800 +++ b/cgi-bin/DW/Controller/Interface/AtomAPI.pm Mon Feb 28 18:47:21 2011 +0800 @@ -28,13 +28,17 @@ require 'ljprotocol.pl'; require 'ljprotocol.pl'; # service document URL is the same for all users -DW::Routing->register_string( "/interface/atom", \&service_document, app => 1, format => "atom" ); +DW::Routing->register_string( "/interface/atom", \&service_document, app => 1, + format => "atom", methods => { GET => 1 } ); # note: safe to put these pages in the user subdomain even if they modify data # because we don't use cookies (so even if a user's cookies are stolen...) -DW::Routing->register_string( "/interface/atom/entries", \&entries_handler, user => 1, format => "atom" ); -DW::Routing->register_string( "/interface/atom/entries/tags", \&categories_document, user => 1, format => "atom" ); -DW::Routing->register_regex( qr#/interface/atom/entries/(\d+)#, \&entry_handler, user => 1, format => "atom" ); +DW::Routing->register_string( "/interface/atom/entries", \&entries_handler, user => 1, + format => "atom", methods => { POST => 1, GET => 1 } ); +DW::Routing->register_string( "/interface/atom/entries/tags", \&categories_document, user => 1, + format => "atom", methods => { GET => 1 } ); +DW::Routing->register_regex( qr#/interface/atom/entries/(\d+)#, \&entry_handler, user => 1, + format => "atom", methods => { GET => 1, PUT => 1, DELETE => 1 } ); sub ok { my ( $message, $status, $content_type ) = @_; @@ -190,10 +194,6 @@ sub service_document { my $r = DW::Request->get; - my $method = $r->method; - return err( "URI scheme /interface/atom/ is incompatible with $method" ) - unless $method eq "GET"; - # FIXME: use XML::Atom::Service? my $ret = qq{<?xml version="1.0"?>}; $ret .= qq{<service xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom">}; @@ -222,8 +222,6 @@ sub categories_document { my $r = DW::Request->get; - return err( "URI scheme /interface/atom/entries/tags is incompatible with " . $r->method ) unless $r->method eq "GET"; - my $ret = qq{<?xml version="1.0"?>}; $ret .= qq{<categories xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom">}; @@ -251,8 +249,6 @@ sub entries_handler { my $r = DW::Request->get; return _create_entry( %$rv ) if $r->method eq "POST"; return _list_entries( %$rv ) if $r->method eq "GET"; - - return err( "URI scheme /interface/atom/entries is incompatible with " . $r->method ); } sub _create_entry { @@ -400,8 +396,6 @@ sub entry_handler { return _retrieve_entry( %$rv, item => $olditem->{events}->[0], entry_obj => $entry_obj ) if $r->method eq "GET"; return _edit_entry( %$rv, item => $olditem->{events}->[0], entry_obj => $entry_obj ) if $r->method eq "PUT"; return _delete_entry( %$rv, item => $olditem->{events}->[0], entry_obj => $entry_obj ) if $r->method eq "DELETE"; - - return err( "URI scheme /interface/atom/entries/$jitemid is incompatible with " . $r->method ); } sub _retrieve_entry { diff -r 37f7a2c8953c -r b0d94d3528e4 cgi-bin/DW/Request/Apache2.pm --- a/cgi-bin/DW/Request/Apache2.pm Mon Feb 28 18:44:54 2011 +0800 +++ b/cgi-bin/DW/Request/Apache2.pm Mon Feb 28 18:47:21 2011 +0800 @@ -274,6 +274,11 @@ sub OK { return Apache2::Const::OK; } +sub HTTP_OK { + my DW::Request::Apache2 $self = $_[0]; + return Apache2::Const::HTTP_OK; +} + sub HTTP_CREATED { return Apache2::Const::HTTP_CREATED; } diff -r 37f7a2c8953c -r b0d94d3528e4 cgi-bin/DW/Request/Standard.pm --- a/cgi-bin/DW/Request/Standard.pm Mon Feb 28 18:44:54 2011 +0800 +++ b/cgi-bin/DW/Request/Standard.pm Mon Feb 28 18:47:21 2011 +0800 @@ -288,7 +288,12 @@ sub call_bml { } # constants sometimes used -sub OK { return 200; } + +# indicates that this request has been handled +sub OK { return 0; } + +# HTTP status codes +sub HTTP_OK { return 200; } sub HTTP_CREATED { return 201; } sub REDIRECT { return 302; } sub NOT_FOUND { return 404; } diff -r 37f7a2c8953c -r b0d94d3528e4 t/atom-post.t --- a/t/atom-post.t Mon Feb 28 18:44:54 2011 +0800 +++ b/t/atom-post.t Mon Feb 28 18:47:21 2011 +0800 @@ -65,7 +65,8 @@ sub do_request { my %routing_data = (); $routing_data{username} = $user_subdomain if $user_subdomain; - DW::Routing->call( %routing_data ); + my $returned = DW::Routing->call( %routing_data ); + $r->status( $returned ) unless $returned eq $r->OK; } # check subject, etc @@ -121,19 +122,18 @@ is( $r->status, $r->HTTP_UNAUTHORIZED, " is( $r->status, $r->HTTP_UNAUTHORIZED, "Passed wrong authorization information." ); do_request( GET => $u->atom_service_document, authenticate => 1 ); -is( $r->status, $r->OK, "Successful authentication." ); +is( $r->status, $r->HTTP_OK, "Successful authentication." ); note( "Service document introspection." ); do_request( POST => $u->atom_service_document ); -is( $r->status, $r->HTTP_UNAUTHORIZED, "Service document protected by authorization." ); +is( $r->status, $r->HTTP_METHOD_NOT_ALLOWED, "Service document needs GET (even unauthorized)" ); do_request( POST => $u->atom_service_document, authenticate => 1 ); -is( $r->status, $r->NOT_FOUND, "Service document needs GET." ); -is( $r->header_in( "Content-Type" ), "text/plain", "Error content type" ); +is( $r->status, $r->HTTP_METHOD_NOT_ALLOWED, "Service document needs GET." ); do_request( GET => $u->atom_service_document, authenticate => 1 ); -is( $r->status, $r->OK, "Got service document." ); +is( $r->status, $r->HTTP_OK, "Got service document." ); like( $r->header_in( "Content-Type" ), qr#^\Qapplication/atomsvc+xml\E#, "Service content type" ); my $service_document_xml = $r->response_content; @@ -146,11 +146,10 @@ is( $r->status, $r->HTTP_UNAUTHORIZED, " is( $r->status, $r->HTTP_UNAUTHORIZED, "Categories document protected by authorization." ); do_request( POST => $u->atom_base . "/entries/tags", authenticate => 1 ); -is( $r->status, $r->NOT_FOUND, "Categories document needs GET." ); -is( $r->header_in( "Content-Type" ), "text/plain", "Error content type" ); +is( $r->status, $r->HTTP_METHOD_NOT_ALLOWED, "Categories document needs GET." ); do_request( GET => $u->atom_base . "/entries/tags", authenticate => 1 ); -is( $r->status, $r->OK, "Got categories document." ); +is( $r->status, $r->HTTP_OK, "Got categories document." ); like( $r->header_in( "Content-Type" ), qr#^\Qapplication/atomcat+xml\E#, "Categories document type" ); my $categories_document_xml = $r->response_content; @@ -231,7 +230,7 @@ is( $r->status, $r->HTTP_UNAUTHORIZED, " is( $r->status, $r->HTTP_UNAUTHORIZED, "Entries feed needs authorization." ); do_request( GET => $u->atom_base . "/entries", authenticate => 1 ); -is( $r->status, $r->OK, "Retrieved entry list" ); +is( $r->status, $r->HTTP_OK, "Retrieved entry list" ); is( $r->header_in( "Content-Type" ), "application/atom+xml", "AtomAPI entry content type" ); my $feed = XML::Atom::Feed->new( \ $r->response_content ); @@ -247,10 +246,10 @@ is( $r->content_type, "text/plain", "Ato is( $r->content_type, "text/plain", "AtomAPI entry content type" ); do_request( POST => $u->atom_base . "/entries/1", authenticate => 1 ); -is( $r->status, $r->NOT_FOUND, $u->atom_base . "/entries/1 does not support POST." ); +is( $r->status, $r->HTTP_METHOD_NOT_ALLOWED, $u->atom_base . "/entries/1 does not support POST." ); do_request( GET => $u->atom_base . "/entries/1", authenticate => 1 ); -is( $r->status, $r->OK, "Retrieved entry" ); +is( $r->status, $r->HTTP_OK, "Retrieved entry" ); is( $r->content_type, "application/atom+xml", "AtomAPI entry content type" ); $atom_entry_server = XML::Atom::Entry->new( \ $r->response_content ); @@ -293,7 +292,7 @@ foreach my $tag ( @tags ) { # put a little bit of time between publish and update sleep( 1 ); do_request( PUT => $u->atom_base . "/entries/1", authenticate => 1, data => { input => $atom_entry->as_xml } ); -is( $r->status, $r->OK, "Edited entry" ); +is( $r->status, $r->HTTP_OK, "Edited entry" ); is( $r->content_type, "application/atom+xml", "AtomAPI entry content type" ); do_request( GET => $u->atom_base . "/entries/1", authenticate => 1 ); @@ -317,7 +316,7 @@ is( $r->status, $r->HTTP_BAD_REQUEST, "M do_request( DELETE => $u->atom_base . "/entries/1", authenticate => 1 ); -is( $r->status, $r->OK, "Deleted entry" ); +is( $r->status, $r->HTTP_OK, "Deleted entry" ); $entry_obj = LJ::Entry->new( $u, jitemid => 1 ); isnt( $entry_obj->valid, "Entry confirmed deleted" ); @@ -349,7 +348,7 @@ note( "Checking community functionality. # community you aren't a member of do_request( GET => $nonmemberof_cu->atom_service_document, authenticate => 1 ); - is( $r->status, $r->OK, "Not a member of the community, but we still get the service document for the user (which doesn't contain the community)." ); + is( $r->status, $r->HTTP_OK, "Not a member of the community, but we still get the service document for the user (which doesn't contain the community)." ); SKIP: { skip "No XML::Atom::Service/XML::Atom::Categories module installed.", 3 @@ -368,7 +367,7 @@ note( "Checking community functionality. # community you are a member of do_request( GET => $memberof_cu->atom_service_document, authenticate => 1 ); - is( $r->status, $r->OK, "Got service document." ); + is( $r->status, $r->HTTP_OK, "Got service document." ); like( $r->header_in( "Content-Type" ), qr#^\Qapplication/atomsvc+xml\E#, "Service content type" ); SKIP: { @@ -447,7 +446,7 @@ note( "Checking community functionality. # community you have posting access to do_request( GET => $memberof_cu->atom_base . "/entries", authenticate => 1 ); - is( $r->status, $r->OK, "Retrieved entry list" ); + is( $r->status, $r->HTTP_OK, "Retrieved entry list" ); is( $r->header_in( "Content-Type" ), "application/atom+xml", "AtomAPI entry content type" ); my $feed = XML::Atom::Feed->new( \ $r->response_content ); @@ -470,7 +469,7 @@ note( "Checking community functionality. # edit (should succeed) # delete (should succeed) do_request( GET => $memberof_cu->atom_base . "/entries/1", authenticate => 1 ); - is( $r->status, $r->OK, "Retrieved entry" ); + is( $r->status, $r->HTTP_OK, "Retrieved entry" ); is( $r->content_type, "application/atom+xml", "AtomAPI entry content type" ); $atom_entry_server = XML::Atom::Entry->new( \ $r->response_content ); @@ -493,7 +492,7 @@ note( "Checking community functionality. do_request( PUT => $memberof_cu->atom_base . "/entries/1", authenticate => 1, data => { input => $atom_entry->as_xml } ); - is( $r->status, $r->OK, "Edited entry" ); + is( $r->status, $r->HTTP_OK, "Edited entry" ); is( $r->content_type, "application/atom+xml", "AtomAPI entry content type" ); do_request( GET => $memberof_cu->atom_base . "/entries/1", authenticate => 1 ); @@ -510,7 +509,7 @@ note( "Checking community functionality. do_request( DELETE => $memberof_cu->atom_base . "/entries/1", authenticate => 1 ); - is( $r->status, $r->OK, "Deleted entry" ); + is( $r->status, $r->HTTP_OK, "Deleted entry" ); $entry_obj = LJ::Entry->new( $memberof_cu, jitemid => 1 ); isnt( $entry_obj->valid, "Entry confirmed deleted" ); @@ -545,14 +544,14 @@ note( "Checking community functionality. # edit (should fail) # delete (should succeed) do_request( GET => $memberof_cu->atom_base . "/entries/2", authenticate => 1, remote => $admin_u ); - is( $r->status, $r->OK, "Retrieved entry" ); + is( $r->status, $r->HTTP_OK, "Retrieved entry" ); is( $r->content_type, "application/atom+xml", "AtomAPI entry content type" ); do_request( PUT => $memberof_cu->atom_base . "/entries/2", authenticate => 1, remote => $admin_u, data => { input => $atom_entry->as_xml } ); is( $r->status, $r->HTTP_UNAUTHORIZED, "You don't own this entry (admin_u, edit)" ); do_request( DELETE => $memberof_cu->atom_base . "/entries/2", authenticate => 1, remote => $admin_u ); - is( $r->status, $r->OK, "Deleted entry (admin_u, delete)" ); + is( $r->status, $r->HTTP_OK, "Deleted entry (admin_u, delete)" ); $entry_obj = LJ::Entry->new( $memberof_cu, jitemid => 2 ); isnt( $entry_obj->valid, "Entry confirmed deleted" ); } --------------------------------------------------------------------------------