source: LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Ad/Group.pm @ 107

Last change on this file since 107 was 107, checked in by nanardon, 15 years ago
  • objects::set_fields is called also to terminate work, so always try update, but detect 'no update' error
  • Property svn:keywords set to Id Rev
File size: 4.5 KB
Line 
1package LATMOS::Accounts::Bases::Ad::Group;
2
3use 5.010000;
4use strict;
5use warnings;
6
7use base qw(LATMOS::Accounts::Bases::Ad::objects);
8use Net::LDAP;
9use Net::LDAP::Entry;
10use Net::LDAP::Control::Paged;
11use Net::LDAP::Constant qw( LDAP_CONTROL_PAGED ); 
12use Net::LDAP::Util     qw( escape_filter_value );
13
14our $VERSION = (q$Rev$ =~ /^Rev: (\d+) /)[0];
15
16=head1 NAME
17
18LATMOS::Ad - Perl extension for blah blah blah
19
20=head1 SYNOPSIS
21
22  use LATMOS::Ad;
23  blah blah blah
24
25=head1 DESCRIPTION
26
27Stub documentation for LATMOS::Ad, created by h2xs. It looks like the
28author of the extension was negligent enough to leave the stub
29unedited.
30
31Blah blah blah.
32
33=head1 FUNCTIONS
34
35=cut
36
37sub _class_filter { '(ObjectClass=group)' }
38
39sub _key_attr { 'cn' } 
40
41sub _delayed_fields {
42    my ($self)= @_;
43    return qw(memberUID member);
44}
45
46sub _canonical_fields {
47    my ($self, $base, $mode) = @_;
48    (
49        qw(gidNumber description member memberUID), # sAMAccountName: conflict with user
50                                                    # must be uniq in AD
51        ($mode !~ /w/
52            ? qw(cn dn)
53            : ()
54        )
55    )
56}
57
58sub _create {
59    my ($class, $base, $id, %data) = @_;
60
61    my $entry = Net::LDAP::Entry->new();
62
63    $entry->dn(join(',',
64        sprintf('cn=%s', escape_filter_value($id)),
65        $base->object_base_dn($class->type),
66    ));
67    $entry->replace(objectClass => [ qw(top group)],);
68    my %delayed;
69    foreach (keys %data) {
70        /^(memberUID|member)$/ and do {
71            $delayed{$_} = $data{$_};
72            next;
73        };
74        $class->_populate_entry($entry, $_, $data{$_});
75    }
76    my $msg = $base->ldap->add($entry);
77    warn $msg->error if ($msg->code);
78    return if ($msg->code);
79    if (! keys %delayed) { return 1 };
80    my $res = $base->get_object('group', $id)->set_fields(%delayed);
81    return defined($res) ? 1 : 0;
82}
83
84sub get_field {
85    my ($self, $field) = @_;
86
87    $field eq 'member' and do {
88        my @res;
89        $self->base->_unlimited_search(
90            base => $self->base->object_base_dn('user'),
91            filter => sprintf(
92                '(&(objectClass=user)(memberOf=%s))',
93                escape_filter_value($self->{entry}->dn),
94            ),
95            callback => sub {
96                my ($mesg, $entry) = @_;
97                ref $entry eq 'Net::LDAP::Entry' or return;
98                push(@res, $entry->get_value('cn'));
99            },
100        );
101        return [ sort(@res) ];
102    };
103    $field eq 'memberUID' and do {
104        my $val = $self->SUPER::get_field($field);
105        return ref $val ? $val : [ grep { $_ } $val ];
106    };
107    $self->SUPER::get_field($field);
108}
109
110sub set_fields {
111    my ($self, %data) = @_;
112    my %ndata;
113    while (my ($f, $val) = each(%data)) {
114        $f eq 'memberUID' and do {
115            my %users;
116            $users{$_}{e} = 1 foreach (@{ $self->get_field('memberUID') || []});
117            $users{$_}{n} = 1 foreach (@{ $val || []});
118            foreach (keys %users) {
119                $users{$_}{e} && $users{$_}{n} and next;
120                my $user = $self->base->get_object('user', $_) or next;
121                if ($users{$_}{e}) {
122                    $self->{entry}->del(memberUID => $_);
123                } elsif ($users{$_}{n}) {
124                    $self->{entry}->add(memberUID => $_);
125                } # else {} # can't happen
126                my $mesg = $self->{entry}->update($self->base->ldap);
127            }
128            next;
129        };
130        $f eq 'member' and do {
131            my %users;
132            $users{$_}{e} = 1 foreach (@{ $self->get_field('member') || []});
133            $users{$_}{n} = 1 foreach (@{ $val || []});
134            foreach (keys %users) {
135                $users{$_}{e} && $users{$_}{n} and next;
136                my $user = $self->base->get_object('user', $_) or next;
137                if ($users{$_}{e}) {
138                    $self->{entry}->del(member => $user->get_field('dn'));
139                } elsif ($users{$_}{n}) {
140                    $self->{entry}->add(member => $user->get_field('dn'));
141                } # else {} # can't happen
142            }
143            next;
144        };
145        $ndata{$f} = $val;
146    }
147    $self->SUPER::set_fields(%ndata);
148}
149
1501;
151
152__END__
153
154=head1 SEE ALSO
155
156=head1 AUTHOR
157
158Olivier Thauvin, E<lt>olivier.thauvin@aerov.jussieu.frE<gt>
159
160=head1 COPYRIGHT AND LICENSE
161
162Copyright (C) 2008 CNRS SA/CETP/LATMOS
163
164This library is free software; you can redistribute it and/or modify
165it under the same terms as Perl itself, either Perl version 5.10.0 or,
166at your option, any later version of Perl 5 you may have available.
167
168
169=cut
Note: See TracBrowser for help on using the repository browser.