mirror of
https://github.com/Adam-Ant/QuotesDB
synced 2024-12-20 11:34:35 +00:00
Add username/password authentication system
This commit is contained in:
parent
679a2d872e
commit
54afcfad1d
73
adduser.py
Normal file
73
adduser.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import pymysql
|
||||||
|
import getpass
|
||||||
|
import sys
|
||||||
|
from passlib.context import CryptContext
|
||||||
|
|
||||||
|
user = realname = passwd = None
|
||||||
|
|
||||||
|
|
||||||
|
pass_ctx = CryptContext(["bcrypt_sha256"])
|
||||||
|
|
||||||
|
# https://stackoverflow.com/questions/3041986/apt-command-line-interface-like-yes-no-input
|
||||||
|
def query_yes_no(question, default="yes"):
|
||||||
|
"""Ask a yes/no question via raw_input() and return their answer.
|
||||||
|
|
||||||
|
"question" is a string that is presented to the user.
|
||||||
|
"default" is the presumed answer if the user just hits <Enter>.
|
||||||
|
It must be "yes" (the default), "no" or None (meaning
|
||||||
|
an answer is required of the user).
|
||||||
|
|
||||||
|
The "answer" return value is True for "yes" or False for "no".
|
||||||
|
"""
|
||||||
|
valid = {"yes": 1, "y": 1, "ye": 1,
|
||||||
|
"no": 0, "n": 0}
|
||||||
|
if default is None:
|
||||||
|
prompt = " [y/n] "
|
||||||
|
elif default == "yes":
|
||||||
|
prompt = " [Y/n] "
|
||||||
|
elif default == "no":
|
||||||
|
prompt = " [y/N] "
|
||||||
|
else:
|
||||||
|
raise ValueError("invalid default answer: '%s'" % default)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
sys.stdout.write(question + prompt)
|
||||||
|
choice = input().lower()
|
||||||
|
if default is not None and choice == '':
|
||||||
|
return valid[default]
|
||||||
|
elif choice in valid:
|
||||||
|
return valid[choice]
|
||||||
|
else:
|
||||||
|
sys.stdout.write("Please respond with 'yes' or 'no' "
|
||||||
|
"(or 'y' or 'n').\n")
|
||||||
|
|
||||||
|
while not user:
|
||||||
|
user = input("Enter Username: ")
|
||||||
|
|
||||||
|
while not realname:
|
||||||
|
realname = input("Enter the real name of the user: ")
|
||||||
|
|
||||||
|
|
||||||
|
while not passwd:
|
||||||
|
passwd = getpass.getpass()
|
||||||
|
|
||||||
|
passwd_v = getpass.getpass(prompt="Reenter password: ")
|
||||||
|
|
||||||
|
while passwd != passwd_v:
|
||||||
|
print ("Error: Passwords do not match!")
|
||||||
|
passwd = getpass.getpass()
|
||||||
|
passwd_v = getpass.getpass()
|
||||||
|
|
||||||
|
passwd_hash = pass_ctx.hash(passwd)
|
||||||
|
|
||||||
|
isadmin = query_yes_no("Is the user an admin?", "no")
|
||||||
|
|
||||||
|
query = "INSERT INTO `Users` (`uid`, `user`, `realname`, `password`, `isadmin`) VALUES (NULL, '%s', '%s', '%s', %d);" % (user, realname, passwd_hash, isadmin)
|
||||||
|
|
||||||
|
db = pymysql.connect(host='dockerdev', port=3306, user='root', passwd='development', db='QuoteDB')
|
||||||
|
cur = db.cursor()
|
||||||
|
cur.execute(query)
|
||||||
|
data = cur.fetchall()
|
||||||
|
cur.close()
|
||||||
|
db.commit()
|
||||||
|
db.close()
|
@ -1,9 +1,9 @@
|
|||||||
CREATE TABLE Users (
|
CREATE TABLE Users (
|
||||||
uid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
uid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
user VARCHAR(255) NOT NULL,
|
user VARCHAR(255) NOT NULL UNIQUE,
|
||||||
realname VARCHAR(255) NOT NULL,
|
realname VARCHAR(255) NOT NULL,
|
||||||
password VARCHAR(255),
|
password VARCHAR(255),
|
||||||
isadmin BIT
|
isadmin BIT NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE Quotes (
|
CREATE TABLE Quotes (
|
||||||
|
52
main.py
52
main.py
@ -1,18 +1,23 @@
|
|||||||
from os import urandom as rand
|
from os import urandom as rand
|
||||||
from flaskext.mysql import MySQL
|
#from flaskext.mysql import MySQL
|
||||||
import pymysql
|
import pymysql
|
||||||
from flask import Flask, render_template, session, redirect, url_for, request, flash
|
from flask import Flask, render_template, session, redirect, url_for, request, flash
|
||||||
|
from passlib.context import CryptContext
|
||||||
import pprint
|
import pprint
|
||||||
|
|
||||||
pp = pprint.PrettyPrinter(indent=4)
|
pp = pprint.PrettyPrinter(indent=4)
|
||||||
|
|
||||||
|
pass_ctx = CryptContext(["bcrypt_sha256"])
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
# Thank you based StackOverflow
|
# Thank you based StackOverflow
|
||||||
|
# Remove Trailing and leading whitespace, strip unicode
|
||||||
def cleanup_string(text):
|
def cleanup_string(text):
|
||||||
text = text.encode("ascii", "replace").decode()
|
text = text.encode("ascii", "replace").decode()
|
||||||
return text.strip()
|
return text.strip()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Load User Table into variable
|
# Load User Table into variable
|
||||||
def mysql_do(query):
|
def mysql_do(query):
|
||||||
db = pymysql.connect(host='dockerdev', port=3306, user='root', passwd='development', db='QuoteDB')
|
db = pymysql.connect(host='dockerdev', port=3306, user='root', passwd='development', db='QuoteDB')
|
||||||
@ -25,13 +30,37 @@ def mysql_do(query):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
def app_init():
|
def app_init():
|
||||||
mysql_do("CREATE TABLE IF NOT EXISTS Users ( uid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, user VARCHAR(255) NOT NULL, realname VARCHAR(255) NOT NULL, password VARCHAR(255), isadmin BIT );")
|
# Check to make sure tables are set up properly
|
||||||
|
mysql_do("CREATE TABLE IF NOT EXISTS Users ( uid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, user VARCHAR(255) NOT NULL UNIQUE, realname VARCHAR(255) NOT NULL, password VARCHAR(255), isadmin BIT NOT NULL);")
|
||||||
mysql_do("CREATE TABLE IF NOT EXISTS Quotes ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, quote VARCHAR(2048) NOT NULL, date VARCHAR(255) NOT NULL, user INT NOT NULL, context VARCHAR(8000), FOREIGN KEY (user) REFERENCES Users(uid) );")
|
mysql_do("CREATE TABLE IF NOT EXISTS Quotes ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, quote VARCHAR(2048) NOT NULL, date VARCHAR(255) NOT NULL, user INT NOT NULL, context VARCHAR(8000), FOREIGN KEY (user) REFERENCES Users(uid) );")
|
||||||
|
|
||||||
|
# Generate random key for session cookies
|
||||||
app.secret_key = rand(24)
|
app.secret_key = rand(24)
|
||||||
|
|
||||||
|
# TODO: Replace this with something dynamic where needed
|
||||||
global userdb
|
global userdb
|
||||||
userdb = mysql_do("SELECT * FROM Users")
|
userdb = mysql_do("SELECT * FROM Users")
|
||||||
|
|
||||||
|
|
||||||
|
def do_user_login(user, password):
|
||||||
|
try:
|
||||||
|
userdata = mysql_do("SELECT * FROM Users WHERE user='%s'" % (user))[0]
|
||||||
|
except IndexError:
|
||||||
|
# Returned when no rows found - no user with that name
|
||||||
|
flash( "Error: Incorrect Username or Password!", "danger")
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
|
||||||
|
if pass_ctx.verify(password, userdata[3]):
|
||||||
|
session['username'] = user
|
||||||
|
session['uid'] = userdata[0]
|
||||||
|
session['isAdmin'] = bool(ord(userdata[4]))
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
|
else:
|
||||||
|
flash( "Error: Incorrect Username or Password!", "danger")
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def index():
|
def index():
|
||||||
if 'username' in session:
|
if 'username' in session:
|
||||||
@ -43,6 +72,12 @@ def quoutepage():
|
|||||||
retdata = mysql_do("SELECT * FROM Quotes ORDER BY ID DESC")
|
retdata = mysql_do("SELECT * FROM Quotes ORDER BY ID DESC")
|
||||||
return render_template("quote_view.html", data=retdata)
|
return render_template("quote_view.html", data=retdata)
|
||||||
|
|
||||||
|
@app.route("/login", methods=['GET', 'POST'])
|
||||||
|
def login():
|
||||||
|
if request.method == 'POST':
|
||||||
|
return do_user_login(request.form['username'], request.form['pw'])
|
||||||
|
return render_template("login.html")
|
||||||
|
|
||||||
@app.route("/addquote", methods=['GET','POST'])
|
@app.route("/addquote", methods=['GET','POST'])
|
||||||
def addquote():
|
def addquote():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
@ -90,14 +125,15 @@ def addquote():
|
|||||||
mysql_do(sql)
|
mysql_do(sql)
|
||||||
flash("Success! The entry was added to the database.","success")
|
flash("Success! The entry was added to the database.","success")
|
||||||
return redirect(url_for('index'))
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
|
# Check if the user is authenticated
|
||||||
|
try:
|
||||||
|
session['username']
|
||||||
|
except KeyError:
|
||||||
|
flash("INFO: Please login first.","info")
|
||||||
|
return redirect(url_for("login"))
|
||||||
return render_template("add_quote.html", users=userdb)
|
return render_template("add_quote.html", users=userdb)
|
||||||
|
|
||||||
@app.route("/login", methods=['GET', 'POST'])
|
|
||||||
def login():
|
|
||||||
if request.method == 'POST':
|
|
||||||
session['username'] = request.form['username']
|
|
||||||
return redirect(url_for('index'))
|
|
||||||
return render_template("login.html")
|
|
||||||
|
|
||||||
@app.route("/logout")
|
@app.route("/logout")
|
||||||
def logout():
|
def logout():
|
||||||
|
Loading…
Reference in New Issue
Block a user