source: trunk/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Zimbra/User.pm @ 2271

Last change on this file since 2271 was 2271, checked in by nanardon, 5 years ago

Zimbra: sn is mandatory, using id as default

File size: 7.2 KB
Line 
1package LATMOS::Accounts::Bases::Zimbra::User;
2
3use 5.010000;
4use strict;
5use warnings;
6use overload '""' => 'stringify';
7
8use LATMOS::Accounts::Log;
9use LATMOS::Accounts::Utils;
10use base qw(LATMOS::Accounts::Bases::Objects);
11use SOAP::Lite;
12
13our $VERSION = (q$Rev$ =~ /^Rev: (\d+) /)[0];
14
15=head1 NAME
16
17LATMOS::Ad - Perl extension for blah blah blah
18
19=head1 DESCRIPTION
20
21Account base access over standard unix file format.
22
23=head1 FUNCTIONS
24
25=cut
26
27sub _get_attr_schema {
28    my ($class, $base) = @_;
29
30    {
31        name => {
32            ro => 1,
33            get => sub {
34                my ($self) = @_;
35                return $self->object->{name}
36            },
37        },
38        zid => { ro => 1, }, # Zimbra internal id
39        uid => { ro => 1, },
40        cn => { },
41        sn => { },
42        givenName => { },
43        mail => { ro => 1, },
44        displayName => { },
45        objectClass => { ro => 1, multiple => 1, },
46        zimbraMailDeliveryAddress => { multiple => 1, ro => 1, },
47        zimbraMailAlias => { 
48            multiple => 1,
49            ro => 1,
50        },
51        aliases => {
52            multiple => 1,
53            get => sub {
54                my ($self) = @_;
55                my $domain = $self->object->base->{domain};
56                return [
57                    map { s/@\Q$domain\E$//; $_ }
58                    ref $self->object->{zinfo}{zimbraMailAlias}
59                        ? @{ $self->object->{zinfo}{zimbraMailAlias} }
60                        : $self->object->{zinfo}{zimbraMailAlias}
61                ]
62            },
63            set => sub {
64                my ($self, $data) = @_;
65                my @zimbraMailAlias = ref $self->object->{zinfo}{zimbraMailAlias}
66                    ? @{ $self->object->{zinfo}{zimbraMailAlias} }
67                    : $self->object->{zinfo}{zimbraMailAlias};
68                my %currentalias = map { $_ => 1 } grep { $_ } @zimbraMailAlias;
69                my %newalias;
70                foreach (grep { $_ } (ref $data ? @{$data} : $data)) {
71                    # Adding domain to unqualified aliases
72                    $_ =~ /@/ or $_ .= '@' . $self->object->base->{domain};
73                    $newalias{lc($_)} = 1;
74                }
75                foreach (keys %currentalias) {
76                    $newalias{$_} and next;
77                    my $xpath = $self->object->base->soapcall(
78                        'RemoveAccountAliasRequest',
79                        SOAP::Data->name('id')->value($self->object->{zinfo}{zid}),
80                        SOAP::Data->name('alias')->value($_),
81                    ) or do {
82                        $self->object->base->la_log('Cannot remove alias $_');
83                        return;
84                    };
85                }
86                foreach (keys %newalias) {
87                    $currentalias{$_} and next;
88                    my $xpath = $self->object->base->soapcall(
89                        'AddAccountAliasRequest',
90                        SOAP::Data->name('id')->value($self->object->{zinfo}{zid}),
91                        SOAP::Data->name('alias')->value($_),
92                    ) or do {
93                        $self->object->base->la_log('Cannot add alias $_');
94                        return;
95                    };
96                }
97            }
98        },
99        zimbraCOSId => { },
100    }
101}
102
103sub new {
104    my ($class, $base, $id) = @_;
105
106    my %users = $class->_lists_account($base);
107
108    if (!$users{$id}) {
109        la_log(LA_DEBUG, "Cannot find user $id");
110        return;
111    } else {
112        my $user = bless {
113            _id => $id,
114            name => $users{$id},
115            _base => $base,
116        }, $class;
117        $user->_get_info();
118        return $user;
119    }
120}
121
122sub get_field {
123    my ($self, $field) = @_;
124
125    my $attribute = $self->attribute($field) or return;
126
127    return $self->{zinfo}{$field};
128}
129
130sub set_fields {
131    my ($self, %data) = @_;
132
133    my @values = ();
134
135    foreach my $key (keys %data) {
136        foreach my $val (ref $data{$key} ? @{ $data{$key} } : $data{$key}) {
137            push(@values, SOAP::Data->name('a')
138                ->attr({ 'n' => $key })
139                ->value($val)
140            );
141        }
142    }
143
144    my $xpath = $self->base->soapcall(
145        'ModifyAccountRequest',
146        SOAP::Data->name('id')->value($self->{zinfo}{zid}),
147        @values,
148    );
149
150}
151
152sub _create {
153    my ($class, $base, $id, %data) = @_;
154
155    my $pass = LATMOS::Accounts::Utils::genpassword();
156    $data{sn} ||= $id;
157
158    my @values = ();
159
160    foreach my $key (keys %data) {
161        foreach my $val (ref $data{$key} ? @{ $data{$key} } : $data{$key}) {
162            push(@values, SOAP::Data->name('a')
163                ->attr({ 'n' => $key })
164                ->value($val)
165            );
166        }
167    }
168
169    my $xpath = $base->soapcall(
170        'CreateAccountRequest',
171        SOAP::Data->name('name')->value($id . '@' . $base->{domain}),
172        SOAP::Data->name('password')->value($pass),
173        @values,
174    );
175
176}
177
178sub _delete {
179    my ($class, $base, $id) = @_;
180
181    my $user = $base->get_object('user', $id) or do {
182        $base->log(LA_ERR, "Cannot get user $id");
183        return;
184    };
185
186    my $xpath = $base->soapcall(
187        'DeleteAccountRequest',
188        SOAP::Data->name('id')->value($user->{zinfo}{zid}),
189    );
190
191}
192
193sub _lists_account {
194    my ($class, $base) = @_;
195
196    my $xpath = $base->soapcall(
197        'GetAllAccountsRequest',
198        SOAP::Data->name('domain')->value($base->{domain})->attr({ by => 'name' }),
199    ) or do {
200        la_log(LA_ERR, "Error while trying to get users list");
201        return;
202    };
203
204    my %users;
205    foreach my $node ($xpath->findnodes('//account')) {
206        my $name = $node->getAttribute('name');
207        foreach ($node->getChildNodes) {
208            $_->getAttribute('n') eq 'uid' and do {
209                $users{$_->string_value} = $name;
210                last;
211            };
212        }
213    }
214
215    %users
216}
217
218sub _get_info {
219    my ($self) = @_;
220
221    my $xpath = $self->base->soapcall(
222        'GetAccountRequest',
223        SOAP::Data->name('account')->value($self->{name})->attr({ by => 'name' }),
224    ) or return;
225    require Data::Dumper;
226    #print Data::Dumper::Dumper($xpath);
227
228    my ($accountnode) = $xpath->findnodes('//account');
229
230    $self->{zinfo}{zid} = $accountnode->getAttribute('id');
231
232    foreach my $node ($xpath->findnodes('//a')) {
233        my $attr = $node->getAttribute('n');
234        if ($self->{zinfo}{$attr}) {
235            if (!ref $self->{zinfo}{$attr}) {
236                my $buf = $self->{zinfo}{$attr};
237                $self->{zinfo}{$attr} = [ $buf, $node->string_value ];
238            } else {
239                push(@{ $self->{zinfo}{$attr} }, $node->string_value);
240            }   
241        } else {
242            $self->{zinfo}{$attr} = $node->string_value;
243        }
244    }
245}
246
247sub list {
248    my ($class, $base) = @_;
249
250    my %users = $class->_lists_account($base);
251    return sort keys(%users);
252}
253
2541;
255
256__END__
257
258=head1 SEE ALSO
259
260=head1 AUTHOR
261
262Olivier Thauvin, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>
263
264=head1 COPYRIGHT AND LICENSE
265
266Copyright (C) 2008, 2009 CNRS SA/CETP/LATMOS
267
268This library is free software; you can redistribute it and/or modify
269it under the same terms as Perl itself, either Perl version 5.10.0 or,
270at your option, any later version of Perl 5 you may have available.
271
272=cut
Note: See TracBrowser for help on using the repository browser.