Firewall/Alias, work in progress UI parts, for https://github.com/opnsense/core/issues/1858

This commit is contained in:
Ad Schellevis 2018-06-26 17:32:46 +02:00
parent 9350297f18
commit 51bd00cf82
3 changed files with 270 additions and 3 deletions

View File

@ -11,6 +11,19 @@
<type>text</type>
<help>The name of the alias may only consist of the characters "a-z, A-Z, 0-9 and _". Aliases can be nested using this name.</help>
</field>
<field>
<id>alias.type</id>
<label>Type</label>
<type>dropdown</type>
</field>
<field>
<id>alias.content</id>
<label>Content</label>
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<separator>#10</separator>
</field>
<field>
<id>alias.description</id>
<label>Description</label>

View File

@ -2,7 +2,7 @@
<mount>//OPNSense/Firewall/Alias</mount>
<version>0.0.1</version>
<description>
OPNsense central management
Firewall aliases
</description>
<items>
<aliases>
@ -20,6 +20,23 @@
</check001>
</Constraints>
</name>
<type type="OptionField">
<Required>Y</Required>
<default>alert</default>
<OptionValues>
<host>Host(s)</host>
<network>Network(s)</network>
<port>Port(s)</port>
<url>URL (IPs)</url>
<url_ports>URL (Ports)</url_ports>
<urltable>URL Table (IPs)</urltable>
<urltable_ports>URL Table (Ports)</urltable_ports>
<geoip>GeoIP</geoip>
<external>External (advanced)</external>
</OptionValues>
</type>
<content type=".\AliasContentField">
</content>
<description type="TextField">
<Required>Y</Required>
<mask>/^([\t\n\v\f\r 0-9a-zA-Z.\-,_\x{00A0}-\x{FFFF}]){1,255}$/u</mask>

View File

