mirror of
https://github.com/avatao-content/test-tutorial-framework
synced 2024-11-15 01:47:16 +00:00
Refactor webservice to use SQLAlchemy and other good stuff
This commit is contained in:
parent
c14b244c1e
commit
db9e2c055f
@ -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" \
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
location /webservice/ {
|
location /webservice/ {
|
||||||
proxy_pass http://127.0.0.1:6666/;
|
proxy_pass http://127.0.0.1:11111/;
|
||||||
}
|
}
|
||||||
|
22
solvable/src/webservice/model.py
Normal file
22
solvable/src/webservice/model.py
Normal 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)
|
@ -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)
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user