source: LATMOS-Accounts/lib/LATMOS/Accounts/Maintenance.pm @ 789

Last change on this file since 789 was 789, checked in by vivat, 14 years ago

Changement pour avoir "Nom Prenom" au lieu de "Prenom Nom"

  • Property svn:keywords set to Id Rev
File size: 7.0 KB
Line 
1package LATMOS::Accounts::Maintenance;
2
3use strict;
4use warnings;
5use base qw(LATMOS::Accounts);
6use LATMOS::Accounts::Log;
7use FindBin qw($Bin);
8use Crypt::RSA;
9use Crypt::RSA::Key::Public::SSH;
10use Crypt::RSA::Key::Private::SSH;
11use MIME::Base64;
12
13sub _base {
14    my ($self) = @_;
15    my $base = $self->SUPER::default_base;
16    $base->type eq 'sql' or die "This module work only with SQL base type\n";
17    $base
18}
19
20sub find_next_expire_users {
21    my ($self, $expire) = @_;
22    my $base = $self->_base;
23
24    my $sth= $base->db->prepare(q{
25        select name, justify_hours(expire - now()) as delay from "user" where
26            expire < now() + ?::interval
27            and expire > now()
28            and expire is not null
29            and exported = True
30            order by expire
31        }
32    );
33    $sth->execute($expire || '1 month');
34    my @users;
35    while (my $res = $sth->fetchrow_hashref) {
36        $res->{delay} =~ s/ day.? .*//;
37        $res->{obj} = $base->get_object('user', $res->{name});
38        $res->{obj}->get_attributes('locked') and next;
39        push(@users, $res);
40    }
41    @users
42}
43
44=head2 warn_next_expire_users(%options)
45
46Send a mail to user having account expiring soon
47
48C<%options are>
49
50=over 4
51
52=item users => []
53
54Warn only this users (if need)
55
56=item to
57
58Send the only to this person.
59
60=back
61
62=cut
63
64sub warn_next_expire_users {
65    my ($self, %options) = @_;
66
67    require Mail::Sendmail;
68    require Template;
69    my $template = Template->new(
70        INCLUDE_PATH => [
71            ($self->val('_default_', 'templatespath')
72               ? $self->val('_default_', 'templatespath') . '/mail'
73               : ()),
74            "$FindBin::Bin/../templates" . '/mail',
75            '/usr/share/latmos-accounts/templates/mail',
76        ],
77        POST_CHOMP   => 1,
78        EXTENSION    => '.mail',
79    );
80    my @summary;
81    foreach my $user ($self->find_next_expire_users($options{delay})) {
82        if ($options{users} && ! grep { $_ eq $user->{name} } @{$options{users}}) {
83            next;
84        }
85        my %mail = (
86            From => $self->val('_default_', 'mailFrom', 'nomail@localhost'),
87            Subject => 'LATMOS Expire in ' . $user->{delay} . 'days',
88            smtp => $self->val('_default_', 'smtp'),
89            'Content-Type' => 'text/plain; charset=utf-8',
90            'X-LATMOS-Accounts' => '$Rev$',
91            'X-LATMOS-Reason' => 'Account expiration',
92        );
93        my ($manager, $mail) = ($user->{obj}->get_c_field('managerContact'),
94            $user->{obj}->get_c_field('mail'));
95        my $managermail = $manager ? $user->{obj}->base->
96            get_object('user', $manager)->get_c_field('mail') : undef;
97 
98        # if user have no mail, mail only to manager, avoiding empty To
99        # NB: at time, for testing purpose, mail is not really sent
100        my ($to, @cc) = grep { $_ } ($mail, $managermail,
101            $self->val('_default_', 'allwayscc'));
102        if ($options{to}) {
103            $mail{to} = $options{to};
104        } else {
105            $mail{to} = $to;
106            $mail{cc} = join(', ', @cc);
107        }
108        $mail{to} or do {
109            la_log(LA_ERR, 
110                "Cannot send expiration for `%s', no mail to send to",
111                $user->{obj}->id,
112            );
113            next;
114        };
115        my $mailcc = join(', ', @cc) || '';
116        push(@summary, sprintf("%s : %s : %s\n",
117                $user->{obj}->queryformat('%{sn} %{givenName} : %{name} : %{department} : %{managerContact} : %{expireText}'),
118                $to || 'Not sent, no destination',
119                ($mailcc ? $mailcc : ''),
120            )
121        );
122        my $message;
123        $template->process('account_expire.mail', $user, \$message)
124            or do {
125                la_log(LA_ERR, "Cannot send expiration mail: %s, exiting",
126                    $template->error());
127                exit(1);
128            };
129
130        if (!$options{test}) {
131            if (Mail::Sendmail::sendmail(
132                    %mail,
133                    Message => $message,
134                )) {
135                la_log(LA_NOTICE, "Expiration mail for %s (%s) sent to %s; cc %s",
136                    $user->{obj}->id,
137                    $user->{delay},
138                    $mail{to}, ($mail{cc} || ''));
139                if ($options{to}) {
140                    la_log(LA_NOTICE,"\tbut sent to %s", $mail{to});
141                }
142            } else {
143                la_log(LA_ERR, "Cannot send mail: %s", $Mail::Sendmail::error);
144            }
145        }
146    }
147
148    if (@summary) {
149        if ($options{test}) {
150            print join('', @summary);
151        } else {
152            if ($self->val('_default_', 'expire_summary_to')) {
153                my %mail = (
154                    From => $self->val('_default_', 'mailFrom', 'nomail@localhost'),
155                    Subject => 'LATMOS account expiration summary',
156                    smtp => $self->val('_default_', 'smtp'),
157                    'Content-Type' => 'text/plain; charset=utf-8',
158                    'X-LATMOS-Accounts' => '$Rev$',
159                    'X-LATMOS-Reason' => 'Account expiration',
160                    To => $self->val('_default_', 'expire_summary_to'),
161                );
162                if (Mail::Sendmail::sendmail(
163                        %mail,
164                        Message => join('', @summary),
165                    )) {
166                    la_log(LA_NOTICE, "Expiration summary mail sent to %s",
167                        $self->val('_default_', 'expire_summary_to'),
168                    );
169                } else {
170                    la_log(LA_ERR, "Cannot send mail: %s", $Mail::Sendmail::error);
171                }
172            }
173        }
174    }
175
176    1;
177}
178
179sub generate_rsa_key {
180    my ($self, $password) = @_;
181   
182    my $rsa = new Crypt::RSA ES => 'PKCS1v15';
183    my ($public, $private) = $rsa->keygen (
184        Identity  => 'LATMOS-Accounts',
185        Size      => 768,
186        Password  => $password,
187        Verbosity => 0,
188        KF=>'SSH',
189    ) or die
190    $self->rsa->errstr(); # TODO avoid die
191    return ($public, $private);
192}
193
194sub store_rsa_key {
195    my ($self, $public, $private) = @_;
196    my $base = $self->_base;
197    $base->set_global_value('rsa_private_key',
198        encode_base64($private->serialize));
199    $base->set_global_value('rsa_public_key',
200        $public->serialize);
201    return;
202}
203
204sub private_key {
205    my ($self, $password) = @_;
206    my $base = $self->_base;
207    my $serialize = $base->get_global_value('rsa_private_key') or return;
208    my $privkey = Crypt::RSA::Key::Private::SSH->new;
209    $privkey->deserialize(String => [ decode_base64($serialize) ],
210        Passphrase => $password);
211    $privkey
212}
213
214sub get_rsa_password {
215    my ($self) = @_;
216    my $base = $self->_base;
217    my $sth = $base->db->prepare(q{
218        select "name", value from "user" join user_attributes_base
219        on "user".ikey = user_attributes_base.okey
220        where user_attributes_base.attr = 'encryptedPassword'
221    });
222    $sth->execute;
223    my %users;
224    while (my $res = $sth->fetchrow_hashref) {
225        $users{$res->{name}} = $res->{value};
226    }
227    %users
228}
229
2301;
Note: See TracBrowser for help on using the repository browser.