1
0
mirror of https://github.com/avatao-content/test-tutorial-framework synced 2024-11-15 01:57:18 +00:00

Refactor webservice to use SQLAlchemy and other good stuff

This commit is contained in:
Kristóf Tóth 2018-04-28 15:51:04 +02:00
parent c14b244c1e
commit db9e2c055f
5 changed files with 55 additions and 52 deletions

View File

@ -1,5 +1,9 @@
FROM eu.gcr.io/avatao-challengestore/tutorial-framework FROM eu.gcr.io/avatao-challengestore/tutorial-framework
# Install webservice dependencies
RUN pip3 install Flask==1.0 \
SQLAlchemy==1.2.7
# Define variables to use later # Define variables to use later
ENV TFW_SERVER_DIR="/srv/.tfw" \ ENV TFW_SERVER_DIR="/srv/.tfw" \
TFW_WEBSERVICE_DIR="/srv/login_service" \ TFW_WEBSERVICE_DIR="/srv/login_service" \

View File

@ -1,3 +1,3 @@
location /webservice/ { location /webservice/ {
proxy_pass http://127.0.0.1:6666/; proxy_pass http://127.0.0.1:11111/;
} }

View File

@ -0,0 +1,22 @@
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
engine = create_engine('sqlite:///db.db', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
username = Column(String, nullable=False, unique=True)
passwordhash = Column(String, nullable=False)
def init_db():
Base.metadata.create_all(bind=engine)

View File

@ -1,30 +1,12 @@
from os import urandom, getenv from os import urandom, getenv
from os.path import exists, join, dirname, realpath
from hashlib import sha512 from hashlib import sha512
import sqlite3 from flask import Flask, render_template, request, session, url_for
from flask import Flask, render_template, request, g, session, url_for
def setup_db(filename):
connection = sqlite3.connect(filename)
cur = connection.cursor()
cur.execute('''CREATE TABLE users
(
id INTEGER PRIMARY KEY,
username TEXT NOT NULL,
pwhash TEXT NOT NULL
)
''')
connection.commit()
connection.close()
from model import db_session, init_db, User
BASEURL = getenv('BASEURL', '') BASEURL = getenv('BASEURL', '')
DBFILE = join(dirname(realpath(__file__)), '.db.db') init_db()
SALT = 'justsomerandombytes'.encode()
if not exists(DBFILE):
setup_db(DBFILE)
app = Flask(__name__) app = Flask(__name__)
app.secret_key = urandom(32) app.secret_key = urandom(32)
@ -34,27 +16,23 @@ def get_url(endpoint):
app.jinja_env.globals.update(get_url=get_url) app.jinja_env.globals.update(get_url=get_url)
@app.before_request @app.teardown_appcontext
def init_database(): def remove_db_session(exception=None):
g.db = sqlite3.connect(DBFILE) db_session.remove()
g.db.row_factory = sqlite3.Row
@app.teardown_request def hash_password(password):
def close_database(exception): salt = 'justsomerandombytes'.encode()
db = getattr(g, 'db', None) return sha512(password.encode()+salt).hexdigest()
if db is not None:
db.close()
@app.route('/', methods=['GET', 'POST']) @app.route('/', methods=['GET', 'POST'])
def index(): def index():
if request.method == 'POST': if request.method == 'POST':
cur = g.db.cursor() user = User.query.filter(User.username == request.form['username'],
cur.execute('SELECT * FROM users WHERE username=? AND pwhash=?', User.passwordhash == hash_password(request.form['password'])).first()
[request.form['username'], sha512(request.form['password'].encode()+SALT).hexdigest()])
query = cur.fetchone() if not user:
if not query:
return render_template('login.html', alert='Invalid credentials!') return render_template('login.html', alert='Invalid credentials!')
else: else:
session['logged_in'] = True session['logged_in'] = True
@ -69,26 +47,25 @@ def index():
@app.route('/register', methods=['GET', 'POST']) @app.route('/register', methods=['GET', 'POST'])
def register(): def register():
if request.method == 'POST': if request.method == 'POST':
cur = g.db.cursor() validate_register_fields(request)
if User.query.filter(User.username == request.form['username']).all():
return render_template('register.html', alert='Username already in use.')
db_session().add(User(username=request.form['username'],
passwordhash=hash_password(request.form['password'])))
db_session().commit()
return render_template('login.html', success='Account "{}" successfully registered. You can log in now!'.format(request.form['username']))
return render_template('register.html')
def validate_register_fields(request):
if not request.form['username'] or not request.form['password'] or not request.form['passwordconfirm']: if not request.form['username'] or not request.form['password'] or not request.form['passwordconfirm']:
return render_template('register.html', alert='You need to fill everything.') return render_template('register.html', alert='You need to fill everything.')
if request.form['password'] != request.form['passwordconfirm']: if request.form['password'] != request.form['passwordconfirm']:
return render_template('register.html', alert='Passwords do not match! Please try again.') return render_template('register.html', alert='Passwords do not match! Please try again.')
cur.execute('SELECT * FROM users WHERE username=?', [request.form['username']])
if cur.fetchone() is not None:
return render_template('register.html', alert='Username already in use.')
cur.execute('INSERT INTO users(username, pwhash) VALUES(?,?)',
[request.form['username'],
sha512(request.form['password'].encode()+SALT).hexdigest()])
g.db.commit()
return render_template('login.html', success='Account "{}" successfully registered. You can log in now!'.format(request.form['username']))
return render_template('register.html')
@app.route('/logout') @app.route('/logout')
def logout(): def logout():
@ -117,4 +94,4 @@ def servererror(error):
if __name__ == '__main__': if __name__ == '__main__':
app.run(host='127.0.0.1', debug=False, port=6666) app.run(host='127.0.0.1', debug=True, port=11111)

View File

@ -2,7 +2,7 @@
{% block content %} {% block content %}
<h2>Welcome, {{session.username}}</h2> <h2>Welcome, {{session.username}}</h2>
<p>You have successfully logged in</p> <p>You have successfully logged in!</p>
<a href="{{get_url('logout')}}" class="btn btn-default" > <a href="{{get_url('logout')}}" class="btn btn-default" >
<span class="glyphicon glyphicon-log-out"></span> Logout <span class="glyphicon glyphicon-log-out"></span> Logout
</a> </a>