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

Last change on this file since 2475 was 2475, checked in by nanardon, 3 years ago

start samba support: manage sambaSID

  • Property svn:keywords set to Id Rev
File size: 10.6 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: 1920 $ =~ /^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 = ? and "user".oalias is NULL
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            autoExclude => {
155                multiple => 1,
156                reference => 'user',
157                label => l('User excluded'),
158            },
159            autoInclude => {
160                multiple => 1,
161                reference => 'user',
162                label => l('User included'),
163            },
164            autoFromSutype => {
165                reference => 'sutype',
166                multiple => 1,
167                set => sub {
168                    my ($self, $data) = @_;
169                    $self->object->set_fields($self->name, $data) or return;
170                    $self->object->populate_dyn_group;
171                    return 1;
172                },
173                label => l('From group type'),
174            },
175            label => {
176                label => l('Label'),
177            },
178            expire => {
179                label => l('Expire'),
180            },
181            description => {
182                label => l('Description'),
183            },
184            comment => {
185                label => l('Comment'),
186            },
187            memberCount => {
188                managed => 1,
189                ro => 1,
190                get => sub {
191                    my ($self) = @_;
192                    scalar(@{$self->object->_get_c_field('memberUID') || []});
193                },
194                label => l('Member count'),
195            },
196
197            # Samba:
198
199            sambaSID => {
200                ro => 1,
201                auto => 1,
202            },
203            _sambaSID => {
204                ro => 1,
205                hide => 1,
206                managed => 1,
207                get => sub {
208                    my ($self) = @_;
209                    my $obj = $self->object;
210                    my $uid = $obj->get_field('gidnumber');
211                    return $obj->base->sambaSID( $uid * 2 + 1001 );
212                }
213            },
214
215        }
216    )
217}
218
219sub _set_group_members {
220    my ($self, $members) = @_;
221    my %member;
222    my $res = 0;
223    foreach (@{ $self->_get_c_field('memberUID') || [] }) {
224        $member{$_}{c} = 1;
225    }
226    foreach (ref $members ? @{ $members || []} : $members) {
227        $_ or next; # avoid undef
228        $member{$_}{n} = 1;
229    }
230
231    foreach (keys %member) {
232        $member{$_}{c} && $member{$_}{n} and next; # no change !
233        my $user = $self->base->get_object('user', $_) or next;
234        if ($member{$_}{n}) {
235            my $sth = $self->db->prepare_cached(
236                q{insert into group_attributes_users (value, attr, okey) values (?,?,?)}
237            );
238            $res += $sth->execute($_, 'memberUID', $self->_get_ikey);
239        } elsif ($member{$_}{c}) {
240            if (($user->get_c_field('department') || '') eq $self->id) {
241                $self->base->log(LA_WARN,
242                    "Don't removing user %s from group %s: is it's department",
243                    $user->id, $self->id);
244                next;
245            }
246            my $sth = $self->db->prepare_cached(
247                q{delete from group_attributes_users where value = ? and attr = ? and okey = ?}
248            );
249            $res += $sth->execute($_, 'memberUID', $self->_get_ikey);
250        } # else {} # can't happend
251    }
252    return $res;
253}
254
255=head2 populate_dyn_group
256
257Synchronise group's members according filter set into C<autoMemberFilter> attribute.
258
259=cut
260
261sub populate_dyn_group {
262    my ($self) = @_;
263
264    if (
265           !$self->get_field('autoMemberFilter')
266        && !$self->get_field('autoFromSutype')) {
267        return 0;
268    }
269    $self->base->log(LA_DEBUG,
270        "Populating group %s from autoMemberFilter/autoFromSutype attribute",
271        $self->id
272    );
273
274    my @Userlist = $self->_filterToUser;
275
276    my $res = $self->_set_group_members( \@Userlist );
277
278    $res;
279}
280
281sub _update_employment_manager {
282    my ($self) = @_;
283
284    my $listEmp = $self->base->db->prepare(q{
285        select name from employment join employment_attributes
286            on employment.ikey = employment_attributes.okey
287        where firstday < now() and (lastday > now() or lastday is NULL)
288            and employment_attributes.attr = 'department' and employment_attributes.value = ?
289        });
290    $listEmp->execute($self->id);
291    while (my $res = $listEmp->fetchrow_hashref()) {
292        $self->base->log(LA_DEBUG, "Checking if employment %s is impacted by managedBy change", $res->{name});
293        my $employment = $self->base->get_object('employment', $res->{name}) or next;
294        $employment->get_attributes('managerContact') and next;
295        my $dpmt  = $employment->_get_attributes('department') or next;
296        my $odmpt = $employment->base->get_object('group', $dpmt) or next;
297        my $manager = $odmpt->get_attributes('managedBy') or next;
298        my $user = $employment->get_attributes('user');
299        my $ouser = $employment->base->get_object('user', $user) or next;
300        $self->base->log(LA_DEBUG, "Updating manager to $manager for user $user due to dpmt update");
301        $ouser->ReportChange(
302            'Update', 'Attr manager updated to match Dpmt manager %s (%s)',
303            $manager,
304            $dpmt,
305        );
306        $ouser->set_fields('manager', $manager);
307    }
308
309    return 1;
310}
311
3121;
313
314__END__
315
316=head1 SEE ALSO
317
318L<LATMOS::Accounts::Bases::Sql>
319
320=head1 AUTHOR
321
322Olivier Thauvin, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>
323
324=head1 COPYRIGHT AND LICENSE
325
326Copyright (C) 2008, 2009 CNRS SA/CETP/LATMOS
327
328This library is free software; you can redistribute it and/or modify
329it under the same terms as Perl itself, either Perl version 5.10.0 or,
330at your option, any later version of Perl 5 you may have available.
331
332=cut
Note: See TracBrowser for help on using the repository browser.