Skip to content

Commit

Permalink
Merge pull request #52 from software-students-spring2024/auth
Browse files Browse the repository at this point in the history
Implement authentication
  • Loading branch information
shriyakalakata authored Feb 27, 2024
2 parents 85ae42f + d5331f5 commit abfc56a
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 21 deletions.
20 changes: 16 additions & 4 deletions app.py
Original file line number Diff line number Diff line change
@@ -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():
Expand All @@ -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("/<username>/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("/<username>/<deckTitle>")
def displayDeck(username, deckTitle):
Expand Down Expand Up @@ -103,3 +114,4 @@ def deleteDeck(username, deckTitle):
if __name__ == "__main__":
FLASK_PORT = os.getenv("FLASK_PORT", "5000")
app.run(port=FLASK_PORT)

76 changes: 60 additions & 16 deletions authentication.py
Original file line number Diff line number Diff line change
@@ -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)



4 changes: 4 additions & 0 deletions static/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,7 @@ h3 {
justify-content: center;
align-items: center;
}

.signup-error, .login-error {
font-size: 25px;
}
3 changes: 3 additions & 0 deletions templates/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
<form class="vertical-align" action={{url_for('login')}} method="post">
<input class="user-input" type="username" name="username" placeholder="Username" required>
<input class="user-input" type="password" name="password" placeholder="Password" required>
{% if invalid_login %}
<p class="login-error"> Password or username is invalid </p>
{% endif %}
<input class="button" type="submit" value="Login">
</form>
</div>
Expand Down
8 changes: 7 additions & 1 deletion templates/signup.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@
<div class="card">
<form class="vertical-align" action="{{action}}" method="post">
<input class="user-input" type="username" name="username" placeholder="Username" required>
{% if username_taken %}
<p class="signup-error"> This username is taken. </p>
{% endif %}
<input class="user-input" type="password" name="password" placeholder="Password" required>
<input class="user-input" type="confirm-password" name="confirm-password" placeholder="Confirm Password" required>
<input class="user-input" type="password" name="confirm-password" placeholder="Confirm Password" required>
{% if passwords_dont_match %}
<p class="signup-error"> The passwords don't match. </p>
{% endif %}
<input class="button" type="submit" value="Sign Up">
</form>
</div>
Expand Down

0 comments on commit abfc56a

Please sign in to comment.