Merge pull request #74 from danielperna84/netstats
Modify BANNED_IPS and ALLOWED_NETWORKS at runtime
This commit is contained in:
commit
07cf5d5219
4 changed files with 601 additions and 7 deletions
19
README.md
19
README.md
|
@ -79,6 +79,25 @@ The way this is implemented works in the following order:
|
|||
- No: Return error 420
|
||||
- Yes: Continue and display UI of configurator
|
||||
|
||||
### API
|
||||
|
||||
Starting at version 0.2.5 you can add / remove IP addresses and networks from and to the `ALLOWED_NETWORKS` and `BANNED_IPS` lists at runtime. Keep in mind though, that these changes are not persistent and will be lost when the service is restarted. The API can be used through the UI in the _Network status_ menu or by sending POST requests. A possible use case could be programmatically allowing access from your dynamic public IP, which can be required for some setups involving SSL.
|
||||
|
||||
#### API targets:
|
||||
|
||||
- `api/allowed_networks`
|
||||
#### Methods:
|
||||
- `add`
|
||||
- `remove`
|
||||
#### Example:
|
||||
- `curl -d "method=add&network=1.2.3.4" -X POST http://127.0.0.1:3218/api/allowed_networks`
|
||||
- `api/banned_ips`
|
||||
#### Methods:
|
||||
- `ban`
|
||||
- `unban`
|
||||
#### Example:
|
||||
- Example: `curl -d "method=ban&ip=9.9.9.9" -X POST http://127.0.0.1:3218/api/banned_ips`
|
||||
|
||||
### Embedding into HASS
|
||||
HASS has the [panel_iframe](https://home-assistant.io/components/panel_iframe/) component. With this it is possible to embed the configurator directly into HASS, allowing you to modify your configuration through the HASS frontend.
|
||||
An example configuration would look like this:
|
||||
|
|
|
@ -2,6 +2,7 @@ Version 0.2.5 (2018-)
|
|||
- Added warning-logs for access failure @danielperna84
|
||||
- Added transparency to whitespace characters @danielperna84
|
||||
- Using external repository for Docker @Munsio
|
||||
- Modify BANNED_IPS and ALLOWED_NETWORKS at runtime @danielperna84
|
||||
|
||||
Version 0.2.4 (2018-01-02)
|
||||
- Added YAML linting @AtoxIO
|
||||
|
|
337
configurator.py
337
configurator.py
|
@ -299,8 +299,13 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
}
|
||||
|
||||
.input-field input[type=text].valid {
|
||||
border-bottom: 1px solid #03a9f4;;
|
||||
box-shadow: 0 1px 0 0 #03a9f4;;
|
||||
border-bottom: 1px solid #03a9f4 !important;
|
||||
box-shadow: 0 1px 0 0 #03a9f4 !important;
|
||||
}
|
||||
|
||||
.input-field input[type=text]:focus {
|
||||
border-bottom: 1px solid #03a9f4 !important;
|
||||
box-shadow: 0 1px 0 0 #03a9f4 !important;
|
||||
}
|
||||
|
||||
.row .input-field input:focus {
|
||||
|
@ -624,6 +629,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
<li><a class="modal-trigger" target="_blank" href="#modal_components">HASS Components</a></li>
|
||||
<li><a class="modal-trigger" target="_blank" href="#modal_icons">Material Icons</a></li>
|
||||
<li><a href="#" data-activates="ace_settings" class="ace_settings-collapse">Editor Settings</a></li>
|
||||
<li><a class="modal-trigger" href="#modal_netstat" onclick="get_netstat()">Network status</a></li>
|
||||
<li><a class="modal-trigger" href="#modal_about">About HASS-Configurator</a></li>
|
||||
<li class="divider"></li>
|
||||
<!--<li><a href="#modal_check_config">Check HASS Configuration</a></li>-->
|
||||
|
@ -640,6 +646,7 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
<li><a target="_blank" href="https://home-assistant.io/components/">HASS Components</a></li>
|
||||
<li><a target="_blank" href="https://materialdesignicons.com/">Material Icons</a></li>
|
||||
<li><a href="#" data-activates="ace_settings" class="ace_settings-collapse">Editor Settings</a></li>
|
||||
<li><a class="modal-trigger" href="#modal_netstat" onclick="get_netstat()">Network status</a></li>
|
||||
<li><a class="modal-trigger" href="#modal_about">About HASS-Configurator</a></li>
|
||||
<li class="divider"></li>
|
||||
<!--<li><a href="#modal_check_config">Check HASS Configuration</a></li>-->
|
||||
|
@ -1343,6 +1350,46 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
<a onclick="restart()" class=" modal-action modal-close waves-effect waves-green btn-flat light-blue-text">Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_a_net_remove" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3">Remove allowed network / IP<i class="mdi mdi-settings right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<p>Do you really want to remove the network / IP <b><span id="removenet"></span></b> from the list of allowed networks?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">No</a>
|
||||
<a onclick="a_net_remove()" class=" modal-action modal-close waves-effect waves-green btn-flat light-blue-text">Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_a_net_add" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3">Add allowed network / IP<i class="mdi mdi-settings right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<p>Do you really want to Add the network / IP <b><span id="addnet"></span></b> to the list of allowed networks?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">No</a>
|
||||
<a onclick="a_net_add()" class=" modal-action modal-close waves-effect waves-green btn-flat light-blue-text">Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_unban" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3">Unban IP<i class="mdi mdi-settings right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<p>Do you really want to unban the IP <b><span id="unbanip"></span></b>?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">No</a>
|
||||
<a onclick="banned_unban()" class=" modal-action modal-close waves-effect waves-green btn-flat light-blue-text">Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_ban" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3">Ban IP<i class="mdi mdi-settings right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<p>Do you really want to ban the IP <b><span id="banip"></span></b>?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">No</a>
|
||||
<a onclick="banned_ban()" class=" modal-action modal-close waves-effect waves-green btn-flat light-blue-text">Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_exec_command" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3">Execute shell command<i class="mdi mdi-laptop right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
|
@ -1412,13 +1459,42 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
<input type="text" id="newbranch">
|
||||
<label class="active" for="newbranch">New Branch Name</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">Cancel</a>
|
||||
<a onclick="newbranch(document.getElementById('newbranch').value)" class=" modal-action modal-close waves-effect waves-green btn-flat light-blue-text">OK</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_netstat" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3">Network status<i class="mdi mdi-network right grey-text text-darken-3" style="font-size: 2.48rem;"></i></h4>
|
||||
<p><label for="listening_address">Listening address: </label><span id="listening_address">$listening_address</span></p>
|
||||
<p><label for="hass_api_address">HASS API address: </label><span id="hass_api_address">$hass_api_address</span></p>
|
||||
<p>Modifying the following lists is not persistent. To statically control access please use the configuration file.</p>
|
||||
<p>
|
||||
<ul id="allowed_networks" class="collection with-header"></ul>
|
||||
<br />
|
||||
<div class="input-field">
|
||||
<a href="#" class="prefix" onclick="helper_a_net_add()"><i class="mdi mdi-plus-circle prefix light-blue-text"></i></a></i>
|
||||
<input placeholder="192.168.0.0/16" id="add_net_ip" type="text">
|
||||
<label for="add_net_ip">Add network / IP</label>
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
<ul id="banned_ips" class="collection with-header"></ul>
|
||||
<br />
|
||||
<div class="input-field">
|
||||
<a href="#" class="prefix" onclick="helper_banned_ban()"><i class="mdi mdi-plus-circle prefix light-blue-text"></i></a></i>
|
||||
<input placeholder="1.2.3.4" id="add_banned_ip" type="text">
|
||||
<label for="add_banned_ip">Ban IP</label>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">Cancel</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_about" class="modal modal-fixed-footer">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3"><a class="black-text" href="https://github.com/danielperna84/hass-configurator/" target="_blank">HASS Configurator</a></h4>
|
||||
|
@ -2378,6 +2454,175 @@ INDEX = Template(r"""<!DOCTYPE html>
|
|||
});
|
||||
}
|
||||
|
||||
function get_netstat() {
|
||||
$.get("api/netstat", function (resp) {
|
||||
if (resp.hasOwnProperty("allowed_networks")) {
|
||||
var allowed_list = document.getElementById("allowed_networks");
|
||||
while (allowed_list.firstChild) {
|
||||
allowed_list.removeChild(allowed_list.firstChild);
|
||||
}
|
||||
var header = document.createElement("li");
|
||||
header.classList.add("collection-header");
|
||||
var header_h4 = document.createElement("h4");
|
||||
header_h4.innerText = "Allowed networks";
|
||||
header_h4.classList.add("grey-text");
|
||||
header_h4.classList.add("text-darken-3");
|
||||
header.appendChild(header_h4);
|
||||
allowed_list.appendChild(header);
|
||||
for (var i = 0; i < resp.allowed_networks.length; i++) {
|
||||
var li = document.createElement("li");
|
||||
li.classList.add("collection-item");
|
||||
var li_div = document.createElement("div");
|
||||
var address = document.createElement("span");
|
||||
address.innerText = resp.allowed_networks[i];
|
||||
li_div.appendChild(address);
|
||||
var li_a = document.createElement("a");
|
||||
li_a.classList.add("light-blue-text");
|
||||
li_a.href = "#!";
|
||||
li_a.classList.add("secondary-content");
|
||||
var li_a_i = document.createElement("i");
|
||||
li_a_i.classList.add("mdi");
|
||||
li_a_i.classList.add("mdi-delete");
|
||||
li_a_i.innerText = "Remove";
|
||||
li_a.appendChild(li_a_i);
|
||||
li_a.setAttribute("onclick", "helper_a_net_remove('" + resp.allowed_networks[i] + "')");
|
||||
li_div.appendChild(li_a);
|
||||
li.appendChild(li_div);
|
||||
allowed_list.appendChild(li);
|
||||
}
|
||||
}
|
||||
if (resp.hasOwnProperty("banned_ips")) {
|
||||
var banlist = document.getElementById("banned_ips");
|
||||
while (banlist.firstChild) {
|
||||
banlist.removeChild(banlist.firstChild);
|
||||
}
|
||||
var header = document.createElement("li");
|
||||
header.classList.add("collection-header");
|
||||
var header_h4 = document.createElement("h4");
|
||||
header_h4.innerText = "Banned IPs";
|
||||
header_h4.classList.add("grey-text");
|
||||
header_h4.classList.add("text-darken-3");
|
||||
header.appendChild(header_h4);
|
||||
banlist.appendChild(header);
|
||||
for (var i = 0; i < resp.banned_ips.length; i++) {
|
||||
var li = document.createElement("li");
|
||||
li.classList.add("collection-item");
|
||||
var li_div = document.createElement("div");
|
||||
var address = document.createElement("span");
|
||||
address.innerText = resp.banned_ips[i];
|
||||
li_div.appendChild(address);
|
||||
var li_a = document.createElement("a");
|
||||
li_a.classList.add("light-blue-text");
|
||||
li_a.href = "#!";
|
||||
li_a.classList.add("secondary-content");
|
||||
var li_a_i = document.createElement("i");
|
||||
li_a_i.classList.add("mdi");
|
||||
li_a_i.classList.add("mdi-delete");
|
||||
li_a_i.innerText = "Unban";
|
||||
li_a.appendChild(li_a_i);
|
||||
li_a.setAttribute("onclick", "helper_banned_unban('" + resp.banned_ips[i] + "')");
|
||||
li_div.appendChild(li_a);
|
||||
li.appendChild(li_div);
|
||||
banlist.appendChild(li);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function helper_a_net_remove(network) {
|
||||
document.getElementById("removenet").innerText = network;
|
||||
$('#modal_netstat').modal('close');
|
||||
$('#modal_a_net_remove').modal('open');
|
||||
}
|
||||
|
||||
function a_net_remove() {
|
||||
var network = document.getElementById("removenet").innerText
|
||||
data = new Object();
|
||||
data.network = network;
|
||||
data.method = 'remove';
|
||||
$.post("api/allowed_networks", data).done(function(resp) {
|
||||
if (resp.error) {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 5000);
|
||||
}
|
||||
else {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function helper_a_net_add() {
|
||||
document.getElementById("addnet").innerText = document.getElementById("add_net_ip").value;
|
||||
document.getElementById("add_net_ip").value = "";
|
||||
$('#modal_netstat').modal('close');
|
||||
$('#modal_a_net_add').modal('open');
|
||||
}
|
||||
|
||||
function a_net_add() {
|
||||
var network = document.getElementById("addnet").innerText
|
||||
data = new Object();
|
||||
data.network = network;
|
||||
data.method = 'add';
|
||||
$.post("api/allowed_networks", data).done(function(resp) {
|
||||
if (resp.error) {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 5000);
|
||||
}
|
||||
else {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function helper_banned_unban(ip) {
|
||||
document.getElementById("unbanip").innerText = ip;
|
||||
$('#modal_netstat').modal('close');
|
||||
$('#modal_unban').modal('open');
|
||||
}
|
||||
|
||||
function banned_unban() {
|
||||
var ip = document.getElementById("unbanip").innerText
|
||||
data = new Object();
|
||||
data.ip = ip;
|
||||
data.method = 'unban';
|
||||
$.post("api/banned_ips", data).done(function(resp) {
|
||||
if (resp.error) {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 5000);
|
||||
}
|
||||
else {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function helper_banned_ban() {
|
||||
document.getElementById("banip").innerText = document.getElementById("add_banned_ip").value;
|
||||
document.getElementById("add_banned_ip").value = "";
|
||||
$('#modal_netstat').modal('close');
|
||||
$('#modal_ban').modal('open');
|
||||
}
|
||||
|
||||
function banned_ban() {
|
||||
var ip = document.getElementById("banip").innerText
|
||||
data = new Object();
|
||||
data.ip = ip;
|
||||
data.method = 'ban';
|
||||
$.post("api/banned_ips", data).done(function(resp) {
|
||||
if (resp.error) {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 5000);
|
||||
}
|
||||
else {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function save() {
|
||||
var filepath = document.getElementById('currentfile').value;
|
||||
if (filepath.length > 0) {
|
||||
|
@ -3063,6 +3308,16 @@ class RequestHandler(BaseHTTPRequestHandler):
|
|||
if os.path.isdir(dirpath):
|
||||
self.wfile.write(os.path.abspath(os.path.dirname(dirpath)))
|
||||
return
|
||||
elif req.path == '/api/netstat':
|
||||
content = ""
|
||||
self.send_header('Content-type', 'text/json')
|
||||
self.end_headers()
|
||||
res = {
|
||||
"allowed_networks": ALLOWED_NETWORKS,
|
||||
"banned_ips": BANNED_IPS
|
||||
}
|
||||
self.wfile.write(bytes(json.dumps(res), "utf8"))
|
||||
return
|
||||
elif req.path == '/api/restart':
|
||||
LOG.info("/api/restart")
|
||||
self.send_header('Content-type', 'text/json')
|
||||
|
@ -3227,7 +3482,10 @@ class RequestHandler(BaseHTTPRequestHandler):
|
|||
states=states,
|
||||
current=VERSION,
|
||||
versionclass=color,
|
||||
separator="\%s" % os.sep if os.sep == "\\" else os.sep)
|
||||
separator="\%s" % os.sep if os.sep == "\\" else os.sep,
|
||||
listening_address="%s://%s:%i" % (
|
||||
'https' if SSL_CERTIFICATE else 'http', LISTENIP, LISTENPORT),
|
||||
hass_api_address="%s" % (HASS_API, ))
|
||||
self.wfile.write(bytes(html, "utf8"))
|
||||
return
|
||||
else:
|
||||
|
@ -3236,6 +3494,7 @@ class RequestHandler(BaseHTTPRequestHandler):
|
|||
self.wfile.write(bytes("File not found", "utf8"))
|
||||
|
||||
def do_POST(self):
|
||||
global ALLOWED_NETWORKS, BANNED_IPS
|
||||
if not check_access(self.client_address[0]):
|
||||
self.do_BLOCK()
|
||||
return
|
||||
|
@ -3649,6 +3908,76 @@ class RequestHandler(BaseHTTPRequestHandler):
|
|||
LOG.warning(err)
|
||||
else:
|
||||
response['message'] = "Missing filename or text"
|
||||
elif req.path == '/api/allowed_networks':
|
||||
try:
|
||||
postvars = parse_qs(self.rfile.read(length).decode('utf-8'), keep_blank_values=1)
|
||||
except Exception as err:
|
||||
LOG.warning(err)
|
||||
response['message'] = "%s" % (str(err))
|
||||
postvars = {}
|
||||
if 'network' in postvars.keys() and 'method' in postvars.keys():
|
||||
if postvars['network'] and postvars['method']:
|
||||
try:
|
||||
network = unquote(postvars['network'][0])
|
||||
method = unquote(postvars['method'][0])
|
||||
if method == 'remove':
|
||||
if network in ALLOWED_NETWORKS:
|
||||
ALLOWED_NETWORKS.remove(network)
|
||||
if not ALLOWED_NETWORKS:
|
||||
ALLOWED_NETWORKS.append("0.0.0.0/0")
|
||||
response['error'] = False
|
||||
elif method == 'add':
|
||||
ipaddress.ip_network(network)
|
||||
ALLOWED_NETWORKS.append(network)
|
||||
response['error'] = False
|
||||
else:
|
||||
response['error'] = True
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'text/json')
|
||||
self.end_headers()
|
||||
response['error'] = False
|
||||
response['message'] = "ALLOWED_NETWORKS (%s): %s" % (method, network)
|
||||
self.wfile.write(bytes(json.dumps(response), "utf8"))
|
||||
return
|
||||
except Exception as err:
|
||||
response['error'] = True
|
||||
response['message'] = "%s" % (str(err))
|
||||
LOG.warning(err)
|
||||
else:
|
||||
response['message'] = "Missing network"
|
||||
elif req.path == '/api/banned_ips':
|
||||
try:
|
||||
postvars = parse_qs(self.rfile.read(length).decode('utf-8'), keep_blank_values=1)
|
||||
except Exception as err:
|
||||
LOG.warning(err)
|
||||
response['message'] = "%s" % (str(err))
|
||||
postvars = {}
|
||||
if 'ip' in postvars.keys() and 'method' in postvars.keys():
|
||||
if postvars['ip'] and postvars['method']:
|
||||
try:
|
||||
ip = unquote(postvars['ip'][0])
|
||||
method = unquote(postvars['method'][0])
|
||||
if method == 'unban':
|
||||
if ip in BANNED_IPS:
|
||||
BANNED_IPS.remove(ip)
|
||||
response['error'] = False
|
||||
elif method == 'ban':
|
||||
ipaddress.ip_network(ip)
|
||||
BANNED_IPS.append(ip)
|
||||
else:
|
||||
response['error'] = True
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'text/json')
|
||||
self.end_headers()
|
||||
response['message'] = "BANNED_IPS (%s): %s" % (method, ip)
|
||||
self.wfile.write(bytes(json.dumps(response), "utf8"))
|
||||
return
|
||||
except Exception as err:
|
||||
response['error'] = True
|
||||
response['message'] = "%s" % (str(err))
|
||||
LOG.warning(err)
|
||||
else:
|
||||
response['message'] = "Missing IP"
|
||||
else:
|
||||
response['message'] = "Invalid method"
|
||||
self.send_response(200)
|
||||
|
|
251
dev.html
251
dev.html
|
@ -220,8 +220,13 @@
|
|||
}
|
||||
|
||||
.input-field input[type=text].valid {
|
||||
border-bottom: 1px solid #03a9f4;;
|
||||
box-shadow: 0 1px 0 0 #03a9f4;;
|
||||
border-bottom: 1px solid #03a9f4 !important;
|
||||
box-shadow: 0 1px 0 0 #03a9f4 !important;
|
||||
}
|
||||
|
||||
.input-field input[type=text]:focus {
|
||||
border-bottom: 1px solid #03a9f4 !important;
|
||||
box-shadow: 0 1px 0 0 #03a9f4 !important;
|
||||
}
|
||||
|
||||
.row .input-field input:focus {
|
||||
|
@ -545,6 +550,7 @@
|
|||
<li><a class="modal-trigger" target="_blank" href="#modal_components">HASS Components</a></li>
|
||||
<li><a class="modal-trigger" target="_blank" href="#modal_icons">Material Icons</a></li>
|
||||
<li><a href="#" data-activates="ace_settings" class="ace_settings-collapse">Editor Settings</a></li>
|
||||
<li><a class="modal-trigger" href="#modal_netstat" onclick="get_netstat()">Network status</a></li>
|
||||
<li><a class="modal-trigger" href="#modal_about">About HASS-Configurator</a></li>
|
||||
<li class="divider"></li>
|
||||
<!--<li><a href="#modal_check_config">Check HASS Configuration</a></li>-->
|
||||
|
@ -561,6 +567,7 @@
|
|||
<li><a target="_blank" href="https://home-assistant.io/components/">HASS Components</a></li>
|
||||
<li><a target="_blank" href="https://materialdesignicons.com/">Material Icons</a></li>
|
||||
<li><a href="#" data-activates="ace_settings" class="ace_settings-collapse">Editor Settings</a></li>
|
||||
<li><a class="modal-trigger" href="#modal_netstat" onclick="get_netstat()">Network status</a></li>
|
||||
<li><a class="modal-trigger" href="#modal_about">About HASS-Configurator</a></li>
|
||||
<li class="divider"></li>
|
||||
<!--<li><a href="#modal_check_config">Check HASS Configuration</a></li>-->
|
||||
|
@ -1264,6 +1271,46 @@
|
|||
<a onclick="restart()" class=" modal-action modal-close waves-effect waves-green btn-flat light-blue-text">Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_a_net_remove" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3">Remove allowed network / IP<i class="mdi mdi-settings right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<p>Do you really want to remove the network / IP <b><span id="removenet"></span></b> from the list of allowed networks?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">No</a>
|
||||
<a onclick="a_net_remove()" class=" modal-action modal-close waves-effect waves-green btn-flat light-blue-text">Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_a_net_add" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3">Add allowed network / IP<i class="mdi mdi-settings right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<p>Do you really want to Add the network / IP <b><span id="addnet"></span></b> to the list of allowed networks?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">No</a>
|
||||
<a onclick="a_net_add()" class=" modal-action modal-close waves-effect waves-green btn-flat light-blue-text">Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_unban" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3">Unban IP<i class="mdi mdi-settings right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<p>Do you really want to unban the IP <b><span id="unbanip"></span></b>?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">No</a>
|
||||
<a onclick="banned_unban()" class=" modal-action modal-close waves-effect waves-green btn-flat light-blue-text">Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_ban" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3">Ban IP<i class="mdi mdi-settings right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
<p>Do you really want to ban the IP <b><span id="banip"></span></b>?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">No</a>
|
||||
<a onclick="banned_ban()" class=" modal-action modal-close waves-effect waves-green btn-flat light-blue-text">Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_exec_command" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3">Execute shell command<i class="mdi mdi-laptop right grey-text text-darken-3" style="font-size: 2rem;"></i></h4>
|
||||
|
@ -1333,13 +1380,42 @@
|
|||
<input type="text" id="newbranch">
|
||||
<label class="active" for="newbranch">New Branch Name</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">Cancel</a>
|
||||
<a onclick="newbranch(document.getElementById('newbranch').value)" class=" modal-action modal-close waves-effect waves-green btn-flat light-blue-text">OK</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_netstat" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3">Network status<i class="mdi mdi-network right grey-text text-darken-3" style="font-size: 2.48rem;"></i></h4>
|
||||
<p><label for="listening_address">Listening address: </label><span id="listening_address">$listening_address</span></p>
|
||||
<p><label for="hass_api_address">HASS API address: </label><span id="hass_api_address">$hass_api_address</span></p>
|
||||
<p>Modifying the following lists is not persistent. To statically control access please use the configuration file.</p>
|
||||
<p>
|
||||
<ul id="allowed_networks" class="collection with-header"></ul>
|
||||
<br />
|
||||
<div class="input-field">
|
||||
<a href="#" class="prefix" onclick="helper_a_net_add()"><i class="mdi mdi-plus-circle prefix light-blue-text"></i></a></i>
|
||||
<input placeholder="192.168.0.0/16" id="add_net_ip" type="text">
|
||||
<label for="add_net_ip">Add network / IP</label>
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
<ul id="banned_ips" class="collection with-header"></ul>
|
||||
<br />
|
||||
<div class="input-field">
|
||||
<a href="#" class="prefix" onclick="helper_banned_ban()"><i class="mdi mdi-plus-circle prefix light-blue-text"></i></a></i>
|
||||
<input placeholder="1.2.3.4" id="add_banned_ip" type="text">
|
||||
<label for="add_banned_ip">Ban IP</label>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class=" modal-action modal-close waves-effect waves-red btn-flat light-blue-text">Cancel</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal_about" class="modal modal-fixed-footer">
|
||||
<div class="modal-content">
|
||||
<h4 class="grey-text text-darken-3"><a class="black-text" href="https://github.com/danielperna84/hass-configurator/" target="_blank">HASS Configurator</a></h4>
|
||||
|
@ -2299,6 +2375,175 @@
|
|||
});
|
||||
}
|
||||
|
||||
function get_netstat() {
|
||||
$.get("api/netstat", function (resp) {
|
||||
if (resp.hasOwnProperty("allowed_networks")) {
|
||||
var allowed_list = document.getElementById("allowed_networks");
|
||||
while (allowed_list.firstChild) {
|
||||
allowed_list.removeChild(allowed_list.firstChild);
|
||||
}
|
||||
var header = document.createElement("li");
|
||||
header.classList.add("collection-header");
|
||||
var header_h4 = document.createElement("h4");
|
||||
header_h4.innerText = "Allowed networks";
|
||||
header_h4.classList.add("grey-text");
|
||||
header_h4.classList.add("text-darken-3");
|
||||
header.appendChild(header_h4);
|
||||
allowed_list.appendChild(header);
|
||||
for (var i = 0; i < resp.allowed_networks.length; i++) {
|
||||
var li = document.createElement("li");
|
||||
li.classList.add("collection-item");
|
||||
var li_div = document.createElement("div");
|
||||
var address = document.createElement("span");
|
||||
address.innerText = resp.allowed_networks[i];
|
||||
li_div.appendChild(address);
|
||||
var li_a = document.createElement("a");
|
||||
li_a.classList.add("light-blue-text");
|
||||
li_a.href = "#!";
|
||||
li_a.classList.add("secondary-content");
|
||||
var li_a_i = document.createElement("i");
|
||||
li_a_i.classList.add("mdi");
|
||||
li_a_i.classList.add("mdi-delete");
|
||||
li_a_i.innerText = "Remove";
|
||||
li_a.appendChild(li_a_i);
|
||||
li_a.setAttribute("onclick", "helper_a_net_remove('" + resp.allowed_networks[i] + "')");
|
||||
li_div.appendChild(li_a);
|
||||
li.appendChild(li_div);
|
||||
allowed_list.appendChild(li);
|
||||
}
|
||||
}
|
||||
if (resp.hasOwnProperty("banned_ips")) {
|
||||
var banlist = document.getElementById("banned_ips");
|
||||
while (banlist.firstChild) {
|
||||
banlist.removeChild(banlist.firstChild);
|
||||
}
|
||||
var header = document.createElement("li");
|
||||
header.classList.add("collection-header");
|
||||
var header_h4 = document.createElement("h4");
|
||||
header_h4.innerText = "Banned IPs";
|
||||
header_h4.classList.add("grey-text");
|
||||
header_h4.classList.add("text-darken-3");
|
||||
header.appendChild(header_h4);
|
||||
banlist.appendChild(header);
|
||||
for (var i = 0; i < resp.banned_ips.length; i++) {
|
||||
var li = document.createElement("li");
|
||||
li.classList.add("collection-item");
|
||||
var li_div = document.createElement("div");
|
||||
var address = document.createElement("span");
|
||||
address.innerText = resp.banned_ips[i];
|
||||
li_div.appendChild(address);
|
||||
var li_a = document.createElement("a");
|
||||
li_a.classList.add("light-blue-text");
|
||||
li_a.href = "#!";
|
||||
li_a.classList.add("secondary-content");
|
||||
var li_a_i = document.createElement("i");
|
||||
li_a_i.classList.add("mdi");
|
||||
li_a_i.classList.add("mdi-delete");
|
||||
li_a_i.innerText = "Unban";
|
||||
li_a.appendChild(li_a_i);
|
||||
li_a.setAttribute("onclick", "helper_banned_unban('" + resp.banned_ips[i] + "')");
|
||||
li_div.appendChild(li_a);
|
||||
li.appendChild(li_div);
|
||||
banlist.appendChild(li);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function helper_a_net_remove(network) {
|
||||
document.getElementById("removenet").innerText = network;
|
||||
$('#modal_netstat').modal('close');
|
||||
$('#modal_a_net_remove').modal('open');
|
||||
}
|
||||
|
||||
function a_net_remove() {
|
||||
var network = document.getElementById("removenet").innerText
|
||||
data = new Object();
|
||||
data.network = network;
|
||||
data.method = 'remove';
|
||||
$.post("api/allowed_networks", data).done(function(resp) {
|
||||
if (resp.error) {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 5000);
|
||||
}
|
||||
else {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function helper_a_net_add() {
|
||||
document.getElementById("addnet").innerText = document.getElementById("add_net_ip").value;
|
||||
document.getElementById("add_net_ip").value = "";
|
||||
$('#modal_netstat').modal('close');
|
||||
$('#modal_a_net_add').modal('open');
|
||||
}
|
||||
|
||||
function a_net_add() {
|
||||
var network = document.getElementById("addnet").innerText
|
||||
data = new Object();
|
||||
data.network = network;
|
||||
data.method = 'add';
|
||||
$.post("api/allowed_networks", data).done(function(resp) {
|
||||
if (resp.error) {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 5000);
|
||||
}
|
||||
else {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function helper_banned_unban(ip) {
|
||||
document.getElementById("unbanip").innerText = ip;
|
||||
$('#modal_netstat').modal('close');
|
||||
$('#modal_unban').modal('open');
|
||||
}
|
||||
|
||||
function banned_unban() {
|
||||
var ip = document.getElementById("unbanip").innerText
|
||||
data = new Object();
|
||||
data.ip = ip;
|
||||
data.method = 'unban';
|
||||
$.post("api/banned_ips", data).done(function(resp) {
|
||||
if (resp.error) {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 5000);
|
||||
}
|
||||
else {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function helper_banned_ban() {
|
||||
document.getElementById("banip").innerText = document.getElementById("add_banned_ip").value;
|
||||
document.getElementById("add_banned_ip").value = "";
|
||||
$('#modal_netstat').modal('close');
|
||||
$('#modal_ban').modal('open');
|
||||
}
|
||||
|
||||
function banned_ban() {
|
||||
var ip = document.getElementById("banip").innerText
|
||||
data = new Object();
|
||||
data.ip = ip;
|
||||
data.method = 'ban';
|
||||
$.post("api/banned_ips", data).done(function(resp) {
|
||||
if (resp.error) {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 5000);
|
||||
}
|
||||
else {
|
||||
var $toastContent = $("<div><pre>" + resp.message + "</pre></div>");
|
||||
Materialize.toast($toastContent, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function save() {
|
||||
var filepath = document.getElementById('currentfile').value;
|
||||
if (filepath.length > 0) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue