Skip to content

Commit

Permalink
Item10097: Add unit tests (fail). Cause is supporting protected USERS…
Browse files Browse the repository at this point in the history
…WEB, Item9809

Sorry, I struggled to make the tests fail inside TopicUserMappingTests.pm, so created
a new TopicUserMappingAsGuestTests.pm instead.

Commenting-out line 1488 in Foswiki::Users::TopicUserMapping.pm makes the test pass.

The problem is that we temporarily change the {session}->{user} = admin, but then
those %USERSWEB%.*Group topics are primed into the Foswiki::MetaCache when the
'actual' user may not necessarily have VIEW access.

Effectively this means that Foswiki::search only checks ACLs on topics once: the
first time it scans over it in a search. If that first time occurs while we happen
to be in TopicUserMapping when {session}->{user} = admin, then the Foswiki::MetaCache
may be contaminated with *Group topics that were supposed to be protected from the
actual user.

git-svn-id: http://svn.foswiki.org/trunk@10270 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
PaulHarvey authored and PaulHarvey committed Dec 12, 2010
1 parent 601786c commit 0bf1bfd
Show file tree
Hide file tree
Showing 4 changed files with 289 additions and 1 deletion.
Expand Up @@ -1484,6 +1484,7 @@ sub _getListOfGroups {
$this->{groupsList} = [];

# Temporarily set the user to admin, otherwise it cannot see groups
# where %USERSWEB% is protected from view
local $this->{session}->{user} = $Foswiki::cfg{SuperAdminGroup};

$this->{session}->search->searchWeb(
Expand Down
@@ -0,0 +1,286 @@
# See bottom of file for license and copyright information
use strict;
use warnings;

package TopicUserMappingAsGuestTests;

# Some basic tests for Foswiki::Users::TopicUserMapping
#
# The tests are performed using the APIs published by the facade class,
# Foswiki:Users, not the actual Foswiki::Users::TopicUserMapping

use FoswikiTestCase;
our @ISA = qw( FoswikiTestCase );

use Foswiki;
use Foswiki::Users;
use Foswiki::Users::TopicUserMapping;
use Error qw( :try );

my $fatwilly;
my $saveTopic;
my $ttpath;

my $testSysWeb = 'TemporaryTopicUserMappingAsGuestTestsSystemWeb';
my $testNormalWeb = "TemporaryTopicUserMappingAsGuestTestsNormalWeb";
my $testUsersWeb = "TemporaryTopicUserMappingAsGuestTestsUsersWeb";
my $testUser;

sub fixture_groups {
return ( [ 'useHtpasswdMgr', 'noPasswdMgr' ],
[ 'NormalTopicUserMapping', 'NamedTopicUserMapping', ] );
}

sub NormalTopicUserMapping {
my $this = shift;
$Foswiki::Users::TopicUserMapping::FOSWIKI_USER_MAPPING_ID = '';
$this->set_up_for_verify();
}

sub NamedTopicUserMapping {
my $this = shift;

# Set a mapping ID for purposes of testing named mappings
$Foswiki::Users::TopicUserMapping::FOSWIKI_USER_MAPPING_ID = 'TestMapping_';
$this->set_up_for_verify();
}

sub useHtpasswdMgr {
my $this = shift;

$Foswiki::cfg{PasswordManager} = "Foswiki::Users::HtPasswdUser";
}

sub noPasswdMgr {
my $this = shift;

$Foswiki::cfg{PasswordManager} = "none";
}

# Override default set_up in base class; will call it after the mapping
# id has been set
sub set_up {
}

# Delay the calling of set_up till after the cfg's are set by above closure
sub set_up_for_verify {
my $this = shift;

$this->SUPER::set_up();

my $original = $Foswiki::cfg{SystemWebName};
$Foswiki::cfg{Htpasswd}{FileName} =
"$Foswiki::cfg{TempfileDir}/junkhtpasswd";
$Foswiki::cfg{UsersWebName} = $testUsersWeb;
$Foswiki::cfg{SystemWebName} = $testSysWeb;
$Foswiki::cfg{LocalSitePreferences} = "$testUsersWeb.SitePreferences";
$Foswiki::cfg{UserMappingManager} = 'Foswiki::Users::TopicUserMapping';
$Foswiki::cfg{Register}{AllowLoginName} = 1;
$Foswiki::cfg{Register}{EnableNewUserRegistration} = 1;

try {
$fatwilly = new Foswiki( $Foswiki::cfg{DefaultUserWikiName} );
Foswiki::Func::createWeb($testUsersWeb);

# the group is recursive to force a recursion block
Foswiki::Func::saveTopic( $testUsersWeb, $Foswiki::cfg{SuperAdminGroup},
undef, " * Set GROUP = $Foswiki::cfg{SuperAdminGroup}\n" );

Foswiki::Func::createWeb( $testSysWeb, $original );
Foswiki::Func::createWeb( $testNormalWeb, '_default' );

my $oprefs =
Foswiki::Meta->load( $fatwilly, $testSysWeb,
$Foswiki::cfg{SitePrefsTopicName} );
my $nprefs =
Foswiki::Meta->new( $fatwilly, $testSysWeb,
$Foswiki::cfg{SitePrefsTopicName},
$oprefs->text() );
$nprefs->copyFrom($oprefs);
$nprefs->save();

$testUser = $this->createFakeUser($fatwilly);
}
catch Foswiki::AccessControlException with {
my $e = shift;
$this->assert( 0, $e->stringify() );
}
catch Error::Simple with {
$this->assert( 0, shift->stringify() || '' );
};
}

sub tear_down {
my $this = shift;

$this->removeWebFixture( $fatwilly, $testUsersWeb );
$this->removeWebFixture( $fatwilly, $testSysWeb );
$this->removeWebFixture( $fatwilly, $testNormalWeb );
unlink $Foswiki::cfg{Htpasswd}{FileName};
$fatwilly->finish();
$this->SUPER::tear_down();
}

sub new {
my $self = shift()->SUPER::new(@_);
return $self;
}

my $initial = <<'THIS';
* A - <a name="A">- - - -</a>
* AttilaTheHun - 10 Jan 1601
* B - <a name="B">- - - -</a>
* BungditDin - 10 Jan 2004
* C - <a name="C">- - - -</a>
* D - <a name="D">- - - -</a>
* E - <a name="E">- - - -</a>
* F - <a name="F">- - - -</a>
* G - <a name="G">- - - -</a>
* GungaDin - 10 Jan 2004
* H - <a name="H">- - - -</a>
* I - <a name="I">- - - -</a>
* J - <a name="J">- - - -</a>
* K - <a name="K">- - - -</a>
* L - <a name="L">- - - -</a>
* M - <a name="M">- - - -</a>
* N - <a name="N">- - - -</a>
* O - <a name="O">- - - -</a>
* P - <a name="P">- - - -</a>
* Q - <a name="Q">- - - -</a>
* R - <a name="R">- - - -</a>
* S - <a name="S">- - - -</a>
* SadOldMan - sad - 10 Jan 2004
* SorryOldMan - 10 Jan 2004
* StupidOldMan - 10 Jan 2004
* T - <a name="T">- - - -</a>
* U - <a name="U">- - - -</a>
* V - <a name="V">- - - -</a>
* W - <a name="W">- - - -</a>
* X - <a name="X">- - - -</a>
* Y - <a name="Y">- - - -</a>
* Z - <a name="Z">- - - -</a>
THIS

sub createFakeUser {
my ( $this, $fatwilly, $text, $name ) = @_;
$this->assert( Foswiki::Func::webExists( $Foswiki::cfg{UsersWebName} ) );
$name ||= '';
my $base = "TemporaryTestUser" . $name;
my $i = 0;
while (
Foswiki::Func::topicExists( $Foswiki::cfg{UsersWebName}, $base . $i ) )
{
$i++;
}
$text ||= '';
my $meta =
Foswiki::Meta->new( $fatwilly, $Foswiki::cfg{UsersWebName}, $base . $i );
$meta->put(
"TOPICPARENT",
{
name => $Foswiki::cfg{UsersWebName} . '.'
. $Foswiki::cfg{HomeTopicName}
}
);
Foswiki::Func::saveTopic( $Foswiki::cfg{UsersWebName},
$base . $i, undef, $text, $meta );
push( @{ $this->{fake_users} }, $base . $i );
return $base . $i;
}

sub groupFix {
my $this = shift;
my $me = $Foswiki::cfg{Register}{RegistrationAgentWikiName};
$fatwilly->{users}->{mapping}->addUser( "auser", "AaronUser", $me );
$fatwilly->{users}->{mapping}->addUser( "guser", "GeorgeUser", $me );
$fatwilly->{users}->{mapping}->addUser( "zuser", "ZebediahUser", $me );
$fatwilly->{users}->{mapping}->addUser( "auser", "AaronUser", $me );
$fatwilly->{users}->{mapping}->addUser( "guser", "GeorgeUser", $me );
$fatwilly->{users}->{mapping}->addUser( "zuser", "ZebediahUser", $me );
$fatwilly->{users}->{mapping}->addUser( "scum", "ScumUser", $me );
Foswiki::Func::saveTopic( $testUsersWeb, 'AmishGroup', undef,
" * Set GROUP = AaronUser,%MAINWEB%.GeorgeUser, scum\n" );
Foswiki::Func::saveTopic( $testUsersWeb, 'BaptistGroup', undef,
" * Set GROUP = GeorgeUser,$testUsersWeb.ZebediahUser\n" );
Foswiki::Func::saveTopic( $testUsersWeb, 'MultiLineGroup', undef,
" * Set GROUP = GeorgeUser,$testUsersWeb.ZebediahUser\n AaronUser, scum\n"
);

# Item10097 - ensure view protected groups don't show up in SEARCHes
Foswiki::Func::saveTopic(
$testUsersWeb, 'SecretGroup', undef, <<"HERE"
* Set GROUP = $Foswiki::cfg{AdminUserLogin}
* Set ALLOWTOPICVIEW = $Foswiki::cfg{SuperAdminGroup}
HERE
);
Foswiki::Func::saveTopic(
$testUsersWeb, 'AanotherSecretGroup', undef, <<"HERE"
* Set GROUP = $Foswiki::cfg{AdminUserLogin}
* Set ALLOWTOPICVIEW = $Foswiki::cfg{SuperAdminGroup}
HERE
);
Foswiki::Func::saveTopic(
$testUsersWeb, 'AaanotherSecretGroup', undef, <<"HERE"
* Set GROUP = $Foswiki::cfg{AdminUserLogin}
* Set ALLOWTOPICVIEW = $Foswiki::cfg{SuperAdminGroup}
HERE
);
}

sub verify_getListOfGroups {
my $this = shift;
$this->groupFix();
my $i = $fatwilly->{users}->eachGroup();
my @l = ();
while ( $i->hasNext() ) { push( @l, $i->next() ) }
my $k = join( ',', sort @l );
$this->assert_str_equals(
"AdminGroup,AmishGroup,BaptistGroup,BaseGroup,MultiLineGroup", $k );
}

sub verify_secretGroupIsHidden {
my $this = shift;
my $expected = 'AdminGroup,AmishGroup,BaptistGroup,MultiLineGroup';
my $result;
my $oldSession = $this->{session};

$this->{session} = new Foswiki( $Foswiki::cfg{DefaultUserLogin} );
$this->groupFix();
$result = Foswiki::Func::expandCommonVariables(<<'HERE');
%SEARCH{
"Group$"
type="regex"
scope="topic"
web="%USERSWEB%"
nonoise="on"
format="$topic"
separator=","
}%
HERE
chomp($result);
$this->assert_str_equals( $expected, $result );
$this->{session}->finish();
$this->{session} = $oldSession;

return;
}

1;
__END__
Foswiki - The Free and Open Source Wiki, http://foswiki.org/
Copyright (C) 2008-2010 Foswiki Contributors. Foswiki Contributors
are listed in the AUTHORS file in the root of this distribution.
NOTE: Please extend that file, not this notice.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. For
more details read LICENSE in the root of this distribution.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
As per the GPL, removal of this notice is prohibited.
Expand Up @@ -8,7 +8,8 @@ use Unit::TestSuite;
our @ISA = 'Unit::TestSuite';

sub include_tests {
return qw(TopicUserMappingContribTests TopicUserMappingTests);
return
qw(TopicUserMappingContribTests TopicUserMappingTests TopicUserMappingAsGuestTests);
}

1;
Expand Down
Empty file.

0 comments on commit 0bf1bfd

Please sign in to comment.