Implemented User Management
This commit is contained in:
62
app.py
62
app.py
@@ -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
65
static/register.css
Normal 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
16
static/register.js
Normal 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";
|
||||
}
|
||||
}
|
||||
@@ -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
61
templates/register.html
Normal 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 %}
|
||||
Reference in New Issue
Block a user