]> git.proxmox.com Git - pmg-api.git/blame - PMG/RuleDB/Notify.pm
delete/deliver_quarantined_mail: use receiver instead of pmail
[pmg-api.git] / PMG / RuleDB / Notify.pm
CommitLineData
758c7b6b
DM
1package PMG::RuleDB::Notify;
2
3use strict;
4use warnings;
758c7b6b
DM
5use DBI;
6use MIME::Body;
7use MIME::Head;
8use MIME::Entity;
9
10use PVE::SafeSyslog;
11
12use PMG::Utils;
13use PMG::ModGroup;
14use PMG::RuleDB::Object;
74d48a9a 15use PMG::MailQueue;
758c7b6b
DM
16
17use base qw(PMG::RuleDB::Object);
18
19sub otype {
20 return 4002;
21}
22
23sub oclass {
24 return 'action';
25}
26
27sub otype_text {
28 return 'Notification';
29}
30
758c7b6b
DM
31sub final {
32 return 0;
33}
34
35sub priority {
36 return 89;
37}
38
39sub new {
40 my ($type, $to, $subject, $body, $attach, $ogroup) = @_;
41
42 my $class = ref($type) || $type;
43
7a2cf7e6 44 my $self = $class->SUPER::new($class->otype(), $ogroup);
758c7b6b
DM
45
46 $to //= '__ADMIN__';
47 $attach //= 'N';
48 $subject //= 'Notification: __SUBJECT__';
49
50 if (!defined($body)) {
51 $body = <<EOB;
52Proxmox Notification:
53
54Sender: __SENDER__
55Receiver: __RECEIVERS__
56Targets: __TARGETS__
57
58Subject: __SUBJECT__
59
60Matching Rule: __RULE__
61
62__RULE_INFO__
63
64__VIRUS_INFO__
65__SPAM_INFO__
66EOB
67 }
68 $self->{to} = $to;
69 $self->{subject} = $subject;
70 $self->{body} = $body;
71 $self->{attach} = $attach;
72
73 return $self;
74}
75
76sub load_attr {
77 my ($type, $ruledb, $id, $ogroup, $value) = @_;
78
79 my $class = ref($type) || $type;
80
9ef3f143 81 defined($value) || die "undefined object attribute: ERROR";
758c7b6b
DM
82
83 my ($subject, $body, $attach);
84
85 my $sth = $ruledb->{dbh}->prepare(
86 "SELECT * FROM Attribut WHERE Object_ID = ?");
87
88 $sth->execute($id);
89
90 while (my $ref = $sth->fetchrow_hashref()) {
91 $subject = $ref->{value} if $ref->{name} eq 'subject';
92 $body = $ref->{value} if $ref->{name} eq 'body';
93 $attach = $ref->{value} if $ref->{name} eq 'attach';
94 }
95
96 $sth->finish();
97
98 my $obj = $class->new($value, $subject, $body, $attach, $ogroup);
99 $obj->{id} = $id;
100
101 $obj->{digest} = Digest::SHA::sha1_hex(
ef092d10 102 $id, $obj->{to}, $obj->{subject}, $obj->{body}, $obj->{attach}, $ogroup);
758c7b6b
DM
103
104 return $obj;
105}
106
107sub save {
108 my ($self, $ruledb, $no_trans) = @_;
109
9ef3f143
DM
110 defined($self->{ogroup}) || die "undefined object attribute: ERROR";
111 defined($self->{to}) || die "undefined object attribute: ERROR";
112 defined($self->{subject}) || die "undefined object attribute: ERROR";
113 defined($self->{body}) || die "undefined object attribute: ERROR";
758c7b6b 114
aa376168
DM
115 $self->{attach} //= 'N';
116
758c7b6b
DM
117 if (defined ($self->{id})) {
118 # update
119
120 eval {
121 $ruledb->{dbh}->begin_work if !$no_trans;
122
123 $ruledb->{dbh}->do(
124 "UPDATE Object SET Value = ? WHERE ID = ?",
125 undef, $self->{to}, $self->{id});
126
127 $ruledb->{dbh}->do(
128 "UPDATE Attribut SET Value = ? " .
129 "WHERE Name = ? and Object_ID = ?",
130 undef, $self->{subject}, 'subject', $self->{id});
131
132 $ruledb->{dbh}->do(
133 "UPDATE Attribut SET Value = ? " .
134 "WHERE Name = ? and Object_ID = ?",
135 undef, $self->{body}, 'body', $self->{id});
136
137 $ruledb->{dbh}->do(
138 "UPDATE Attribut SET Value = ? " .
139 "WHERE Name = ? and Object_ID = ?",
140 undef, $self->{attach}, 'attach', $self->{id});
141
142 $ruledb->{dbh}->commit if !$no_trans;
143 };
144 if (my $err = $@) {
145 die $err if !$no_trans;
146 $ruledb->{dbh}->rollback;
147 syslog('err', $err);
148 return undef;
149 }
150
151 } else {
152 # insert
153
154 $ruledb->{dbh}->begin_work if !$no_trans;
155
156 eval {
157
158 my $sth = $ruledb->{dbh}->prepare(
159 "INSERT INTO Object (Objectgroup_ID, ObjectType, Value) " .
160 "VALUES (?, ?, ?);");
161
162 $sth->execute($self->ogroup, $self->otype, $self->{to});
163
164 $self->{id} = PMG::Utils::lastid($ruledb->{dbh}, 'object_id_seq');
165
166 $sth->finish();
167
168 $ruledb->{dbh}->do("INSERT INTO Attribut " .
169 "(Object_ID, Name, Value) " .
170 "VALUES (?, ?, ?)", undef,
171 $self->{id}, 'subject', $self->{subject});
172 $ruledb->{dbh}->do("INSERT INTO Attribut " .
173 "(Object_ID, Name, Value) " .
174 "VALUES (?, ?, ?)", undef,
175 $self->{id}, 'body', $self->{body});
176 $ruledb->{dbh}->do("INSERT INTO Attribut " .
177 "(Object_ID, Name, Value) " .
178 "VALUES (?, ?, ?)", undef,
179 $self->{id}, 'attach', $self->{attach});
180
181 $ruledb->{dbh}->commit if !$no_trans;
182 };
183 if (my $err = $@) {
184 die $err if !$no_trans;
185 $ruledb->{dbh}->rollback;
186 syslog('err', $err);
187 return undef;
188 }
189 }
190
191 return $self->{id};
192}
193
194sub execute {
195 my ($self, $queue, $ruledb, $mod_group, $targets,
196 $msginfo, $vars, $marks) = @_;
197
198 my $original;
199
200 my $from = 'postmaster';
201
202 my $body = PMG::Utils::subst_values($self->{body}, $vars);
203 my $subject = PMG::Utils::subst_values($self->{subject}, $vars);
204 my $to = PMG::Utils::subst_values($self->{to}, $vars);
205
206 if ($to =~ m/^\s*$/) {
207 # this happens if a notification is triggered by bounce mails
208 # which notifies the sender <> - we just log and then ignore it
209 syslog('info', "%s: notify <> (ignored)", $queue->{logid});
210 return;
211 }
212
213 $to =~ s/[;,]/ /g;
214 $to =~ s/\s+/,/g;
215
216 my $top = MIME::Entity->build(
217 From => $from,
218 To => $to,
219 Subject => $subject,
220 Data => $body);
221
222 if ($self->{attach} eq 'O') {
223 # attach original mail
74d48a9a
DM
224 my $spooldir = $PMG::MailQueue::spooldir;
225 my $path = "$spooldir/active/$queue->{uid}";
758c7b6b
DM
226 $original = $top->attach(
227 Path => $path,
228 Filename => "original_message.eml",
229 Type => "message/rfc822",);
230 }
231
232 if ($msginfo->{testmode}) {
233 my $fh = $msginfo->{test_fh};
234 print $fh "notify: $self->{to}\n";
235 print $fh "notify content:\n";
236
237 if ($self->{attach} eq 'O') {
238 # make result reproducable for regression testing
239 $top->head->replace('content-type',
240 'multipart/mixed; boundary="---=_1234567"');
241 }
242 $top->print ($fh);
243 print $fh "notify end\n";
244 } else {
245 my @targets = split(/\s*,\s*/, $to);
246 my $qid = PMG::Utils::reinject_mail(
247 $top, $from, \@targets, undef, $msginfo->{fqdn});
248 foreach (@targets) {
249 if ($qid) {
250 syslog('info', "%s: notify <%s> (%s)", $queue->{logid}, $_, $qid);
251 } else {
252 syslog ('err', "%s: notify <%s> failed", $queue->{logid}, $_);
253 }
254 }
255 }
256}
257
758c7b6b
DM
258sub short_desc {
259 my $self = shift;
260
261 return "notify $self->{to}";
262}
263
4cb22484
DC
264sub properties {
265 my ($class) = @_;
266
267 return {
268 to => {
269 description => "The Receiver E-Mail address",
270 type => 'string',
271 maxLength => 200,
272 },
273 subject => {
274 description => "The Notification subject",
275 type => 'string',
276 maxLength => 100,
277 },
278 attach => {
279 description => "Attach original E-Mail",
280 type => 'boolean',
281 optional => 1,
282 default => 0,
283 },
284 body => {
285 description => "The Notification Body",
286 type => 'string',
287 maxLength => 2048
288 }
289 };
290}
291
292sub get {
293 my ($self) = @_;
294
295 return {
296 to => $self->{to},
297 subject => $self->{subject},
298 body => $self->{body},
299 attach => ($self->{attach} eq 'O') ? 1 : 0,
300 };
301}
302
303sub update {
304 my ($self, $param) = @_;
305
306 $self->{to} = $param->{to};
307 $self->{subject} = $param->{subject};
308 $self->{body} = $param->{body};
aa376168 309 $self->{attach} = $param->{attach} ? 'O' : 'N';
4cb22484
DC
310}
311
758c7b6b
DM
3121;
313
314__END__
315
316=head1 PMG::RuleDB::Notify
317
318Notifications.