diff --git a/app.py b/app.py index 5a25882..86413cc 100644 --- a/app.py +++ b/app.py @@ -1,9 +1,15 @@ from flask import Flask, render_template, request, redirect, abort, url_for, make_response +from flask_login import current_user from authentication import * from db import * import random app = Flask(__name__) +login_manager.init_app(app) + +# Secret key for login session management, set this up in your .env file +load_dotenv() +app.secret_key = os.getenv("SECRET_KEY") @app.route("/", methods=["GET", "POST"]) def home(): @@ -19,20 +25,25 @@ def home(): # Handle authentication related stuff in authentication.py file @app.route('/login', methods=["GET", "POST"]) def login(): - return authLogin() + return auth_login() @app.route('/signup', methods=["GET", "POST"]) def signup(): - return authSignup() + return auth_signup() @app.route("//decks") def allDecks(username): - # would need to first find user in db, but not set up yet if username == "guest": mainDecks = db.decks.find({}) return render_template('decks.html', mainDecks=mainDecks) else: - return "to do: for users" + if (not current_user.is_authenticated or current_user.id != username): + # TODO: Implement proper 404 screen to redirect here. + return username + " needs to log in first." + else: + # TODO: Redirect to the decks of the current user + return "Here would be the decks of " + current_user.id + "." + @app.route("//") def displayDeck(username, deckTitle): @@ -103,3 +114,4 @@ def deleteDeck(username, deckTitle): if __name__ == "__main__": FLASK_PORT = os.getenv("FLASK_PORT", "5000") app.run(port=FLASK_PORT) + diff --git a/authentication.py b/authentication.py index e76ec9a..1f6a91f 100644 --- a/authentication.py +++ b/authentication.py @@ -1,31 +1,75 @@ -from flask import render_template, request, redirect, url_for, session -from flask_login import LoginManager +from flask import render_template, request, redirect, url_for, session, flash +from flask_login import LoginManager, UserMixin, login_user from db import * - +from pymongo import * +from werkzeug.security import generate_password_hash, check_password_hash login_manager = LoginManager() -class User(): - def __init__(self, username, password, is_authenticated, is_active, is_anonymous): - self.is_authenticated = is_authenticated - self.is_active = is_active - self.is_anonymous = is_anonymous +''' +NOTE: +To get the active user from a different file or somewhere else +you need to import flask_login first then you can retrieve the active user with current_user +Example: + from flask_login import current_user + if current_user.is_authenticated: + # Do something with current_user +Also check allDecks function in app.py for example usage +''' +# Automatically implements is_authenticated, is_anonymous, is_active and get_id() +# through UserMixin +class User(UserMixin): + def __init__(self, user_id, password): + self.id = user_id + self.password = password + + def verify_password(self, pwd): + return check_password_hash(self.password, pwd) + @login_manager.user_loader def load_user(user_id): - return User.get(user_id) + data = db['users'].find_one({"user_id": user_id}) + if (data): + return User(data['user_id'], data['password']) + else: + return None + -def authLogin(): +def auth_login(): + collections = db.list_collection_names() if request.method == 'POST': - ## TODO: Login - return "Someone pressed the login button huh, I better log you in." + user_id = request.form["username"] + password = request.form["password"] + user = load_user(user_id) + if user and user.verify_password(password): + # TODO: Redirect to the appropriate page for the logged in user + login_user(user) + return redirect('/') + else: + return render_template('login.html', invalid_login=True) else: - return render_template('login.html') + return render_template('login.html', invalid_login=False) + -def authSignup(): +def auth_signup(): if request.method == 'POST': - username = request.form["username"] + user_id = request.form["username"] password = request.form["password"] + confirm_password = request.form["confirm-password"] + if load_user(user_id): + return render_template('signup.html', username_taken=True, passwords_dont_match=False) + elif password != confirm_password: + return render_template('signup.html', username_taken=False, passwords_dont_match=True) + else: + user = User(user_id, generate_password_hash(password)) + db['users'].insert_one({"user_id": user.id, "password": user.password}) + login_user(user) + # TODO: Redirect to the appropriate page for the logged in user + return redirect('/') + else: - return render_template('signup.html') + return render_template('signup.html', username_taken=False, passwords_dont_match=False) + + diff --git a/static/css/style.css b/static/css/style.css index 5a5d1e3..76cca7e 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -116,3 +116,7 @@ h3 { justify-content: center; align-items: center; } + +.signup-error, .login-error { + font-size: 25px; +} diff --git a/templates/login.html b/templates/login.html index 06b9613..0bc1657 100644 --- a/templates/login.html +++ b/templates/login.html @@ -6,6 +6,9 @@
+ {% if invalid_login %} + + {% endif %}
diff --git a/templates/signup.html b/templates/signup.html index 03c05d4..d659d7b 100644 --- a/templates/signup.html +++ b/templates/signup.html @@ -5,8 +5,14 @@
+ {% if username_taken %} + + {% endif %} - + + {% if passwords_dont_match %} + + {% endif %}