Add login, user_edit, user_info

This commit is contained in:
David Hoppenbrouwers
2022-10-07 14:37:18 +02:00
parent d72fd14c92
commit 6f3b4de047
8 changed files with 151 additions and 8 deletions

View File

@@ -49,5 +49,44 @@ class DB:
return str(parent) + str(children) return str(parent) + str(children)
return parent return parent
def get_user_password(self, username):
return self._db().execute('''
select user_id, password
from users
where name = ?
''',
(username,)
).fetchone()
def get_user_public_info(self, user_id):
return self._db().execute('''
select name, about
from users
where user_id = ?
''',
(user_id,)
).fetchone()
def get_user_private_info(self, user_id):
return self._db().execute('''
select about
from users
where user_id = ?
''',
(user_id,)
).fetchone()
def set_user_private_info(self, user_id, about):
print('BROH', about)
db = self._db()
db.execute('''
update users
set about = ?
where user_id = ?
''',
(about, user_id)
)
db.commit()
def _db(self): def _db(self):
return sqlite3.connect(self.conn) return sqlite3.connect(self.conn)

64
main.py
View File

@@ -1,32 +1,88 @@
from flask import Flask, render_template from flask import Flask, render_template, session, request, redirect, url_for, flash
from db.sqlite import DB from db.sqlite import DB
import os import os
import passlib.hash
import time
app = Flask(__name__) app = Flask(__name__)
db = DB(os.getenv('DB')) db = DB(os.getenv('DB'))
NAME = 'Agrepy' NAME = 'Agrepy'
# TODO config file
app.config['SECRET_KEY'] = 'totally random'
@app.route('/') @app.route('/')
def index(): def index():
return render_template('index.html', title = NAME, subforums = db.get_subforums()) return render_template('index.html', title = NAME, subforums = db.get_subforums())
@app.route('/forum/<forum_id>/') @app.route('/forum/<int:forum_id>/')
def subforum(forum_id): def subforum(forum_id):
title, description = db.get_subforum(forum_id) title, description = db.get_subforum(forum_id)
threads = db.get_threads(forum_id) threads = db.get_threads(forum_id)
return render_template('subforum.html', title = title, description = description, threads = threads) return render_template('subforum.html', title = title, description = description, threads = threads)
@app.route('/thread/<thread_id>/') @app.route('/thread/<int:thread_id>/')
def thread(thread_id): def thread(thread_id):
title, text, author, comments = db.get_thread(thread_id) title, text, author, comments = db.get_thread(thread_id)
comments = create_comment_tree(comments) comments = create_comment_tree(comments)
return render_template('thread.html', title = title, text = text, author = author, comments = comments) return render_template('thread.html', title = title, text = text, author = author, comments = comments)
@app.route('/comment/<comment_id>/') @app.route('/comment/<int:comment_id>/')
def comment(comment_id): def comment(comment_id):
#return str(db.get_comment_tree(comment_id)[0]) #return str(db.get_comment_tree(comment_id)[0])
return str(db.get_comment_tree(comment_id)) return str(db.get_comment_tree(comment_id))
@app.route('/login/', methods = ['GET', 'POST'])
def login():
if request.method == 'POST':
v = db.get_user_password(request.form['username'])
if v is not None:
id, hash = v
if passlib.hash.argon2.verify(request.form['password'], hash):
flash('Logged in', 'success')
session['user_id'] = id
session['username'] = request.form['username']
return redirect(url_for('index'))
else:
# Sleep to reduce effectiveness of bruteforce
time.sleep(0.1)
flash('Username or password is invalid', 'error')
return render_template('login.html', title = "Login")
return render_template('login.html', title = "Login")
@app.route('/logout/')
def logout():
session.pop('user_id')
return redirect(url_for('index'))
@app.route('/user/', methods = ['GET', 'POST'])
def user_edit():
user_id = session.get('user_id')
if user_id is None:
return redirect(url_for('login'))
if request.method == 'POST':
about = request.form['about']
db.set_user_private_info(user_id, about)
else:
about, = db.get_user_private_info(user_id)
return render_template(
'user_edit.html',
name = session.get('username', '???'),
title = 'Edit profile',
about = about
)
@app.route('/user/<int:user_id>')
def user_info(user_id):
name, about = db.get_user_public_info(user_id)
return render_template(
'user_info.html',
title = 'Profile',
name = name,
about = about
)
class Comment: class Comment:
def __init__(self, author, text): def __init__(self, author, text):

