From 7eb5f2860ab566b1f5f43c14910b1e5c16552eae Mon Sep 17 00:00:00 2001 From: Sean Lim Date: Thu, 2 Jan 2020 18:27:30 +0800 Subject: [PATCH] Did some shit --- pyproject.toml | 1 + src/app.py | 35 +++++++++++++++++++++++++++++------ src/middleware/auth.py | 7 ++++--- src/model/attendee.py | 30 +++++++++++++++++++----------- src/model/features.py | 2 +- start.sh | 0 6 files changed, 54 insertions(+), 21 deletions(-) mode change 100644 => 100755 start.sh diff --git a/pyproject.toml b/pyproject.toml index d6c8fd9..4440be6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ marshmallow-sqlalchemy = "^0.19.0" psycopg2 = "^2.8" pyjwt = "^1.7" python-dotenv = "^0.10.3" +bcrypt = "^3.1.7" [tool.poetry.dev-dependencies] diff --git a/src/app.py b/src/app.py index f50f2fb..a018153 100644 --- a/src/app.py +++ b/src/app.py @@ -3,38 +3,61 @@ from model.eventowner import add_event_owner, get_event_owner from model.base import Session, engine, Base from model.comparator import compare_features -from middleware.auth import auth +from middleware.auth import auth import json app = Flask(__name__) Base.metadata.create_all(engine) @app.route("/api/attendee") @auth -def get_attendee(): +def attendee_get(): email = request.args.get('email') return get_attendee(email); @app.route("/api/attendee/new", methods=['POST']) @auth -def create_attendee(): +def attendee_post(): data = request.get_json() return add_attendee(data) @app.route("/api/eventowner") @auth -def get_event_owner(): +def event_owner_get(): eventowner_id = request.args.get('eventowner_id') return getEventOwner(eventowner_id) @app.route("/api/eventowner/new", methods=['POST']) @auth -def create_event_owner(): +def event_owner_post(): data = request.get_json() return addEventOwner(data) @app.route("/api/identify", methods=['POST']) @auth -def compare(): +def compare_post(): data = request.get_json() return compare_features(data) +@app.route("/user/login", methods=['POST']) +def login_post(): + email = request.args.get('email') + password = request.args.get('password') + + app.logger.info(email) + app.logger.info(password) + + # This sucks + result = get_attendee(email, app.logger) + error_response = ("Email and password combination is incorrect", 401) + if result[1] == 404: + return error_response + + password_correct = result[0].authenticate(password) + + # Generate a new token + if password_correct: + token = result[0].encode_auth_token() + return token, 200 + + return error_response + diff --git a/src/middleware/auth.py b/src/middleware/auth.py index dc99a9c..f34877e 100644 --- a/src/middleware/auth.py +++ b/src/middleware/auth.py @@ -1,8 +1,10 @@ import flask +from functools import wraps from flask import g from model.attendee import decode_auth_token def auth(f): + @wraps(f) def _auth(*args, **kwargs): data = flask.request.get_json() if not data: @@ -10,8 +12,7 @@ def _auth(*args, **kwargs): try: user_id = decode_auth_token(data["token"]) g.user_id = user_id - f(*args, **kwargs) + return f(*args, **kwargs) except Exception as e: - flask.abort(401) - _auth.__name__ = f.__name__ + flask.abort(401, 'Session invalid') return _auth diff --git a/src/model/attendee.py b/src/model/attendee.py index 33a7e9d..1e22097 100644 --- a/src/model/attendee.py +++ b/src/model/attendee.py @@ -1,5 +1,6 @@ import os import jwt +import bcrypt from sqlalchemy import Column, String, Integer, Date, Boolean, BIGINT from sqlalchemy.types import ARRAY from .base import Base, Session @@ -21,7 +22,7 @@ class Attendee(Base): status = Column(Boolean) email = Column(String) passHash = Column(String) - def __init__(self, id, course, year, gender, status, email): + def __init__(self, id, course, year, gender, status, email, passHash): self.id = id self.course = course self.year = year @@ -29,12 +30,14 @@ def __init__(self, id, course, year, gender, status, email): self.status = status self.email = email self.passHash = passHash - def encode_auth_token(self, id): + def authenticate(self, password): + return self.passHash == bcrypt.hashpw(password, self.passHash) + def encode_auth_token(self): try: payload = { 'exp': datetime.utcnow() + timedelta(days=0, seconds=5), 'iat': datetime.utcnow(), - 'sub': id + 'sub': self.id } return jwt.encode( payload, @@ -70,7 +73,8 @@ def add_attendee(data): year = data['year'], gender = data['gender'], status = data['status'], - email = data['email'] + email = data['email'], + passHash = bcrypt.hashpw(data['password'], bcrypt.gensalt()) ) session.add(new_attendee) try: @@ -84,13 +88,17 @@ def add_attendee(data): else: return "Add attendee failed", 200 -def get_attendee(id): - attendee = session.query(Attendee).filter_by(email = id).first() - if attendee is None: - return "Attendee not found", 404 - else: - result = attendee_schema.dump(attendee) - return result, 200 +def get_attendee(email, logger): + try: + session = Session() + attendee = session.query(Attendee).filter_by(email = email).first() + if attendee is None: + return "Attendee not found", 404 + else: + result = attendee_schema.dump(attendee) + return result, 200 + except Exception as e: + logger.error(e) def get_attendee_by_id(id): attendee = session.query(Attendee).filter_by(id = id).first() diff --git a/src/model/features.py b/src/model/features.py index 5c81fed..d7ee447 100644 --- a/src/model/features.py +++ b/src/model/features.py @@ -49,7 +49,7 @@ def generateFeaturesFromBase64(arrOBase64): features.append(convertNumToString) return features -def addFeatures(data): +def add_features(data): featuresArr = generateFeaturesFromBase64(data['features']) success = True if featuresArr != []: diff --git a/start.sh b/start.sh old mode 100644 new mode 100755