Firewall: add categories to nat/portforward page. for https://github.com/opnsense/core/issues/4587

This commit is contained in:
Ad Schellevis 2021-01-14 17:30:11 +01:00
parent ca110dc008
commit 5d173f52cf
3 changed files with 64 additions and 4 deletions

View File

@ -67,7 +67,7 @@ class Category extends BaseModel
{
$has_changed = false;
$cfgObj = Config::getInstance()->object();
$source = [array('filter', 'rule')];
$source = [['filter', 'rule'], ['nat', 'rule']];
$used_categories = [];
foreach ($source as $aliasref) {
$cfgsection = $cfgObj;
@ -96,6 +96,7 @@ class Category extends BaseModel
unset($used_categories[array_search((string)$category->name, $used_categories)]);
}
}
foreach ($used_categories as $name) {
$node = $this->categories->category->add();
$node->name = $name;

View File

@ -271,11 +271,42 @@ $( document ).ready(function() {
$(".rule_select").prop("checked", $(this).prop("checked"));
});
// move category block
$("#category_block").detach().appendTo($(".page-content-head > .container-fluid > .list-inline"));
$("#category_block").addClass("pull-right");
// our usual zebra striping doesn't respect hidden rows, hook repaint on .opnsense-rules change() and fire initially
$(".opnsense-rules > tbody > tr").each(function(){
// save zebra color
let tr_color = $(this).children(0).css("background-color");
if (tr_color != 'transparent' && !tr_color.includes('(0, 0, 0')) {
$("#fw_category").data('stripe_color', tr_color);
}
});
$(".opnsense-rules").removeClass("table-striped");
$(".opnsense-rules").change(function(){
$(".opnsense-rules > tbody > tr:visible").each(function (index) {
$(this).css("background-color", "inherit");
if ( index % 2 == 0) {
$(this).css("background-color", $("#fw_category").data('stripe_color'));
}
});
});
// hook category functionality
hook_firewall_categories();
// watch scroll position and set to last known on page load
watchScrollPosition();
});
</script>
<?php include("fbegin.inc"); ?>
<div class="hidden">
<div id="category_block" style="z-index:-100;">
<select class="selectpicker hidden-xs hidden-sm hidden-md" data-live-search="true" data-size="5" multiple title="<?=gettext("Select category");?>" id="fw_category">
</select>
</div>
</div>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
@ -290,7 +321,7 @@ $( document ).ready(function() {
<input type="hidden" id="id" name="id" value="" />
<input type="hidden" id="action" name="act" value="" />
<div class="table-responsive">
<table class="table table-striped">
<table class="table table-striped opnsense-rules">
<thead>
<tr>
<td colspan="5"> </td>
@ -338,7 +369,7 @@ $( document ).ready(function() {
<?php $nnats = 0;
foreach ($a_nat as $natent):
?>
<tr <?=isset($natent['disabled'])?"class=\"text-muted\"":"";?> ondblclick="document.location='firewall_nat_edit.php?id=<?=$nnats;?>';">
<tr class="rule <?=isset($natent['disabled'])?"text-muted":"";?>" data-category="<?=!empty($natent['category']) ? $natent['category'] : "";?>" ondblclick="document.location='firewall_nat_edit.php?id=<?=$nnats;?>';">
<td>
<input class="rule_select" type="checkbox" name="rule[]" value="<?=$nnats;?>" />
</td>

View File

@ -58,7 +58,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
if (isset($configId)) {
// copy 1-on-1
foreach (array('protocol','target','local-port','descr','interface','associated-rule-id','nosync','log',
'natreflection','created','updated','ipprotocol','tag','tagged','poolopts') as $fieldname) {
'natreflection','created','updated','ipprotocol','tag','tagged','poolopts', 'category') as $fieldname) {
if (isset($a_nat[$configId][$fieldname])) {
$pconfig[$fieldname] = $a_nat[$configId][$fieldname];
} else {
@ -124,6 +124,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$pconfig[$fieldname] = null;
}
}
$pconfig['category'] = !empty($pconfig['category']) ? explode(",", $pconfig['category']) : [];
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
$pconfig = $_POST;
$input_errors = array();
@ -212,6 +213,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$natent['protocol'] = $pconfig['protocol'];
}
$natent['interface'] = implode(",", $pconfig['interface']);
$natent['category'] = implode(",", $pconfig['category']);
$natent['ipprotocol'] = $pconfig['ipprotocol'];
$natent['descr'] = $pconfig['descr'];
$natent['tag'] = $pconfig['tag'];
@ -327,6 +329,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
}
$filterent['descr'] = $pconfig['descr'];
$filterent['category'] = $natent['category'];
// If this is a new rule, create an ID and add the rule
if (!empty($pconfig['filter-rule-association']) && $pconfig['filter-rule-association'] != 'pass') {
@ -356,6 +359,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
}
}
OPNsense\Core\Config::getInstance()->fromArray($config);
$catmdl = new OPNsense\Firewall\Category();
if ($catmdl->sync()) {
$catmdl->serializeToConfig();
$config = OPNsense\Core\Config::getInstance()->toArray(listtags());
}
write_config();
mark_subsystem_dirty('natconf');
@ -370,6 +379,9 @@ include("head.inc");
?>
<body>
<script src="<?= cache_safe('/ui/js/tokenize2.js') ?>"></script>
<link rel="stylesheet" type="text/css" href="<?= cache_safe(get_themed_filename('/css/tokenize2.css')) ?>">
<script src="<?= cache_safe('/ui/js/opnsense_ui.js') ?>"></script>
<script>
$( document ).ready(function() {
// show source fields (advanced)
@ -493,6 +505,7 @@ $( document ).ready(function() {
// IPv4/IPv6 select
hook_ipv4v6('ipv4v6net', 'network-id');
formatTokenizersUI();
});
@ -969,6 +982,21 @@ $( document ).ready(function() {
</div>
</td>
</tr>
<tr>
<td><a id="help_for_category" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Category"); ?></td>
<td>
<select name="category[]" id="category" multiple="multiple" class="tokenize" data-allownew="true" data-width="334px" data-live-search="true">
<?php
foreach ((new OPNsense\Firewall\Category())->iterateCategories() as $category):
$catname = htmlspecialchars($category['name'], ENT_QUOTES | ENT_HTML401);?>
<option value="<?=$catname;?>" <?=in_array($catname, $pconfig['category']) ? 'selected="selected"' : '';?> ><?=$catname;?></option>
<?php
endforeach;?>
</select>
<div class="hidden" data-for="help_for_category">
<?=gettext("You may enter or select a category here to group firewall rules (not parsed)."); ?>
</div>
</tr>
<tr>
<td><a id="help_for_descr" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Description"); ?></td>
<td>