diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Unbound/Api/OverviewController.php b/src/opnsense/mvc/app/controllers/OPNsense/Unbound/Api/OverviewController.php
index 09e3961b8b..7c51262d8b 100644
--- a/src/opnsense/mvc/app/controllers/OPNsense/Unbound/Api/OverviewController.php
+++ b/src/opnsense/mvc/app/controllers/OPNsense/Unbound/Api/OverviewController.php
@@ -36,23 +36,10 @@ use OPNsense\Firewall\Util;
class OverviewController extends ApiControllerBase
{
private $mdl = null;
- private $types = [];
- private $nodes = [];
public function __construct()
{
$this->mdl = new \OPNsense\Unbound\Unbound();
- $this->types = $this->mdl->dnsbl->blocklist->getTemplateNode()->type->getNodeData();
- $this->nodes = $this->mdl->dnsbl->blocklist->getNodes();
- }
-
- private function getBlocklistDescription($shortcode)
- {
- if (array_key_exists($shortcode, $this->types)) {
- return $this->types[$shortcode]['value'];
- }
-
- return null;
}
public function isEnabledAction()
@@ -65,7 +52,8 @@ class OverviewController extends ApiControllerBase
/* XXX deprecated and to be removed for 26.7 */
public function isBlockListEnabledAction()
{
- return ['enabled' => (bool)array_filter($this->nodes, fn($v) => $v['enabled'])];
+ $nodes = $this->mdl->dnsbl->blocklist->getNodes();
+ return ['enabled' => (bool)array_filter($nodes, fn($v) => $v['enabled'])];
}
public function RollingAction($timeperiod, $clients = '0')
@@ -108,10 +96,12 @@ class OverviewController extends ApiControllerBase
}
$parsed = json_decode($response, true) ?? [];
+ $policies = $this->getPoliciesAction();
+ $types = $this->mdl->dnsbl->blocklist->getTemplateNode()->type->getNodeData();
foreach ($parsed as $idx => $query) {
- $parsed[$idx]['blocklist'] ??= $this->getBlocklistDescription($query['blocklist']);
-
+ $parsed[$idx]['blocklist'] = $types[$query['blocklist']]['value'] ?? $query['blocklist'];
+ $parsed[$idx]['policy'] = $policies[$query['uuid']]['description'] ?? '';
/* Handle front-end color status mapping, start off with OK */
$parsed[$idx]['status'] = 0;
@@ -133,21 +123,14 @@ class OverviewController extends ApiControllerBase
return $response;
}
- public function getPoliciesAction($uuid = null)
+ public function getPoliciesAction()
{
- $response = ['policies' => []];
+ $response = [];
foreach ($this->mdl->dnsbl->blocklist->iterateItems() as $policy_uuid => $policy) {
- if ($uuid !== null && $uuid == $policy_uuid) {
- $response = $policy->getNodeContent();
- $response['uuid'] = $policy_uuid;
- break;
- }
-
- $response['policies'][$policy_uuid] = $policy->getNodeContent();
+ $response[$policy_uuid] = $policy->getNodeContent();
}
- $response['blocklistDescriptions'] = $this->types;
return $response;
}
}
diff --git a/src/opnsense/mvc/app/views/OPNsense/Unbound/overview.volt b/src/opnsense/mvc/app/views/OPNsense/Unbound/overview.volt
index e90b7f8bd1..99ea34f612 100644
--- a/src/opnsense/mvc/app/views/OPNsense/Unbound/overview.volt
+++ b/src/opnsense/mvc/app/views/OPNsense/Unbound/overview.volt
@@ -381,7 +381,7 @@
function createTopList(id, data, type, maxDomains = 10) {
ajaxGet('/api/unbound/overview/get_policies', {}, function(policies, status) {
- const enabled = Object.values(policies.policies).some(v => v.enabled === "1");
+ const enabled = Object.values(policies).some(v => v.enabled === "1");
for (let i = 0; i < maxDomains; i++) {
let category = type === 'block' ? data.top_blocked : data.top;
let domain = Object.keys(category)[i];
@@ -411,7 +411,7 @@
openPoliciesDialog(domain, uuid, action, statObj?.blocklist ?? "");
});
- let bl = (uuid && uuid in policies.policies) ? `(${policies.policies[uuid].description})` : '';
+ let bl = (uuid && uuid in policies) ? `(${policies[uuid].description})` : '';
let $li = $(`
@@ -564,20 +564,29 @@
const cleanDomain = domain.replace(/\.$/, "");
ajaxGet('/api/unbound/overview/get_policies', {}, function (data, status) {
+ let $container = $('');
+ const enabled = Object.values(data).some(v => v.enabled === "1");
+
+ if (!enabled) {
+ $container.html(`
+ {{ lang._('There are no blocklist policies defined. You can create them %shere%s') | format('
', '') }}
+ `);
+ dialogRef.setMessage($container);
+ return;
+ }
+
const $table = $('
');
const $tbody = $('');
const $thead = $('').append(
$('').append(
- $('| ').text("{{ lang._('Blocklist') }}"),
+ $(' | ').text("{{ lang._('Policy') }}"),
$(' | ').text("{{ lang._('Source net(s)') }}"),
$(' | ').text("{{ lang._('Action') }}")
)
);
$table.append($thead, $tbody);
- const descriptions = data['blocklistDescriptions'];
-
- for (const [policy_uuid, policy] of Object.entries(data.policies)) {
+ for (const [policy_uuid, policy] of Object.entries(data)) {
if (policy.enabled == '0') continue;
const description =
@@ -618,12 +627,14 @@
$tbody.append($tr);
}
- const blocklistMatch = descriptions[blocklist]?.value ?? blocklist;
- $container = $(`
-
- {{ lang._('Blocklist match:')}} ${blocklistMatch}
-
- `);
+ if (blocklist != "") {
+ $container = $(`
+
+ {{ lang._('Blocklist match:')}} ${blocklist}
+
+ `);
+ }
+
$container.append($table);
dialogRef.setMessage($container);
@@ -663,108 +674,92 @@
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
if (e.target.id == 'query_details_tab') {
$("#grid-queries").bootgrid('destroy');
- ajaxGet('/api/unbound/overview/get_policies', {}, function(policies, status) {
- const enabled = Object.values(policies.policies).some(v => v.enabled === "1");
- let grid_queries = $("#grid-queries").UIBootgrid({
- search:'/api/unbound/overview/search_queries/',
- commands: {
- action: {
- title: "{{ lang._('Quick action') }}",
- classname: 'fa fa-cogs',
- sequence: 100,
- filter: function(cell) {
- const data = cell.getData();
- return enabled && (data.action == 'Pass' || data.action == 'Block');
- },
- onRendered: function(cell) {
- const $el = $(this);
- const data = cell.getData();
- const uuid = data.uuid;
- const domain = data.domain;
- const appliedAction = data.action;
- const blocklist = data.blocklist;
+ let grid_queries = $("#grid-queries").UIBootgrid({
+ search:'/api/unbound/overview/search_queries/',
+ commands: {
+ action: {
+ title: "{{ lang._('Quick action') }}",
+ classname: 'fa fa-cogs',
+ sequence: 100,
+ filter: function(cell) {
+ const data = cell.getData();
+ return data.action == 'Pass' || data.action == 'Block';
+ },
+ onRendered: function(cell) {
+ const $el = $(this);
+ const data = cell.getData();
+ const uuid = data.uuid;
+ const domain = data.domain;
+ const appliedAction = data.action;
+ const blocklist = data.blocklist;
- $el.click(function() {
- openPoliciesDialog(domain, uuid, appliedAction, blocklist);
- });
- }
+ $el.click(function() {
+ openPoliciesDialog(domain, uuid, appliedAction, blocklist);
+ });
+ }
+ }
+ },
+ options: {
+ virtualDOM: true,
+ rowSelect: false,
+ multiSelect: false,
+ selection: false,
+ useRequestHandlerOnGet: true,
+ requestHandler: function(request) {
+ if (g_clientFilter != null && g_timeFilter != null) {
+ let timestamp = g_timeFilter / 1000;
+ let interval = $("#timeperiod-clients").val() == 1 ? 60 : 600;
+
+ request['client'] = g_clientFilter;
+ request['timeStart'] = timestamp;
+ request['timeEnd'] = timestamp + interval;
+ }
+
+ return request;
+ },
+ formatters: {
+ "timeformatter": function (column, row) {
+ return moment.unix(row.time).local().format('YYYY-MM-DD HH:mm:ss');
+ },
+ "resolveformatter": function (column, row) {
+ return row.resolve_time_ms + 'ms';
+ },
+ "domain": function (column, row) {
+ return row.domain;
}
},
- options: {
- virtualDOM: true,
- rowSelect: false,
- multiSelect: false,
- selection: false,
- useRequestHandlerOnGet: true,
- requestHandler: function(request) {
- if (g_clientFilter != null && g_timeFilter != null) {
- let timestamp = g_timeFilter / 1000;
- let interval = $("#timeperiod-clients").val() == 1 ? 60 : 600;
-
- request['client'] = g_clientFilter;
- request['timeStart'] = timestamp;
- request['timeEnd'] = timestamp + interval;
- }
-
- return request;
- },
- formatters: {
- "timeformatter": function (column, row) {
- return moment.unix(row.time).local().format('YYYY-MM-DD HH:mm:ss');
- },
- "resolveformatter": function (column, row) {
- return row.resolve_time_ms + 'ms';
- },
- "domain": function (column, row) {
- return row.domain;
- },
- "blocklist": function (column, row) {
- if (row.uuid && policies.policies[row.uuid]) {
- return policies.policies[row.uuid].description;
- }
-
- return '';
- }
- },
- statusMapping: {
- 0: "query-success",
- 1: "query-info",
- 2: "query-warning",
- 3: "query-danger",
- 4: "query-error"
- }
+ statusMapping: {
+ 0: "query-success",
+ 1: "query-info",
+ 2: "query-warning",
+ 3: "query-danger",
+ 4: "query-error"
}
- }).on("loaded.rs.jquery.bootgrid", function (e) {
- if (g_clientFilter != null && g_timeFilter != null && !$('#searchFilter').length) {
- // Add a badge to signify we're in a drill-down
- let label = (typeof g_labelFilter != 'undefined') ? g_labelFilter : g_clientFilter;
- $('div.actionBar').prepend($(''));
- let timeStart = moment.unix(g_timeFilter / 1000).local().format('MM-DD HH:mm');
- let interval = $("#timeperiod-clients").val() == 1 ? 60 : 600;
- let timeEnd = moment.unix((g_timeFilter / 1000) + interval).local().format('MM-DD HH:mm');
- $('#searchFilter').append('' +
- label + ' (' + timeStart + ' - ' + timeEnd + ')' +
- '');
+ }
+ }).on("loaded.rs.jquery.bootgrid", function (e) {
+ if (g_clientFilter != null && g_timeFilter != null && !$('#searchFilter').length) {
+ // Add a badge to signify we're in a drill-down
+ let label = (typeof g_labelFilter != 'undefined') ? g_labelFilter : g_clientFilter;
+ $('div.actionBar').prepend($(''));
+ let timeStart = moment.unix(g_timeFilter / 1000).local().format('MM-DD HH:mm');
+ let interval = $("#timeperiod-clients").val() == 1 ? 60 : 600;
+ let timeEnd = moment.unix((g_timeFilter / 1000) + interval).local().format('MM-DD HH:mm');
+ $('#searchFilter').append('' +
+ label + ' (' + timeStart + ' - ' + timeEnd + ')' +
+ '');
- $('#removeFilter').click(function(e) {
- // Reset filters set by a client drill-down
- g_clientFilter = null;
- g_timeFilter = null;
- g_labelFilter = null;
- $('#searchFilter').remove();
- $('#grid-queries').bootgrid('reload');
- })
- }
-
- if (!enabled) {
- $(".hide-col").css("display", "none");
- } else {
- $(".hide-col").css('display', '');
- }
- $(".domain-content").tooltip({placement: "auto left"});
- });
- })
+ $('#removeFilter').click(function(e) {
+ // Reset filters set by a client drill-down
+ g_clientFilter = null;
+ g_timeFilter = null;
+ g_labelFilter = null;
+ $('#searchFilter').remove();
+ $('#grid-queries').bootgrid('reload');
+ })
+ }
+ $(".domain-content").tooltip({placement: "auto left"});
+ });
}
if (e.target.id == 'query_overview_tab') {
// Reset filters set by a client drill-down
@@ -963,6 +958,7 @@
| {{ lang._('Resolve time') }} |
{{ lang._('TTL') }} |
{{ lang._('Blocklist') }} |
+ {{ lang._('Policy') }} |
{{ lang._('Commands') }} |