diff --git a/src/core/__init__.py b/src/core/__init__.py index 88fd085..d39459d 100644 --- a/src/core/__init__.py +++ b/src/core/__init__.py @@ -1,5 +1,6 @@ from flask import Flask -from flask_sqlalchemy import SQLAlchemy +from flask_bcrypt import Bcrypt +from flask_login import current_user, login_user, logout_user, LoginManager app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///static/db/database.db" @@ -9,9 +10,12 @@ app.config['TITLE'] = ':::APP TITLE:::' # For csrf...change!! app.config['SECRET_KEY'] = '48e80dcf4ed6ea952ca1b7b564be22d665e6e178f7fda84828fdd5e7cdca097a' -from core.models import db -db.init_app(app) +login_manager = LoginManager(app) +bcrypt = Bcrypt(app) + +from core.models import db, User +db.init_app(app) from core.forms import RegisterForm, LoginForm from core import routes diff --git a/src/core/forms.py b/src/core/forms.py index 37a230a..7b568c3 100644 --- a/src/core/forms.py +++ b/src/core/forms.py @@ -1,6 +1,7 @@ from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, SubmitField -from wtforms.validators import DataRequired, Length, Email, EqualTo +from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError +from core import User @@ -12,6 +13,11 @@ class RegisterForm(FlaskForm): validators=[DataRequired(), EqualTo('password', message="Passwords must match!")]) submit = SubmitField("Sign Up") + def validate_username(self, username): + user = User.query.filter_by(username=username.data).first() + if user: + raise ValidationError("User exists already! Please use a different name!") + class LoginForm(FlaskForm): username = StringField('Username', validators=[DataRequired(), Length(min=4, max=24)]) diff --git a/src/core/models.py b/src/core/models.py index e63bf42..7126fb6 100644 --- a/src/core/models.py +++ b/src/core/models.py @@ -1,17 +1,17 @@ from flask_sqlalchemy import SQLAlchemy - -db = SQLAlchemy() +from core import app, login_manager +from flask_login import UserMixin -class Table(db.Model): - id = db.Column(db.Integer, nullable=False, primary_key=True, unique=True, autoincrement=True) +db = SQLAlchemy(app) - def __repr__(self): - return f"['{self.title}', '{self.icon}', '{self.link}', '{self.id}']" +@login_manager.user_loader +def load_user(user_id): + return User.query.get(int(user_id)) -class User(db.Model): - username = db.Column(db.String, nullable=False) +class User(db.Model, UserMixin): + username = db.Column(db.String, unique=True, nullable=False) email = db.Column(db.String, nullable=False) password = db.Column(db.String, nullable=False) id = db.Column(db.Integer, nullable=False, primary_key=True, unique=True, autoincrement=True) diff --git a/src/core/routes/Routes.py b/src/core/routes/Routes.py index 8b0c752..00a1ef8 100644 --- a/src/core/routes/Routes.py +++ b/src/core/routes/Routes.py @@ -5,7 +5,6 @@ from flask import request, render_template # App imports from core import app, db # Get from __init__ -from core.models import Table # Get db models from core.MessageHandler import MessageHandler # Get simple message processor diff --git a/src/core/routes/pages/Login.py b/src/core/routes/pages/Login.py index 16800b8..a21e859 100644 --- a/src/core/routes/pages/Login.py +++ b/src/core/routes/pages/Login.py @@ -1,10 +1,11 @@ # Python imports # Lib imports -from flask import request, render_template +from flask import request, render_template, flash, redirect, url_for +from flask_login import current_user, login_user, logout_user # App imports -from core import app, db, LoginForm +from core import app, bcrypt, db, User, LoginForm from core.MessageHandler import MessageHandler # Get simple message processor @@ -13,8 +14,25 @@ TITLE = app.config['TITLE'] @app.route('/login', methods=['GET', 'POST']) def login(): - _form = LoginForm() + if current_user.is_authenticated: + return redirect(url_for("home")) - return render_template('login.html', - title=TITLE, - form=_form) + _form = LoginForm() + if _form.validate_on_submit(): + user = db.session.query(User).filter(User.username == _form.username.data).first() + + if user and bcrypt.check_password_hash(user.password, _form.password.data): + login_user(user, remember=False) + flash("Logged in successfully!", "success") + return redirect(url_for("home")) + + flash("Username or password incorrect! Please try again...", "danger") + + return render_template('login.html', title=TITLE, form=_form) + + +@app.route('/logout') +def logout(): + logout_user() + flash("Logged out successfully!", "success") + return redirect(url_for("home")) diff --git a/src/core/routes/pages/Register.py b/src/core/routes/pages/Register.py index 64e5701..c6ebb50 100644 --- a/src/core/routes/pages/Register.py +++ b/src/core/routes/pages/Register.py @@ -4,7 +4,8 @@ from flask import request, render_template, url_for, redirect, flash # App imports -from core import app, db, RegisterForm +from core import app, bcrypt, db, current_user, RegisterForm # Get from __init__ +from core.models import User from core.MessageHandler import MessageHandler # Get simple message processor @@ -13,12 +14,18 @@ TITLE = app.config['TITLE'] @app.route('/register', methods=['GET', 'POST']) def register(): - _form = RegisterForm() - - if _form.validate_on_submit(): - flash("Account created successfully!", "success") + if current_user.is_authenticated: return redirect(url_for("home")) + _form = RegisterForm() + if _form.validate_on_submit(): + hashed_password = bcrypt.generate_password_hash(_form.password.data).decode("utf-8") + user = User(username=_form.username.data, email=_form.email.data, password=hashed_password) + db.session.add(user) + db.session.commit() + flash("Account created successfully!", "success") + return redirect(url_for("login")) + return render_template('register.html', title=TITLE, form=_form) diff --git a/src/core/static/db/database.db b/src/core/static/db/database.db index 6d261d2..5ae7bc0 100644 Binary files a/src/core/static/db/database.db and b/src/core/static/db/database.db differ diff --git a/src/core/templates/body-header.html b/src/core/templates/body-header.html index 0543d68..db1ea69 100644 --- a/src/core/templates/body-header.html +++ b/src/core/templates/body-header.html @@ -22,19 +22,22 @@ + + + {% if not current_user.is_authenticated %} + {% endif %} - + + {% if current_user.is_authenticated %} + + {% endif %} diff --git a/src/core/templates/layout.html b/src/core/templates/layout.html index f6dd7b8..b360f37 100644 --- a/src/core/templates/layout.html +++ b/src/core/templates/layout.html @@ -30,16 +30,6 @@ {% endblock header_css_additional %} {% endblock %} - - {% with messages = get_flashed_messages(with_categories=true) %} - {% if messages %} -
- {% for category, message in messages %} -
  • {{ message }}
  • - {% endfor %} -
    - {% endif %} - {% endwith %} {% block header_scripts %} {% block header_scripts_additional %} @@ -49,7 +39,6 @@ {{title}} Background Logo - {% block body_header %} {% include "body-header.html" %} @@ -57,6 +46,16 @@ {% endblock body_header_additional%} {% endblock %} + +{% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} +
    + {% for category, message in messages %} +
  • {{ message }}
  • + {% endfor %} +
    + {% endif %} +{% endwith %} {% block body_content %} {% block body_content_additional %} diff --git a/src/core/templates/login.html b/src/core/templates/login.html index 3bbeed7..ffb7c3c 100644 --- a/src/core/templates/login.html +++ b/src/core/templates/login.html @@ -30,10 +30,10 @@
    {{ form.password.label(class="form-control-label") }} - {% if form.email.errors %} - {{ form.email(class="form-control form-control-sm is-invalid", autocomplete="off") }} + {% if form.password.errors %} + {{ form.password(class="form-control form-control-sm is-invalid", autocomplete="off") }}
    - {% for error in form.email.errors %} + {% for error in form.password.errors %} {{ error }} {% endfor %} {% else %}