openwebrxplus/owrx/controllers/clients.py

115 lines
4.6 KiB
Python

from owrx.controllers.admin import AuthorizationMixin
from owrx.controllers.template import WebpageController
from owrx.breadcrumb import Breadcrumb, BreadcrumbItem, BreadcrumbMixin
from owrx.client import ClientRegistry
import json
import re
import logging
logger = logging.getLogger(__name__)
class ClientController(AuthorizationMixin, WebpageController):
def indexAction(self):
self.serve_template("clients.html", **self.template_variables())
def template_variables(self):
variables = super().template_variables()
variables["clients"] = self.renderClients()
return variables
@staticmethod
def renderClients():
return """
<table class='table'>
<tr>
<th>IP Address</th>
<th>Chat Name</th>
<th>SDR Profile</th>
<th>Local Time</th>
<th>Actions</th>
</tr>
{clients}
<tr>
<td></td>
<td></td>
<td></td>
<td colspan="2" style="text-align:right;">
ban for
<select id="ban-minutes">
<option value="15">15 minutes</option>
<option value="30">30 minutes</option>
<option value="60">1 hour</option>
<option value="180">3 hours</option>
<option value="360">6 hours</option>
<option value="720">12 hours</option>
<option value="1440">1 day</option>
</select>
</td>
</tr>
</table>
""".format(
clients="".join(ClientController.renderClient(c) for c in ClientRegistry.getSharedInstance().listAll())
)
@staticmethod
def renderClient(c):
return "<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3} {4}</td><td>{5}</td></tr>".format(
ClientController.renderIp(c["ip"]),
c["name"] if "name" in c else "",
"banned" if c["ban"] else c["sdr"] + " " + c["band"] if "sdr" in c else "n/a",
"until" if c["ban"] else "since",
c["ts"].strftime('%H:%M:%S'),
ClientController.renderButtons(c)
)
@staticmethod
def renderIp(ip):
ip = re.sub("^::ffff:", "", ip)
return """
<a href="https://www.geolocation.com/en_us?ip={0}#ipresult" target="_blank">{1}</a>
""".format(ip, ip)
@staticmethod
def renderButtons(c):
action = "unban" if c["ban"] else "ban"
return """
<button type="button" class="btn btn-sm btn-danger client-{0}" value="{1}">{2}</button>
""".format(action, c["ip"], action)
def ban(self):
try:
data = json.loads(self.get_body().decode("utf-8"))
mins = int(data["mins"]) if "mins" in data else 0
if "ip" in data and mins > 0:
logger.info("Banning {0} for {1} minutes".format(data["ip"], mins))
ClientRegistry.getSharedInstance().banIp(data["ip"], mins)
self.send_response("{}", content_type="application/json", code=200)
except Exception as e:
logger.debug("ban(): " + str(e))
self.send_response("{}", content_type="application/json", code=400)
def unban(self):
try:
data = json.loads(self.get_body().decode("utf-8"))
if "ip" in data:
logger.info("Unbanning {0}".format(data["ip"]))
ClientRegistry.getSharedInstance().unbanIp(data["ip"])
self.send_response("{}", content_type="application/json", code=200)
except Exception as e:
logger.debug("unban(): " + str(e))
self.send_response("{}", content_type="application/json", code=400)
def broadcast(self):
try:
data = json.loads(self.get_body().decode("utf-8"))
text = data["text"].strip() if "text" in data else ""
if len(text) > 0:
logger.info("Broadcasting '{0}' to all clients".format(text))
ClientRegistry.getSharedInstance().broadcastAdminMessage(text)
self.send_response("{}", content_type="application/json", code=200)
except Exception as e:
logger.debug("broadcast(): " + str(e))
self.send_response("{}", content_type="application/json", code=400)