Skip to content

Commit

Permalink
Item12849: convertTopicPreferences utility
Browse files Browse the repository at this point in the history
It was dropping trailing blank lines
It failed to convert DENY in Meta Preferences

Add information to release notes

git-svn-id: http://svn.foswiki.org/trunk@17580 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
GeorgeClark authored and GeorgeClark committed Apr 24, 2014
1 parent 821b5a2 commit 46d5880
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 22 deletions.
81 changes: 80 additions & 1 deletion core/data/System/ReleaseNotes01x02.txt
@@ -1,4 +1,4 @@
%META:TOPICINFO{author="ProjectContributor" date="1395597014" format="1.1" version="1"}%
%META:TOPICINFO{author="ProjectContributor" date="1398367593" format="1.1" version="1"}%
%META:TOPICPARENT{name="ReleaseHistory"}%
---+!! Foswiki Release 1.2 - not released yet
%RED% These are not actual release notes, but a collection of documented changes that we should not forget to mention. %ENDCOLOR%
Expand Down Expand Up @@ -43,8 +43,87 @@ Foswiki 1.2 is shipped with the following:

#Release01x02Changes
---++ Important changes since Foswiki 1.2

---+++ Authentication and Authorization

* users can authenticate via 'TemplateLogin' with their email address

---++++ Deprecation of empty DENY rules

The intention to deprecate the use of an empty =DENYTOPIC<action>= rule to act as an "ALLOW all" has been completed. This has been a
pending change predating Foswiki 1.0.0.

<blockquote class="foswikiHelp">%X% *ACTION REQUIRED* Any topics in the system that allow access by supplying an empty DENYTOPIC
rule need to be updated. A utility has been provided to find and convert existing empty DENY rules to the new ALLOW format.
You can choose to defer this action by enabling =$Foswiki::cfg{AccessControlACL}{enableDeprecatedEmptyDeny}= in the _Security and Authentication_
section under the _Access control_ tab.
</blockquote>

With release 1.2 of Foswiki, a new ACL rule, the asterisk, is used as a
wildcard to match *any* user, including the guest user, !WikiGuest. Prior to
Foswiki 1.2, a topic could be made accessable to everyone by coding
an empty =DENYTOPIC&lt;action&gt;= rule. This rule is no longer active by
default.

A conversion tool is availabe in the tools directory. =tools/convertTopicSettings.pl= It can perform the following actions:
* Convert empty =DENYTOPIC&lt;action&gt;= rules to the corresponding <tt>ALLOWTOPIC&lt;action&gt;= *</tt>
* Optionally convert inline ACLs into META settings. This is recommended for Foswiki 1.2
* Optionally convert __all__ inline settings into META settings.

<verbatim>
# perl -I bin tools/convertTopicSettings -fixdeny

# SYNOPSIS
# convertTopicSettings [-update] [-fixdeny] [-convert] [-all] [-verbose]
# [-debug] [WEB ...]
#
# DESCRIPTION
#
# -update: topics will be updated. Without the -update
# option, candidate topic changes will be reported but will not be written.
#
# -fixdeny: Removes empty DENYTOPIC rules, replacing them with ALLOWTOPIC
# wildcard
#
# -convert: Convert Preference into META settings. Inline ACLs are
# removed.
#
# -all: Convert all settings from inline sets to meta settings.
# Default is to
# process ACL settings
#
# -verbose: Report details on what is changed.
#
# -debug: Print additional detailed information
#
# If you specify web names, only those specified are processed. Otherwise,
# all writable webs are processed.
#
# WARNING
# This script uses the Foswiki APIs. It MUST be run as the web server user
# (apache, or www-data depending on the distribution). If run as root, it
# will make the foswiki log unusable by the foswiki web server.
#
</verbatim>

---++ New Pluggable Access Control implementations.

Foswiki has made the Access Control implementation "Pluggable". New ACL
methods may be more easily implemented in the future. The default method is
=$Foswiki::cfg{AccessControl} = 'Foswiki::Access::TopicACLAccess';=.

Two additional methods are now included which may be of help to the
Administrator:

$ =AdminOnlyAccess=: When selected, all requests for access are denied except when requested by users in the AdminGroup.
$ =TopicACLReadOnlyAccess=: The topic ACLs are applied as usual, but any access other than VIEW access is denied, except for users in the AdminGroup

<blockquote class="foswikiHelp">%X% *Caution:* These controls are enforced at
the ACL Level. Extensions have the ability to ignore access controls. If an
extension fails to check for access permission, then these new methods will
not block access.
</blockquote>

---+++ Configure has been given a major restructuring

* Configure now requires JavaScript.
Expand Down
71 changes: 50 additions & 21 deletions core/tools/convertTopicSettings.pl
Expand Up @@ -14,7 +14,7 @@

# You must add the Foswiki bin dir to the
# search path for this script, so it can find the rest of Foswiki e.g.
# perl -I /usr/local/Foswiki/bin /usr/local/Foswiki/tools/rewriteTopicACLs
# perl -I bin tools/convertTopicSettings -fixdeny -update Sandbox

# SYNOPSIS
# convertTopicSettings [-update] [-fixdeny] [-convert] [-all] [-verbose] [-debug] [WEB ...]
Expand Down Expand Up @@ -63,6 +63,8 @@ BEGIN
my $verbose;
my $debug;

my $savedTopics = 0; # Global counter of saved topics

my $session = Foswiki->new('unknown'); #$Foswiki::cfg{AdminUserLogin} );

