completed authentication system

This commit is contained in:
2022-11-19 15:55:38 -05:00
parent 30493ec187
commit 400c870056
7 changed files with 144 additions and 44 deletions

72
app.py
View File

@@ -1,9 +1,11 @@
import os
from flask import Flask, render_template, redirect
from flask import Flask, render_template, redirect, url_for, request, flash
from flask_migrate import Migrate
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import (LoginManager, login_user, login_required, logout_user, current_user)
from misc import datetime, date, time, currDay
from db import (db, Period, Task, Event)
from forms import (TaskForm, EventForm, PeriodForm)
from db import (db, Period, Task, Event, User)
from forms import (TaskForm, EventForm, PeriodForm, SignupForm, LoginForm)
from create_events import createEvents
basedir = os.path.abspath(os.path.dirname(__file__))
@@ -19,22 +21,73 @@ db.init_app(app)
migrate = Migrate()
migrate.init_app(app, db)
# Authentication stuff
from auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint)
login_manager = LoginManager()
login_manager.login_view = 'login'
login_manager.init_app(app)
signup_enabled = False
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
# Index route
@app.route('/')
def index():
createEvents(db, currDay, Period, Event)
return redirect('/events')
# Authentication routes
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
userName = form.userName.data
password = form.password.data
user = User.query.filter_by(userName=userName).first()
if not user or not check_password_hash(user.password, password):
flash('Credentials incorrect! Please try again')
return redirect(url_for('login'))
login_user(user)
return redirect(url_for('events'))
return render_template('login.html', form=form)
@app.route('/createaccount', methods=['GET', 'POST'])
def createAccount():
if signup_enabled == True:
form = SignupForm()
if form.validate_on_submit():
usernameExists = User.query.filter_by(userName=form.userName.data).first()
if usernameExists:
flash('Username already exists')
return redirect(url_for('createAccount'))
new_user = User(email=form.email.data, userName=form.userName.data, realName=form.realName.data,
password=generate_password_hash(form.password.data, method='sha256'))
db.session.add(new_user)
db.session.commit()
return redirect(url_for('login'))
return render_template('createAccount.html', form=form)
else:
return 'Account creation is currently disabled'
@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('index'))
# Periods routes
@app.route('/periods')
@login_required
def periods():
periods = Period.query.all()
return render_template('periods.html', periods=periods, datetime=datetime)
@app.route('/period/new', methods=('GET', 'POST'))
@login_required
def newPeriod():
form = PeriodForm()
if form.validate_on_submit():
@@ -49,6 +102,7 @@ def newPeriod():
@app.route('/period/edit/<int:periodNum>', methods=('GET', 'POST'))
@login_required
def editPeriod(periodNum):
period = Period.query.get_or_404(periodNum)
form = PeriodForm(obj=period)
@@ -60,6 +114,7 @@ def editPeriod(periodNum):
return render_template('editPeriod.html', period=period, form=form, datetime=datetime)
@app.post('/period/delete/<int:periodNum>')
@login_required
def delete_period(periodNum):
period = Period.query.get_or_404(periodNum)
db.session.delete(period)
@@ -69,6 +124,7 @@ def delete_period(periodNum):
# Events routes
@app.route('/events')
@login_required
def events():
events = Event.query.all()
periods = Period.query.all()
@@ -77,6 +133,7 @@ def events():
return render_template('events.html', events=events, periods=periods, datetime=datetime, date=date)
@app.route('/event/edit/<int:event_id>/', methods=('GET', 'POST'))
@login_required
def editEvent(event_id):
event = Event.query.get_or_404(event_id)
form = EventForm(obj=event)
@@ -91,16 +148,19 @@ def editEvent(event_id):
# Tasks routes
@app.route('/tasks')
@login_required
def tasks():
tasks = Task.query.all()
return render_template('tasks.html', str=str, tasks=tasks, datetime=datetime, date=date)
@app.route('/task/<int:task_id>/')
@login_required
def task(task_id):
task = Task.query.get_or_404(task_id)
return render_template('task.html', str=str, task=task, datetime=datetime, date=date)
@app.route('/task/new', methods=('GET', 'POST'))
@login_required
def newTask():
form = TaskForm()
if form.validate_on_submit():
@@ -113,6 +173,7 @@ def newTask():
return render_template('newtask.html', form=form)
@app.route('/task/<int:task_id>/edit', methods=('GET', 'POST'))
@login_required
def editTask(task_id):
task = Task.query.get_or_404(task_id)
form = TaskForm(obj=task)
@@ -123,6 +184,7 @@ def editTask(task_id):
return redirect(f'/task/{task_id}')
return render_template('edittask.html', task=task, form=form)
@app.post('/task/<int:task_id>/delete')
@login_required
def delete_task(task_id):
task = Task.query.get_or_404(task_id)
db.session.delete(task)

