source: branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/Group.pm @ 1284

Last change on this file since 1284 was 1284, checked in by nanardon, 9 years ago

backport changes from trunk

  • Property svn:keywords set to Id Rev
File size: 6.9 KB
Line 
1package LATMOS::Accounts::Bases::Sql::Group;
2
3use 5.010000;
4use strict;
5use warnings;
6
7use base qw(LATMOS::Accounts::Bases::Sql::objects);
8use LATMOS::Accounts::Log;
9
10our $VERSION = (q$Rev$ =~ /^Rev: (\d+) /)[0];
11
12=head1 NAME
13
14LATMOS::Accounts::Bases::Sql::Group - Groups objects support
15
16=cut
17
18sub _object_table { 'group' }
19
20sub _key_field { 'name' }
21
22sub _has_extended_attributes { 1 }
23
24sub _get_attr_schema {
25    my ($class, $base) = @_;
26
27    $class->SUPER::_get_attr_schema($base,
28        {
29            gidNumber  => { inline => 1, uniq => 1, iname => 'gidnumber',
30                mandatory => 1, },
31            gidnumber  => { inline => 1, uniq => 1, hide => 1, },
32            exported   => { inline => 1, },
33            name       => { inline => 1, ro => 1 },
34            cn         => { inline => 1, ro => 1, iname => 'name', },
35            create     => { inline => 1, ro => 1 },
36            date       => { inline => 1, ro => 1 },
37            memberUID  => {
38                hide => 1,
39                reference => 'user',
40                multiple => 1,
41                delayed => 1,
42                ro => sub {
43                    $_[0] && 
44                    (($_[0]->_get_c_field('sutype') ||'') =~ /^(jobtype|contrattype)$/
45                     || $_[0]->_get_c_field('autoMemberFilter'))
46                    ? 1 : 0 
47                },
48            },
49            member     => {
50                reference => 'user',
51                multiple => 1, 
52                delayed => 1,
53                can_values => sub { $base->list_objects('user') },
54                ro => sub {
55                    $_[0] && 
56                    (($_[0]->_get_c_field('sutype') ||'') =~ /^(jobtype|contrattype)$/
57                     || $_[0]->_get_c_field('autoMemberFilter'))
58                    ? 1 : 0 
59                },
60            },
61            sAMAccountName => { iname => 'name', ro => 1 },
62            groupname  => { ro => 1 },
63            managedBy  => {
64                notify => 1,
65                reference => 'user',
66                can_values => sub {
67                    my %uniq = map { $_ => 1 } grep { $_ }
68                    ($_[1] ? $_[1]->get_attributes('manager') : ()),
69                    $base->search_objects('user', 'active=*');
70                    sort keys %uniq;
71                },
72            },
73            managedAlsoBy  => {
74                notify => 1,
75                reference => 'user',
76                multiple => 1,
77                delayed => 1,
78                can_values => sub {
79                    my %uniq = map { $_ => 1 } grep { $_ }
80                    ($_[1] ? $_[1]->get_attributes('manager') : ()),
81                    $base->search_objects('user', 'active=*');
82                    sort keys %uniq;
83                },
84            },
85            sutype => {
86                reference => 'sutype',
87                notify => 1,
88            },
89            autoMemberFilter => {
90                multiple => 1,
91            }
92        }
93    )
94}
95
96sub get_field {
97    my ($self, $field) = @_;
98    for ($field) {
99        /^(member|memberUID)$/ and do {
100            my $sth = $self->db->prepare_cached(
101                q{
102                select value from group_attributes
103                join "group" on "group".ikey = group_attributes.okey
104                join "user" on "user".name = group_attributes.value
105                where "group".name = ? and attr = ?
106                } .
107                ($self->base->{wexported} ? '' : 'and "user".exported = true')
108            );
109            $sth->execute($self->id, 'memberUID');
110            my @res;
111            while (my $res = $sth->fetchrow_hashref) {
112                push(@res, $res->{value});
113            }
114            return \@res;
115        };
116    }
117    $self->SUPER::get_field($field);
118}
119
120sub _set_group_members {
121    my ($self, $members) = @_;
122    my %member;
123    my $res = 0;
124    foreach (@{ $self->get_field('memberUID') }) {
125        $member{$_}{c} = 1;
126    }
127    foreach (ref $members ? @{ $members || []} : $members) {
128        $_ or next; # avoid undef
129        $member{$_}{n} = 1;
130    }
131
132    foreach (keys %member) {
133        $member{$_}{c} && $member{$_}{n} and next; # no change !
134        my $user = $self->base->get_object('user', $_) or next;
135        if ($member{$_}{n}) {
136            my $sth = $self->db->prepare_cached(
137                q{insert into group_attributes_users (value, attr, okey) values (?,?,?)}
138            );
139            $sth->execute($_, 'memberUID', $self->_get_ikey);
140            $res++;
141        } elsif ($member{$_}{c}) {
142            if (($user->get_c_field('department') || '') eq $self->id) {
143                $self->base->log(LA_WARN,
144                    "Don't removing user %s from group %s: is it's department",
145                    $user->id, $self->id);
146                next;
147            }
148            my $sth = $self->db->prepare_cached(
149                q{delete from group_attributes_users where value = ? and attr = ? and okey = ?}
150            );
151            $sth->execute($_, 'memberUID', $self->_get_ikey);
152            $res++;
153        } # else {} # can't happend
154    }
155    return $res;
156}
157
158sub set_fields {
159    my ($self, %data) = @_;
160    my %fdata;
161    my $res = 0;
162    foreach my $attr (keys %data) {
163        $attr =~ /^memberUID|member$/ and do {
164            if (($self->_get_c_field('sutype') ||'') =~ /^(jobtype|contrattype)$/ ||
165                 $self->get_field('autoMemberFilter')) {
166                $self->base->log(LA_WARN,
167                    "Group %s is managed, ignoring member set request",
168                    $self->id);
169                next;
170            }
171            $self->_set_group_members($data{$attr});
172            next;
173        };
174        $fdata{$attr} = $data{$attr};
175    }
176
177    if (keys %fdata) {
178            my $setres = $self->SUPER::set_fields(%fdata);
179        if (exists($fdata{autoMemberFilter})) {
180            $res += $self->populate_dyn_group;
181        }
182            if (defined($setres)) { return $res + $setres; }
183            else { return; } 
184    } else {
185        $res
186    }
187}
188
189=head2 populate_dyn_group
190
191Synchronise group's members according filter set into C<autoMemberFilter> attribute.
192
193=cut
194
195sub populate_dyn_group {
196    my ($self) = @_;
197
198    if (!$self->get_field('autoMemberFilter')) {
199        return 0;
200    }
201    $self->base->log(LA_DEBUG,
202        "Populating group %s from autoMemberFilter attribute",
203        $self->id
204    );
205    my $filter = $self->get_field('autoMemberFilter');
206    $self->_set_group_members(
207        [ $self->base->search_objects(
208            'user',
209            ref $filter ? @{ $filter } : $filter
210        ) ]
211    )
212}
213
2141;
215
216__END__
217
218=head1 SEE ALSO
219
220L<LATMOS::Accounts::Bases::Sql>
221
222=head1 AUTHOR
223
224Olivier Thauvin, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>
225
226=head1 COPYRIGHT AND LICENSE
227
228Copyright (C) 2008, 2009 CNRS SA/CETP/LATMOS
229
230This library is free software; you can redistribute it and/or modify
231it under the same terms as Perl itself, either Perl version 5.10.0 or,
232at your option, any later version of Perl 5 you may have available.
233
234=cut
Note: See TracBrowser for help on using the repository browser.