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

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

Strip domain when fetching zimbra aliases

File size: 7.1 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
157    my @values = ();
158
159    foreach my $key (keys %data) {
160        foreach my $val (ref $data{$key} ? @{ $data{$key} } : $data{$key}) {
161            push(@values, SOAP::Data->name('a')
162                ->attr({ 'n' => $key })
163                ->value($val)
164            );
165        }
166    }
167
168    my $xpath = $base->soapcall(
169        'CreateAccountRequest',
170        SOAP::Data->name('name')->value($id . '@' . $base->{domain}),
171        SOAP::Data->name('password')->value($pass),
172        @values,
173    );
174
175}
176
177sub _delete {
178    my ($class, $base, $id) = @_;
179
180    my $user = $base->get_object('user', $id) or do {
181        $base->log(LA_ERR, "Cannot get user $id");
182        return;
183    };
184
185    my $xpath = $base->soapcall(
186        'DeleteAccountRequest',
187        SOAP::Data->name('id')->value($user->{zinfo}{zid}),
188    );
189
190}
191
192sub _lists_account {
193    my ($class, $base) = @_;
194
195    my $xpath = $base->soapcall(
196        'GetAllAccountsRequest',
197        SOAP::Data->name('domain')->value($base->{domain})->attr({ by => 'name' }),
198    ) or do {
199        la_log(LA_ERR, "Error while trying to get users list");
200        return;
201    };
202
203    my %users;
204    foreach my $node ($xpath->findnodes('//account')) {
205        my $name = $node->getAttribute('name');
206        foreach ($node->getChildNodes) {
207            $_->getAttribute('n') eq 'uid' and do {
208                $users{$_->string_value} = $name;
209                last;
210            };
211        }
212    }
213
214    %users
215}
216
217sub _get_info {
218    my ($self) = @_;
219
220    my $xpath = $self->base->soapcall(
221        'GetAccountRequest',
222        SOAP::Data->name('account')->value($self->{name})->attr({ by => 'name' }),
223    ) or return;
224    require Data::Dumper;
225    #print Data::Dumper::Dumper($xpath);
226
227    my ($accountnode) = $xpath->findnodes('//account');
228
229    $self->{zinfo}{zid} = $accountnode->getAttribute('id');
230
231    foreach my $node ($xpath->findnodes('//a')) {
232        my $attr = $node->getAttribute('n');
233        if ($self->{zinfo}{$attr}) {
234            if (!ref $self->{zinfo}{$attr}) {
235                my $buf = $self->{zinfo}{$attr};
236                $self->{zinfo}{$attr} = [ $buf, $node->string_value ];
237            } else {
238                push(@{ $self->{zinfo}{$attr} }, $node->string_value);
239            }   
240        } else {
241            $self->{zinfo}{$attr} = $node->string_value;
242        }
243    }
244}
245
246sub list {
247    my ($class, $base) = @_;
248
249    my %users = $class->_lists_account($base);
250    return sort keys(%users);
251}
252
2531;
254
255__END__
256
257=head1 SEE ALSO
258
259=head1 AUTHOR
260
261Olivier Thauvin, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>
262
263=head1 COPYRIGHT AND LICENSE
264
265Copyright (C) 2008, 2009 CNRS SA/CETP/LATMOS
266
267This library is free software; you can redistribute it and/or modify
268it under the same terms as Perl itself, either Perl version 5.10.0 or,
269at your option, any later version of Perl 5 you may have available.
270
271=cut
Note: See TracBrowser for help on using the repository browser.