Compare commits

...

1 Commits

Author SHA1 Message Date
2435d015fc sign up feature added 2018-06-16 16:42:31 -04:00
2 changed files with 130 additions and 1 deletions

View File

@ -4,7 +4,9 @@ Simple file host using Flask.
""" """
import os import os
import time import time
import string
import urllib import urllib
import functools
from flask import Flask, session, request, abort, redirect, url_for, g, \ from flask import Flask, session, request, abort, redirect, url_for, g, \
render_template render_template
@ -12,6 +14,7 @@ from flask_socketio import SocketIO, emit, join_room
from flask_paranoid import Paranoid from flask_paranoid import Paranoid
import MySQLdb import MySQLdb
import bleach import bleach
from passlib.hash import argon2
class ReverseProxied(object): class ReverseProxied(object):
""" """
@ -97,6 +100,77 @@ def init():
db_execute(cmd) db_execute(cmd)
def login_required(url=None):
"""
A decorator function to protect certain endpoints by requiring the user
to either pass a valid session cookie, or pass thier username and
password along with the request to login.
"""
def actual_decorator(func):
@functools.wraps(func)
def _nop(*args, **kwargs):
username = session.get("username")
if verify_username(username):
return func(*args, **kwargs)
username = request.form.get("user")
password = request.form.get("pass")
if verify_password(username, password):
return func(*args, **kwargs)
if url:
return redirect(url_for(url))
else:
abort(401)
return _nop
return actual_decorator
def add_user(username, password):
"""
Adds a user to the database.
"""
if verify_username(username): # username taken
return "username_taken"
elif len(username) > 20:
return "username_too_long"
pw_hash = argon2.hash(password)
db_execute(
"INSERT INTO `users` (`username`, `password_hash`) VALUES (%s, %s)",
(username, pw_hash))
return "success"
def verify_password(username, password):
"""
Verifies a user's password.
"""
user = verify_username(username)
if not user:
return False
user_id, _, pw_hash = user
if argon2.verify(password, pw_hash):
session["user_id"] = user_id
return True
else:
return False
def verify_username(username):
"""
Checks to see if the given username is in the database.
"""
user = db_execute("SELECT * FROM `users` WHERE `username` = %s",
(username,)).fetchone()
if user:
return user
else:
return False
@socketio.on('joined', namespace="/chat") @socketio.on('joined', namespace="/chat")
def joined(data): def joined(data):
""" """
@ -156,6 +230,7 @@ def quest(quest_title):
@app.route("/create_quest", methods=["GET", "POST"]) @app.route("/create_quest", methods=["GET", "POST"])
@login_required("login")
def create_quest(): def create_quest():
""" """
Starts a new quest. Starts a new quest.
@ -175,6 +250,58 @@ def create_quest():
return redirect(url_for('quest', quest_title=ident_title)) return redirect(url_for('quest', quest_title=ident_title))
@app.route("/login", methods=["GET", "POST"])
def login():
"""
Logs the user in.
"""
if request.method == "GET":
return render_template("login.html")
username = request.form.get("user")
password = request.form.get("pass")
if verify_password(username, password):
session["username"] = username
return redirect(url_for("index"))
else:
abort(401)
@app.route("/signup", methods=["GET", "POST"])
def signup():
"""
Create a new account.
"""
if request.method == "GET":
return render_template("signup.html")
username = request.form.get("user")
password = request.form.get("pass")
verify_password = request.form.get("verify_pass")
if len(username) > 20:
"username_too_long"
elif len(username) < 3:
"username_too_short"
chrs = [c not in string.ascii_letters + string.digits for c in username]
if any(chrs):
"username_bad_chars"
if verify_username(username):
"username_taken"
if len(password) > 1024:
"password_too_long"
elif len(password) < 8:
"password_too_short"
if password != verify_password:
"passwords_dont_match"
res = add_user(username, password)
return redirect(url_for("index"))
@app.route("/") @app.route("/")
def index(): def index():
""" """

View File

@ -6,6 +6,8 @@
<body> <body>
<h1>Quests 'n Shiet</h1> <h1>Quests 'n Shiet</h1>
<a href="./quest/unga-bunga-quest">Unga Bunga Quest</a><br /> <a href="./quest/unga-bunga-quest">Unga Bunga Quest</a><br />
<a href="./create_quest">Create New Quest</a> <a href="./create_quest">Create New Quest</a><br />
<a href="./signup">Sign up</a><br />
<a href="./login">Login</a><br />
</body> </body>
</html> </html>