source: trunk/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/Group.pm @ 1920

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

Fix manager update when department change

  • Property svn:keywords set to Id Rev
File size: 10.4 KB
Line 
1package LATMOS::Accounts::Bases::Sql::Group;
2
3use 5.010000;
4use strict;
5use warnings;
6use overload '""' => 'stringify';
7
8use base qw(LATMOS::Accounts::Bases::Sql::objects);
9use LATMOS::Accounts::Log;
10use LATMOS::Accounts::I18N;
11
12our $VERSION = (q$Rev$ =~ /^Rev: (\d+) /)[0];
13
14=head1 NAME
15
16LATMOS::Accounts::Bases::Sql::Group - Groups objects support
17
18=cut
19
20sub stringify {
21    my ($self) = @_;
22
23    $self->get_field('label')
24    || $self->id;
25}
26
27sub _object_table { 'group' }
28
29sub _key_field { 'name' }
30
31sub _has_extended_attributes { 1 }
32
33sub _get_attr_schema {
34    my ($class, $base) = @_;
35
36    $class->SUPER::_get_attr_schema($base,
37        {
38            gidNumber  => {
39                inline => 1,
40                uniq => 1,
41                iname => 'gidnumber',
42                mandatory => 1,
43                label => l('GID'),
44            },
45            gidnumber  => { inline => 1, uniq => 1, hide => 1, },
46            cn         => { inline => 1, ro => 1, iname => 'name', },
47            memberUID  => {
48                monitored => 1,
49                hide => 1,
50                reference => 'user',
51                multiple => 1,
52                delayed => 1,
53                ro => sub {
54                    $_[0] &&
55                    (($_[0]->_get_c_field('sutype') ||'') =~ /^(jobtype|contrattype)$/
56                     || $_[0]->_get_c_field('autoMemberFilter')
57                     || $_[0]->_get_c_field('autoFromSutype'))
58                    ? 1 : 0
59                },
60                get => sub {
61                    my ($self) = @_;
62                    my $sth = $self->base->db->prepare_cached(
63                        q{
64                        select value from group_attributes
65                        join "group" on "group".ikey = group_attributes.okey
66                        join "user" on "user".name = group_attributes.value
67                        where "group".name = ? and attr = ?
68                        } .
69                        ($self->base->{wexported} ? '' : 'and "user".exported = true')
70                    );
71                    $sth->execute($self->object->id, 'memberUID');
72                    my @res;
73                    while (my $res = $sth->fetchrow_hashref) {
74                        push(@res, $res->{value});
75                    }
76                    return \@res;
77                },
78                set => sub {
79                    my ($self, $data) = @_;
80                    $self->object->_set_group_members($data);
81                },
82                label => l('Member'),
83            },
84            member     => {
85                monitored => 1,
86                reference => 'user',
87                multiple => 1,
88                delayed => 1,
89                iname => 'memberUID',
90                can_values => sub { $base->list_objects('user') },
91                ro => sub {
92                    $_[0] &&
93                    (($_[0]->_get_c_field('sutype') ||'') =~ /^(jobtype|contrattype)$/
94                     || $_[0]->_get_c_field('autoMemberFilter')
95                     || $_[0]->_get_c_field('autoFromSutype'))
96                    ? 1 : 0
97                },
98                get => sub {
99                    my ($self) = @_;
100                    $self->object->_get_c_field('memberUID');
101                },
102                set => sub {
103                    my ($self, $data) = @_;
104                    $self->object->_set_group_members($data);
105                },
106                label => l('Member'),
107            },
108            sAMAccountName => { iname => 'name', ro => 1 },
109            groupname  => { ro => 1 },
110            managedBy  => {
111                monitored => 1,
112                reference => 'user',
113                can_values => sub {
114                    my %uniq = map { $_ => 1 } grep { $_ }
115                    (($_[1] ? $_[1]->get_attributes('managedBy') : ()),
116                    $base->search_objects('user', 'active=*'));
117                    sort keys %uniq;
118                },
119                label => l('Manager'),
120                post => sub {
121                    my ($self, $value) = @_;
122                    $self->object->_update_employment_manager;
123                },
124            },
125            managedAlsoBy  => {
126                monitored => 1,
127                reference => 'user',
128                multiple => 1,
129                delayed => 1,
130                can_values => sub {
131                    my %uniq = map { $_ => 1 } grep { $_ }
132                    ($_[1] ? $_[1]->get_attributes('managedBy') : ()),
133                    $base->search_objects('user', 'active=*');
134                    sort keys %uniq;
135                },
136                label => l('Secondary Manager'),
137            },
138            sutype => {
139                reference => 'sutype',
140                monitored => 1,
141                label => l('Structure'),
142                multiple => 1,
143            },
144            autoMemberFilter => {
145                multiple => 1,
146                set => sub {
147                    my ($self, $data) = @_;
148                    $self->object->set_fields($self->name, $data) or return;
149                    $self->object->populate_dyn_group;
150                    return 1;
151                },
152                label => l('Automatics filters'),
153            },
154            autoFromSutype => {
155                reference => 'sutype',
156                multiple => 1,
157                set => sub {
158                    my ($self, $data) = @_;
159                    $self->object->set_fields($self->name, $data) or return;
160                    $self->object->populate_dyn_group;
161                    return 1;
162                },
163                label => l('From group type'),
164            },
165            label => {
166                label => l('Label'),
167            },
168            expire => {
169                label => l('Expire'),
170            },
171            description => {
172                label => l('Description'),
173            },
174            comment => {
175                label => l('Comment'),
176            },
177            memberCount => {
178                managed => 1,
179                ro => 1,
180                get => sub {
181                    my ($self) = @_;
182                    scalar(@{$self->object->_get_c_field('memberUID') || []});
183                },
184                label => l('Member count'),
185            },
186        }
187    )
188}
189
190sub _set_group_members {
191    my ($self, $members) = @_;
192    my %member;
193    my $res = 0;
194    foreach (@{ $self->_get_c_field('memberUID') || [] }) {
195        $member{$_}{c} = 1;
196    }
197    foreach (ref $members ? @{ $members || []} : $members) {
198        $_ or next; # avoid undef
199        $member{$_}{n} = 1;
200    }
201
202    foreach (keys %member) {
203        $member{$_}{c} && $member{$_}{n} and next; # no change !
204        my $user = $self->base->get_object('user', $_) or next;
205        if ($member{$_}{n}) {
206            my $sth = $self->db->prepare_cached(
207                q{insert into group_attributes_users (value, attr, okey) values (?,?,?)}
208            );
209            $res += $sth->execute($_, 'memberUID', $self->_get_ikey);
210        } elsif ($member{$_}{c}) {
211            if (($user->get_c_field('department') || '') eq $self->id) {
212                $self->base->log(LA_WARN,
213                    "Don't removing user %s from group %s: is it's department",
214                    $user->id, $self->id);
215                next;
216            }
217            my $sth = $self->db->prepare_cached(
218                q{delete from group_attributes_users where value = ? and attr = ? and okey = ?}
219            );
220            $res += $sth->execute($_, 'memberUID', $self->_get_ikey);
221        } # else {} # can't happend
222    }
223    return $res;
224}
225
226=head2 populate_dyn_group
227
228Synchronise group's members according filter set into C<autoMemberFilter> attribute.
229
230=cut
231
232sub populate_dyn_group {
233    my ($self) = @_;
234
235    if (
236           !$self->get_field('autoMemberFilter')
237        && !$self->get_field('autoFromSutype')) {
238        return 0;
239    }
240    $self->base->log(LA_DEBUG,
241        "Populating group %s from autoMemberFilter/autoFromSutype attribute",
242        $self->id
243    );
244
245    my %users;
246
247    if (my $filter = $self->get_field('autoFromSutype')) {
248        my @suTypeFilter = map { "sutype=$_" } (ref $filter ? @{ $filter } : $filter);
249        foreach my $group ($self->base->search_objects('group', @suTypeFilter)) {
250            foreach ($self->base->search_objects('user', "memberOf=$group")) {
251                $users{$_} = 1;
252            }
253        }
254    }
255
256    if (my $filter = $self->get_field('autoMemberFilter')) {
257        foreach ($self->base->search_objects(
258                'user',
259                'oalias=NULL',
260                ref $filter ? @{ $filter } : $filter)) {
261            $users{$_} = 1;
262        }
263    }
264
265    my $res = $self->_set_group_members([ keys %users ]);
266
267    $res;
268}
269
270sub _update_employment_manager {
271    my ($self) = @_;
272
273    my $listEmp = $self->base->db->prepare(q{
274        select name from employment join employment_attributes
275            on employment.ikey = employment_attributes.okey
276        where firstday < now() and (lastday > now() or lastday is NULL)
277            and employment_attributes.attr = 'department' and employment_attributes.value = ?
278        });
279    $listEmp->execute($self->id);
280    while (my $res = $listEmp->fetchrow_hashref()) {
281        $self->base->log(LA_DEBUG, "Checking if employment %s is impacted by managedBy change", $res->{name});
282        my $employment = $self->base->get_object('employment', $res->{name}) or next;
283        $employment->get_attributes('managerContact') and next;
284        my $dpmt  = $employment->_get_attributes('department') or next;
285        my $odmpt = $employment->base->get_object('group', $dpmt) or next;
286        my $manager = $odmpt->get_attributes('managedBy') or next;
287        my $user = $employment->get_attributes('user');
288        my $ouser = $employment->base->get_object('user', $user) or next;
289        $self->base->log(LA_DEBUG, "Updating manager to $manager for user $user due to dpmt update");
290        $ouser->ReportChange(
291            'Update', 'Attr manager updated to match Dpmt manager %s (%s)',
292            $manager,
293            $dpmt,
294        );
295        $ouser->set_fields('manager', $manager);
296    }
297
298    return 1;
299}
300
3011;
302
303__END__
304
305=head1 SEE ALSO
306
307L<LATMOS::Accounts::Bases::Sql>
308
309=head1 AUTHOR
310
311Olivier Thauvin, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>
312
313=head1 COPYRIGHT AND LICENSE
314
315Copyright (C) 2008, 2009 CNRS SA/CETP/LATMOS
316
317This library is free software; you can redistribute it and/or modify
318it under the same terms as Perl itself, either Perl version 5.10.0 or,
319at your option, any later version of Perl 5 you may have available.
320
321=cut
Note: See TracBrowser for help on using the repository browser.