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

Last change on this file since 1869 was 1869, checked in by nanardon, 7 years ago

Ensure member attribute receive an array

  • Property svn:keywords set to Id Rev
File size: 6.0 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 );
13use LATMOS::Accounts::Log;
14
15our $VERSION = (q$Rev$ =~ /^Rev: (\d+) /)[0];
16
17=head1 NAME
18
19LATMOS::Ad - Perl extension for blah blah blah
20
21=head1 SYNOPSIS
22
23  use LATMOS::Ad;
24  blah blah blah
25
26=head1 DESCRIPTION
27
28Stub documentation for LATMOS::Ad, created by h2xs. It looks like the
29author of the extension was negligent enough to leave the stub
30unedited.
31
32Blah blah blah.
33
34=head1 FUNCTIONS
35
36=cut
37
38sub _class_filter { '(ObjectClass=group)' }
39
40sub _key_attr { 'cn' } 
41
42sub _my_ldap_classes { qw(top group) }
43
44sub _get_attr_schema {
45    my ($class, $base) = @_;
46    my $info = {
47        gidNumber  => { uniq => 1, },
48        description => { },
49        member => {
50            delayed => 1,
51            can_values => sub { $base->list_objects('user') },
52            multiple => 1,
53        },
54        memberUID => {
55            delayed => 1,
56            multiple => 1,
57        },
58        sAMAccountName => { },
59        managedBy => {
60            delayed => 1,
61            can_values => sub { $base->list_objects('user') },
62        },
63        cn => { ro => 1, },
64        dn => { ro => 1, },
65        objectClass => {
66            ro => 1,
67            multiple => 1,
68        },
69        msSFU30NisDomain => { },
70        msSFU30Name => { },
71    };
72
73    $info->{$class->_key_attribute($base)}{ro} = 1;
74    $info->{$class->_dn_attribute($base)}{ro} = 1;
75
76    $info
77}
78
79sub _create {
80    my ($class, $base, $id, %data) = @_;
81
82    $data{sAMAccountName} = 'GR-' . $id;
83    my $entry = Net::LDAP::Entry->new();
84
85    $entry->dn(join(',',
86        sprintf('%s=%s',
87            $class->_dn_attribute($base),
88            escape_filter_value($id)),
89            $base->object_base_dn($class->type
90        ),
91    ));
92    $entry->replace(objectClass => [ $class->_my_ldap_classes ],);
93    $data{$class->_key_attribute($base)} = $id;
94    my %delayed;
95    foreach (keys %data) {
96        /^(memberUID|member)$/ and do {
97            $delayed{$_} = $data{$_};
98            next;
99        };
100        $class->_populate_entry($entry, $_, $data{$_}, $base);
101    }
102    my $msg = $base->ldap->add($entry);
103    $base->log(LA_ERR, "Cannot create group: %s", $msg->error) if ($msg->code);
104    return if ($msg->code);
105    if (! keys %delayed) { return 1 };
106    my $res = $base->get_object('group', $id)->set_fields(%delayed);
107    return defined($res) ? 1 : 0;
108}
109
110sub get_field {
111    my ($self, $field) = @_;
112    require LATMOS::Accounts::Bases::Ad::User;
113
114    $field eq 'member' and do {
115        my @res;
116        $self->base->_unlimited_search(
117            base => $self->base->object_base_dn('user'),
118            filter => sprintf(
119                '(&(objectClass=user)(memberOf=%s))',
120                escape_filter_value($self->{entry}->dn),
121            ),
122            callback => sub {
123                my ($mesg, $entry) = @_;
124                ref $entry eq 'Net::LDAP::Entry' or return;
125                push(@res, $entry->get_value(
126                        LATMOS::Accounts::Bases::Ad::User->_key_attribute($self->base)
127                    )
128                );
129            },
130        );
131        return [ sort(@res) ];
132    };
133    $field eq 'memberUID' and do {
134        my $val = $self->SUPER::get_field($field);
135        return ref $val ? $val : [ grep { $_ } $val ];
136    };
137    $self->SUPER::get_field($field);
138}
139
140sub _populate_entry {
141    my ($self, $entry, $field, $value, $base) = @_;
142    $base ||= $self->base;
143    for ($field) {
144        /managedBy$/ and do {
145            if ($value && (my $user = $base->get_object('user', $value))) {
146                $value = $user->get_field('dn');
147            } else {
148                $value = undef;
149            }
150            next;
151        };
152        /^sAMAccountName$/ and do {
153            # Hack... to avoid clash with user
154            if ($value !~ /^GR-/) {
155                $value = 'GR-' . $value;
156            }
157            next;
158        };
159    }
160    $self->SUPER::_populate_entry($entry, $field, $value, $base);
161}
162
163sub set_fields {
164    my ($self, %data) = @_;
165    my %ndata;
166    while (my ($f, $val) = each(%data)) {
167        $f eq 'memberUID' and do {
168            $val = [ $val ] unless(ref $val);
169            my %users;
170            $users{$_}{e} = 1 foreach (@{ $self->get_field('memberUID') || []});
171            $users{$_}{n} = 1 foreach (@{ $val || []});
172            foreach (keys %users) {
173                $users{$_}{e} && $users{$_}{n} and next;
174                if ($users{$_}{e}) {
175                    $self->{entry}->delete(memberUID => $_);
176                } elsif ($users{$_}{n} && $self->base->get_object('user', $_)) {
177                    $self->{entry}->add(memberUID => $_);
178                } # else {} # can't happen
179            }
180            next;
181        };
182        $f eq 'member' and do {
183            my %users;
184            $val = [ $val ] unless(ref $val);
185            $users{$_}{e} = 1 foreach (@{ $self->get_field('member') || []});
186            $users{$_}{n} = 1 foreach (@{ $val || []});
187            foreach (keys %users) {
188                $users{$_}{e} && $users{$_}{n} and next;
189                my $user = $self->base->get_object('user', $_) or next;
190                if ($users{$_}{e}) {
191                    $self->{entry}->delete(member => $user->get_field('dn'));
192                } elsif ($users{$_}{n}) {
193                    $self->{entry}->add(member => $user->get_field('dn'));
194                } # else {} # can't happen
195            }
196            next;
197        };
198        $ndata{$f} = $val;
199    }
200    $self->SUPER::set_fields(%ndata);
201}
202
2031;
204
205__END__
206
207=head1 SEE ALSO
208
209=head1 AUTHOR
210
211Olivier Thauvin, E<lt>olivier.thauvin@aerov.jussieu.frE<gt>
212
213=head1 COPYRIGHT AND LICENSE
214
215Copyright (C) 2008 CNRS SA/CETP/LATMOS
216
217This library is free software; you can redistribute it and/or modify
218it under the same terms as Perl itself, either Perl version 5.10.0 or,
219at your option, any later version of Perl 5 you may have available.
220
221
222=cut
Note: See TracBrowser for help on using the repository browser.