Added clients page filter by subnet range

This commit is contained in:
0xCA 2023-11-06 02:53:55 +05:00
parent 53eaab0079
commit 2027b3fa5d
7 changed files with 103 additions and 7 deletions

View file

@ -18,6 +18,11 @@ function renderClientList(data) {
allowedIpsHtml += `<small class="badge badge-secondary">${obj}</small>&nbsp;`;
})
let subnetRangesString = "";
if (obj.Client.subnet_ranges && obj.Client.subnet_ranges.length > 0) {
subnetRangesString = obj.Client.subnet_ranges.join(',')
}
// render client html content
let html = `<div class="col-sm-6 col-md-6 col-lg-4" id="client_${obj.Client.id}">
<div class="info-box">
@ -59,6 +64,7 @@ function renderClientList(data) {
<hr>
<span class="info-box-text"><i class="fas fa-user"></i> ${obj.Client.name}</span>
<span class="info-box-text" style="display: none"><i class="fas fa-key"></i> ${obj.Client.public_key}</span>
<span class="info-box-text" style="display: none"><i class="fas fa-subnetrange"></i>${subnetRangesString}</span>
<span class="info-box-text"><i class="fas fa-envelope"></i> ${obj.Client.email}</span>
<span class="info-box-text"><i class="fas fa-clock"></i>
${prettyDateTime(obj.Client.created_at)}</span>

View file

@ -366,6 +366,10 @@ func GetClients(db store.IStore) echo.HandlerFunc {
})
}
for i, clientData := range clientDataList {
clientDataList[i] = util.FillClientSubnetRange(clientData)
}
return c.JSON(http.StatusOK, clientDataList)
}
}
@ -391,7 +395,7 @@ func GetClient(db store.IStore) echo.HandlerFunc {
return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "Client not found"})
}
return c.JSON(http.StatusOK, clientData)
return c.JSON(http.StatusOK, util.FillClientSubnetRange(clientData))
}
}

View file

@ -12,6 +12,7 @@ type Client struct {
PresharedKey string `json:"preshared_key"`
Name string `json:"name"`
Email string `json:"email"`
SubnetRanges []string `json:"subnet_ranges,omitempty"`
AllocatedIPs []string `json:"allocated_ips"`
AllowedIPs []string `json:"allowed_ips"`
ExtraAllowedIPs []string `json:"extra_allowed_ips"`
@ -29,7 +30,7 @@ type ClientData struct {
}
type QRCodeSettings struct {
Enabled bool
IncludeDNS bool
IncludeMTU bool
Enabled bool
IncludeDNS bool
IncludeMTU bool
}

View file

@ -58,11 +58,13 @@
</div>
<div class="form-group form-group-sm">
<select name="status-selector" id="status-selector" class="custom-select form-control-navbar" style="margin-left: 0.5em; height: 90%; font-size: 14px;">
<!-- SEE updateSearchList() in clients.html BEFORE EDITING -->
<option value="All">All</option>
<option value="Enabled">Enabled</option>
<option value="Disabled">Disabled</option>
<option value="Connected">Connected</option>
<option value="Disconnected">Disconnected</option>
<!-- SEE updateSearchList() in clients.html BEFORE EDITING -->
</select>
</div>
</form>
@ -210,7 +212,7 @@
<input type="text" class="form-control" id="client_email" name="client_email">
</div>
<div class="form-group">
<label for="subnet_ranges" class="control-label">Subnet ranges</label>
<label for="subnet_ranges" class="control-label">Subnet range</label>
<select id="subnet_ranges" class="select2"
data-placeholder="Select a subnet range" style="width: 100%;">
</select>
@ -374,7 +376,6 @@
$(document).ready(function () {
addGlobalStyle(`
.toast-top-right-fix {
top: 67px;
@ -387,6 +388,8 @@
toastr.options.positionClass = 'toast-top-right-fix';
updateApplyConfigVisibility()
// from clients.html
updateSearchList()
});

View file

@ -279,6 +279,36 @@ Wireguard Clients
});
});
}
function updateSearchList() {
$.getJSON("{{.basePath}}/api/subnet-ranges", null, function(data) {
$("#status-selector option").remove();
$("#status-selector").append(
$("<option></option>")
.text("All")
.val("All"),
$("<option></option>")
.text("Enabled")
.val("Enabled"),
$("<option></option>")
.text("Disabled")
.val("Disabled"),
$("<option></option>")
.text("Connected")
.val("Connected"),
$("<option></option>")
.text("Disconnected")
.val("Disconnected")
);
$.each(data, function(index, item) {
$("#status-selector").append(
$("<option></option>")
.text(item)
.val(item)
);
});
});
}
</script>
<script>
// load client list
@ -368,7 +398,18 @@ Wireguard Clients
});
break;
default:
$('.col-lg-4').show();
$('.col-lg-4').hide();
const selectedSR = $("#status-selector").val()
$(".fa-subnetrange").each(function () {
const srs = $(this).parent().text().trim().split(',')
for (const sr of srs) {
if (sr === selectedSR) {
$(this).closest('.col-lg-4').show();
break
}
}
})
// $('.col-lg-4').show();
break;
}
});

3
util/cache.go Normal file
View file

@ -0,0 +1,3 @@
package util
var IPToSubnetRange = map[string]uint16{}

View file

@ -410,6 +410,44 @@ func ValidateIPAllocation(serverAddresses []string, ipAllocatedList []string, ip
return true, nil
}
// findSubnetRangeForIP to find first SR for IP, and cache the match
func findSubnetRangeForIP(cidr string) (uint16, error) {
ip, _, err := net.ParseCIDR(cidr)
if err != nil {
return 0, err
}
if srName, ok := IPToSubnetRange[ip.String()]; ok {
return srName, nil
}
for srIndex, sr := range SubnetRangesOrder {
for _, srCIDR := range SubnetRanges[sr] {
if srCIDR.Contains(ip) {
IPToSubnetRange[ip.String()] = uint16(srIndex)
return uint16(srIndex), nil
}
}
}
return 0, fmt.Errorf("Subnet range not foud for this IP")
}
// FillClientSubnetRange to fill subnet ranges client belongs to, does nothing if SRs are not found
func FillClientSubnetRange(client model.ClientData) model.ClientData {
cl := *client.Client
for _, ip := range cl.AllocatedIPs {
sr, err := findSubnetRangeForIP(ip)
if err != nil {
continue
}
cl.SubnetRanges = append(cl.SubnetRanges, SubnetRangesOrder[sr])
}
return model.ClientData{
Client: &cl,
QRCode: client.QRCode,
}
}
// ValidateAndFixSubnetRanges to check if subnet ranges are valid for the server configuration
// Removes all non-valid CIDRs
func ValidateAndFixSubnetRanges(db store.IStore) error {