Compare commits

1 Commits

Author SHA1 Message Date
d09a875488 prev work 2025-12-25 22:29:59 +01:00
7 changed files with 71 additions and 2 deletions

View File

@@ -10,6 +10,8 @@ The MQTT Client is a FastAPI App and can be launched natively or with FastAPI pr
The script ``sql_startup.sql`` contains commands to set up the layout of the database which the program expects.
TODO: probably delete the "extra commands" and segment the example data out
## Dependencies
This repository does not include two external dependencies, namely the SQL server and MQTT broker. The tested choices for those dependencies are MariaDB and Mosquitto, but alternatives may work as well

View File

@@ -92,10 +92,18 @@ class DatabaseConnect:
else:
return res[0] == 1
def get_all_perms(self) -> list[tuple[str, str, bool, bool, bool]]:
self.cursor.execute("SELECT users.`username`, rooms.`shortname`, permissions.`view`, permissions.`control`, permissions.`administer` FROM permissions LEFT JOIN users ON permissions.`userID` = users.`ID` LEFT JOIN rooms ON permissions.`roomID` = rooms.`ID`;")
return [x for x in self.cursor.fetchall()]
# def roomID_from_shortname(self, shortname):
# self.cursor.execute("SELECT rooms.`ID` from rooms WHERE rooms.shortname = ?;",(shortname,))
# return self.cursor.fetchone()
def get_devices_in_room_shortname(self, shortname) -> list[tuple[int, str]]:
self.cursor.execute("Select devices.`ID`, devices.`name` FROM devices LEFT JOIN rooms ON devices.`roomID` = rooms.`ID` WHERE rooms.shortname = ?;",(shortname,))
return [x for x in self.cursor.fetchall()]
def get_sensors_in_room_shortname(self, shortname) -> list[tuple[int, int]]:
self.cursor.execute("Select sensors.`ID`, sensors.`Type` FROM sensors LEFT JOIN devices ON devices.`ID` = sensors.`deviceID` LEFT JOIN rooms ON devices.`roomID` = rooms.`ID` WHERE rooms.shortname = ?;",(shortname,))
return [x for x in self.cursor.fetchall()]

View File

@@ -52,3 +52,7 @@ SELECT permissions.`view` FROM permissions LEFT JOIN rooms ON permissions.`roomI
# get latest reading from a sensor
SELECT readings.`Timestamp`, readings.`reading` FROM readings WHERE readings.`sensorID` = '1' ORDER BY readings.`Timestamp` DESC FETCH FIRST 1 ROWS ONLY;
Select sensors.`ID`, sensors.`Type` FROM sensors LEFT JOIN devices ON devices.`ID` = sensors.`deviceID` LEFT JOIN rooms ON devices.`roomID` = rooms.`ID` WHERE rooms.shortname = "101";
SELECT users.`ID`, users.`username`, users.`administer` FROM Users;

View File

@@ -105,7 +105,7 @@ a:hover {
padding: 20px;
display: flex;
flex-direction: column;
flex-grow: 9;
flex-grow: 15;
}
.topline {

1
web.py
View File

@@ -156,6 +156,7 @@ def room_page(room_name=None):
).render()
@app.route("/users", methods=["GET","POST"])
@login_required
def user_management():
if request.method == "POST":
# no options allowed for logged out users

View File

@@ -27,7 +27,10 @@
</div>
<hr>
<div><a href="/devices">Device Management</a></div>
<div><a href="/users">User Management</a></div>
{% if user %}
<div><a href="/users.html">User Management</a></div>
{% endif %}
</div>
</div>
<div class="right-flex">

View File

@@ -74,6 +74,57 @@
{% endfor %}
</tbody>
</table>
<h3>User Permissions:</h3>
<table>
<thead>
<tr class="table-header">
<th>Username</th>
<th>Room</th>
<th>View</th>
<th>Control</th>
<th>Administer</th>
<th></th>
</tr>
<tr class="searchbar">
<td colspan="255">
<input type="text" id="permSearch" placeholder="Search by username..." onkeyup="tableSearch('permSearch', 'permlist',0)">
</td>
</tr>
</thead>
<tbody id="permlist">
{% for perm in permlist %}
<tr>
<form method="POST" action="/users">
<td> {{ perm[0] }} </td>
<td> {{ perm[1] }} </td>
<td>
<input type="checkbox" name="change-view"
{% if perm[2] %}
checked
{% else %}
{% endif %}
>
</td>
<td>
<input type="checkbox" name="change-purge"
{% if perm[3] %}
checked
{% else %}
{% endif %}
>
</td>
<td>
<input type="checkbox" name="change-administer"
{% if perm[2] %}
checked
{% else %}
{% endif %}
>
</td>
</form>
</tr>
{% endfor %}
</tbody>
{% else %}
{% endif %}