2017-10-03 01:18:13 +00:00
from os import urandom as rand
2017-10-04 00:04:18 +00:00
#from flaskext.mysql import MySQL
2017-10-03 01:18:13 +00:00
import pymysql
from flask import Flask , render_template , session , redirect , url_for , request , flash
2017-10-04 00:04:18 +00:00
from passlib . context import CryptContext
2017-10-03 01:18:13 +00:00
import pprint
pp = pprint . PrettyPrinter ( indent = 4 )
2017-10-04 00:04:18 +00:00
pass_ctx = CryptContext ( [ " bcrypt_sha256 " ] )
2017-10-03 01:18:13 +00:00
app = Flask ( __name__ )
# Thank you based StackOverflow
2017-10-04 00:04:18 +00:00
# Remove Trailing and leading whitespace, strip unicode
2017-10-03 01:18:13 +00:00
def cleanup_string ( text ) :
text = text . encode ( " ascii " , " replace " ) . decode ( )
return text . strip ( )
2017-10-05 00:22:55 +00:00
def get_userdb ( ) :
global userdb
global numusers
# Counting on primary key is quickest operation
cur_num = mysql_do ( " SELECT count(`uid`) FROM `Users`; " ) [ 0 ] [ 0 ]
if numusers < cur_num :
# Update the database!
userdb = mysql_do ( " SELECT * FROM Users " )
return userdb
2017-10-04 00:04:18 +00:00
2017-10-05 01:08:32 +00:00
def gen_page ( template , data = None ) :
# This fire if we need to pass something into templating
if data :
print ( " DATA " )
pp . pprint ( data )
if ' username ' in session :
return render_template ( template , user = session [ " username " ] , data = data )
else :
return render_template ( template , data = data )
if ' username ' in session :
return render_template ( template , user = session [ " username " ] )
return render_template ( template )
2017-10-04 00:04:18 +00:00
2017-10-03 01:18:13 +00:00
# Load User Table into variable
def mysql_do ( query ) :
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 ( )
return data
2017-10-03 22:27:51 +00:00
def app_init ( ) :
2017-10-04 00:04:18 +00:00
# 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); " )
2017-10-04 23:32:33 +00:00
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), addedby INT NOT NULL, FOREIGN KEY (user) REFERENCES Users(uid) ); " )
2017-10-04 00:04:18 +00:00
# Generate random key for session cookies
2017-10-03 22:27:51 +00:00
app . secret_key = rand ( 24 )
2017-10-04 00:04:18 +00:00
2017-10-05 00:22:55 +00:00
# Init the counter, then run a query
global numusers
numusers = 0
get_userdb ( )
2017-10-03 22:27:51 +00:00
2017-10-03 01:18:13 +00:00
2017-10-04 00:04:18 +00:00
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 ' ) )
2017-10-03 01:18:13 +00:00
@app.route ( " / " )
def index ( ) :
2017-10-05 01:08:32 +00:00
return gen_page ( " index.html " )
2017-10-03 01:18:13 +00:00
@app.route ( " /quotes " )
def quoutepage ( ) :
retdata = mysql_do ( " SELECT * FROM Quotes ORDER BY ID DESC " )
2017-10-05 01:08:32 +00:00
return gen_page ( " quote_view.html " , retdata )
2017-10-03 01:18:13 +00:00
2017-10-04 00:04:18 +00:00
@app.route ( " /login " , methods = [ ' GET ' , ' POST ' ] )
def login ( ) :
if request . method == ' POST ' :
return do_user_login ( request . form [ ' username ' ] , request . form [ ' pw ' ] )
2017-10-05 01:08:32 +00:00
return gen_page ( " login.html " )
2017-10-04 00:04:18 +00:00
2017-10-05 14:17:12 +00:00
@app.route ( " /logout " )
def logout ( ) :
session . pop ( ' username ' , None )
return redirect ( url_for ( ' index ' ) )
@app.route ( " /resetpass " , methods = [ " GET " , " POST " ] )
def pwreset ( ) :
if request . method == " POST " :
try :
session [ ' username ' ]
except KeyError :
flash ( " INFO: Please login first. " , " info " )
return redirect ( url_for ( " login " ) )
if request . form [ ' pw ' ] != request . form [ ' pw_verify ' ] :
flash ( " Error: New Passwords do not match! " , " danger " )
return redirect ( url_for ( " pwreset " ) )
try :
userdata = mysql_do ( " SELECT * FROM Users WHERE user= ' %s ' " % ( session [ ' username ' ] ) ) [ 0 ]
except IndexError :
# Returned when no rows found - no user with that name
flash ( " Error: Internal server error - user not found " , " danger " )
return redirect ( url_for ( ' index ' ) )
if not pass_ctx . verify ( request . form [ ' current_passwd ' ] , userdata [ 3 ] ) :
flash ( " Error: Current password is incorrect " , " danger " )
return redirect ( url_for ( " pwreset " ) )
mysql_do ( " UPDATE Users SET password= \" %s \" WHERE uid= %d ; " % ( pymysql . escape_string ( pass_ctx . hash ( request . form [ ' pw ' ] ) ) , session [ ' uid ' ] ) )
flash ( " INFO: Password updated successfully! " , " success " )
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 gen_page ( " passwd_reset.html " )
2017-10-03 01:18:13 +00:00
@app.route ( " /addquote " , methods = [ ' GET ' , ' POST ' ] )
def addquote ( ) :
if request . method == " POST " :
2017-10-04 23:36:01 +00:00
try :
session [ ' username ' ]
except KeyError :
flash ( " INFO: Please login first. " , " info " )
return redirect ( url_for ( " login " ) )
2017-10-03 01:18:13 +00:00
quotein = pymysql . escape_string ( request . form [ ' quote ' ] )
contextin = pymysql . escape_string ( request . form [ ' context ' ] )
userin = pymysql . escape_string ( request . form [ ' user ' ] )
#Remove Trailing and leading whitespace, strip unicode
quotein = cleanup_string ( quotein )
contextin = cleanup_string ( contextin )
if not quotein or quotein . isspace ( ) :
flash ( " Error: You must enter a quote! " , " danger " )
return redirect ( url_for ( " addquote " ) )
# Check if the <textarea> has been tampered with...
if ( len ( quotein ) > 500 ) or ( len ( contextin ) > 500 ) :
flash ( " Error: Quote too long. Stop fucking with the code :P " , " danger " )
return redirect ( url_for ( " addquote " ) )
# This checks if the user value has been changed to a non integer
try :
userin = int ( userin )
except :
flash ( " Error: Invalid userID. Stop fucking with the code :P " , " danger " )
return redirect ( url_for ( " addquote " ) )
# Check if the value is out of range of the valid uid's
if ( userin > int ( userdb [ - 1 ] [ 0 ] ) or ( userin < = 0 ) ) :
flash ( " Error: Invalid userID. Stop fucking with the code :P " , " danger " )
return redirect ( url_for ( " addquote " ) )
if not contextin :
contextin = " NULL "
else :
contextin = " \' " + contextin + " \' "
2017-10-04 23:32:33 +00:00
sql = " INSERT INTO `Quotes` (`id`, `quote`, `date`, `user`, `context`, `addedby`) VALUES (NULL, ' %s ' , CURRENT_TIMESTAMP, %d , %s , %s ); " % ( quotein , userin , contextin , session [ ' uid ' ] )
2017-10-03 01:18:13 +00:00
print ( sql )
mysql_do ( sql )
flash ( " Success! The entry was added to the database. " , " success " )
return redirect ( url_for ( ' index ' ) )
2017-10-04 00:04:18 +00:00
# Check if the user is authenticated
try :
session [ ' username ' ]
except KeyError :
flash ( " INFO: Please login first. " , " info " )
return redirect ( url_for ( " login " ) )
2017-10-05 01:08:32 +00:00
return gen_page ( " add_quote.html " , get_userdb ( ) )
2017-10-03 01:18:13 +00:00
@app.context_processor
def utility_processor ( ) :
def uid_to_user ( uid ) :
for user in userdb :
if user [ 0 ] == uid :
return user [ 1 ]
return dict ( uid_to_user = uid_to_user )
if __name__ == " __main__ " :
2017-10-03 22:27:51 +00:00
app_init ( )
2017-10-03 01:18:13 +00:00
app . run ( host = " 0.0.0.0 " , debug = True )