Implemented User Management

This commit is contained in:
2026-04-15 00:25:21 -05:00
parent 4dddf30c4c
commit 9797cbc52e
5 changed files with 208 additions and 6 deletions

62
app.py
View File

@@ -142,6 +142,64 @@ def login():
return redirect(url_for(session.get("main", "index_ade")))
@app.route("/register", methods=["GET", "POST"])
def register():
if request.method == "POST":
act = request.form.get("action")
match act:
case "create":
username = request.form["username"]
password = request.form["password"]
udata = db.users.find_one({"id": username})
if udata or not username or not password:
abort(400)
salt = urandom(32)
hash = scrypt(password.encode("utf-8"), salt=salt, **SCRYPT_PARAMS)
db.users.insert_one(
{
"id": username,
"hash": hash,
"salt": salt,
"perm": [],
"quad": ["ade"],
}
)
case "edit":
for entry in request.form:
if entry.count("/") == 2:
ptype, pid, uid = entry.split("/")
value = request.form[entry]
if ptype == "perm":
cur_perms = db.users.find_one(
{"_id": ObjectId(uid)}, {"perm": 1}
).get("perm", [])
if value == "True":
if pid not in cur_perms:
cur_perms.append(pid)
else:
if pid in cur_perms:
cur_perms.remove(pid)
db.users.update_one(
{"_id": ObjectId(uid)}, {"$set": {"perm": cur_perms}}
)
if ptype == "quad":
cur_quads = db.users.find_one(
{"_id": ObjectId(uid)}, {"quad": 1}
).get("quad", [])
if value == "True":
if pid not in cur_quads:
cur_quads.append(pid)
else:
if pid in cur_quads:
cur_quads.remove(pid)
db.users.update_one(
{"_id": ObjectId(uid)}, {"$set": {"quad": cur_quads}}
)
udatas = list(db.users.find())
ddatas = sorted(db.domains.find({"public": False}), key=lambda ddata: ddata["id"])
return render_template("register.html", udatas=udatas, ddatas=ddatas)
@app.route("/search")
def search():
stype = request.args.get("search-type")
@@ -347,6 +405,8 @@ def lighting():
result[-1] = {"name": "Ungrouped", "lights": {}}
for light in raw["lights"]:
ldata = raw["lights"][light]
if not ldata["state"]["reachable"]:
continue
if not ldata["state"]["on"]:
color = "#000000"
elif ldata["state"].get("colormode") == "hs":
@@ -361,6 +421,6 @@ def lighting():
ungrouped = False
if ungrouped:
result[-1]["lights"][light] = ldata
return render_template("lighting.html", ldata=result)
return render_template("lighting.html", ldatas=result)
except requests.exceptions.ConnectionError:
abort(500)

65
static/register.css Normal file
View File

@@ -0,0 +1,65 @@
th {
writing-mode: sideways-lr;
}
th#save-box {
writing-mode: inherit;
>button {
display: none;
}
}
.pgrid[data-mark=True] {
background-color: black;
}
.pgrid[data-changed] {
border: 3px solid red;
}
tr {
background-color: var(--color-bg2);
}
.qheader {
background-color: var(--color-bg1);
vertical-align: top;
}
#users {
background-color: inherit;
}
#qh-ade,
.quad-ade {
--hue: var(--ade);
}
#qh-bea,
.quad-bea {
--hue: var(--bea);
}
#qh-cam,
.quad-cam {
--hue: var(--cam);
}
#qh-des,
.quad-des {
--hue: var(--des);
}
#useradd {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 1em;
align-items: end;
justify-content: center;
>div>label {
display: block;
}
}

16
static/register.js Normal file
View File

@@ -0,0 +1,16 @@
function getFirst(item, className) {
return item.getElementsByClassName(className)[0]
}
var saveBtn = document.getElementById("save-btn");
for (chk of document.getElementsByClassName("pgrid")) {
chk.onclick = (event) => {
console.log(event.target)
event.target.dataset.mark = event.target.dataset.mark == "True" ? "False" : "True"
event.target.children[0].name = event.target.dataset.targ;
event.target.children[0].value = event.target.dataset.mark;
event.target.dataset.changed = true;
saveBtn.style.display = "block";
}
}

View File

@@ -8,14 +8,14 @@
{% block content %}
<main>
{% for group in ldata %}
{% if ldata[group]["lights"] %}
{% for group in ldatas %}
{% if ldatas[group]["lights"] %}
<div class="group">
<h2>{{ ldata[group]["name"] }}</h2>
<h2>{{ ldatas[group]["name"] }}</h2>
<div>
{% for light in ldata[group]["lights"] %}
{% for light in ldatas[group]["lights"] %}
<form method="post" class="light">
{% set ldata = ldata[group]["lights"][light] %}
{% set ldata = ldatas[group]["lights"][light] %}
<h3>{{ ldata["name"] }}</h3>
<div class="view">
<div class="view-symb">

61
templates/register.html Normal file
View File

@@ -0,0 +1,61 @@
{% extends "base.html" %}
{% block head %}
<link rel="stylesheet" href="{{ url_for('static', filename='register.css') }}">
<script src="{{ url_for('static', filename='register.js') }}" defer></script>
{% endblock %}
{% block content %}
<main>
<form method="post">
<table>
<tr id="users">
<th id="save-box"><button id="save-btn" type="submit" name="action" value="edit">SAVE CHANGES</button>
</th>
{% for udata in udatas %}
<th>{{ udata["id"] }}</th>
{% endfor %}
</tr>
{% set quads = ["ade", "bea", "cam", "des"] %}
{% for quad in quads %}
<tr id="qh-{{ quad }}" class="qheader">
<td>
<h2>{{ quad }}</h2>
</td>
{% for udata in udatas %}
<td class="pgrid" data-targ="quad/{{ quad }}/{{ udata['_id'] }}"
data-mark="{{ quad in udata['quad'] }}">
<input type="hidden">
</td>
{% endfor %}
</tr>
{% for ddata in ddatas %}
{% if ddata["quad"] == quad %}
<tr class="quad-{{ quad }}">
<td>{{ ddata["name"] }} ({{ ddata["id"] }})</td>
{% for udata in udatas %}
<td class="pgrid" data-targ="perm/{{ ddata['id'] }}/{{ udata['_id'] }}" data-mark="{{ ddata['id'] in
udata['perm'] }}">
<input type="hidden">
</td>
{% endfor %}
</tr>
{% endif %}
{% endfor %}
{% endfor %}
</table>
</form>
<hr>
<form id="useradd" method="post">
<div>
<label for="username">Username:</label>
<input id="username" name="username" autocomplete="username">
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password" autocomplete="new-password">
</div>
<button type="submit" name="action" value="create">Create User</button>
</form>
</main>
{% endblock %}