Skip to content

Commit

Permalink
Item14348: Support for ordered user mappings.
Browse files Browse the repository at this point in the history
- usermap key of a connection definition can now be an array ref to fix
a potential problem with a user being member of few groups defined in
the map.

- Fixed a mistype.
  • Loading branch information
vrurg committed Apr 2, 2017
1 parent 9fa6234 commit 7840e21
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 13 deletions.
41 changes: 31 additions & 10 deletions lib/Foswiki/Contrib/DatabaseContrib.pm
Expand Up @@ -319,7 +319,7 @@ sub _set_codepage {
sub add_acl_inheritance {
my $self = shift;

$self->fail( "Odd number of elements in call to "
$self->_fail( "Odd number of elements in call to "
. ref($self)
. "::add_acl_inheritance()" )
unless scalar(@_) % 2 == 0;
Expand Down Expand Up @@ -465,7 +465,7 @@ sub connect {
foreach my $field (@required_fields) {
unless ( defined $connection->{$field} ) {
return undef
if $self->fail(
if $self->_fail(
"Required field $field is not defined for database connection $conname.\n"
);
}
Expand All @@ -477,15 +477,36 @@ sub connect {

if ( defined( $connection->{usermap} ) ) {

# Individual mappings are checked first.
my @maps =
sort { ( $a =~ /Group$/ ) <=> ( $b =~ /Group$/ ) }
keys %{ $connection->{usermap} };
my @maps;
if ( ref( $connection->{usermap} ) eq 'HASH' ) {

# SMELL: *there is no ordering implied* other than 'check users
# first, then check groups'. So if your user is a member of
# several matching groups, it is *random* which group mapping
# will be used to access the DB.
# SMELL: *there is no ordering implied* other than 'check users
# first, then check groups'. So if your user is a member of
# several matching groups, it is *random* which group mapping
# will be used to access the DB.

# Individual mappings are checked first.
@maps =
sort { ( $a =~ /Group$/ ) <=> ( $b =~ /Group$/ ) }
keys %{ $connection->{usermap} };
}
elsif ( ref( $connection->{usermap} ) eq 'ARRAY' ) {
my ( @u, @g ); # User and group mappings
foreach my $ent ( @{ $connection->{usermap} } ) {
if ( $ent =~ /Group$/ ) {
push @g, $ent;
}
else {
push @u, $ent;
}
}
@maps = ( @u, @g );
}
else {
return undef
if $self->_fail(
"Connection '$conname' usermap is neither hash nor arrayref");
}

my $usermap_key = $self->_find_mapping( \@maps );
if ($usermap_key) {
Expand Down
6 changes: 3 additions & 3 deletions test/unit/DatabaseContrib/DatabaseContribTestCommon.pm
Expand Up @@ -62,7 +62,7 @@ sub set_up {
'Failed to create a new admin' );

$this->assert( db_init, "DatabaseContrib init failed" );

$this->{check_pairs} = {
valid => {
allow_do => [
Expand Down Expand Up @@ -208,8 +208,8 @@ sub loadExtraConfig {
'Sandbox.QTestTopic' => [qw(JohnSmith)],
"$this->{test_web}.QSomeImaginableTopic" =>
[qw(TestGroup DummyGuest)],
"Sandbox.GlobM*Topic" => [qw(DummyGroup)],
"Sandbox.GlobsTopic" => [qw(D*Group El*y)],
"Sandbox.GlobM*Topic" => [qw(DummyGroup)],
"Sandbox.GlobsTopic" => [qw(D*Group El*y)],
"Sandbox.GlobsTopicRestrict" => [qw(Any*Q*Group)],
},
usermap => {
Expand Down

0 comments on commit 7840e21

Please sign in to comment.