View File

@@ -3,7 +3,7 @@ create table users (
name varchar(32) unique not null, name varchar(32) unique not null,
password varchar(128) not null, password varchar(128) not null,
email varchar(254), email varchar(254),
about text, about text not null default '',
join_date integer, join_date integer,
role integer not null default 0 role integer not null default 0
); );

View File

@@ -5,8 +5,18 @@
<body> <body>
<nav> <nav>
<a href="{{ url_for('index') }}">Home</a> <a href="{{ url_for('index') }}">Home</a>
{% if 'user_id' in session %}
<a href="{{ url_for('user_edit') }}">{{ session.get('username', '???') }}</a>
|
<a href="{{ url_for('logout') }}">Logout</a>
{% else %}
<a href="{{ url_for('login') }}">Login</a>
{% endif %}
</nav> </nav>
<h1>{{ title }}</h1> <h1>{{ title }}</h1>
{% for category, msg in get_flashed_messages(True) %}
<p>{{ category}}: {{ msg }}</p>
{% endfor %}
<main> <main>
{% block content %}{% endblock %} {% block content %}{% endblock %}
</main> </main>

9
templates/login.html Normal file
View File

@@ -0,0 +1,9 @@
{% extends 'base.html' %}
{% block content %}
<form method="post">
<p>Username: <input type="text" name="username"></p>
<p>Password: <input type="password" name="password"></p>
<input type="submit" value="Login">
</form>
{% endblock %}

9
templates/user_edit.html Normal file
View File

@@ -0,0 +1,9 @@
{% extends 'base.html' %}
{% block content %}
<form method="post">
<p>{{ name }}</p>
<textarea name="about">{{ about }}</textarea>
<input type="submit" value="Update">
</form>
{% endblock %}

6
templates/user_info.html Normal file
View File

@@ -0,0 +1,6 @@
{% extends 'base.html' %}
{% block content %}
<p>{{ name }}</p>
<p>{{ about }}<p>
{% endblock %}

View File

@@ -1,6 +1,20 @@
insert into users (name, password, email) values ("Foo", "supasecret", "foo@bar.baz"); insert into users (name, password, email) values (
insert into users (name, password, email) values ("Bar", "rgjieogir", "bar@foo.baz"); "Foo",
insert into users (name, password) values ("bazzers", "reogke"); -- supasecret
"$argon2id$v=19$m=65536,t=3,p=4$qBWCEAKgdA4BYOy915qzlg$KhGy3UF0QMlplt2eB7r7QNL2kDcggXUimRWUrWql8sI",
"foo@bar.baz"
);
insert into users (name, password, email) values (
"Bar",
-- abraca
"$argon2id$v=19$m=65536,t=3,p=4$klJKCUFoDaF07j3nPCeEUA$lCphd5n1YIs8MaVop2vGNirwknkh91qJIZHMuBOlgWA",
"bar@foo.baz"
);
insert into users (name, password) values (
"bazzers",
-- e
"$argon2id$v=19$m=65536,t=3,p=4$9v5fS2ktxTinNEbIGUOoFQ$LMdEuAuuTCJ7utOE88+nXn7o6R/DEKY8ZA6wV+YkVGQ"
);
insert into subforums (name, description, allowed_roles_mask) insert into subforums (name, description, allowed_roles_mask)
values ("Earth", "The totality of all space and time; all that is, has been, and will be.", 1); values ("Earth", "The totality of all space and time; all that is, has been, and will be.", 1);