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

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

aliases are all lowercase in zimbra db

File size: 7.0 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                return ref $self->object->{zinfo}{zimbraMailAlias}
56                    ? @{ $self->object->{zinfo}{zimbraMailAlias} }
57                    : $self->object->{zinfo}{zimbraMailAlias};
58            },
59            set => sub {
60                my ($self, $data) = @_;
61                my @zimbraMailAlias = ref $self->object->{zinfo}{zimbraMailAlias}
62                    ? @{ $self->object->{zinfo}{zimbraMailAlias} }
63                    : $self->object->{zinfo}{zimbraMailAlias};
64                my %currentalias = map { $_ => 1 } grep { $_ } @zimbraMailAlias;
65                my %newalias;
66                foreach (grep { $_ } (ref $data ? @{$data} : $data)) {
67                    # Adding domain to unqualified aliases
68                    $_ =~ /@/ or $_ .= '@' . $self->object->base->{domain};
69                    $newalias{lc($_)} = 1;
70                }
71                foreach (keys %currentalias) {
72                    $newalias{$_} and next;
73                    my $xpath = $self->object->base->soapcall(
74                        'RemoveAccountAliasRequest',
75                        SOAP::Data->name('id')->value($self->object->{zinfo}{zid}),
76                        SOAP::Data->name('alias')->value($_),
77                    ) or do {
78                        $self->object->base->la_log('Cannot remove alias $_');
79                        return;
80                    };
81                }
82                foreach (keys %newalias) {
83                    $currentalias{$_} and next;
84                    my $xpath = $self->object->base->soapcall(
85                        'AddAccountAliasRequest',
86                        SOAP::Data->name('id')->value($self->object->{zinfo}{zid}),
87                        SOAP::Data->name('alias')->value($_),
88                    ) or do {
89                        $self->object->base->la_log('Cannot add alias $_');
90                        return;
91                    };
92                }
93            }
94        },
95        zimbraCOSId => { },
96    }
97}
98
99sub new {
100    my ($class, $base, $id) = @_;
101
102    my %users = $class->_lists_account($base);
103
104    if (!$users{$id}) {
105        la_log(LA_DEBUG, "Cannot find user $id");
106        return;
107    } else {
108        my $user = bless {
109            _id => $id,
110            name => $users{$id},
111            _base => $base,
112        }, $class;
113        $user->_get_info();
114        return $user;
115    }
116}
117
118sub get_field {
119    my ($self, $field) = @_;
120
121    my $attribute = $self->attribute($field) or return;
122
123    return $self->{zinfo}{$field};
124}
125
126sub set_fields {
127    my ($self, %data) = @_;
128
129    my @values = ();
130
131    foreach my $key (keys %data) {
132        foreach my $val (ref $data{$key} ? @{ $data{$key} } : $data{$key}) {
133            push(@values, SOAP::Data->name('a')
134                ->attr({ 'n' => $key })
135                ->value($val)
136            );
137        }
138    }
139
140    my $xpath = $self->base->soapcall(
141        'ModifyAccountRequest',
142        SOAP::Data->name('id')->value($self->{zinfo}{zid}),
143        @values,
144    );
145
146}
147
148sub _create {
149    my ($class, $base, $id, %data) = @_;
150
151    my $pass = LATMOS::Accounts::Utils::genpassword();
152
153    my @values = ();
154
155    foreach my $key (keys %data) {
156        foreach my $val (ref $data{$key} ? @{ $data{$key} } : $data{$key}) {
157            push(@values, SOAP::Data->name('a')
158                ->attr({ 'n' => $key })
159                ->value($val)
160            );
161        }
162    }
163
164    my $xpath = $base->soapcall(
165        'CreateAccountRequest',
166        SOAP::Data->name('name')->value($id . '@' . $base->{domain}),
167        SOAP::Data->name('password')->value($pass),
168        @values,
169    );
170
171}
172
173sub _delete {
174    my ($class, $base, $id) = @_;
175
176    my $user = $base->get_object('user', $id) or do {
177        $base->log(LA_ERR, "Cannot get user $id");
178        return;
179    };
180
181    my $xpath = $base->soapcall(
182        'DeleteAccountRequest',
183        SOAP::Data->name('id')->value($user->{zinfo}{zid}),
184    );
185
186}
187
188sub _lists_account {
189    my ($class, $base) = @_;
190
191    my $xpath = $base->soapcall(
192        'GetAllAccountsRequest',
193        SOAP::Data->name('domain')->value($base->{domain})->attr({ by => 'name' }),
194    ) or do {
195        la_log(LA_ERR, "Error while trying to get users list");
196        return;
197    };
198
199    my %users;
200    foreach my $node ($xpath->findnodes('//account')) {
201        my $name = $node->getAttribute('name');
202        foreach ($node->getChildNodes) {
203            $_->getAttribute('n') eq 'uid' and do {
204                $users{$_->string_value} = $name;
205                last;
206            };
207        }
208    }
209
210    %users
211}
212
213sub _get_info {
214    my ($self) = @_;
215
216    my $xpath = $self->base->soapcall(
217        'GetAccountRequest',
218        SOAP::Data->name('account')->value($self->{name})->attr({ by => 'name' }),
219    ) or return;
220    require Data::Dumper;
221    #print Data::Dumper::Dumper($xpath);
222
223    my ($accountnode) = $xpath->findnodes('//account');
224
225    $self->{zinfo}{zid} = $accountnode->getAttribute('id');
226
227    foreach my $node ($xpath->findnodes('//a')) {
228        my $attr = $node->getAttribute('n');
229        if ($self->{zinfo}{$attr}) {
230            if (!ref $self->{zinfo}{$attr}) {
231                my $buf = $self->{zinfo}{$attr};
232                $self->{zinfo}{$attr} = [ $buf, $node->string_value ];
233            } else {
234                push(@{ $self->{zinfo}{$attr} }, $node->string_value);
235            }   
236        } else {
237            $self->{zinfo}{$attr} = $node->string_value;
238        }
239    }
240}
241
242sub list {
243    my ($class, $base) = @_;
244
245    my %users = $class->_lists_account($base);
246    return sort keys(%users);
247}
248
2491;
250
251__END__
252
253=head1 SEE ALSO
254
255=head1 AUTHOR
256
257Olivier Thauvin, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>
258
259=head1 COPYRIGHT AND LICENSE
260
261Copyright (C) 2008, 2009 CNRS SA/CETP/LATMOS
262
263This library is free software; you can redistribute it and/or modify
264it under the same terms as Perl itself, either Perl version 5.10.0 or,
265at your option, any later version of Perl 5 you may have available.
266
267=cut
Note: See TracBrowser for help on using the repository browser.