GetOptions(
Expand All @@ -86,12 +88,15 @@ BEGIN
my $topicCounter = 0;
foreach my $topic ( Foswiki::Func::getTopicList($web) ) {

#next unless ( $topic =~ /TestTopic/ );
next unless ( $topic =~ /TestTopic/ );

next if ( $topic eq $Foswiki::cfg{WebPrefsTopicName} );
scanTopic( $web, $topic );
$topicCounter++;
}
print STDERR "Processed $topicCounter topics in $web\n";
print STDERR
"Processed $topicCounter topics in $web; Updated $savedTopics\n";
$savedTopics = 0;
}

exit 0;
Expand All @@ -105,16 +110,9 @@ sub scanTopic {
my %aclHash = ();
print STDERR "Processing $web.$topic\n" if $verbose;

use Data::Dumper;
print STDERR "=================$topic BEFORE====================\n"
if $debug;
print STDERR Data::Dumper::Dumper( \$text ) if $debug;

my $newText = parse( $topicObject, \%aclHash );

print STDERR "=================$topic AFTER=====================\n"
_dumpTopic( "$topic BEFORE", $topicObject->getEmbeddedStoreForm() )
if $debug;
print STDERR Data::Dumper::Dumper( \$newText ) if $debug;
my $newText = parse( \$topicObject, \%aclHash );

if ( %aclHash && $verbose ) {
foreach my $type ( keys %aclHash ) {
Expand All @@ -126,12 +124,16 @@ sub scanTopic {
}
}

print STDERR "$topic.$web text has been updated.\n"
unless ( $text eq $newText );

if ($update) {
$topicObject->text($newText);
if ( $convert && %aclHash ) {
foreach my $type ( keys %aclHash ) {
next if ( $type eq 'fixup' );
foreach my $key ( keys %{ $aclHash{$type} } ) {
print STDERR "PUT $key value $aclHash{$type}{ $key, } \n";
$topicObject->putKeyed(
'PREFERENCE',
{
Expand All @@ -144,9 +146,12 @@ sub scanTopic {
}
}
}
if ( $text ne $newText ) {
if ( $text ne $newText || $aclHash{fixup} ) {
_dumpTopic( "$topic AFTER", $topicObject->getEmbeddedStoreForm() )
if $debug;
my $newrev = $topicObject->save();
print STDERR "Saved $web.$topic as rev $newrev\n";
$savedTopics++;
print STDERR
"---------------------------------------------------------------------------------------------------\n";
}
Expand All @@ -155,6 +160,19 @@ sub scanTopic {
return;
}

sub _dumpTopic {

print STDERR "================= $_[0] =====================\n";
require Data::Dumper;
print STDERR Data::Dumper::Dumper( \$_[1] );

#my $hex = '';
#foreach my $ch ( split ( //, $newText ) ) {
# $hex .= ( $ch lt "\x20" || $ch gt "\x7e" ) ? "\'" . unpack("H2",$ch) . "\'" : $ch;
# }
#print STDERR "($hex)\n";
}

=begin TML
---++ parse( $topicObject, $prefs )
Expand All @@ -172,17 +190,22 @@ sub scanTopic {
sub parse {
my ( $topicObject, $prefs ) = @_;

#use Data::Dumper;
#print STDERR Data::Dumper::Dumper( \$topicObject );

# Process text first
my $key = '';
my $value = '';
my $type;
my $text = $topicObject->text();
my $text = $$topicObject->text();
$text = '' unless defined $text;
my @newText;
my $line;

# This processes the topic text line-by-line to capture multi-line preferences.
foreach $line ( split( "\n", $text ) ) {
# Use -1 limit so that trailing lines are preserved

foreach $line ( split( /\n/ms, $text, -1 ) ) {

if ( $line =~ m/$Foswiki::regex{setVarRegex}/os ) {

Expand All @@ -200,7 +223,7 @@ sub parse {

unless ( $all || $key =~ m/^(?:ALLOW|DENY)(?:WEB|TOPIC)/ ) {
$type = undef;
print STDERR "Not an ACL: $key = $value\n";
print STDERR "Not an ACL: $key = $value\n" if $verbose;
}

# Convert the empty DENY here so it can be written inline.
Expand Down Expand Up @@ -245,18 +268,24 @@ sub parse {
push @newText, $line if defined $line;

# Now process PREFERENCEs
my @fields = $topicObject->find('PREFERENCE');
my @fields = $$topicObject->find('PREFERENCE');
foreach my $field (@fields) {
print STDERR
"d - Found a meta pref: $field->{type} / $field->{name} / $field->{value} \n"
if $debug;

# Copy the values, convert_DENY updates in place!
my $key = $field->{name};
my $value = $field->{value};
$type = $field->{type} || 'Set';
insert_pref( $prefs, $type, $field->{name}, $field->{value} );
if ( convert_DENY( $prefs, $type, $key, $value ) ) {
print STDERR "Removing $type, $field->{name} \n";
$$topicObject->remove( 'PREFERENCE', $field->{name} );
}
insert_pref( $prefs, $type, $key, $value );
}

# If original topic didn't end with a newline, don't add one.
my $nl = ( substr( $text, -1 ) eq "\n" ) ? "\n" : '';
return join( "\n", @newText ) . $nl;
return join( "\n", @newText );

# #### Code to process prefs in Forms ... NOT USED ###
# # Note that the use of the "S" attribute to support settings in
Expand Down

0 comments on commit 46d5880

Please sign in to comment.