Skip Menu |

This queue is for tickets about the Net-LDAP-Class CPAN distribution.

Report information
The Basics
Id: 65658
Status: resolved
Priority: 0/
Queue: Net-LDAP-Class

People
Owner: karman [...] cpan.org
Requestors: dekimsey [...] ufl.edu
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 0.25
Fixed in: (no value)



Subject: Performing batch add/remove of users on a group object fails
Performing multiple add_user/remove_user on a group object and then performing a $group->update fails to properly update the group membership. Specifically each add_user/remove_user invocation resets the internal users list. Attached is a test that demonstrates the issue as well as a patch I believe address the issue. Additionally, the action_for_update appears to have a side-effect in how it manipulates the internal users list which can mask the behavior. The attached files do not address this possible issue. Thanks, if you require any further information please let me know.
Subject: batch-add-remove.t
use Test::More tests => 46; use strict; use_ok('Net::LDAP::Class'); use_ok('Net::LDAP::Class::User::AD'); use_ok('Net::LDAP::Class::Group::AD'); use lib 't/lib'; use Net::LDAP; use Data::Dump qw( dump ); use LDAPTestAD; ok( my $server = LDAPTestAD::spawn_server(), "spawn server" ); ok( my $ldap = Net::LDAP->new( LDAPTestAD::server_host(), port => LDAPTestAD::server_port() ), "connect to server" ); { package MyLDAPUser; use base 'Net::LDAP::Class::User::AD'; __PACKAGE__->metadata->setup( base_dn => 'dc=test,dc=local', attributes => __PACKAGE__->AD_attributes, unique_attributes => __PACKAGE__->AD_unique_attributes, ); sub init_group_class {'MyLDAPGroup'} } { package MyLDAPGroup; use base 'Net::LDAP::Class::Group::AD'; __PACKAGE__->metadata->setup( base_dn => 'dc=test,dc=local', attributes => __PACKAGE__->AD_attributes, unique_attributes => __PACKAGE__->AD_unique_attributes, ); sub init_user_class {'MyLDAPUser'} } ok( $ldap->bind, "bind to server" ); ok( my $group = MyLDAPGroup->new( cn => 'foogroup', ldap => $ldap, ), "new group" ); ok( $group->create, "create $group" ); ### Test of removing multiple users. my $R = 3; for my $n ( 1 .. $R ) { ok( my $u = MyLDAPUser->new( sAMAccountName => $n, ldap => $ldap, groups => [$group], cn => $n, ), "new user $n" ); ok( $u->create, "create user $u" ); } ok( $group->read, "group update ok" ); for my $n ( 1 .. $R ){ ok( my $u = MyLDAPUser->new( ldap => $ldap, username => $n )->read, "user $n read ok"); ok( $group->has_user($u), "group has user $n"); } for my $n ( 1 .. $R ){ my $u = MyLDAPUser->new( ldap => $ldap, username => $n ); ok( $group->remove_user( $u ), "removed user ok" ); } ok( $group->update, "group update succeded" ); for my $n ( 1 .. $R ){ ok( my $u = MyLDAPUser->new( ldap => $ldap, username => $n )->read, "$n read ok"); ok( ! $group->has_user($u), "group doesn't have user $n"); } ### Test of adding multiple users. ok( my $group2 = MyLDAPGroup->new( cn => 'bargroup', ldap => $ldap, ), "new group2" ); ok( $group2->create, "group2 create ok" ); for my $n ( 1 .. $R ){ ok( my $u = MyLDAPUser->new( ldap => $ldap, username => $n )->read, "user $n read ok"); ok( $group2->add_user( $u ), "added user $u ok"); } ok( $group2->update, "group2 update ok"); for my $n ( 1 .. $R ){ ok( my $u = MyLDAPUser->new( ldap => $ldap, username => $n )->read, "user $n read ok"); ok( $group2->has_user( $u ), "has post-update user $u ok"); }
Subject: batch-user.patch
diff --git a/lib/Net/LDAP/Class/Group/AD.pm b/lib/Net/LDAP/Class/Group/AD.pm index c76bf47..117b0a9 100644 --- a/lib/Net/LDAP/Class/Group/AD.pm +++ b/lib/Net/LDAP/Class/Group/AD.pm @@ -390,12 +390,15 @@ sub add_user { croak "User object must have at least a username before adding to group $self"; } - for my $u ( $self->secondary_users ) { + if( not defined $self->{users} ){ + $self->{users} = $self->secondary_users; + } + my @users = @{ $self->{users} }; + for my $u ( @users ) { if ( "$u" eq "$user" ) { croak "User $user is already a member of group $self"; } } - my @users = $self->secondary_users; push( @users, $user ); $self->{users} = \@users; } @@ -418,7 +421,11 @@ sub remove_user { croak "User object must have at least a username before removing from group $self"; } - my %users = map { $_->username => $_ } @{ $self->secondary_users }; + if( not defined $self->{users} ){ + $self->{users} = $self->secondary_users; + } + my @users = @{ $self->{users} }; + my %users = map { $_->username => $_ } @users; if ( !exists $users{ $user->username } ) { croak "User $user is not a member of group $self"; }