12
auth.py
View File

@@ -1,12 +0,0 @@
from flask import Blueprint, render_template
from app import db
auth = Blueprint('auth', __name__)
@auth.route('/login')
def login():
return render_template('login.html')
@auth.route('/logout')
def logout():
return 'Logout'

3
db.py
View File

@@ -1,4 +1,5 @@
from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin
db = SQLAlchemy()
@@ -36,7 +37,7 @@ class Event(db.Model):
return f'<Event "{self.id}">'
class User(db.Model):
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
userName = db.Column(db.String(1000))
email = db.Column(db.String(100), unique=True)

View File

@@ -1,7 +1,7 @@
from db import Task
from flask_wtf import FlaskForm
from wtforms import (StringField, DateField, TimeField, TextAreaField, IntegerField, BooleanField,
RadioField)
RadioField, EmailField, PasswordField)
from wtforms.validators import InputRequired, Length
from wtforms_sqlalchemy.orm import QuerySelectField
@@ -20,3 +20,13 @@ class EventForm(FlaskForm):
class PeriodForm(FlaskForm):
weekendSchedule = BooleanField(label='Include on Weekends?', false_values=None)
periodTime = TimeField('Time', format="%H:%M")
class SignupForm(FlaskForm):
userName = StringField('Username', validators=[InputRequired()])
password = PasswordField('Password', validators=[InputRequired()])
realName = StringField('Real Name')
email = EmailField('Email Address')
class LoginForm(FlaskForm):
userName = StringField('Username', validators=[InputRequired()])
password = PasswordField('Password', validators=[InputRequired()])

View File

@@ -29,6 +29,14 @@
</li>
</ul>
</div>
<div class="float-right">
{% if current_user.is_authenticated %}
<a href="{{ url_for('logout') }}" class="nav-link"> Logout {{current_user.userName}} </a>
{% endif %}
{% if not current_user.is_authenticated %}
<a href="{{ url_for('login') }}" class="nav-link"> Login </a>
{% endif %}
</div>
</nav>
<hr>
<div class="container">

View File

@@ -0,0 +1,34 @@
{% extends "base.html" %}
{% block content %}
<span><h1>{% block title %} Create Account {% endblock %}</h1></span>
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="notification is-danger">
{{ messages[0] }}. Go to <a href="{{ url_for('login') }}">login page</a>.
</div>
{% endif %}
{% endwith %}
<form method="post">
{{ form.csrf_token }}
<p>
{{ form.userName.label }}
{{ form.userName }}
</p>
<p>
{{ form.password.label }}
{{ form.password }}
</p>
<p>
{{ form.realName.label }}
{{ form.realName }}
</p>
<p>
{{ form.email.label }}
{{ form.email }}
</p>
<p>
<button class="btn btn-primary" type="submit">Submit</button>
</p>
</form>
{% endblock %}

View File

@@ -1,29 +1,26 @@
{% extends "base.html" %}
{% block content %}
<div>
<h3>Login</h3>
<div>
<form method="POST" action="/login">
<div>
<div>
<input type="email" name="email" placeholder="Your Email" autofocus="">
</div>
</div>
<div>
<div>
<input type="password" name="password" placeholder="Your Password">
</div>
</div>
<div>
<label>
<input type="checkbox" name="remember">
Remember me
</label>
</div>
<button>Login</button>
</form>
<span><h1>{% block title %} Login {% endblock %}</h1></span>
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="notification is-danger">
{{ messages[0] }}
</div>
</div>
{% endif %}
{% endwith %}
<form method="post">
{{ form.csrf_token }}
<p>
{{ form.userName.label }}
{{ form.userName }}
</p>
<p>
{{ form.password.label }}
{{ form.password }}
</p>
<p>
<button class="btn btn-primary" type="submit">Submit</button>
</p>
</form>
{% endblock %}