]> git.proxmox.com Git - pmg-api.git/blame - PMG/API2/Quarantine.pm
PMG/DBTools.pm - new helper load_mail_data()
[pmg-api.git] / PMG / API2 / Quarantine.pm
CommitLineData
b66faa68
DM
1package PMG::API2::Quarantine;
2
3use strict;
4use warnings;
5use Time::Local;
6use Time::Zone;
7use Data::Dumper;
8
dae021a8
DM
9use Mail::Header;
10
b66faa68
DM
11use PVE::SafeSyslog;
12use PVE::Exception qw(raise_param_exc);
13use PVE::Tools qw(extract_param);
14use PVE::JSONSchema qw(get_standard_option);
15use PVE::RESTHandler;
16use PVE::INotify;
17
dae021a8 18use PMG::Utils;
b66faa68
DM
19use PMG::AccessControl;
20use PMG::DBTools;
21
22use base qw(PVE::RESTHandler);
23
24
dae021a8
DM
25my $parse_header_info = sub {
26 my ($ref) = @_;
27
28 my $res = { subject => '', from => '' };
29
30 my @lines = split('\n', $ref->{header});
31 my $head = Mail::Header->new(\@lines);
32
33 $res->{subject} = PMG::Utils::decode_rfc1522(PVE::Tools::trim($head->get('subject'))) // '';
34
35 my @fromarray = split('\s*,\s*', $head->get('from') || $ref->{sender});
36
37 $res->{from} = PMG::Utils::decode_rfc1522(PVE::Tools::trim ($fromarray[0])) // '';
38
39 my $sender = PMG::Utils::decode_rfc1522(PVE::Tools::trim($head->get('sender')));
40 $res->{sender} = $sender if $sender;
41
42 $res->{envelope_sender} = $ref->{sender};
43 $res->{receiver} = $ref->{receiver};
44 $res->{id} = $ref->{cid} . '_' . $ref->{rid};
45 $res->{time} = $ref->{time};
46 $res->{bytes} = $ref->{bytes};
47
48 return $res;
49};
50
b66faa68
DM
51__PACKAGE__->register_method ({
52 name => 'index',
53 path => '',
54 method => 'GET',
55 permissions => { user => 'all' },
56 description => "Directory index.",
57 parameters => {
58 additionalProperties => 0,
59 properties => {},
60 },
61 returns => {
62 type => 'array',
63 items => {
64 type => "object",
65 properties => {},
66 },
67 links => [ { rel => 'child', href => "{name}" } ],
68 },
69 code => sub {
70 my ($param) = @_;
71
72 my $result = [
73 { name => 'deliver' },
74 { name => 'spam' },
75 { name => 'virus' },
76 ];
77
78 return $result;
79 }});
80
81__PACKAGE__->register_method ({
82 name => 'spam',
83 path => 'spam',
84 method => 'GET',
85 permissions => { check => [ 'admin', 'qmanager', 'audit', 'quser'] },
86 description => "Show spam mails distribution (per day).",
87 parameters => {
88 additionalProperties => 0,
89 properties => {
90 starttime => {
91 description => "Only consider entries newer than 'startime' (unix epoch).",
92 type => 'integer',
93 minimum => 0,
94 optional => 1,
95 },
96 endtime => {
97 description => "Only consider entries older than 'endtime' (unix epoch).",
98 type => 'integer',
99 minimum => 1,
100 optional => 1,
101 },
102 pmail => {
ded33c7c 103 description => "List entries for the user with this primary email address. Quarantine users cannot speficy this parameter, but it is required for all other roles.",
b66faa68
DM
104 type => 'string', format => 'email',
105 optional => 1,
106 },
107 },
108 },
109 returns => {
110 type => 'array',
111 items => {
112 type => "object",
113 properties => {
114 day => {
115 description => "Day (as unix epoch).",
116 type => 'integer',
117 },
bc1ebe25 118 count => {
b66faa68
DM
119 description => "Number of quarantine entries.",
120 type => 'integer',
121 },
122 spamavg => {
123 description => "Average spam level.",
124 type => 'number',
bc1ebe25 125 },
b66faa68
DM
126 },
127 },
ded33c7c 128 links => [ { rel => 'child', href => "{day}" } ],
b66faa68
DM
129 },
130 code => sub {
131 my ($param) = @_;
132
133 my $rpcenv = PMG::RESTEnvironment->get();
134 my $authuser = $rpcenv->get_user();
135 my $role = $rpcenv->get_role();
136
137 my $pmail = $param->{pmail};
138
139 if ($role eq 'quser') {
140 raise_param_exc({ pmail => "paramater not allwed with role '$role'"})
141 if defined($pmail);
142 $pmail = $authuser;
ded33c7c
DM
143 } else {
144 raise_param_exc({ pmail => "paramater required with role '$role'"})
145 if !defined($pmail);
b66faa68
DM
146 }
147
148 my $res = [];
bc1ebe25 149
b66faa68
DM
150 my $dbh = PMG::DBTools::open_ruledb();
151
ec7035c2 152 my $start = $param->{starttime};
b66faa68
DM
153 my $end = $param->{endtime};
154
155 my $timezone = tz_local_offset();
156
157 my $sth = $dbh->prepare(
158 "SELECT " .
159 "((time + $timezone) / 86400) * 86400 - $timezone as day, " .
160 "count (ID) as count, avg (Spamlevel) as spamavg " .
161 "FROM CMailStore, CMSReceivers WHERE " .
ec7035c2
DM
162 (defined($start) ? "time >= $start AND " : '') .
163 (defined($end) ? "time < $end AND " : '') .
ded33c7c 164 "pmail = ? AND " .
b66faa68
DM
165 "QType = 'S' AND CID = CMailStore_CID AND RID = CMailStore_RID " .
166 "AND Status = 'N' " .
167 "GROUP BY day " .
168 "ORDER BY day DESC");
169
ded33c7c
DM
170 $sth->execute($pmail);
171
172 while (my $ref = $sth->fetchrow_hashref()) {
173 push @$res, $ref;
174 }
175
176 return $res;
177 }});
178
179__PACKAGE__->register_method ({
180 name => 'spamlist',
181 path => 'spam/{starttime}',
182 method => 'GET',
183 permissions => { check => [ 'admin', 'qmanager', 'audit', 'quser'] },
184 description => "Show spam mails distribution (per day).",
185 parameters => {
186 additionalProperties => 0,
187 properties => {
188 starttime => {
189 description => "Only consider entries newer than 'starttime' (unix epoch).",
190 type => 'integer',
191 minimum => 0,
192 },
193 endtime => {
194 description => "Only consider entries older than 'endtime' (unix epoch). This is set to '<start> + 1day' by default.",
195 type => 'integer',
196 minimum => 1,
197 optional => 1,
198 },
199 pmail => {
200 description => "List entries for the user with this primary email address. Quarantine users cannot speficy this parameter, but it is required for all other roles.",
201 type => 'string', format => 'email',
202 optional => 1,
203 },
204 },
205 },
206 returns => {
207 type => 'array',
208 items => {
209 type => "object",
dae021a8
DM
210 properties => {
211 id => {
212 description => 'Unique ID',
213 type => 'string',
214 },
215 bytes => {
216 description => "Size of raw email.",
217 type => 'integer' ,
218 },
219 envelope_sender => {
220 description => "SMTP envelope sender.",
221 type => 'string',
222 },
223 from => {
224 description => "Header 'From' field.",
225 type => 'string',
226 },
227 sender => {
228 description => "Header 'Sender' field.",
229 type => 'string',
230 optional => 1,
231 },
232 receiver => {
233 description => "Receiver email address",
234 type => 'string',
235 },
236 subject => {
237 description => "Header 'Subject' field.",
238 type => 'string',
239 },
240 time => {
241 description => "Receive time stamp",
242 type => 'integer',
243 },
244 },
ded33c7c
DM
245 },
246 },
247 code => sub {
248 my ($param) = @_;
249
250 my $rpcenv = PMG::RESTEnvironment->get();
251 my $authuser = $rpcenv->get_user();
252 my $role = $rpcenv->get_role();
253
254 my $pmail = $param->{pmail};
255
256 if ($role eq 'quser') {
257 raise_param_exc({ pmail => "paramater not allwed with role '$role'"})
258 if defined($pmail);
259 $pmail = $authuser;
b66faa68 260 } else {
ded33c7c
DM
261 raise_param_exc({ pmail => "paramater required with role '$role'"})
262 if !defined($pmail);
b66faa68
DM
263 }
264
ded33c7c
DM
265 my $res = [];
266
267 my $dbh = PMG::DBTools::open_ruledb();
268
269 my $start = $param->{starttime};
270 my $end = $param->{endtime} // ($start + 86400);
271
272 my $sth = $dbh->prepare(
273 "SELECT * " .
274 "FROM CMailStore, CMSReceivers WHERE " .
275 "pmail = ? AND time >= $start AND time < $end AND " .
276 "QType = 'S' AND CID = CMailStore_CID AND RID = CMailStore_RID " .
277 "AND Status = 'N' ORDER BY pmail, time, receiver");
278
279 $sth->execute($pmail);
280
b66faa68 281 while (my $ref = $sth->fetchrow_hashref()) {
dae021a8
DM
282 my $data = $parse_header_info->($ref);
283 push @$res, $data;
b66faa68
DM
284 }
285
286 return $res;
287 }});
288
2891;