diff --git a/backend/application/api_functions.py b/backend/application/api_functions.py new file mode 100644 index 0000000..7d673ce --- /dev/null +++ b/backend/application/api_functions.py @@ -0,0 +1,138 @@ +import hashlib +import os +from datetime import datetime +from flask_sqlalchemy import inspect +from .users_model import Users, db +from .logs_model import Logs + + +def hash_password(salt, password): + return hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, 100000) + + +def db_login(ip, email, password): + user = Users.query.filter( + Users.email == email + ).first() + if not user: + message = f'{email} does not exist.' + log = Logs( + date=datetime.now().strftime('%Y-%m-%dT%H:%M:%S'), + id_user=None, + ip=ip, + table='users', + action='login', + message=message, + has_succeeded=False, + status_code=1 + ) + db.session.add(log) + db.session.commit() + return {'status': 1, 'message': message} # User does not exist + + # Check Hash Pass + salt = user.get_salt() + hash_pass = hash_password(salt, password) + + user = Users.query\ + .filter(Users.email == email)\ + .filter(Users.hash_pass == hash_pass)\ + .first() + + if not user: + message = f'Email or password invalid' + log = Logs( + date=datetime.now().strftime('%Y-%m-%dT%H:%M:%S'), + id_user=None, + ip=ip, + table='users', + action='login', + message=message, + has_succeeded=False, + status_code=2 + ) + db.session.add(log) + db.session.commit() + return {'status': 2, 'message': message} # Email or password invalid + else: + message = 'User authenticated.' + log = Logs( + date=datetime.now().strftime('%Y-%m-%dT%H:%M:%S'), + id_user=user.get_id(), + ip=ip, + table='users', + action='login', + message=message, + has_succeeded=True, + status_code=0 + ) + db.session.add(log) + db.session.commit() + return {'status': 0, 'message': message, 'data': user.json()} + + +def db_register(ip, email, login, password, is_admin): + user = Users.query.filter( + Users.email == email or Users.login == login + ).first() + if user: + message = f'{email} ({login}) already exist.' + log = Logs( + date=datetime.now().strftime('%Y-%m-%dT%H:%M:%S'), + id_user=None, + ip=ip, + table='users', + action='register', + message=message, + has_succeeded=False, + status_code=1 + ) + db.session.add(log) + db.session.commit() + return {'status': 1, 'message': message} # User already exist + + # Salt Hash Pass with SHA256 + salt = os.urandom(32) + print('salt: ', salt) + hash_pass = hash_password(salt, password) + + user = Users( + email=email, + login=login, + hash_pass=hash_pass, + salt=salt, + is_admin=is_admin + ) + user_inspect = inspect(user) + db.session.add(user) + check_inspect = user_inspect.pending + db.session.commit() + + # Add to logs + if check_inspect: + id_user = user.json()['id'] + message = 'User registered.' + has_succeeded = True + status_code = 0 + else: + id_user = None + message = 'Internal Error: User not registered.' + has_succeeded = False + status_code = 1 + + log = Logs( + date=datetime.now().strftime('%Y-%m-%dT%H:%M:%S'), + id_user=id_user, + ip=ip, + table='users', + action='register', + message=message, + has_succeeded=has_succeeded, + status_code=status_code + ) + db.session.add(log) + db.session.commit() + if status_code == 0: + return {'status': 0, 'message': message, 'data': user.json()} + elif status_code == 1: + return {'status': 1, 'message': message} diff --git a/backend/application/routes.py b/backend/application/routes.py index 0def9de..976491c 100644 --- a/backend/application/routes.py +++ b/backend/application/routes.py @@ -1,41 +1,47 @@ from flask import current_app as app from flask import request -from .users_model import Users, db from .responses import send_message, send_error +from .api_functions import db_login, db_register # Login @app.route('/api/login', methods=['POST']) def login(): - return send_message('Login not implemented', None) + post_json = request.json + post_email = str(post_json['email']) + post_password = str(post_json['password']) + if post_email and post_password: + ip = request.remote_addr + res = db_login(ip, post_email, post_password) + # TODO: Token Authentication + if res['status'] == 0: + return send_message(res['message'], res['data']) + elif res['status'] == 1: + return send_error(500, res['message']) + elif res['status'] == 2: + return send_error(404, res['message']) + else: + return send_error(400, 'POST Request Error : Need email, password fields.') # Register @app.route('/api/register', methods=['POST']) def register(): - post_email = str(request.form['email']) - post_login = str(request.form['login']) - post_hash_pass = str(request.form['hashPass']) - post_role = str(request.form['role']) - - if post_email and post_login and post_hash_pass and post_role: - user = Users.query.filter( - Users.email == post_email or Users.login == post_login - ).first() - if user: - return send_message(f"{post_email} ({post_login}) already exist.", None) - user = Users( - email=post_email, - login=post_login, - hashPass=post_hash_pass, - role=post_role - ) - db.session.add(user) - db.session.commit() - return send_message('User registered.', user) + post_json = request.json + post_email = str(post_json['email']) + post_login = str(post_json['login']) + post_password = str(post_json['password']) + post_is_admin = bool(post_json['is_admin']) + if post_email and post_login and post_password and post_is_admin: + ip = request.remote_addr + res = db_register(ip, post_email, post_login, post_password, post_is_admin) + if res['status'] == 1: + return send_error(500, res['message']) + elif res['status'] == 0: + return send_message(res['message'], res['data']) else: - return send_error(400, 'POST Request Error : Need email, login, hashPass and role fields.') + return send_error(400, 'POST Request Error : Need email, login, password and is_admin fields.') # Logout @@ -80,13 +86,7 @@ def admin_delete_user(): return send_message('Admin.delete.user not implemented', None) -# List of User (must be authenticated) +# List of User (must be authenticated) & Search @app.route('/api/users', methods=['GET']) def users(): return send_message('Users not implemented', None) - - -# Search User -@app.route('/api/users/search', methods=['POST']) -def users_search(): - return send_message('Users.search not implemented', None)