]> git.proxmox.com Git - pmg-gui.git/commitdiff
add Attachment Quarantine
authorDominik Csapak <d.csapak@proxmox.com>
Thu, 10 Oct 2019 09:22:04 +0000 (11:22 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Thu, 17 Oct 2019 13:25:31 +0000 (15:25 +0200)
the Quarantine part is mostly copied from VirusQuarantine and adapted
the AttachmentGrid is inspired by the SpamScore list

this adds a new quarantine type 'Attachment' in the gui, where the admins
can review and control the mails in the attachment quarantine

it also shows a list of attachment/parts and a link where they can
be downloaded (in case the admin want to only forward a single
attachment or review the file in detail)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Reviewed-By: Stoiko Ivanov <s.ivanov@proxmox.com>
Tested-By: Stoiko Ivanov <s.ivanov@proxmox.com>
js/AttachmentGrid.js [new file with mode: 0644]
js/AttachmentQuarantine.js [new file with mode: 0644]
js/Makefile
js/NavigationTree.js

diff --git a/js/AttachmentGrid.js b/js/AttachmentGrid.js
new file mode 100644 (file)
index 0000000..e31bd12
--- /dev/null
@@ -0,0 +1,61 @@
+Ext.define('PMG.grid.AttachmentGrid',{
+    extend: 'Ext.grid.GridPanel',
+    xtype: 'pmgAttachmentGrid',
+
+    store: {
+       autoDestroy: true,
+       fields: [ 'name', 'content-type', 'size' ],
+       proxy: {
+           type: 'proxmox',
+       }
+    },
+
+    setID: function(rec) {
+       var me = this;
+       if (!rec || !rec.data || !rec.data.id) {
+           me.getStore().removeAll();
+           return;
+       }
+       var url = '/api2/json/quarantine/listattachments?id=' + rec.data.id;
+       me.mailid = rec.data.id;
+       me.store.proxy.setUrl(url);
+       me.store.load();
+    },
+
+    emptyText: gettext('No Attachments'),
+
+    download: function() {
+       alert(arguments);
+    },
+
+    columns: [
+       {
+           text: gettext('Filename'),
+           dataIndex: 'name',
+           flex: 1,
+       },
+       {
+           text: gettext('Filetype'),
+           dataIndex: 'content-type',
+           renderer: PMG.Utils.render_filetype,
+           flex: 1,
+       },
+       {
+           text: gettext('Size'),
+           renderer: Proxmox.Utils.format_size,
+           dataIndex: 'size',
+           flex: 1,
+       },
+       {
+           header: gettext('Download'),
+           renderer: function(value, mD, rec) {
+               var me = this;
+               let url = '/api2/json/quarantine/download';
+               url += '?mailid=' + me.mailid;
+               url += '&attachmentid=' + rec.data.id;
+               return "<a target='_blank' class='download' download='"+ rec.data.name +"' href='" +
+               url + "'><i class='fa fa-fw fa-download'</i></a>";
+           },
+       }
+    ]
+});
diff --git a/js/AttachmentQuarantine.js b/js/AttachmentQuarantine.js
new file mode 100644 (file)
index 0000000..c143d6a
--- /dev/null
@@ -0,0 +1,185 @@
+/*global Proxmox*/
+/*jslint confusion: true*/
+/*format is a string and a function*/
+Ext.define('pmg-attachment-list', {
+    extend: 'Ext.data.Model',
+    fields: [ 'id', 'envelope_sender', 'from', 'sender', 'receiver', 'subject',
+       { type: 'integer', name: 'bytes' },
+       { type: 'date', dateFormat: 'timestamp', name: 'time' },
+       {
+           type: 'string',
+           name: 'day',
+           convert: function(v, rec) {
+               return Ext.Date.format(rec.get('time'), 'Y-m-d');
+           }, depends: ['time']
+       }
+    ],
+    proxy: {
+        type: 'proxmox',
+       url: "/api2/json/quarantine/attachment"
+    },
+    idProperty: 'id'
+});
+
+Ext.define('PMG.AttachmentQuarantine', {
+    extend: 'Ext.container.Container',
+    xtype: 'pmgAttachmentQuarantine',
+
+    border: false,
+    layout: { type: 'border' },
+
+    defaults: { border: false },
+
+    controller: {
+
+       xclass: 'Ext.app.ViewController',
+
+       updatePreview: function(raw, rec) {
+           var preview = this.lookupReference('preview');
+
+           if (!rec || !rec.data || !rec.data.id)  {
+               preview.update('');
+               preview.setDisabled(true);
+               return;
+           }
+
+           var url = '/api2/htmlmail/quarantine/content?id=' + rec.data.id + ((raw)?'&raw=1':'');
+           preview.setDisabled(false);
+           preview.update("<iframe frameborder=0 width=100% height=100% sandbox='allow-same-origin' src='" + url +"'></iframe>");
+       },
+
+       toggleRaw: function(button) {
+           var me = this;
+           var list = this.lookupReference('list');
+           var rec = list.getSelection()[0] || {};
+           me.raw = !me.raw;
+           me.updatePreview(me.raw, rec);
+       },
+
+       btnHandler: function(button, e) {
+           var list = this.lookupReference('list');
+           var selected = list.getSelection();
+           if (!selected.length) {
+               return;
+           }
+
+           var action = button.reference;
+
+           PMG.Utils.doQuarantineAction(action, selected[0].data.id, function() {
+               list.getController().load();
+           });
+       },
+
+       onSelectMail: function() {
+           var me = this;
+           var list = this.lookupReference('list');
+           var rec = list.getSelection()[0] || {};
+
+           me.updatePreview(me.raw || false, rec);
+           this.lookupReference('attachmentlist').setID(rec);
+       },
+
+       control: {
+           'button[reference=raw]': {
+               click: 'toggleRaw'
+           },
+           'pmgQuarantineList': {
+               selectionChange: 'onSelectMail'
+           }
+       }
+
+    },
+
+    items: [
+       {
+           title: gettext('Attachment Quarantine'),
+           xtype: 'pmgQuarantineList',
+           emptyText: gettext('No data in database'),
+           emailSelection: false,
+           reference: 'list',
+           region: 'west',
+           width: 500,
+           split: true,
+           collapsible: false,
+           store: {
+               model: 'pmg-attachment-list',
+               groupField: 'day',
+               groupDir: 'DESC',
+               sorters: [{
+                   property: 'time',
+                   direction: 'DESC'
+               }]
+           },
+
+           columns: [
+               {
+                   header: gettext('Sender/Subject'),
+                   dataIndex: 'subject',
+                   renderer: PMG.Utils.sender_renderer,
+                   flex: 1
+               },
+               {
+                   header: gettext('Size') + ' (KB)',
+                   renderer: function(v) { return Ext.Number.toFixed(v/1024, 0); },
+                   dataIndex: 'bytes',
+                   align: 'right',
+                   width: 90
+               },
+               {
+                   header: gettext('Date'),
+                   dataIndex: 'day',
+                   hidden: true
+               },
+               {
+                   xtype: 'datecolumn',
+                   header: gettext('Time'),
+                   dataIndex: 'time',
+                   format: 'H:i:s'
+               }
+           ]
+       },
+       {
+           title: gettext('Selected Mail'),
+           border: false,
+           region: 'center',
+           split: true,
+           reference: 'preview',
+           disabled: true,
+           dockedItems: [
+               {
+                   xtype: 'toolbar',
+                   dock: 'top',
+                   items: [
+                       {
+                           xtype: 'button',
+                           reference: 'raw',
+                           text: gettext('Toggle Raw'),
+                           enableToggle: true,
+                           iconCls: 'fa fa-file-code-o'
+                       },
+                       '->',
+                       {
+                           reference: 'deliver',
+                           text: gettext('Deliver'),
+                           iconCls: 'fa fa-paper-plane-o',
+                           handler: 'btnHandler'
+                       },
+                       {
+                           reference: 'delete',
+                           text: gettext('Delete'),
+                           iconCls: 'fa fa-trash-o',
+                           handler: 'btnHandler'
+                       }
+                   ]
+               },
+               {
+                   xtype: 'pmgAttachmentGrid',
+                   minHeight: 50,
+                   maxHeight: 250,
+                   scrollable: true,
+                   reference: 'attachmentlist',
+               }
+           ]
+       }
+    ]
+});
index 6f4d449beae8100bec8e37911d76ec1d6a54d8a4..d377c32e11161159d359ffca2720484aef3b5a58 100644 (file)
@@ -55,6 +55,8 @@ JSSRC=                                                        \
        VirusDetectorOptions.js                         \
        VirusQuarantineOptions.js                       \
        VirusQuarantine.js                              \
+       AttachmentQuarantine.js                         \
+       AttachmentGrid.js                               \
        ClamAVDatabase.js                               \
        VirusDetectorConfiguration.js                   \
        LDAPConfig.js                                   \
index 342c715b91be9c004f16e95e643b1d43927e8688..b14cf1f03e0911d562157b9bdd28d1a565736151 100644 (file)
@@ -106,6 +106,12 @@ Ext.define('PMG.store.NavigationStore', {
                        path: 'pmgVirusQuarantine',
                        leaf: true
                    },
+                   {
+                       text: gettext('Attachment Quarantine'),
+                       iconCls: 'fa fa-paperclip',
+                       path: 'pmgAttachmentQuarantine',
+                       leaf: true
+                   },
                    {
                        text: gettext('User Whitelist'),
                        iconCls: 'fa fa-file-o',