@ -1,3 +1,13 @@
<link href="/ui/css/flags/flag-icon.css" rel="stylesheet">
<style>
@media (min-width: 768px) {
.modal-dialog {
width: 90%;
max-width:1200px;
}
}
</style>
<script>
$( document ).ready(function() {
$("#grid-aliases").UIBootgrid(
@ -9,6 +19,89 @@
toggle:'/api/firewall/alias/toggleItem/'
}
);
/**
* fetch regions and countries for geoip selection
*/
ajaxGet("/api/firewall/alias/listCountries", {}, function(data){
var regions = [];
$.each(data, function(country, item) {
if (!regions.includes(item.region) && item.region != null) {
regions.push(item.region);
}
});
regions.sort();
regions.map(function(item){
var $tr = $("<tr/>");
$tr.append("<td/>").text(item);
$tr.append(
$("<td/>").append($("<select class='selectpicker geoip_select' multiple='multiple' data-id='"+'geoip_region_'+item+"'/>"))
);
$("#alias_type_geoip > tbody").append($tr);
});
$.each(data, function(country, item) {
if (item.region != null) {
console.log($('.geoip_select[data-id="geoip_region_'+item.region+'"'));
$('.geoip_select[data-id="geoip_region_'+item.region+'"').append(
$("<option/>")
.val(country)
.data('icon', 'flag-icon flag-icon-' + country.toLowerCase() + ' flag-icon-squared')
.html(item.name)
);
}
});
$(".geoip_select").selectpicker();
$(".geoip_select").change(function(){
// unlink on change event
$("#alias\\.content").unbind('tokenize:tokens:change');
// copy items from geoip fields to content field
$("#alias\\.content").tokenize2().trigger('tokenize:clear');
$(".geoip_select").each(function () {
$.each($(this).val(), function(key, item){
$("#alias\\.content").tokenize2().trigger('tokenize:tokens:add', item);
});
});
$("#alias\\.content").tokenize2().trigger('tokenize:select');
// link on change event back
$("#alias\\.content").on('tokenize:tokens:change', function(e, value){
$("#alias\\.content").change();
});
});
});
/**
* Type selector, show correct type input.
*/
$("#alias\\.type").change(function(){
$(".alias_type").hide();
switch ($(this).val()) {
case 'geoip':
$("#alias_type_geoip").show();
break;
default:
$("#alias_type_default").show();
break;
}
});
/**
* push content changes to GeopIP selectors
*/
$("#alias\\.content").change(function(){
var items = $(this).val();
$(".geoip_select").each(function(){
var geo_item = $(this);
geo_item.val([]);
for (var i=0; i < items.length; ++i) {
geo_item.find('option[value="'+items[i]+'"]').prop("selected", true);
}
});
$(".geoip_select").selectpicker('refresh');
})
});
</script>
@ -45,5 +138,149 @@
</div>
</section>
{# include dialogs #}
{{ partial("layout_partials/base_dialog",['fields':formDialogAlias,'id':'DialogAlias','label':lang._('Edit Alias')])}}
{# Edit dialog #}
<div class="modal fade" id="DialogAlias" tabindex="-1" role="dialog" aria-labelledby="DialogAliasLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="formDialogAliasLabel">{{lang._('Edit Alias')}}</h4>
</div>
<div class="modal-body">
<form id="frm_DialogAlias">
<div class="table-responsive">
<table class="table table-striped table-condensed">
<colgroup>
<col class="col-md-3"/>
<col class="col-md-5"/>
<col class="col-md-4"/>
</colgroup>
<tbody>
<tr>
<td></td>
<td colspan="2" style="text-align:right;">
<small>{{ lang._('full help') }} </small>
<a href="#">
<i class="fa fa-toggle-off text-danger" id="show_all_help_formDialogformDialogAlias">
</i>
</a>
</td>
</tr>
<tr id="row_alias.enabled" >
<td>
<div class="control-label" id="control_label_alias.enabled">
<a id="help_for_alias.enabled" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a>
<b>enabled</b>
</div>
</td>
<td>
<input type="checkbox" id="alias.enabled">
<div class="hidden" data-for="help_for_alias.enabled">
<small>enable this alias</small>
</div>
</td>
<td>
<span class="help-block" id="help_block_alias.enabled"></span>
</td>
</tr>
<tr id="row_alias.name" >
<td>
<div class="control-label" id="control_label_alias.name">
<a id="help_for_alias.name" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a>
<b>{{lang._('Name')}}</b>
</div>
</td>
<td>
<input type="text" class="form-control" size="50" id="alias.name" >
<div class="hidden" data-for="help_for_alias.name">
<small>
{{lang._('The name of the alias may only consist of the characters "a-z, A-Z, 0-9 and _". Aliases can be nested using this name.')}}
</small>
</div>
</td>
<td>
<span class="help-block" id="help_block_alias.name"></span>
</td>
</tr>
<tr id="row_alias.type" >
<td>
<div class="control-label" id="control_label_alias.type">
<i class="fa fa-info-circle text-muted"></i>
<b>{{lang._('Type')}}</b>
</div>
</td>
<td>
<select id="alias.type" class="selectpicker" data-width="334px"></select>
</td>
<td>
<span class="help-block" id="help_block_alias.type"></span>
</td>
</tr>
<tr id="row_alias.content" >
<td>
<div class="control-label" id="control_label_alias.content">
<i class="fa fa-info-circle text-muted"></i>
<b>{{lang._('Content')}}</b>
</div>
</td>
<td>
<div class="alias_type" id="alias_type_default">
<select multiple="multiple"
id="alias.content"
class="tokenize"
data-width="334px"
data-allownew="true"
data-nbdropdownelements="10"
data-live-search="true"
data-separator="#10">
</select>
</div>
<table class="table table-condensed alias_type" id="alias_type_geoip" style="display: none">
<thead>
<tr>
<th>region</th>
<th>countries</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<br/><a href="#" class="text-danger" id="clear-options_alias.content"><i class="fa fa-times-circle"></i>
<small>{{lang._('Clear All')}}</small></a>
</td>
<td>
<span class="help-block" id="help_block_alias.content"></span>
</td>
</tr>
<tr id="row_alias.description" >
<td>
<div class="control-label" id="control_label_alias.description">
<a id="help_for_alias.description" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a>
<b>{{lang._('Description')}}</b>
</div>
</td>
<td>
<input type="text" class="form-control" size="50" id="alias.description" >
<div class="hidden" data-for="help_for_alias.description">
<small>{{lang._('You may enter a description here for your reference (not parsed).')}}</small>
</div>
</td>
<td>
<span class="help-block" id="help_block_alias.description"></span>
</td>
</tr>
</tbody>
</table>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{ lang._('Close') }}</button>
<button type="button" class="btn btn-primary" id="btn_DialogAlias_save">{{ lang._('Save changes') }}
<i id="btn_formDialogAlias_save_progress" class=""></i></button>
</div>
</div>
</div>
</div>