summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/usr/local/www/firewall_nat.php76
-rw-r--r--src/usr/local/www/firewall_nat_edit.php8
-rw-r--r--src/usr/local/www/firewall_rules.php170
-rw-r--r--src/usr/local/www/jquery/pfSenseHelpers.js156
4 files changed, 250 insertions, 160 deletions
diff --git a/src/usr/local/www/firewall_nat.php b/src/usr/local/www/firewall_nat.php
index 869fbff..8b481d1 100644
--- a/src/usr/local/www/firewall_nat.php
+++ b/src/usr/local/www/firewall_nat.php
@@ -87,6 +87,16 @@ if (array_key_exists('order-store', $_POST)) {
$a_nat = $a_nat_new;
+
+ $config['nat']['separator'] = "";
+
+ if ($_POST['separator']) {
+ $idx = 0;
+ foreach ($_POST['separator'] as $separator) {
+ $config['nat']['separator']['sep' . $idx++] = $separator;
+ }
+ }
+
if (write_config()) {
mark_subsystem_dirty('filter');
}
@@ -130,6 +140,16 @@ if ($_GET['act'] == "del") {
}
unset($a_nat[$_GET['id']]);
+ // Update the separators
+ $a_separators = &$config['nat']['separator'];
+
+ for ($idx=0; isset($a_separators['sep' . $idx]); $idx++ ) {
+ $seprow = substr($a_separators['sep' . $idx]['row']['0'], 2);
+ if ($seprow >= $_GET['id']) {
+ $a_separators['sep' . $idx]['row']['0'] = 'fr' . ($seprow - 1);
+ }
+ }
+
if (write_config()) {
mark_subsystem_dirty('natconf');
if ($want_dirty_filter) {
@@ -145,8 +165,11 @@ if ($_GET['act'] == "del") {
if (isset($_POST['del_x'])) {
/* delete selected rules */
if (is_array($_POST['rule']) && count($_POST['rule'])) {
+ $a_separators = &$config['nat']['separator'];
+
foreach ($_POST['rule'] as $rulei) {
- $target = $rule['target'];
+ $target = $rule['target'];
+
// Check for filter rule associations
if (isset($a_nat[$rulei]['associated-rule-id'])) {
delete_id($a_nat[$rulei]['associated-rule-id'], $config['filter']['rule']);
@@ -155,6 +178,14 @@ if (isset($_POST['del_x'])) {
}
unset($a_nat[$rulei]);
+
+ // Update the separators
+ for ($idx=0; isset($a_separators['sep' . $idx]); $idx++ ) {
+ $seprow = substr($a_separators['sep' . $idx]['row']['0'], 2);
+ if ($seprow >= $rulei) {
+ $a_separators['sep' . $idx]['row']['0'] = 'fr' . ($seprow - 1);
+ }
+ }
}
if (write_config()) {
@@ -197,13 +228,15 @@ $tab_array[] = array(gettext("1:1"), false, "firewall_nat_1to1.php");
$tab_array[] = array(gettext("Outbound"), false, "firewall_nat_out.php");
$tab_array[] = array(gettext("NPt"), false, "firewall_nat_npt.php");
display_top_tabs($tab_array);
+
+$columns_in_table = 13;
?>
<form action="firewall_nat.php" method="post" name="iform">
<div class="panel panel-default">
<div class="panel-heading"><h2 class="panel-title"><?=gettext('Rules')?></h2></div>
<div class="panel-body table-responsive">
- <table class="table table-striped table-hover table-condensed">
+ <table id="ruletable" class="table table-striped table-hover table-condensed">
<thead>
<tr>
<th><!-- Checkbox --></th>
@@ -226,6 +259,15 @@ display_top_tabs($tab_array);
$nnats = $i = 0;
+// There can be a separator before any rules are listed
+if ($config['nat']['separator']['sep0']['row'][0] == "fr-1") {
+ $cellcolor = $config['nat']['separator']['sep0']['color'];
+ print('<tr class="ui-sortable-handle separator">' .
+ '<td class="' . $cellcolor . '" colspan="' . ($columns_in_table -1) . '">' . '<span class="' . $cellcolor . '">' . $config['nat']['separator']['sep0']['text'] . '</span></td>' .
+ '<td class="' . $cellcolor . '"><a href="#"><i class="fa fa-trash no-confirm sepdel" title="delete this separator"></i></a></td>' .
+ '</tr>' . "\n");
+}
+
foreach ($a_nat as $natent):
$alias = rule_columns_with_alias(
@@ -386,6 +428,18 @@ foreach ($a_nat as $natent):
</td>
</tr>
<?php
+
+ if (isset($config['nat']['separator']['sep0'])) {
+ foreach ($config['nat']['separator'] as $rulesep) {
+ if ($rulesep['row']['0'] == "fr" . $nnats) {
+ $cellcolor = $rulesep['color'];
+ print('<tr class="ui-sortable-handle separator">' .
+ '<td class="' . $cellcolor . '" colspan="' . ($columns_in_table -1) . '">' . '<span class="' . $cellcolor . '">' . $rulesep['text'] . '</span></td>' .
+ '<td class="' . $cellcolor . '"><a href="#"><i class="fa fa-trash no-confirm sepdel" title="delete this separator"></i></a></td>' .
+ '</tr>' . "\n");
+ }
+ }
+ }
$i++;
$nnats++;
endforeach;
@@ -412,11 +466,23 @@ endforeach;
<i class="fa fa-save icon-embed-btn"></i>
<?=gettext("Save")?>
</button>
+ <button type="submit" id="addsep" name="addsep" class="btn btn-sm btn-warning" title="<?=gettext('Add separator')?>">
+ <i class="fa fa-plus icon-embed-btn"></i>
+ <?=gettext("Separator")?>
+ </button>
</nav>
</form>
<script type="text/javascript">
//<![CDATA[
+//Need to create some variables here so that jquert/pfSenseHelpers.php can read them
+iface = "<?=strtolower($if)?>";
+cncltxt = '<?=gettext("Cancel")?>';
+svtxt = '<?=gettext("Save")?>';
+svbtnplaceholder = '<?=gettext("Enter a description, Save, then drag to final location.")?>';
+configsection = "nat";
+dirty = false;
+
events.push(function() {
// Make rules sortable
@@ -425,6 +491,8 @@ events.push(function() {
update: function(event, ui) {
$('#order-store').removeAttr('disabled');
dirty = true;
+ reindex_rules(ui.item.parent('tbody'));
+ dirty = true;
}
});
@@ -432,8 +500,12 @@ events.push(function() {
$('#order-store').click(function () {
$('[id^=frc]').prop('checked', true);
+ // Save the separator bar configuration
+ save_separators();
+
// Suppress the "Do you really want to leave the page" message
saving = true;
+
});
// Globals
diff --git a/src/usr/local/www/firewall_nat_edit.php b/src/usr/local/www/firewall_nat_edit.php
index 65316f0..c23c9d7 100644
--- a/src/usr/local/www/firewall_nat_edit.php
+++ b/src/usr/local/www/firewall_nat_edit.php
@@ -514,6 +514,14 @@ if ($_POST) {
$natent['created'] = make_config_revision_entry();
if (is_numeric($after)) {
array_splice($a_nat, $after+1, 0, array($natent));
+
+ // Update the separators
+ $a_separators = &$config['nat']['separator'];
+
+ for ($idx=0; isset($a_separators['sep' . $idx]); $idx++ ) {
+ $seprow = substr($a_separators['sep' . $idx]['row']['0'], 2);
+ $a_separators['sep' . $idx]['row']['0'] = 'fr' . ($seprow + 1);
+ }
} else {
$a_nat[] = $natent;
}
diff --git a/src/usr/local/www/firewall_rules.php b/src/usr/local/www/firewall_rules.php
index fc14e2c..0c2ab29 100644
--- a/src/usr/local/www/firewall_rules.php
+++ b/src/usr/local/www/firewall_rules.php
@@ -200,7 +200,6 @@ if (!$if || !isset($iflist[$if])) {
}
if ($_POST) {
-
$pconfig = $_POST;
if ($_POST['apply']) {
@@ -290,6 +289,7 @@ if (isset($_POST['del_x'])) {
exit;
}
} else if ($_POST['order-store']) {
+
/* update rule order, POST[rule] is an array of ordered IDs */
if (is_array($_POST['rule']) && !empty($_POST['rule'])) {
$a_filter_new = array();
@@ -469,9 +469,10 @@ $seps = 0;
// There can be a separator before any rules are listed
if ($config['filter']['separator'][strtolower($if)]['sep0']['row'][0] == "fr-1") {
+ $cellcolor = $config['filter']['separator'][strtolower($if)]['sep0']['color'];
print('<tr class="ui-sortable-handle separator">' .
- '<td bgcolor="#cce5ff" colspan="' . ($columns_in_table -1 ) . '">' . '<font color="#002699">' . $config['filter']['separator'][strtolower($if)]['sep0']['text'] . '</font></td>' .
- '<td bgcolor="#cce5ff"><a href="#"><i class="fa fa-trash no-confirm sepdel" title="delete this separator"></i></a></td>' .
+ '<td class="' . $cellcolor . '" colspan="' . ($columns_in_table -1) . '">' . '<span class="' . $cellcolor . '">' . $config['filter']['separator'][strtolower($if)]['sep0']['text'] . '</span></td>' .
+ '<td class="' . $cellcolor . '"><a href="#"><i class="fa fa-trash no-confirm sepdel" title="delete this separator"></i></a></td>' .
'</tr>' . "\n");
}
@@ -875,6 +876,14 @@ for ($i = 0; isset($a_filter[$i]); $i++):
<script type="text/javascript">
//<![CDATA[
+
+//Need to create some variables here so that jquer/pfSenseHelpers.php can read them
+iface = "<?=strtolower($if)?>";
+cncltxt = '<?=gettext("Cancel")?>';
+svtxt = '<?=gettext("Save")?>';
+svbtnplaceholder = '<?=gettext("Enter a description, Save, then drag to final location.")?>';
+configsection = "filter";
+
events.push(function() {
// Make rules sortable
@@ -898,148 +907,6 @@ events.push(function() {
saving = true;
});
- // Separator bar stuff ------------------------------------------------------------------------
-
- // Globals
- gColor = 'bg-info';
- newSeperator = false;
- saving = false;
- dirty = false;
-
- $("#addsep").prop('type' ,'button');
-
- $("#addsep").click(function() {
- if (newSeperator) {
- return(false);
- }
-
- gColor = 'bg-info';
- // Inset a temporary bar in which the user can enter some optional text
- sepcols = $( "#ruletable tr th" ).length - 2;
-
- $('#ruletable > tbody:last').append('<tr>' +
- '<td class="' + gColor + '" colspan="' + sepcols + '"><input id="newsep" placeholder="<?=gettext("Enter a description, Save, then drag to final location.")?>" class="col-md-12" type="text" /></td>' +
- '<td class="' + gColor + '" colspan="2"><button class="btn btn-default btn-sm" id="btnnewsep"><?=gettext("Save")?></button>' +
- '<button class="btn btn-default btn-sm" id="btncncsep"><?=gettext("Cancel")?></button>' +
- '&nbsp;&nbsp;&nbsp;&nbsp;' +
- '&nbsp;&nbsp;<a id="sepclrblue" value="bg-info"><i class="fa fa-circle text-info icon-pointer"></i></a>' +
- '&nbsp;&nbsp;<a id="sepclrred" value="bg-danger"><i class="fa fa-circle text-danger icon-pointer"></i></a>' +
- '&nbsp;&nbsp;<a id="sepclrgreen" value="bg-success"><i class="fa fa-circle text-success icon-pointer"></i></a>' +
- '&nbsp;&nbsp;<a id="sepclrorange" value="bg-warning"><i class="fa fa-circle text-warning icon-pointer"></i></button>' +
- '</td></tr>');
-
- $('#newsep').focus();
- newSeperator = true;
-
- $("#btnnewsep").prop('type' ,'button');
-
- // Watch escape and enter keys
- $('#newsep').keyup(function(e) {
- if(e.which == 27) {
- $('#btncncsep').trigger('click');
- }
- });
-
- $('#newsep').keypress(function(e) {
- if(e.which == 13) {
- $('#btnnewsep').trigger('click');
- }
- });
-
- handle_colors();
-
- // Remove the temporary separator bar and replace it with the final version containing the
- // user's text and a delete icon
- $("#btnnewsep").click(function() {
- var septext = escapeHtml($('#newsep').val());
- sepcols = $( "#ruletable tr th" ).length - 1;
-
- $('#ruletable > tbody:last >tr:last').remove();
- $('#ruletable > tbody:last').append('<tr class="ui-sortable-handle separator">' +
- '<td class="' + gColor + '" colspan="' + sepcols + '">' + '<span class="' + gColor + '">' + septext + '</span></td>' +
- '<td class="' + gColor + '"><a href="#"><i class="fa fa-trash sepdel"></i></a>' +
- '</td></tr>');
-
- $('#order-store').removeAttr('disabled');
- newSeperator = false;
- dirty = true;
- });
-
- // Cancel button
- $('#btncncsep').click(function(e) {
- e.preventDefault();
- $(this).parents('tr').remove();
- newSeperator = false;
- });
- });
-
- // Delete a separator row
- $(function(){
- $('table').on('click','tr a .sepdel',function(e){
- e.preventDefault();
- $(this).parents('tr').remove();
- $('#order-store').removeAttr('disabled');
- dirty = true;
- });
- });
-
- // Compose an inout array containing the row #, color and text for each separator
- function save_separators() {
- var seprow = 0;
- var sepinput;
- var sepnum = 0;
-
- $('#ruletable > tbody > tr').each(function() {
- if ($(this).hasClass('separator')) {
- seprow = $(this).prev('tr').attr("id");
- if (seprow == undefined) {
- seprow = "fr-1";
- }
-
- sepinput = '<input type="hidden" name="separator[' + sepnum + '][row]" value="' + seprow + '"></input>';
- $('form').append(sepinput);
- sepinput = '<input type="hidden" name="separator[' + sepnum + '][text]" value="' + escapeHtml($(this).find('td').text()) + '"></input>';
- $('form').append(sepinput);
- sepinput = '<input type="hidden" name="separator[' + sepnum + '][color]" value="' + $(this).find('td').prop('class') + '"></input>';
- $('form').append(sepinput);
- sepinput = '<input type="hidden" name="separator[' + sepnum + '][if]" value="<?=strtolower($if)?>"></input>';
- $('form').append(sepinput);
- sepnum++;
- }
-
- if ($(this).parent('tbody').hasClass('user-entries')) {
- seprow++;
- }
- });
- }
-
- function reindex_rules(section) {
- var row = 0;
-
- section.find('tr').each(function() {
- if(this.id) {
- $(this).attr("id", "fr" + row);
- row++;
- }
- })
- }
-
- function handle_colors() {
- $('[id^=sepclr]').prop("type", "button");
-
- $('[id^=sepclr]').click(function () {
- var color = $(this).attr('value');
- // Clear all the color classes
- $(this).parent('td').prop('class', '');
- $(this).parent('td').prev('td').prop('class', '');
- // Install our new color class
- $(this).parent('td').addClass(color);
- $(this).parent('td').prev('td').addClass(color);
- // Set the global color
- gColor = color;
- });
- }
-
// provide a warning message if the user tries to change page before saving
$(window).bind('beforeunload', function(){
if ((!saving && dirty) || newSeperator) {
@@ -1049,19 +916,6 @@ events.push(function() {
}
});
- //JS equivalent to PHP htmlspecialchars()
- function escapeHtml(text) {
- var map = {
- '&': '&amp;',
- '<': '&lt;',
- '>': '&gt;',
- '"': '&quot;',
- "'": '&#039;'
- };
-
- return text.replace(/[&<>"']/g, function(m) { return map[m]; });
- }
- // --------------------------------------------------------------------------------------------
});
//]]>
</script>
diff --git a/src/usr/local/www/jquery/pfSenseHelpers.js b/src/usr/local/www/jquery/pfSenseHelpers.js
index 476cc4f..76aaf51 100644
--- a/src/usr/local/www/jquery/pfSenseHelpers.js
+++ b/src/usr/local/www/jquery/pfSenseHelpers.js
@@ -465,3 +465,159 @@ $('.container .panel-heading a[data-toggle="collapse"]').each(function (idx, el)
}
});
});
+
+ // Separator bar stuff ------------------------------------------------------------------------
+
+ // Globals
+ gColor = 'bg-info';
+ newSeperator = false;
+ saving = false;
+ dirty = false;
+
+ $("#addsep").prop('type' ,'button');
+
+ $("#addsep").click(function() {
+ if (newSeperator) {
+ return(false);
+ }
+
+ gColor = 'bg-info';
+ // Inset a temporary bar in which the user can enter some optional text
+ sepcols = $( "#ruletable tr th" ).length - 2;
+
+ $('#ruletable > tbody:last').append('<tr>' +
+ '<td class="' + gColor + '" colspan="' + sepcols + '"><input id="newsep" placeholder="' + svbtnplaceholder + '" class="col-md-12" type="text" /></td>' +
+ '<td class="' + gColor + '" colspan="2"><button class="btn btn-default btn-sm" id="btnnewsep">' + svtxt + '</button>' +
+ '<button class="btn btn-default btn-sm" id="btncncsep">' + cncltxt + '</button>' +
+ '&nbsp;&nbsp;&nbsp;&nbsp;' +
+ '&nbsp;&nbsp;<a id="sepclrblue" value="bg-info"><i class="fa fa-circle text-info icon-pointer"></i></a>' +
+ '&nbsp;&nbsp;<a id="sepclrred" value="bg-danger"><i class="fa fa-circle text-danger icon-pointer"></i></a>' +
+ '&nbsp;&nbsp;<a id="sepclrgreen" value="bg-success"><i class="fa fa-circle text-success icon-pointer"></i></a>' +
+ '&nbsp;&nbsp;<a id="sepclrorange" value="bg-warning"><i class="fa fa-circle text-warning icon-pointer"></i></button>' +
+ '</td></tr>');
+
+ $('#newsep').focus();
+ newSeperator = true;
+
+ $("#btnnewsep").prop('type' ,'button');
+
+ // Watch escape and enter keys
+ $('#newsep').keyup(function(e) {
+ if(e.which == 27) {
+ $('#btncncsep').trigger('click');
+ }
+ });
+
+ $('#newsep').keypress(function(e) {
+ if(e.which == 13) {
+ $('#btnnewsep').trigger('click');
+ }
+ });
+
+ handle_colors();
+
+ // Remove the temporary separator bar and replace it with the final version containing the
+ // user's text and a delete icon
+ $("#btnnewsep").click(function() {
+ var septext = escapeHtml($('#newsep').val());
+ sepcols = $( "#ruletable tr th" ).length - 1;
+
+ $('#ruletable > tbody:last >tr:last').remove();
+ $('#ruletable > tbody:last').append('<tr class="ui-sortable-handle separator">' +
+ '<td class="' + gColor + '" colspan="' + sepcols + '">' + '<span class="' + gColor + '">' + septext + '</span></td>' +
+ '<td class="' + gColor + '"><a href="#"><i class="fa fa-trash sepdel"></i></a>' +
+ '</td></tr>');
+
+ $('#order-store').removeAttr('disabled');
+ newSeperator = false;
+ dirty = true;
+ });
+
+ // Cancel button
+ $('#btncncsep').click(function(e) {
+ e.preventDefault();
+ $(this).parents('tr').remove();
+ newSeperator = false;
+ });
+ });
+
+ // Delete a separator row
+ $(function(){
+ $('table').on('click','tr a .sepdel',function(e){
+ e.preventDefault();
+ $(this).parents('tr').remove();
+ $('#order-store').removeAttr('disabled');
+ dirty = true;
+ });
+ });
+
+ // Compose an inout array containing the row #, color and text for each separator
+ function save_separators() {
+ var seprow = 0;
+ var sepinput;
+ var sepnum = 0;
+
+ $('#ruletable > tbody > tr').each(function() {
+ if ($(this).hasClass('separator')) {
+ seprow = $(this).prev('tr').attr("id");
+ if (seprow == undefined) {
+ seprow = "fr-1";
+ }
+
+ sepinput = '<input type="hidden" name="separator[' + sepnum + '][row]" value="' + seprow + '"></input>';
+ $('form').append(sepinput);
+ sepinput = '<input type="hidden" name="separator[' + sepnum + '][text]" value="' + escapeHtml($(this).find('td').text()) + '"></input>';
+ $('form').append(sepinput);
+ sepinput = '<input type="hidden" name="separator[' + sepnum + '][color]" value="' + $(this).find('td').prop('class') + '"></input>';
+ $('form').append(sepinput);
+ sepinput = '<input type="hidden" name="separator[' + sepnum + '][if]" value="' + iface + '"></input>';
+ $('form').append(sepinput);
+ sepnum++;
+ }
+
+ if ($(this).parent('tbody').hasClass('user-entries')) {
+ seprow++;
+ }
+ });
+ }
+
+ function reindex_rules(section) {
+ var row = 0;
+
+ section.find('tr').each(function() {
+ if(this.id) {
+ $(this).attr("id", "fr" + row);
+ row++;
+ }
+ })
+ }
+
+ function handle_colors() {
+ $('[id^=sepclr]').prop("type", "button");
+
+ $('[id^=sepclr]').click(function () {
+ var color = $(this).attr('value');
+ // Clear all the color classes
+ $(this).parent('td').prop('class', '');
+ $(this).parent('td').prev('td').prop('class', '');
+ // Install our new color class
+ $(this).parent('td').addClass(color);
+ $(this).parent('td').prev('td').addClass(color);
+ // Set the global color
+ gColor = color;
+ });
+ }
+
+ //JS equivalent to PHP htmlspecialchars()
+ function escapeHtml(text) {
+ var map = {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&quot;',
+ "'": '&#039;'
+ };
+
+ return text.replace(/[&<>"']/g, function(m) { return map[m]; });
+ }
+ // --------------------------------------------------------------------------------------------
OpenPOWER on IntegriCloud