diff --git a/lib/LDV/LDAP.pm b/lib/LDV/LDAP.pm index 2cecb2c..643649d 100644 --- a/lib/LDV/LDAP.pm +++ b/lib/LDV/LDAP.pm @@ -111,13 +111,25 @@ sub update { unless ($data); my $dn = sprintf "uid=%s,%s", $uid, $self->{userbase}; - my %upd = (); + my %allowed = map { $_ => 1 } @{$self->{defattrs}}; + my @chg = (); while (my ($key, $value) = each(%$attrs)) { - next unless ($value and exists $data->{$key}); + next unless exists $allowed{$key}; next if ($key eq 'uid'); # rename protection - $upd{$key} = $value; + if ($value and not exists $data->{$key}) { + push @chg, add => [$key => $value]; + next; + } + if ($data->{$key} and $value) { + push @chg, replace => [$key => $value]; + next; + } + if ($data->{$key} and not $value) { + push @chg, delete => [$key => $value]; + next; + } } - my $result = $conn->modify($dn, replace => \%upd); + my $result = $conn->modify($dn, changes => \@chg); $conn->unbind; return $result->error if ($result->code); @@ -171,7 +183,8 @@ Get user attributes. Returns HASH on success or undef if not found. my $err = $ldap->update($user, \%attrs); Returns nothing on success or scalar with text on error. -Each key in %attrs must exists for this user's entry. -Empty values will be silently skipped. + +See list of allowed keys in config, 'ldap/defattrs' parameter. +'uid' key will be ignored, because it's structural in our schema. =cut diff --git a/t/LDAP.t b/t/LDAP.t index 85b5394..f11fb60 100644 --- a/t/LDAP.t +++ b/t/LDAP.t @@ -7,12 +7,12 @@ use utf8; use LDV::LDAP; use File::Slurp; use Data::Dumper; -use Test::More tests => 8; +use Test::More tests => 9; my $hash = read_file('conf/ldv.conf'); my $config = eval "$hash"; SKIP: { - skip "Can't load config", 8 unless (ref($config) eq 'HASH'); + skip "Can't load config", 9 unless (ref($config) eq 'HASH'); my $ldap = LDV::LDAP->new($config->{ldap}); isa_ok($ldap, "LDV::LDAP", "LDV::LDAP->new"); @@ -26,6 +26,8 @@ SKIP: { $attrs = {uid => 'test20', cn => 'Полиграф', sn => 'Шариков'}; is($ldap->update("test20", $attrs), undef, "updating user data"); + is($ldap->update("test20", {mail => 'abigvalg@example.com'}), undef, "updating user data"); + $attrs->{mail} = 'abigvalg@example.com'; is_deeply($ldap->get("test20"), $attrs, "getting data of updated user"); is($ldap->delete("test20"), undef, "deleting user");