Skip to content

Commit

Permalink
Item1879: two problems; first, subwebs were not being searched for re…
Browse files Browse the repository at this point in the history
…ferences to topics being renamed; and second, it wasn't respecting VIEW constraints on referring webs and topics. Fixed and added unit test that covers both of these.

git-svn-id: http://svn.foswiki.org/trunk@4634 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
CrawfordCurrie authored and CrawfordCurrie committed Aug 10, 2009
1 parent c0d3667 commit 7dfdb2a
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 9 deletions.
91 changes: 91 additions & 0 deletions UnitTestContrib/test/unit/RenameTests.pm
Expand Up @@ -183,12 +183,16 @@ sub check {
} }
} }


# Check the results of _getReferringTopics. $all means all webs. $expected
# is an array of topic names that should be seen. $forgiving means that
# the actual set may contain other topics besides those expected.
sub checkReferringTopics { sub checkReferringTopics {
my ( $this, $web, $topic, $all, $expected, $forgiving ) = @_; my ( $this, $web, $topic, $all, $expected, $forgiving ) = @_;


my $m = Foswiki::Meta->new( $this->{session}, $web, $topic ); my $m = Foswiki::Meta->new( $this->{session}, $web, $topic );
my $refs = my $refs =
Foswiki::UI::Rename::_getReferringTopics( $this->{session}, $m, $all ); Foswiki::UI::Rename::_getReferringTopics( $this->{session}, $m, $all );

$this->assert_str_equals( 'HASH', ref($refs) ); $this->assert_str_equals( 'HASH', ref($refs) );
if ($forgiving) { if ($forgiving) {
foreach my $k ( keys %$refs ) { foreach my $k ( keys %$refs ) {
Expand All @@ -198,13 +202,16 @@ sub checkReferringTopics {
} }
} }


# Check that all expected topics were seen
my %expected_but_unseen; my %expected_but_unseen;
my %e = map { $_ => 1 } @$expected; my %e = map { $_ => 1 } @$expected;
foreach my $r ( keys %e ) { foreach my $r ( keys %e ) {
unless ( $refs->{$r} ) { unless ( $refs->{$r} ) {
$expected_but_unseen{$r} = 1; $expected_but_unseen{$r} = 1;
} }
} }

# Check that no unexpected topics were seen
my %not_expected; my %not_expected;
foreach my $r ( keys %$refs ) { foreach my $r ( keys %$refs ) {
$this->assert_not_null($r); $this->assert_not_null($r);
Expand Down Expand Up @@ -439,6 +446,90 @@ THIS
); );
} }


# There's a reference in a topic in a web which doesn't allow
# read access for the current user [[Foswiki:Tasks.Item1879]]
sub test_rename_topic_reference_in_denied_web {
my $this = shift;

# Make sure the reference can't exist outside the text fixture
my $fnord = "FnordMustNotBeFound".time;

# Create the referred-to topic that we're renaming
my $m =
Foswiki::Meta->new( $this->{session}, $this->{test_web}, $fnord );
$m->text("");
$m->save();

# Create a subweb
$m =
Foswiki::Meta->new( $this->{session}, "$this->{test_web}/Swamp" );
$m->populateNewWeb();

# Create a topic in the subweb that refers to the topic we're renaming
$m = Foswiki::Meta->new(
$this->{session}, "$this->{test_web}/Swamp", 'TopSecret' );
$m->text("[[$this->{test_web}.$fnord]]");
$m->save();

# Make sure the subweb is unprotected (readable)
$m = Foswiki::Meta->new(
$this->{session}, "$this->{test_web}/Swamp", 'WebPreferences' );
$m->text(" * Set ALLOWWEBCHANGE = \n * Set ALLOWWEBVIEW = \n");
$m->save();

# Have to restart to clear prefs cache
$this->{session}->finish();
$this->{session} = new Foswiki( $this->{test_user_login},
new Unit::Request( ) );

$this->checkReferringTopics(
$this->{test_web}, $fnord,
1,
[
"$this->{test_web}/Swamp.TopSecret"
]
);

# Protect the web we made (deny view access)
$m = Foswiki::Meta->new(
$this->{session}, "$this->{test_web}/Swamp", 'WebPreferences' );
$m->text(" * Set ALLOWWEBVIEW = PickMeOhPickMe");
$m->save();

# Have to restart to clear prefs cache
$this->{session}->finish();
$this->{session} = new Foswiki( $this->{test_user_login},
new Unit::Request( ) );

$this->checkReferringTopics(
$this->{test_web}, $fnord,
1,
[
# Should be empty
]
);

# Protect the web we made (deny change access)
# We need to be able to see these references.
$m = Foswiki::Meta->new(
$this->{session}, "$this->{test_web}/Swamp", 'WebPreferences' );
$m->text(" * Set ALLOWWEBCHANGE = PickMeOhPickMe");
$m->save();

# Have to restart to clear prefs cache
$this->{session}->finish();
$this->{session} = new Foswiki( $this->{test_user_login},
new Unit::Request( ) );

$this->checkReferringTopics(
$this->{test_web}, $fnord,
1,
[
"$this->{test_web}/Swamp.TopSecret"
]
);
}

# Rename OldTopic to NewTopic within the same web # Rename OldTopic to NewTopic within the same web
sub test_renameTopic_same_web_new_topic_name { sub test_renameTopic_same_web_new_topic_name {
my $this = shift; my $this = shift;
Expand Down
24 changes: 15 additions & 9 deletions core/lib/Foswiki/UI/Rename.pm
Expand Up @@ -255,8 +255,8 @@ sub _renameTopicOrAttachment {
my $refs; my $refs;
unless ($attachment) { unless ($attachment) {
$refs = $refs =
_getReferringTopicsListFromURL( $session, $oldWeb, $oldTopic, $newWeb, _getReferringTopicsListFromURL(
$newTopic ); $session, $oldWeb, $oldTopic, $newWeb, $newTopic );
} }


_moveTopicOrAttachment( $session, $old, $new, $attachment, $newAttachment, _moveTopicOrAttachment( $session, $old, $new, $attachment, $newAttachment,
Expand Down Expand Up @@ -486,7 +486,7 @@ sub _renameWeb {


# Lease topics and build # Lease topics and build
# up a hash containing permissions and lock info. # up a hash containing permissions and lock info.
my $it = $oldWebObject->eachWeb(); my $it = $oldWebObject->eachWeb(1);
_leaseContents( $session, $info, $oldWebObject->web, $confirm ); _leaseContents( $session, $info, $oldWebObject->web, $confirm );
while ( $it->hasNext() ) { while ( $it->hasNext() ) {
my $subweb = $it->next(); my $subweb = $it->next();
Expand Down Expand Up @@ -626,7 +626,7 @@ sub _renameWeb {


# now remove leases on all topics inside $newWeb. # now remove leases on all topics inside $newWeb.
my $nwom = Foswiki::Meta->new( $session, $newWeb ); my $nwom = Foswiki::Meta->new( $session, $newWeb );
my $it = $nwom->eachWeb(); my $it = $nwom->eachWeb(1);
_releaseContents( $session, $newWeb ); _releaseContents( $session, $newWeb );
while ( $it->hasNext() ) { while ( $it->hasNext() ) {
my $subweb = $it->next(); my $subweb = $it->next();
Expand Down Expand Up @@ -1271,6 +1271,7 @@ sub _getReferringTopicsListFromURL {
# SMELL: this will only work as long as searchInText searches meta-data # SMELL: this will only work as long as searchInText searches meta-data
# as well. It sould really do a query over the meta-data as well, but at the # as well. It sould really do a query over the meta-data as well, but at the
# moment that is just duplication and it's too slow already. # moment that is just duplication and it's too slow already.
# Calling user *must* have view access on the topics.
sub _getReferringTopics { sub _getReferringTopics {
my ( $session, $om, $allWebs ) = @_; my ( $session, $om, $allWebs ) = @_;
my $renderer = $session->renderer; my $renderer = $session->renderer;
Expand All @@ -1280,7 +1281,7 @@ sub _getReferringTopics {


if ($allWebs) { if ($allWebs) {
my $root = Foswiki::Meta->new($session); my $root = Foswiki::Meta->new($session);
my $it = $root->eachWeb(); my $it = $root->eachWeb(1);
while ( $it->hasNext() ) { while ( $it->hasNext() ) {
push( @webs, $it->next() ); push( @webs, $it->next() );
} }
Expand All @@ -1290,6 +1291,10 @@ sub _getReferringTopics {
my $interWeb = ( $searchWeb ne $om->web() ); my $interWeb = ( $searchWeb ne $om->web() );
next if ( $allWebs && !$interWeb ); next if ( $allWebs && !$interWeb );


my $webObject = Foswiki::Meta->new( $session, $searchWeb );

next unless $webObject->haveAccess('VIEW');

# Search for both the foswiki form and the URL form # Search for both the foswiki form and the URL form
my $searchString = Foswiki::Render::getReferenceRE( my $searchString = Foswiki::Render::getReferenceRE(
$om->web(), $om->topic(), $om->web(), $om->topic(),
Expand All @@ -1303,8 +1308,6 @@ sub _getReferringTopics {
interweb => $interWeb, interweb => $interWeb,
url => 1 url => 1
); );
my @topicList = ();
my $webObject = Foswiki::Meta->new( $session, $searchWeb );


#print STDERR "SEARCH $searchString in $searchWeb\n"; #print STDERR "SEARCH $searchString in $searchWeb\n";
my $matches = $webObject->searchInText( my $matches = $webObject->searchInText(
Expand All @@ -1314,13 +1317,16 @@ sub _getReferringTopics {
); );


foreach my $searchTopic ( keys %$matches ) { foreach my $searchTopic ( keys %$matches ) {

#print STDERR "Found $searchTopic\n";
next next
if ( $searchWeb eq $om->web if ( $searchWeb eq $om->web
&& $om->topic && $om->topic
&& $searchTopic eq $om->topic ); && $searchTopic eq $om->topic );


# Individual topics may be view restricted. Only return
# those we can see.
my $m = Foswiki::Meta->new( $session, $searchWeb, $searchTopic );
next unless $m->haveAccess('VIEW');

$results{ $searchWeb . '.' . $searchTopic } = 1; $results{ $searchWeb . '.' . $searchTopic } = 1;
} }
} }
Expand Down

0 comments on commit 7dfdb2a

Please sign in to comment.