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

Last change on this file since 1238 was 1238, checked in by nanardon, 11 years ago

don't list unxeported user as member of group

  • Property svn:keywords set to Id Rev
File size: 6.8 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                reference => 'user',
65                can_values => sub {
66                    my %uniq = map { $_ => 1 } grep { $_ }
67                    ($_[1] ? $_[1]->get_attributes('manager') : ()),
68                    $base->search_objects('user', 'active=*');
69                    sort keys %uniq;
70                },
71            },
72            managedAlsoBy  => {
73                reference => 'user',
74                multiple => 1,
75                delayed => 1,
76                can_values => sub {
77                    my %uniq = map { $_ => 1 } grep { $_ }
78                    ($_[1] ? $_[1]->get_attributes('manager') : ()),
79                    $base->search_objects('user', 'active=*');
80                    sort keys %uniq;
81                },
82            },
83            sutype => {
84                reference => 'sutype',
85            },
86            autoMemberFilter => {
87                multiple => 1,
88            }
89        }
90    )
91}
92
93sub get_field {
94    my ($self, $field) = @_;
95    for ($field) {
96        /^(member|memberUID)$/ and do {
97            my $sth = $self->db->prepare_cached(
98                q{
99                select value from group_attributes
100                join "group" on "group".ikey = group_attributes.okey
101                join "user" on "user".name = group_attributes.value
102                where "group".name = ? and attr = ?
103                } .
104                ($self->base->{wexported} ? '' : 'and "user".exported = true')
105            );
106            $sth->execute($self->id, 'memberUID');
107            my @res;
108            while (my $res = $sth->fetchrow_hashref) {
109                push(@res, $res->{value});
110            }
111            return \@res;
112        };
113    }
114    $self->SUPER::get_field($field);
115}
116
117sub _set_group_members {
118    my ($self, $members) = @_;
119    my %member;
120    my $res = 0;
121    foreach (@{ $self->get_field('memberUID') }) {
122        $member{$_}{c} = 1;
123    }
124    foreach (ref $members ? @{ $members || []} : $members) {
125        $_ or next; # avoid undef
126        $member{$_}{n} = 1;
127    }
128
129    foreach (keys %member) {
130        $member{$_}{c} && $member{$_}{n} and next; # no change !
131        my $user = $self->base->get_object('user', $_) or next;
132        if ($member{$_}{n}) {
133            my $sth = $self->db->prepare_cached(
134                q{insert into group_attributes_users (value, attr, okey) values (?,?,?)}
135            );
136            $sth->execute($_, 'memberUID', $self->_get_ikey);
137            $res++;
138        } elsif ($member{$_}{c}) {
139            if (($user->get_c_field('department') || '') eq $self->id) {
140                $self->base->log(LA_WARN,
141                    "Don't removing user %s from group %s: is it's department",
142                    $user->id, $self->id);
143                next;
144            }
145            my $sth = $self->db->prepare_cached(
146                q{delete from group_attributes_users where value = ? and attr = ? and okey = ?}
147            );
148            $sth->execute($_, 'memberUID', $self->_get_ikey);
149            $res++;
150        } # else {} # can't happend
151    }
152    return $res;
153}
154
155sub set_fields {
156    my ($self, %data) = @_;
157    my %fdata;
158    my $res = 0;
159    foreach my $attr (keys %data) {
160        $attr =~ /^memberUID|member$/ and do {
161            if (($self->_get_c_field('sutype') ||'') =~ /^(jobtype|contrattype)$/ ||
162                 $self->get_field('autoMemberFilter')) {
163                $self->base->log(LA_WARN,
164                    "Group %s is managed, ignoring member set request",
165                    $self->id);
166                next;
167            }
168            $self->_set_group_members($data{$attr});
169            next;
170        };
171        $fdata{$attr} = $data{$attr};
172    }
173
174    if (keys %fdata) {
175            my $setres = $self->SUPER::set_fields(%fdata);
176        if (exists($fdata{autoMemberFilter})) {
177            $res += $self->populate_dyn_group;
178        }
179            if (defined($setres)) { return $res + $setres; }
180            else { return; } 
181    } else {
182        $res
183    }
184}
185
186=head2 populate_dyn_group
187
188Synchronise group's members according filter set into C<autoMemberFilter> attribute.
189
190=cut
191
192sub populate_dyn_group {
193    my ($self) = @_;
194
195    if (!$self->get_field('autoMemberFilter')) {
196        return 0;
197    }
198    $self->base->log(LA_DEBUG,
199        "Populating group %s from autoMemberFilter attribute",
200        $self->id
201    );
202    my $filter = $self->get_field('autoMemberFilter');
203    $self->_set_group_members(
204        [ $self->base->search_objects(
205            'user',
206            ref $filter ? @{ $filter } : $filter
207        ) ]
208    )
209}
210
2111;
212
213__END__
214
215=head1 SEE ALSO
216
217L<LATMOS::Accounts::Bases::Sql>
218
219=head1 AUTHOR
220
221Olivier Thauvin, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>
222
223=head1 COPYRIGHT AND LICENSE
224
225Copyright (C) 2008, 2009 CNRS SA/CETP/LATMOS
226
227This library is free software; you can redistribute it and/or modify
228it under the same terms as Perl itself, either Perl version 5.10.0 or,
229at your option, any later version of Perl 5 you may have available.
230
231=cut
Note: See TracBrowser for help on using the repository browser.