source: LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/User.pm @ 414

Last change on this file since 414 was 414, checked in by nanardon, 15 years ago
  • allow to set forward attribute from user object (create an aliases object in background)
  • Property svn:keywords set to Id Rev
File size: 11.0 KB
Line 
1package LATMOS::Accounts::Bases::Sql::User;
2
3use 5.010000;
4use strict;
5use warnings;
6
7use LATMOS::Accounts::Utils;
8use LATMOS::Accounts::Log;
9use base qw(LATMOS::Accounts::Bases::Sql::objects);
10
11our $VERSION = (q$Rev$ =~ /^Rev: (\d+) /)[0];
12
13=head1 NAME
14
15LATMOS::Ad - Perl extension for blah blah blah
16
17=head1 SYNOPSIS
18
19  use LATMOS::Accounts::Bases;
20  my $base = LATMOS::Accounts::Bases->new('sql');
21  ...
22
23=head1 DESCRIPTION
24
25Account base access over standard unix file format.
26
27=head1 FUNCTIONS
28
29=cut
30
31=head2 new(%options)
32
33Create a new LATMOS::Ad object for windows AD $domain.
34
35domain / server: either the Ad domain or directly the server
36
37ldap_args is an optionnal list of arguments to pass to L<Net::LDAP>.
38
39=cut
40
41sub object_table { 'user' }
42
43sub key_field { 'name' }
44
45sub has_extended_attributes { 1 }
46
47sub _delayed_fields {
48    my ($self)= @_;
49    return qw(memberOf manager directReports);
50}
51
52sub _office_address_fields { qw(telephoneNumber physicalDeliveryOfficeName site) }
53
54sub _inline_fields {
55    my ($class, $for, $base) = @_;
56    return (
57        $class->SUPER::_inline_fields($for, $base),
58        uidNumber => 'uidnumber',
59        gidNumber => 'gidnumber',
60    );
61}
62
63sub _managed_fields {
64    my ($self, $for, $base) = @_;
65    return (
66        memberOf        => 'memberOf',
67        forward => 'forward',
68        (map { $_ => $_ } $self->_address_fields),
69        (map { $_ => $_ } $self->_office_address_fields),
70        (($for !~ /w/) ? (
71        uid => 'name',
72        cn => 'name',
73        gecos        => 'gecos',
74        displayName  => 'displayName',
75        sAMAccountName  => 'sAMAccountName',
76        accountExpires => 'accountExpires',
77        shadowExpire => 'shadowExpire',
78        directReports => 'directReports',
79        managedObjects => 'managedObjects',
80        department => 'department',
81        otheraddress => 'otheraddress',
82        mainaddress => 'mainaddress',
83        aliases => 'aliases',
84        revaliases => 'revaliases',
85        ) : ()),
86    )
87}
88
89sub get_field {
90    my ($self, $field) = @_;
91    if ($field eq 'gecos') {
92        return to_ascii(
93            join(' ', grep { $_ } ($self->_get_c_field('givenName'), ($self->_get_c_field('sn'))))
94        ) || to_ascii($self->_get_c_field('description'));
95    } elsif ($field eq 'displayName') {
96        return join(' ', grep { $_ } ($self->_get_c_field('givenName'), ($self->_get_c_field('sn'))))
97            || $self->id;
98    } elsif ($field eq 'sAMAccountName') {
99        return $self->id;
100    } elsif ($field eq 'memberOf') {
101        my $sth = $self->db->prepare_cached(
102            q{
103            select name from "group" join
104            group_attributes_users on group_attributes_users.okey = "group".ikey
105            where value = ? and attr = ?
106            }
107        );
108        $sth->execute($self->id, 'memberUID');
109        my @res;
110        while (my $res = $sth->fetchrow_hashref) {
111            push(@res, $res->{name});
112        }
113        return \@res;
114    } elsif ($field eq 'directReports') {
115        my $sth = $self->db->prepare_cached(
116            q{
117            select name from "user" join
118            user_attributes on user_attributes.okey = "user".ikey
119            where value = ? and attr = ?
120            }
121        );
122        $sth->execute($self->id, 'manager');
123        my @res;
124        while (my $res = $sth->fetchrow_hashref) {
125            push(@res, $res->{name});
126        }
127        return \@res;
128    } elsif ($field eq 'department') {
129        my $sth = $self->db->prepare_cached(
130            q{
131            select name from "group" join
132            group_attributes on "group".ikey = group_attributes.okey
133            where okey in (select okey from group_attributes_users where value = ?)
134            and attr = ? and value = ?
135            }
136        );
137        $sth->execute($self->id, 'sutype', 'dpmt');
138        my @res;
139        while (my $res = $sth->fetchrow_hashref) {
140            push(@res, $res->{name});
141        }
142        return join(',', @res);
143    } elsif ($field eq 'managedObjects') {
144        my $sth = $self->db->prepare_cached(
145            q{
146            select name from "group" join
147            group_attributes on group_attributes.okey = "group".ikey
148            where value = ? and attr = ?
149            }
150        );
151        $sth->execute($self->id, 'managedBy');
152        my @res;
153        while (my $res = $sth->fetchrow_hashref) {
154            push(@res, $res->{name});
155        }
156        return \@res;
157    } elsif ($field eq 'accountExpires') {
158        my $sth = $self->db->prepare_cached(
159            sprintf(
160                q{select extract(epoch from expire) + 11644474161 as expire
161                from %s where %s = ?},
162                $self->db->quote_identifier($self->object_table),
163                $self->db->quote_identifier($self->key_field),
164            )
165        );
166        $sth->execute($self->id);
167        my $res = $sth->fetchrow_hashref;
168        $sth->finish;
169        return $res->{expire} ? sprintf("%.f", $res->{expire} * 1E7) : '9223372036854775807';
170    } elsif ($field eq 'shadowExpire') {
171        my $sth = $self->db->prepare_cached(
172            sprintf(
173                q{select justify_hours(expire - '1/1/1970'::timestamp) as expire
174                from %s where %s = ?},
175                $self->db->quote_identifier($self->object_table),
176                $self->db->quote_identifier($self->key_field),
177            )
178        );
179        $sth->execute($self->id);
180        my $res = $sth->fetchrow_hashref;
181        $sth->finish;
182        return -1 unless($res->{expire});
183        $res->{expire} =~ /(\d+) days\s*(\w)?/;
184        return $1 + ($2 ? 1 : 0);
185    } elsif ($field eq 'otheraddress') {
186        my $sth = $self->db->prepare_cached(q{
187            select name from address where "user" = ?
188        });
189        $sth->execute($self->id);
190        my @values;
191        while (my $res = $sth->fetchrow_hashref) {
192            push(@values, $res->{name});
193        }
194        return \@values;
195    } elsif ($field eq 'mainaddress') {
196        my $sth = $self->db->prepare_cached(q{
197            select name from address join address_attributes on ikey = okey
198            where "user" = ? and attr = 'isMainAddress'
199            });
200        $sth->execute($self->id);
201        my $res = $sth->fetchrow_hashref;
202        $sth->finish;
203        return $res->{name};
204    } elsif (grep { $field eq $_ } __PACKAGE__->_address_fields(), $self->_office_address_fields) {
205        if (my $fmainaddress = $self->get_c_field('mainaddress')) {
206            my $address = $self->base->get_object('address', $fmainaddress);
207            if ($address) {
208                return $address->get_c_field($field);
209            } else { # can't happend
210                return;
211            }
212        } else {
213            return $self->SUPER::get_field($field);
214        }
215    } elsif ($field eq 'aliases') {
216        my $sth = $self->db->prepare(q{
217            select name from aliases where forward = ?
218        } . ($self->base->{wexported} ? '' : 'and exported = true'));
219        $sth->execute($self->id);
220        my @values;
221        while (my $res = $sth->fetchrow_hashref) {
222            push(@values, $res->{name});
223        }
224        return \@values;
225    } elsif ($field eq 'forward') {
226        my $sth = $self->db->prepare(q{
227            select forward from aliases where name = ?
228        } . ($self->base->{wexported} ? '' : ' and exported = true'));
229        $sth->execute($self->id);
230        my $res = $sth->fetchrow_hashref;
231        $sth->finish;
232        return $res->{forward}
233    } elsif ($field eq 'revaliases') {
234        my $sth = $self->db->prepare(q{
235            select "as" from revaliases where name = ?
236        } . ($self->base->{wexported} ? '' : ' and exported = true'));
237        $sth->execute($self->id);
238        my $res = $sth->fetchrow_hashref;
239        $sth->finish;
240        return $res->{as}
241    } else {
242        return $self->SUPER::get_field($field);
243    }
244}
245
246sub set_fields {
247    my ($self, %data) = @_;
248    my %fdata;
249    my $res = 0;
250    foreach my $attr (keys %data) {
251        $attr =~ /^memberOf$/ and do {
252            my %member;
253            foreach (@{ $self->get_field('memberOf') }) {
254                $member{$_}{c} = 1;
255            }
256            foreach (ref $data{$attr} ? @{ $data{$attr} || []} : $data{$attr}) {
257                $member{$_}{n} = 1;
258            }
259
260            foreach (keys %member) {
261                $member{$_}{c} && $member{$_}{n} and next; # no change !
262                my $group = $self->base->get_object('group', $_) or next;
263                if ($member{$_}{n}) {
264                    my $sth = $self->db->prepare_cached(
265                        q{insert into group_attributes_users (value, attr, okey) values (?,?,?)}
266                    );
267                    $sth->execute($self->id, 'memberUID', $group->_get_ikey);
268                    $res++;
269                } elsif ($member{$_}{c}) {
270                    my $sth = $self->db->prepare_cached(
271                        q{delete from group_attributes_users where value = ? and attr = ? and okey = ?}
272                    );
273                    $sth->execute($self->id, 'memberUID', $group->_get_ikey);
274                    $res++;
275                } # else {} # can't happend
276            }
277            next;
278        };
279        $attr =~ /^forward$/ and do {
280            if ($data{$attr}) {
281                if (my $f = $self->base->get_object('aliases', $self->id)) {
282                    $res += $f->set_c_fields(forward => $data{$attr});
283                } else {
284                    $self->base->create_c_object('aliases', $self->id,
285                        forward => $data{$attr}) and $res++;
286                }
287            } else {
288                $self->base->delete_object('aliases', $self->id);
289                $res++;
290            }
291            next;
292        };
293        grep { $attr eq $_ } (__PACKAGE__->_office_address_fields, __PACKAGE__->_address_fields()) and do {
294            my $fmainaddress = $self->_get_c_field('mainaddress');
295            if (!$fmainaddress) {
296                $fmainaddress = $self->id . '-' . join('', map { ('a'..'z')[rand(26)] }
297                (0..4));
298                $self->base->create_c_object(
299                    'address', $fmainaddress,
300                    user => $self->id,
301                    isMainAddress => 1, ) or do {
302                    $self->base->log(LA_ERR,
303                        "Cannot create main address for user %s", $self->id);
304                    return;
305                };
306            }
307            if (my $address = $self->base->get_object('address', $fmainaddress)) {
308                $res += $address->set_c_fields($attr => $data{$attr});
309            }
310            next;
311        };
312        $fdata{$attr} = $data{$attr} || undef;
313    }
314    if (keys %fdata) {
315        return $self->SUPER::set_fields(%fdata) + $res;
316    } else { return $res; }
317}
318
319
3201;
321
322__END__
323
324=head1 SEE ALSO
325
326=head1 AUTHOR
327
328Olivier Thauvin, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>
329
330=head1 COPYRIGHT AND LICENSE
331
332Copyright (C) 2008, 2009 CNRS SA/CETP/LATMOS
333
334This library is free software; you can redistribute it and/or modify
335it under the same terms as Perl itself, either Perl version 5.10.0 or,
336at your option, any later version of Perl 5 you may have available.
337
338
339=cut
Note: See TracBrowser for help on using the repository browser.