LiCoM::Person: Encode/Decode UTF-8 sen[dt] to/from LDAP-server.
authorFlorian Forster <octo@verplant.org>
Mon, 11 Sep 2006 21:54:39 +0000 (23:54 +0200)
committerFlorian Forster <octo@verplant.org>
Mon, 11 Sep 2006 21:54:39 +0000 (23:54 +0200)
lib/LiCoM/Person.pm

index 3c43a4b..efc37c2 100644 (file)
@@ -3,6 +3,9 @@ package LiCoM::Person;
 use strict;
 use warnings;
 
+use Carp (qw(cluck confess));
+use Encode (qw(encode decode is_utf8));
+
 use LiCoM::Config (qw(get_config));
 use LiCoM::Connection (qw($Ldap));
 
@@ -59,7 +62,16 @@ sub new
        for (keys %ValidFields)
        {
                my $key = $_;
-               $obj->{$key} = $entry->get_value ($key, asref => $ValidFields{$key});
+               my $val = $entry->get_value ($key, asref => $ValidFields{$key});
+
+               if (ref ($val))
+               {
+                       $obj->{$key} = [map { decode ('UTF-8', $_) } (@$val)];
+               }
+               else
+               {
+                       $obj->{$key} = decode ('UTF-8', $val);
+               }
        }
 
        return (bless ($obj, $pkg));
@@ -84,8 +96,8 @@ sub load
 
        if (!$retval)
        {
-               warn ("CN '$cn' could not be found");
-               return (undef);
+               cluck ("CN '$cn' could not be found");
+               return;
        }
        
        return ($retval);
@@ -125,11 +137,11 @@ sub create
                {
                        if (ref ($val) eq 'ARRAY')
                        {
-                               $entry->add ($field => [@$val]) if (@$val);
+                               $entry->add ($field => [map { encode ('UTF-8', $_) } (@$val)]) if (@$val);
                        }
                        elsif (!ref ($val))
                        {
-                               $entry->add ($field => [$val]) if ($val);
+                               $entry->add ($field => [encode ('UTF-8', $val)]) if ($val);
                        }
                        else
                        {
@@ -141,32 +153,33 @@ sub create
                        my $temp;
                        if (ref ($val) eq 'ARRAY')
                        {
-                               $temp = $val->[0];
+                               $temp = encode ('UTF-8', $val->[0]);
                        }
                        elsif (!ref ($val))
                        {
-                               $temp = $val;
+                               $temp = encode ('UTF-8', $val);
                        }
                        else
                        {
                                warn ("You cannot pass ref-type " . ref ($val));
                        }
 
-                       $entry->add ($field => $val) if (defined ($val) and $val);
+                       $entry->add ($field => $temp) if (defined ($temp) and $temp);
                }
        }
 
+       # $sn and $gn are UTF-8
        my $sn = $entry->get_value ('sn');
        my $gn = $entry->get_value ('givenName');
 
        if (!defined ($sn) or !defined ($gn))
        {
                warn ("sn or givenName not given");
-               return (undef);
+               return;
        }
 
-       $ou = 'Person';
-       $dn = "cn=$sn $gn,ou=$ou," . get_config ('base_dn');
+       $ou = encode ('UTF-8', 'Person');
+       $dn = "cn=$sn $gn,ou=$ou," . encode ('UTF-8', get_config ('base_dn'));
        
        $entry->add (cn => "$sn $gn", ou => $ou);
        $entry->dn ($dn);
@@ -176,8 +189,9 @@ sub create
 
        if ($mesg->is_error ())
        {
-               warn ("Error while creating entry '$dn' on LDAP server: " . $mesg->error_text ());
-               return (undef);
+               my $tmp = decode ('UTF-8', $dn);
+               warn ("Error while creating entry '$tmp' on LDAP server: " . $mesg->error_text ());
+               return;
        }
 
        return (new ($pkg, $entry));
@@ -228,6 +242,8 @@ sub search
 
                        $value =~ s/([\(\)\\])/\\$1/g;
 
+                       confess ("Value is not UTF-8 encoded: `$value'") if (!is_utf8 ($value));
+
                        push (@disjunc, "($field=$value)");
                }
                        
@@ -258,7 +274,7 @@ sub search
        $mesg = $Ldap->search
        (
                base   => 'ou=Person,' . get_config ('base_dn'),
-               filter => $filter
+               filter => encode ('UTF-8', $filter)
        );
 
        if ($mesg->is_error ())
@@ -290,7 +306,7 @@ sub get_user
        my $dn = shift;
        my ($search) = $dn =~ m/cn\s*=\s*([^,]+)/i;
 
-       die unless ($search);
+       return unless ($search);
        
        my $cn = '';
        my $id = '';
@@ -303,8 +319,8 @@ sub get_user
 
        if ($mesg->is_error ())
        {
-               warn ("Error while querying LDAP server: " . $mesg->error_text ());
-               return ('');
+               cluck ("Error while querying LDAP server: " . $mesg->error_text ());
+               return;
        }
 
        for ($mesg->entries ())
@@ -355,22 +371,35 @@ Get or set the lastname.
 
 sub _update_dn
 {
+       confess ("Wrong number of arguments") if (@_ != 3);
        my $obj = shift;
+
+       my $obj_new;
+       my %hash_new;
+
+       my $sn = shift;
+       my $gn = shift;
+
        my $entry = $obj->{'ldap'};
-       my $sn = $obj->{'sn'};
-       my $gn = $obj->{'givenName'};
-       my $cn = "$sn $gn";
-       my $dn = "cn=$cn,ou=Person," . get_config ('base_dn');
 
-       $obj->{'cn'} = $cn;
+       if (($sn eq $obj->{'sn'}) && ($gn eq $obj->{'givenName'}))
+       {
+               return;
+       }
 
-       print STDERR "This is _update_dn, trying to set dn=$dn";
+       $hash_new{$_} = $obj->{$_} for (keys %ValidFields);
+       $hash_new{'sn'} = $sn;
+       $hash_new{'givenName'} = $gn;
+       delete ($hash_new{'cn'});
 
-       $entry->changetype ('modify');
-       $entry->replace (sn => $sn, givenName => $gn, cn => $cn);
-       $entry->update ($Ldap);
-       $entry->dn ($dn);
-       $entry->update ($Ldap);
+       $obj_new = LiCoM::Person->create (%hash_new)
+               or confess ("Cannot duplicate LDAP entry");
+
+       $obj->delete ();
+
+       %$obj = %$obj_new;
+
+       return ($obj->{'dn'});
 }
 
 sub lastname
@@ -379,8 +408,7 @@ sub lastname
 
        if (@_)
        {
-               $obj->{'sn'} = shift;
-               _update_dn ($obj);
+               _update_dn ($obj, shift, $obj->{'givenName'});
        }
 
        return ($obj->{'sn'});
@@ -398,8 +426,7 @@ sub firstname
 
        if (@_)
        {
-               $obj->{'givenName'} = shift;
-               _update_dn ($obj);
+               _update_dn ($obj, $obj->{'sn'}, shift);
        }
 
        return ($obj->{'givenName'});
@@ -495,6 +522,8 @@ sub set
 
        if (defined ($value))
        {
+               $_ = encode ('UTF-8', $_) for (@$value);
+
                $entry->changetype ('modify');
 
                if ($ValidFields{$field})