mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-13 16:14:40 +00:00
Firewall: add model for categories. work in progress for https://github.com/opnsense/core/issues/4587
o replace type ahead with tokenizer (mutli select) while here, since the type ahead needed fixes which we rather don't copy to the other firewall sections o we might want to change the model serializeToConfig() and reload and send it to a separate function in config.inc later to ease migration later. Part of it could be separated with a callback, but it's not super needed o hook categories into model for firewall rules
This commit is contained in:
parent
c6f4d40ae0
commit
416fc37ee9
@ -42,14 +42,21 @@ class Category extends BaseModel
|
||||
{
|
||||
public function getByName($name)
|
||||
{
|
||||
foreach ($this->categories->category->iterateItems() as $alias) {
|
||||
if ((string)$alias->name == $name) {
|
||||
return $alias;
|
||||
foreach ($this->categories->category->iterateItems() as $category) {
|
||||
if ((string)$category->name == $name) {
|
||||
return $category;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function iterateCategories()
|
||||
{
|
||||
foreach ($this->categories->category->iterateItems() as $category) {
|
||||
yield ['name' => (string)$category->name];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* collect unique categories from rules and updates the model with auto generated items.
|
||||
* XXX: if this operation turns out to be a bottleneck, we should move the maintance responsibiliy to the caller
|
||||
@ -71,8 +78,12 @@ class Category extends BaseModel
|
||||
}
|
||||
if ($cfgsection != null) {
|
||||
foreach ($cfgsection as $node) {
|
||||
if (!empty($node->category) && !in_array((string)$node->category, $used_categories)) {
|
||||
$used_categories[] = (string)$node->category;
|
||||
if (!empty($node->category)) {
|
||||
foreach (explode(",", (string)$node->category) as $cat) {
|
||||
if (!in_array($cat, $used_categories)) {
|
||||
$used_categories[] = $cat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -512,7 +512,14 @@ $( document ).ready(function() {
|
||||
}
|
||||
});
|
||||
$(".rule").each(function(){
|
||||
if (selected_values.indexOf($(this).data('category')) == -1 && selected_values.length > 0) {
|
||||
let rule_categories = $(this).data('category').split(',');
|
||||
let is_selected = false;
|
||||
rule_categories.forEach(function(item){
|
||||
if (selected_values.indexOf(item) > -1) {
|
||||
is_selected = true;
|
||||
}
|
||||
});
|
||||
if (!is_selected && selected_values.length > 0) {
|
||||
$(this).hide();
|
||||
$(this).find("input").prop('disabled', true);
|
||||
} else {
|
||||
@ -624,17 +631,12 @@ $( document ).ready(function() {
|
||||
<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">
|
||||
<?php
|
||||
// collect unique list of categories and append to option list
|
||||
$categories = array();
|
||||
foreach ($a_filter as $tmp_rule) {
|
||||
if (!empty($tmp_rule['category']) && !in_array($tmp_rule['category'], $categories)) {
|
||||
$categories[] = $tmp_rule['category'];
|
||||
}
|
||||
}
|
||||
foreach ($categories as $category):?>
|
||||
<option value="<?=$category;?>" <?=in_array($category, $selected_category) ? "selected=\"selected\"" : "" ;?>><?=$category;?></option>
|
||||
foreach ((new OPNsense\Firewall\Category())->iterateCategories() as $category):?>
|
||||
<option value="<?=$category['name'];?>" <?=in_array($category['name'], $selected_category) ? "selected=\"selected\"" : "" ;?>>
|
||||
<?=$category['name'];?>
|
||||
</option>
|
||||
<?php
|
||||
endforeach;?>
|
||||
endforeach;?>
|
||||
</select>
|
||||
<button id="btn_inspect" class="btn btn-default hidden-xs">
|
||||
<i class="fa fa-eye" aria-hidden="true"></i>
|
||||
|
||||
@ -139,6 +139,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
$pconfig[$fieldname] = $a_filter[$configId][$fieldname];
|
||||
}
|
||||
}
|
||||
$pconfig['category'] = !empty($pconfig['category']) ? explode(",", $pconfig['category']) : [];
|
||||
|
||||
// process fields with some kind of logic
|
||||
address_to_pconfig($a_filter[$configId]['source'], $pconfig['src'],
|
||||
@ -534,6 +535,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
// sort filter items per interface, not really necessary but leaves a bit nicer sorted config.xml behind.
|
||||
filter_rules_sort();
|
||||
// write to config
|
||||
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('filter');
|
||||
|
||||
@ -552,6 +559,9 @@ $priorities = interfaces_vlan_priorities();
|
||||
include("head.inc");
|
||||
|
||||
?>
|
||||
<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>
|
||||
<body>
|
||||
<script>
|
||||
$( document ).ready(function() {
|
||||
@ -672,67 +682,7 @@ include("head.inc");
|
||||
$("#toggleAdvanced").click();
|
||||
<?php endif;?>
|
||||
|
||||
// add typeahead for existing categories, all options are saves in the select option "existing_categories"
|
||||
var categories = [];
|
||||
$("#existing_categories > option").each(function(){
|
||||
categories.push($(this).val());
|
||||
});
|
||||
$("#category").typeahead({
|
||||
source: categories
|
||||
});
|
||||
|
||||
/***************************************************************************************************************
|
||||
* typeahead seems to be broken since jQuery 3.3.0
|
||||
* temporary fix to make sure "position()" returns the expected values as suggested in:
|
||||
* https://github.com/bassjobsen/Bootstrap-3-Typeahead/issues/384
|
||||
*
|
||||
* When being used outside position: relative items, the plugin still seems to be working
|
||||
* (which is likely why the menu quick search isn't affected).
|
||||
***************************************************************************************************************/
|
||||
$.fn.position = function() {
|
||||
if ( !this[ 0 ] ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var offsetParent, offset, doc,
|
||||
elem = this[ 0 ],
|
||||
parentOffset = { top: 0, left: 0 };
|
||||
|
||||
// position:fixed elements are offset from the viewport, which itself always has zero offset
|
||||
if ( jQuery.css( elem, "position" ) === "fixed" ) {
|
||||
|
||||
// Assume position:fixed implies availability of getBoundingClientRect
|
||||
offset = elem.getBoundingClientRect();
|
||||
|
||||
} else {
|
||||
offset = this.offset();
|
||||
|
||||
// Account for the *real* offset parent, which can be the document or its root element
|
||||
// when a statically positioned element is identified
|
||||
doc = elem.ownerDocument;
|
||||
offsetParent = elem.offsetParent || doc.documentElement;
|
||||
while ( offsetParent &&
|
||||
offsetParent !== doc &&
|
||||
( offsetParent !== doc.body && offsetParent !== doc.documentElement ) &&
|
||||
jQuery.css( offsetParent, "position" ) === "static" ) {
|
||||
|
||||
offsetParent = offsetParent.parentNode;
|
||||
}
|
||||
if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
|
||||
|
||||
// Incorporate borders into its offset, since they are outside its content origin
|
||||
parentOffset = jQuery( offsetParent ).offset();
|
||||
parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
|
||||
parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
|
||||
}
|
||||
}
|
||||
|
||||
// Subtract parent offsets and element margins
|
||||
return {
|
||||
top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
|
||||
left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
|
||||
};
|
||||
};
|
||||
formatTokenizersUI();
|
||||
});
|
||||
|
||||
</script>
|
||||
@ -1265,23 +1215,18 @@ include("head.inc");
|
||||
<tr>
|
||||
<td><a id="help_for_category" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Category"); ?></td>
|
||||
<td>
|
||||
<input name="category" type="text" class="formfld unknown" id="category" size="40" value="<?=$pconfig['category'];?>" />
|
||||
<div class="hidden" data-for="help_for_category">
|
||||
<?=gettext("You may enter or select a category here to group firewall rules (not parsed)."); ?>
|
||||
</div>
|
||||
<select class="hidden" id="existing_categories">
|
||||
<select name="category[]" id="category" multiple="multiple" class="tokenize" data-allownew="true" data-width="334px">
|
||||
<?php
|
||||
$categories = array();
|
||||
foreach ($a_filter as $tmp_rule) {
|
||||
if (!empty($tmp_rule['category']) && !in_array($tmp_rule['category'], $categories)) {
|
||||
$categories[] = $tmp_rule['category'];
|
||||
}
|
||||
}
|
||||
foreach ($categories as $category):?>
|
||||
<option value="<?=$category;?>"></option>
|
||||
foreach ((new OPNsense\Firewall\Category())->iterateCategories() as $category):?>
|
||||
<option value="<?=$category['name'];?>" <?=in_array($category['name'], $pconfig['category']) ? 'selected="selected"' : '';?> >
|
||||
<?=$category['name'];?>
|
||||
</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>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user