Author: dom Date: 2008-10-20 00:24:51 +0100 (Mon, 20 Oct 2008) New Revision: 1240
Added: trunk/t/81_node_moderate_whitelist.t Modified: trunk/Build.PL trunk/Changes trunk/MANIFEST trunk/lib/OpenGuides.pm trunk/lib/OpenGuides/Config.pm trunk/lib/OpenGuides/Test.pm trunk/lib/OpenGuides/Utils.pm Log: Add the ability to whitelist hosts who can change moderated nodes without explicit moderation - thanks Oliver (fixes #203)
Modified: trunk/Build.PL =================================================================== --- trunk/Build.PL 2008-10-19 17:09:42 UTC (rev 1239) +++ trunk/Build.PL 2008-10-19 23:24:51 UTC (rev 1240) @@ -311,6 +311,8 @@ 'URI::Escape' => 0, 'XML::RSS' => 0, 'Data::Validate::URI' => 0, + 'Net::Netmask' => 0, + 'List::Utils' => 0, }, build_requires => { 'Module::Build' => '0.26', # API change for accessing config data
Modified: trunk/Changes =================================================================== --- trunk/Changes 2008-10-19 17:09:42 UTC (rev 1239) +++ trunk/Changes 2008-10-19 23:24:51 UTC (rev 1240) @@ -16,6 +16,8 @@ Fix install with CPAN when Config::Tiny not already installed (#224) Add an admin navbar, to be displayed if the user requests (#261) Move the node image outside the metadata div, to aid styling (#222) + Add the ability to whitelist hosts who can change moderated nodes + without explicit moderation (#203)
0.63 16 August 2008 Major overhaul of RDF output.
Modified: trunk/MANIFEST =================================================================== --- trunk/MANIFEST 2008-10-19 17:09:42 UTC (rev 1239) +++ trunk/MANIFEST 2008-10-19 23:24:51 UTC (rev 1240) @@ -145,6 +145,7 @@ t/77_send_email.t t/78_about.t t/79_host_blacklist.t +t/81_node_moderate_whitelist.t t/85_universal_edit_link.t t/templates/15_test.tt wiki.cgi
Modified: trunk/lib/OpenGuides/Config.pm =================================================================== --- trunk/lib/OpenGuides/Config.pm 2008-10-19 17:09:42 UTC (rev 1239) +++ trunk/lib/OpenGuides/Config.pm 2008-10-19 23:24:51 UTC (rev 1240) @@ -22,7 +22,8 @@ custom_template_path geo_handler ellipsoid gmaps_api_key centre_long show_gmap_in_node_display google_analytics_key centre_lat default_gmaps_zoom default_gmaps_search_zoom force_wgs84 - licence_name licence_url licence_info_url moderation_requires_password + licence_name licence_url licence_info_url + moderation_requires_password moderate_whitelist enable_node_image enable_common_categories enable_common_locales spam_detector_module host_checker_module static_path static_url send_moderation_notifications website_link_max_chars @@ -80,6 +81,7 @@ indexing_directory => "/usr/lib/cgi-bin/openguides/indexes/", enable_page_deletion => 0, moderation_requires_password => 1, + moderate_whitelist => "", admin_pass => "Change This!", enable_node_image => 1, enable_common_categories => 0, @@ -202,6 +204,7 @@ static_url => "What is the URL corresponding to the static content?", send_moderation_notifications => "Should we send email notifications when a moderated node is edited?", website_link_max_chars => "How many characters of the URL of node websites should be displayed?", + moderate_whitelist => "Enter a comma-separated list of IP addresses able to make changes to moderated nodes and have them show up immediately", );
foreach my $var ( keys %questions ) { @@ -336,6 +339,8 @@
=item * send_moderation_notifications
+=item * moderate_whitelist + =item * website_link_max_chars (default: C<20>)
=back
Modified: trunk/lib/OpenGuides/Test.pm =================================================================== --- trunk/lib/OpenGuides/Test.pm 2008-10-19 17:09:42 UTC (rev 1239) +++ trunk/lib/OpenGuides/Test.pm 2008-10-19 23:24:51 UTC (rev 1240) @@ -66,6 +66,7 @@ geo_handler => 1, force_wgs84 => 1, contact_email => 'admins@example.org', + moderate_whitelist => "", } );
Modified: trunk/lib/OpenGuides/Utils.pm =================================================================== --- trunk/lib/OpenGuides/Utils.pm 2008-10-19 17:09:42 UTC (rev 1239) +++ trunk/lib/OpenGuides/Utils.pm 2008-10-19 23:24:51 UTC (rev 1240) @@ -10,6 +10,8 @@ use Wiki::Toolkit::Plugin::RSS::Reader; use URI::Escape; use MIME::Lite; +use Net::Netmask; +use List::Util qw( first ); use Data::Validate::URI qw( is_web_uri );
=head1 NAME @@ -497,6 +499,35 @@ } }
+=item B<in_moderate_whitelist> + + if (OpenGuides::Utils->in_moderate_whitelist( '127.0.0.1' )) { + # skip moderation and apply new verson to published site + } + +Admins can supply a comma separated list of IP addresses or CIDR-notation +subnets indicating the hosts which can bypass enforced moderation. Any +values which cannot be parsed by CNetAddr::IP will be ignored. + +=cut + +sub in_moderate_whitelist { + my ($self, $config, $ip) = @_; + return undef if not defined $ip; + + # create NetAddr::IP object of the test IP + my $addr = Net::Netmask->new2($ip) or return undef; + + # load the configured whitelist + my @whitelist + = split ',', $config->moderate_whitelist; + + # test each entry in the whitelist + return eval{ + first { Net::Netmask->new2($_)->match($addr->base) } @whitelist + }; +} + =back
=head1 AUTHOR
Modified: trunk/lib/OpenGuides.pm =================================================================== --- trunk/lib/OpenGuides.pm 2008-10-19 17:09:42 UTC (rev 1239) +++ trunk/lib/OpenGuides.pm 2008-10-19 23:24:51 UTC (rev 1240) @@ -1556,7 +1556,10 @@ # Skip this for nodes needing moderation - this occurs for them once # they've been moderated my $needs_moderation = $wiki->node_required_moderation($node); - unless( $needs_moderation ) { + my $in_moderate_whitelist + = OpenGuides::Utils->in_moderate_whitelist($self->config, $new_metadata{host}); + + if ( $in_moderate_whitelist or not $needs_moderation ) { $self->_autoCreateCategoryLocale( id => $node, metadata => %new_metadata @@ -1567,22 +1570,30 @@ %new_metadata );
if ($written) { - if ( $needs_moderation and $config->send_moderation_notifications ) { - my $body = "The node '$node' in the OpenGuides installation\n" . - "'" . $config->site_name . "' requires moderation. ". - "Please visit\n" . - $config->script_url . $config->script_name . - "?action=show_needing_moderation\nat your convenience.\n"; - eval { - OpenGuides::Utils->send_email( - config => $config, - subject => "Node requires moderation", - body => $body, - admin => 1, - return_output => $return_output + if ( $needs_moderation ) { + if ( $in_moderate_whitelist ) { + $self->wiki->moderate_node( + name => $node, + version => $written ); - }; - warn $@ if $@; + } + elsif ( $config->send_moderation_notifications ) { + my $body = "The node '$node' in the OpenGuides installation\n" . + "'" . $config->site_name . "' requires moderation. ". + "Please visit\n" . + $config->script_url . $config->script_name . + "?action=show_needing_moderation\nat your convenience.\n"; + eval { + OpenGuides::Utils->send_email( + config => $config, + subject => "Node requires moderation", + body => $body, + admin => 1, + return_output => $return_output + ); + }; + warn $@ if $@; + } }
my $output = $self->redirect_to_node($node);
Added: trunk/t/81_node_moderate_whitelist.t =================================================================== --- trunk/t/81_node_moderate_whitelist.t (rev 0) +++ trunk/t/81_node_moderate_whitelist.t 2008-10-19 23:24:51 UTC (rev 1240) @@ -0,0 +1,96 @@ +use strict; +use Wiki::Toolkit::Setup::SQLite; +use OpenGuides; +use OpenGuides::Test; +use Test::More; + +eval { require DBD::SQLite; }; + +if ( $@ ) { + my ($error) = $@ =~ /^(.*?)\n/; + plan skip_all => "DBD::SQLite could not be used - no database to test with ($error)"; +} + +plan tests => 12; + +Wiki::Toolkit::Setup::SQLite::setup( { dbname => "t/node.db" } ); +my $config = OpenGuides::Test->make_basic_config; +$config->script_name( "wiki.cgi" ); +$config->script_url( "http://example.com/" ); +$config->moderate_whitelist( "127.0.0.1,127.0.0.2" ); +my $guide = OpenGuides->new( config => $config ); +isa_ok( $guide, "OpenGuides" ); +my $wiki = $guide->wiki; +isa_ok( $wiki, "Wiki::Toolkit" ); + +# Clear out the database from any previous runs. +foreach my $del_node ( $wiki->list_all_nodes ) { + print "# Deleting node $del_node\n"; + $wiki->delete_node( $del_node ) or die "Can't delete $del_node"; +} + + +# Add a page +my $q = CGI->new; +$q->param( -name => "content", -value => "foo" ); +$q->param( -name => "categories", -value => "Alpha" ); +$q->param( -name => "locales", -value => "" ); +$q->param( -name => "phone", -value => "" ); +$q->param( -name => "fax", -value => "" ); +$q->param( -name => "website", -value => "" ); +$q->param( -name => "hours_text", -value => "" ); +$q->param( -name => "address", -value => "" ); +$q->param( -name => "postcode", -value => "" ); +$q->param( -name => "map_link", -value => "" ); +$q->param( -name => "os_x", -value => "" ); +$q->param( -name => "os_y", -value => "" ); +$q->param( -name => "username", -value => "bob" ); +$q->param( -name => "comment", -value => "foo" ); +$q->param( -name => "edit_type", -value => "Minor tidying" ); +$ENV{REMOTE_ADDR} = "127.0.0.1"; + +my $output = $guide->commit_node( + return_output => 1, + id => "Wombats", + cgi_obj => $q, + ); + +# Check it's moderated +my %details = $wiki->retrieve_node("Wombats"); +is($details{'moderated'}, 1, "Moderated"); +is($wiki->node_required_moderation("Wombats"), 0, "No moderation"); + +# Turn on moderation +$wiki->set_node_moderation( + name => "Wombats", + required => 1, +); +is($wiki->node_required_moderation("Wombats"), 1, "Moderation"); + + +# Now add a new one, with new categories and locales +$q->param( -name => "categories", -value => "Alpha\r\nBeta" ); +$q->param( -name => "locales", -value => "Hello" ); +$q->param( -name => "edit_type", -value => "Normal edit" ); +$q->param( -name => "checksum", -value => $details{checksum} ); +$output = $guide->commit_node( + return_output => 1, + id => "Wombats", + cgi_obj => $q, + ); + +# Check that the current version is now 2 +%details = $wiki->retrieve_node("Wombats"); +is($details{'version'}, 2, "Still on v1"); +is($details{'moderated'}, 1, "v1 Moderated"); + +# Check that version 2 is moderated +my %v2 = $wiki->retrieve_node(name=>"Wombats",version=>2); +is($v2{'version'}, 2, "Is v2"); +is($v2{'moderated'}, 1, "Moderated"); + +# Check that the new categories and locales are there +is(1, $wiki->node_exists("Category Alpha"), "Right Categories"); +is(1, $wiki->node_exists("Category Beta"), "Right Categories"); +is(1, $wiki->node_exists("Locale Hello"), "Right Locales"); +
openguides-commits@lists.openguides.org