add account management to web

This commit is contained in:
r 2024-04-22 21:06:28 -05:00
parent 7d8cf7a36e
commit f9165e89e6
6 changed files with 130 additions and 33 deletions

View File

@ -688,7 +688,8 @@ class HTML(object):
"""
@cherrypy.expose
def login(self, username=None, password=None):
def account(self, username=None, password=None, color=None, updateUsername=None,
updatePassword=None, passwordConfirmation=None):
database = sqlite3.connect(dbname)
cookie = cherrypy.request.cookie
if username and password:
@ -706,15 +707,48 @@ class HTML(object):
if "username" in cookie and "auth_hash" in cookie:
user = db.user_resolve(database, cookie["username"].value)
if cookie["auth_hash"].value.lower() == user["auth_hash"]:
if user and cookie["auth_hash"].value.lower() == user["auth_hash"]:
authorized_user = user
if color:
try:
color_number = int(color)
if color_number in (0, 1, 2, 3, 4, 5, 6):
db.user_update(database, authorized_user, {"color": color_number})
raise cherrypy.HTTPRedirect("/account")
except ValueError:
return "Color must be a number, 0-6"
elif updateUsername:
try:
db.validate([["user_name", updateUsername]])
update = db.user_update(database, authorized_user, {"user_name": updateUsername})
cherrypy.response.cookie["username"] = update["user_name"]
cherrypy.response.cookie["username"]["max-age"] = 34560000
raise cherrypy.HTTPRedirect("/account")
except BBJUserError as e:
return e.description
elif updatePassword and passwordConfirmation:
if len(updatePassword) > 4096:
return "Password is too long."
elif updatePassword != passwordConfirmation:
return "Password and password confirmation do not match."
auth_hash = sha256(bytes(updatePassword, "utf8")).hexdigest()
try:
db.validate([["auth_hash", auth_hash]])
update = db.user_update(database, authorized_user, {"auth_hash": auth_hash})
cherrypy.response.cookie["auth_hash"] = update["auth_hash"]
cherrypy.response.cookie["auth_hash"]["max-age"] = 34560000
except BBJParameterError:
return e.description
else:
authorized_user = None
else:
authorized_user = None
template = template_environment.get_template("login.html")
template = template_environment.get_template("account.html")
variables = {
"authorized_user": authorized_user
}
@ -763,7 +797,7 @@ class HTML(object):
if "username" in cookie and "auth_hash" in cookie:
user = db.user_resolve(database, cookie["username"].value)
if cookie["auth_hash"].value.lower() == user["auth_hash"]:
if user and cookie["auth_hash"].value.lower() == user["auth_hash"]:
authorized_user = user
else:
authorized_user = None
@ -810,7 +844,7 @@ class HTML(object):
if "username" in cookie and "auth_hash" in cookie:
user = db.user_resolve(database, cookie["username"].value)
if cookie["auth_hash"].value.lower() == user["auth_hash"]:
if user and cookie["auth_hash"].value.lower() == user["auth_hash"]:
authorized_user = user
else:
authorized_user = None
@ -832,7 +866,7 @@ class HTML(object):
cookie = cherrypy.request.cookie
if "username" in cookie and "auth_hash" in cookie:
user = db.user_resolve(database, cookie["username"].value)
if cookie["auth_hash"].value.lower() == user["auth_hash"]:
if user and cookie["auth_hash"].value.lower() == user["auth_hash"]:
if title and postContent and title.strip() and postContent.strip():
thread = db.thread_create(database, user["user_id"], postContent, title)
raise cherrypy.HTTPRedirect("/thread?id=" + thread["thread_id"])
@ -853,7 +887,7 @@ class HTML(object):
cookie = cherrypy.request.cookie
if "username" in cookie and "auth_hash" in cookie:
user = db.user_resolve(database, cookie["username"].value)
if cookie["auth_hash"].value.lower() != user["auth_hash"]:
if user and cookie["auth_hash"].value.lower() != user["auth_hash"]:
return "Authorization info not correct."
if postContent.strip():
db.thread_reply(database, user["user_id"], threadId, postContent)

View File

@ -462,6 +462,10 @@ def validate(keys_and_values):
if not value:
raise BBJUserError(
"Username may not be empty.")
elif type(value) != str:
raise BBJUserError(
"Username must be a string.")
elif contains_nonspaces(value):
raise BBJUserError(

81
templates/account.html Normal file
View File

@ -0,0 +1,81 @@
<!DOCTYPE html>
<html>
<head>
<title>Log In: BBJ</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/css/base.css">
</head>
<body>
<div id="navbar">
<span class="bbjLogo" onclick="window.location.href='/index'">&lt;- Index</span>
{% if authorized_user %}
Account: <span class="color{{ authorized_user['color']}}">~{{ authorized_user["user_name"] }}</span>
{% else %}
<span>Not logged in.</span>
{% endif %}
{% if authorized_user %}
Settings
{% endif %}
</div>
{% if authorized_user %}
<div class="settingsBlock">
<h3>Login Info</h3>
<span>Currently logged in as <span class="color{{ authorized_user['color'] }}">~{{ authorized_user["user_name"] }}</span></span>
<br>
<a href="/logout">Log out.</a>
</div>
<div class="settingsBlock">
<h3>Change Username</h3>
<form autocomplete="off" action="/account">
<label for="updateUsername">Update Username:</label><br>
<input type="text" autocomplete="off" id="updateUsername" name="updateUsername"><br>
<input type="submit" value="Submit">
</form>
</div>
<div class="settingsBlock">
<h3>Change Password</h3>
<form autocomplete="off" action="/account">
<label for="updatePassword">Update password:</label><br>
<input autocomplete="off" type="password" name="updatePassword" id="updatePassword"><br>
<label for="passwordConfirmation">Type it again:</label><br>
<input autocomplete="off" type="password" name="passwordConfirmation" id="passwordConfirmation"><br>
<input type="submit" value="Submit">
</form>
</div>
<div class="settingsBlock">
<h3>Username Color</h3>
<form method="get" action="/account">
<input type="radio" id="color0" name="color" value="0">
<label for="color0">None</label><br>
<input type="radio" id="color1" name="color" value="1">
<label for="color1"><span class="color1">One</span></label><br>
<input type="radio" id="color2" name="color" value="2">
<label for="color2"><span class="color2">Two</span></label><br>
<input type="radio" id="color3" name="color" value="3">
<label for="color3"><span class="color3">Three</span></label><br>
<input type="radio" id="color4" name="color" value="4">
<label for="color4"><span class="color4">Four</span></label><br>
<input type="radio" id="color5" name="color" value="5">
<label for="color5"><span class="color5">Five</span></label><br>
<input type="radio" id="color6" name="color" value="6">
<label for="color6"><span class="color6">Six</span></label><br>
<input type="submit" value="Save">
</form>
</div>
{% else %}
<div class="settingsBlock">
<form class="loginForm" method="post" action="/account">
<label for="username">Username:</label>
<input type="text" name="username" /><br />
<label for="password">Password:</label>
<input type="password" name="password" /><br />
<input type="submit" value="Log in" />
</form>
</div>
{% endif %}
</body>
</html>

View File

@ -1,22 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Log In: BBJ</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/css/base.css">
</head>
<body>
{% if authorized_user %}
<span>Currently logged in as <span class="color{{ authorized_user['color'] }}">~{{ authorized_user["user_name"] }}</span></span>
<br>
<a href="/logout">Log out.</a>
{% endif %}
<form class="loginForm" method="post" action="/login">
<label for="username">Username:</label>
<input type="text" name="username" /><br />
<label for="password">Password:</label>
<input type="password" name="password" /><br />
<input type="submit" value="Log in" />
</form>
</body>
</html>

View File

@ -17,9 +17,9 @@
<span>Not logged in.</span>
{% endif %}
{% if authorized_user %}
<a class="navbarLink" href="/login">Manage</a>
<a class="navbarLink" href="/account">Manage</a>
{% else %}
<a class="navbarLink" href="/login">Login</a>
<a class="navbarLink" href="/account">Login</a>
{% endif %}
</div>

View File

@ -19,9 +19,9 @@
<span>Not logged in.</span>
{% endif %}
{% if authorized_user %}
<a class="navbarLink" href="/login">Manage</a>
<a class="navbarLink" href="/account">Manage</a>
{% else %}
<a class="navbarLink" href="/login">Login</a>
<a class="navbarLink" href="/account">Login</a>
{% endif %}
</div>