diff --git a/config.py b/config.py index 6be4581..55b15e6 100644 --- a/config.py +++ b/config.py @@ -7,6 +7,9 @@ class Config(object): DEBUG = False DEVELOPMENT = False SECRET_KEY = '97867c1491bea5ee6a8e8436eb11bf2ba6a69ff53ab1b17ecba450d0f2e572e1' + JWT_SECRET_KEY = '60a4ba120437004cfc8fc1cf571150f16d950d31aa7c5a4a2fe7a262d4d24bec' + JWT_TOKEN_LOCATION = ['cookies'] + JWT_COOKIE_SECURE = True class DevConfig(Config): @@ -15,6 +18,7 @@ class DevConfig(Config): SQLALCHEMY_DATABASE_URI = 'postgresql+pg8000://josako@localhost:5432/eveAI' SQLALCHEMY_BINDS = {'public': 'postgresql+pg8000://josako@localhost:5432/eveAI'} EXPLAIN_TEMPLATE_LOADING = True + JWT_COOKIE_SECURE = False class ProdConfig(Config): diff --git a/eveai_app/__init__.py b/eveai_app/__init__.py index 6528192..5abcc41 100644 --- a/eveai_app/__init__.py +++ b/eveai_app/__init__.py @@ -35,6 +35,8 @@ def register_extensions(app): def register_blueprints(app): from .views.user_views import user_bp app.register_blueprint(user_bp) + from .views.auth_views import auth_bp + app.register_blueprint(auth_bp) def register_api(app): diff --git a/eveai_app/templates/login.html b/eveai_app/templates/login.html new file mode 100644 index 0000000..0044689 --- /dev/null +++ b/eveai_app/templates/login.html @@ -0,0 +1,17 @@ +{% extends 'base.html' %} + +{% block title %}Login{% endblock %} + +{% block content %} +
+{% endblock %} \ No newline at end of file diff --git a/eveai_app/views/auth_forms.py b/eveai_app/views/auth_forms.py new file mode 100644 index 0000000..b952a41 --- /dev/null +++ b/eveai_app/views/auth_forms.py @@ -0,0 +1,10 @@ +from flask_wtf import FlaskForm +from wtforms import PasswordField, SubmitField, EmailField, BooleanField +from wtforms.validators import DataRequired, Length, Email + + +class LoginForm(FlaskForm): + email = EmailField('Email', validators=[DataRequired(), Email()]) + password = PasswordField('Password', validators=[DataRequired(), Length(min=8)]) + # remember_me = BooleanField('Remember me') + submit = SubmitField('Login') diff --git a/eveai_app/views/auth_views.py b/eveai_app/views/auth_views.py new file mode 100644 index 0000000..9c04bb8 --- /dev/null +++ b/eveai_app/views/auth_views.py @@ -0,0 +1,47 @@ +from datetime import datetime as dt, timezone as tz +from flask import request, redirect, url_for, flash, render_template, Blueprint, jsonify +from ..models.user import User, Tenant +from ..extensions import db, bcrypt +from .auth_forms import LoginForm +from flask_jwt_extended import (create_access_token, create_refresh_token, set_access_cookies, set_refresh_cookies, + unset_jwt_cookies) + +auth_bp = Blueprint('auth_bp', __name__) + + +@auth_bp.route('/login', methods=['GET', 'POST']) +def login(): + if request.method == 'POST': + email = request.form.get('email') + password = request.form.get('password') + remember_me = True if request.form.get('remember_me') else False + + user = User.query.filter_by(email=email).first() + if user: + if bcrypt.check_password_hash(user.password, password): + response = jsonify({'msg': 'Login Successful'}) + flash('Logged in successfully!', category='success') + access_token = create_access_token( + identity=user.id, + additional_claims={'tenant': user.tenant_id}) + refresh_token = create_refresh_token( + identity=user.id, + additional_claims={'tenant': user.tenant_id}) + set_access_cookies(response, access_token) + set_refresh_cookies(response, refresh_token) + + return redirect(url_for('user_bp.user')) + else: + flash('Incorrect password, try again.', category='error') + else: + flash('Email does not exist.', category='error') + + form = LoginForm() + return render_template('login.html', form=form) + + +@auth_bp.route('/logout', methods=['POST']) +def logout(): + response = jsonify({'msg': 'Logout Successful'}) + unset_jwt_cookies(response) + return redirect(url_for('/'))