VPN: WireGuard: Peers - add instances column and move backreference logic to model using the volatile switch recently introduced for the Trust section. closes https://github.com/opnsense/core/issues/7221

This commit is contained in:
Ad Schellevis 2024-03-17 13:34:02 +01:00
parent 8faa33eeba
commit bc2ca23c93
5 changed files with 147 additions and 28 deletions

View File

@ -44,27 +44,39 @@ class ClientController extends ApiMutableModelControllerBase
return ['psk' => trim((new Backend())->configdRun('wireguard gen_psk')), 'status' => 'ok' ];
}
public function listServersAction()
{
if ($this->request->isGet()) {
$results = ['rows' => [], 'status' => 'ok'];
foreach ((new Server())->servers->server->iterateItems() as $key => $node) {
$results['rows'][] = [
'uuid' => $key,
'name' => (string)$node->name
];
}
return $results;
}
return ['status' => 'failed'];
}
public function searchClientAction()
{
$servers = $this->request->get('servers');
$filter_funct = function ($record) use ($servers) {
return empty($servers) || array_intersect(explode(',', $record->servers), $servers);
};
return $this->searchBase(
'clients.client',
["enabled", "name", "pubkey", "tunneladdress", "serveraddress", "serverport"]
["enabled", "name", "pubkey", "tunneladdress", "serveraddress", "serverport", "servers"],
null,
$filter_funct
);
}
public function getClientAction($uuid = null)
{
$result = $this->getBase('client', 'clients.client', $uuid);
if (!empty($result['client'])) {
$result['client']['servers'] = [];
foreach ((new Server())->servers->server->iterateItems() as $key => $node) {
$result['client']['servers'][$key] = [
'value' => (string)$node->name,
'selected' => in_array($uuid, explode(',', (string)$node->peers)) ? '1' : '0'
];
}
}
return $result;
return $this->getBase('client', 'clients.client', $uuid);
}
public function addClientAction()

View File

@ -4,7 +4,7 @@
<version>1.0.0</version>
<items>
<clients>
<client type="ArrayField">
<client type=".\ClientField">
<enabled type="BooleanField">
<Default>1</Default>
<Required>Y</Required>
@ -53,6 +53,16 @@
<MaximumValue>86400</MaximumValue>
<ValidationMessage>Please specify a value between 1 and 86400.</ValidationMessage>
</keepalive>
<servers type="ModelRelationField" volatile="true">
<Model>
<template>
<source>OPNsense.Wireguard.Server</source>
<items>servers.server</items>
<display>name</display>
</template>
</Model>
<Multiple>Y</Multiple>
</servers>
</client>
</clients>
</items>

View File

@ -0,0 +1,59 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\Wireguard\FieldTypes;
use OPNsense\Base\FieldTypes\ArrayField;
use OPNsense\Wireguard\Server;
class ClientField extends ArrayField
{
/**
* backreference servers
*/
protected function actionPostLoadingEvent()
{
$peers = [];
foreach ((new Server())->servers->server->iterateItems() as $key => $node) {
if (!empty((string)$node->peers)) {
foreach (explode(',', (string)$node->peers) as $peer) {
if (!isset($peers[$peer])) {
$peers[$peer] = [];
}
$peers[$peer][] = $key;
}
}
}
foreach ($this->internalChildnodes as $key => $node) {
if (isset($peers[$key])) {
$node->servers->setValue(implode(',', $peers[$key]));
}
}
return parent::actionPostLoadingEvent();
}
}

View File

@ -35,8 +35,8 @@
del:'/api/trust/cert/del/',
options:{
requestHandler: function(request){
if ( $('#ca_filter').val().length > 0) {
request['carefs'] = $('#ca_filter').val();
if ( $('#server_filter').val().length > 0) {
request['servers'] = $('#server_filter').val();
}
return request;
}

View File

@ -33,25 +33,49 @@
$('.selectpicker').selectpicker('refresh');
});
$("#grid-peers").UIBootgrid(
let grid_peers = $("#grid-peers").UIBootgrid(
{
'search':'/api/wireguard/client/searchClient',
'get':'/api/wireguard/client/getClient/',
'set':'/api/wireguard/client/setClient/',
'add':'/api/wireguard/client/addClient/',
'del':'/api/wireguard/client/delClient/',
'toggle':'/api/wireguard/client/toggleClient/'
search: '/api/wireguard/client/searchClient',
get: '/api/wireguard/client/getClient/',
set: '/api/wireguard/client/setClient/',
add: '/api/wireguard/client/addClient/',
del: '/api/wireguard/client/delClient/',
toggle: '/api/wireguard/client/toggleClient/',
options:{
requestHandler: function(request){
if ( $('#server_filter').val().length > 0) {
request['servers'] = $('#server_filter').val();
}
return request;
}
},
}
);
grid_peers.on("loaded.rs.jquery.bootgrid", function (e){
// reload servers before grid load
if ($("#server_filter > option").length == 0) {
ajaxGet('/api/wireguard/client/list_servers', {}, function(data, status){
if (data.rows !== undefined) {
for (let i=0; i < data.rows.length ; ++i) {
let row = data.rows[i];
$("#server_filter").append($("<option/>").val(row.uuid).html(row.name));
}
$("#server_filter").selectpicker('refresh');
}
});
}
});
$("#grid-instances").UIBootgrid(
{
'search':'/api/wireguard/server/searchServer',
'get':'/api/wireguard/server/getServer/',
'set':'/api/wireguard/server/setServer/',
'add':'/api/wireguard/server/addServer/',
'del':'/api/wireguard/server/delServer/',
'toggle':'/api/wireguard/server/toggleServer/'
search: '/api/wireguard/server/searchServer',
get: '/api/wireguard/server/getServer/',
set: '/api/wireguard/server/setServer/',
add: '/api/wireguard/server/addServer/',
del: '/api/wireguard/server/delServer/',
toggle: '/api/wireguard/server/toggleServer/'
}
);
@ -86,6 +110,11 @@
}
});
})
$("#filter_container").detach().prependTo('#grid-peers-header > .row > .actionBar > .actions');
$("#server_filter").change(function(){
$('#grid-peers').bootgrid('reload');
});
// update history on tab state and implement navigation
if(window.location.hash != "") {
$('a[href="' + window.location.hash + '"]').click()
@ -112,6 +141,14 @@
<i class="fa fa-fw fa-gear"></i>
</button>
</span>
<div class="hidden">
<!-- filter per server container -->
<div id="filter_container" class="btn-group">
<select id="server_filter" data-title="{{ lang._('Instances') }}" class="selectpicker" data-live-search="true" data-size="5" multiple data-width="200px">
</select>
</div>
</div>
<table id="grid-peers" class="table table-condensed table-hover table-striped" data-editDialog="dialogEditWireguardClient">
<thead>
<tr>
@ -121,6 +158,7 @@
<th data-column-id="serveraddress" data-type="string" data-visible="true">{{ lang._('Endpoint address') }}</th>
<th data-column-id="serverport" data-type="string" data-visible="true">{{ lang._('Endpoint port') }}</th>
<th data-column-id="tunneladdress" data-type="string" data-visible="true">{{ lang._('Allowed IPs') }}</th>
<th data-column-id="servers" data-type="string" data-visible="true">{{ lang._('Instances') }}</th>
<th data-column-id="commands" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
</tr>
</thead>