Finished auth
This commit is contained in:
parent
47d549be85
commit
b3b8a3fd5f
91
app.py
91
app.py
@ -1,12 +1,30 @@
|
||||
import datetime
|
||||
import hashlib
|
||||
|
||||
from flask import Flask, render_template, redirect, url_for, request
|
||||
from flask_login import login_required, LoginManager
|
||||
from flask_login import login_required, LoginManager, login_user, logout_user, current_user
|
||||
|
||||
from models.User import User
|
||||
from utils import anonymous_required
|
||||
|
||||
# Create a new Flask instance
|
||||
app = Flask(__name__)
|
||||
app.secret_key = 'PSSSSSHHHT!'
|
||||
|
||||
# Initialize the Flask-Login extension
|
||||
login_manager = LoginManager()
|
||||
login_manager.login_view = 'login'
|
||||
login_manager.init_app(app)
|
||||
|
||||
|
||||
@login_manager.user_loader
|
||||
def load_user(user_id):
|
||||
return User.get(user_id)
|
||||
|
||||
|
||||
@app.context_processor
|
||||
def inject_user():
|
||||
return dict(user=current_user)
|
||||
|
||||
|
||||
# Create a new route
|
||||
@ -15,20 +33,25 @@ def index():
|
||||
# return 'Hello World'
|
||||
return render_template('index.html', title='Home', utc_dt=datetime.datetime.now().strftime("%d.%m.%Y %H:%M:%S"))
|
||||
|
||||
|
||||
@app.route('/test')
|
||||
@login_required
|
||||
def secret():
|
||||
return 'Pssst!'
|
||||
|
||||
|
||||
@app.route('/login')
|
||||
@anonymous_required
|
||||
def login():
|
||||
return render_template('auth/login.html')
|
||||
return render_template('auth/login.html', errors={})
|
||||
|
||||
|
||||
@app.route('/signup')
|
||||
@anonymous_required
|
||||
def signup():
|
||||
return render_template('auth/signup.html', errors={})
|
||||
|
||||
|
||||
@app.route('/signup', methods=['POST'])
|
||||
def signup_post():
|
||||
email = request.form.get('email')
|
||||
@ -44,36 +67,66 @@ def signup_post():
|
||||
if not password:
|
||||
errors['password'] = 'Password is required.'
|
||||
|
||||
return render_template(
|
||||
'auth/signup.html',
|
||||
email=email,
|
||||
name=name,
|
||||
password=password,
|
||||
errors=errors
|
||||
)
|
||||
if errors:
|
||||
return render_template(
|
||||
'auth/signup.html',
|
||||
email=email,
|
||||
name=name,
|
||||
password=password,
|
||||
errors=errors
|
||||
)
|
||||
|
||||
# Save user to database. Maybe log the user in directly.
|
||||
user = User.create(name, email, password)
|
||||
login_user(user)
|
||||
|
||||
# Redirect to login page
|
||||
return redirect(url_for('login'))
|
||||
return redirect(url_for('secret'))
|
||||
|
||||
|
||||
@app.route('/login', methods=['POST'])
|
||||
def login_post():
|
||||
email = request.form.get('email')
|
||||
password = request.form.get('password')
|
||||
|
||||
# Check for errors
|
||||
errors = {}
|
||||
if not email:
|
||||
errors['email'] = 'Email is required.'
|
||||
if not password:
|
||||
errors['password'] = 'Password is required.'
|
||||
|
||||
# Check if user exists
|
||||
user = User.get_by_email(email)
|
||||
|
||||
if not user:
|
||||
errors['email'] = 'User does not exist.'
|
||||
elif user.password is None or hashlib.sha256(password.encode()).hexdigest() != user.password:
|
||||
errors['password'] = 'Password incorrect.'
|
||||
|
||||
if errors:
|
||||
return render_template(
|
||||
'auth/login.html',
|
||||
email=email,
|
||||
password=password,
|
||||
errors=errors
|
||||
)
|
||||
|
||||
login_user(user)
|
||||
|
||||
# Redirect to login page
|
||||
return redirect(url_for('secret'))
|
||||
|
||||
|
||||
@app.route('/logout')
|
||||
@login_required
|
||||
def logout():
|
||||
# Log out functionality
|
||||
logout_user()
|
||||
|
||||
return redirect(url_for('index'))
|
||||
|
||||
|
||||
# Run the application
|
||||
if __name__ == '__main__':
|
||||
login_manager = LoginManager()
|
||||
login_manager.login_view = 'login'
|
||||
login_manager.init_app(app)
|
||||
app.secret_key = 'PSSSSSHHHT!'
|
||||
|
||||
@login_manager.user_loader
|
||||
def load_user(user_id):
|
||||
return User.get(user_id)
|
||||
|
||||
app.run(port=5000, debug=True)
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
from datetime import datetime
|
||||
import hashlib
|
||||
import sqlite3
|
||||
|
||||
@ -7,9 +8,11 @@ def con3():
|
||||
return conn
|
||||
|
||||
|
||||
def create_user(name, email, password):
|
||||
password = hashlib.md5(password.encode()).hexdigest()
|
||||
query = f"INSERT INTO users (name, email, password) VALUES ({name}, {email}, {password})"
|
||||
def create_user(name: str, email: str, password: str):
|
||||
password = hashlib.sha256(password.encode()).hexdigest()
|
||||
now = datetime.now().isoformat()
|
||||
query = (f"INSERT INTO users (name, email, password, created_at, updated_at) VALUES ('{name}', '{email}', "
|
||||
f"'{password}', '{now}', '{now}');")
|
||||
conn = con3()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(query)
|
||||
@ -18,8 +21,18 @@ def create_user(name, email, password):
|
||||
return cursor.lastrowid
|
||||
|
||||
|
||||
def get_user(id):
|
||||
query = f"SELECT * FROM users WHERE id = {id}"
|
||||
def get_user(id: int):
|
||||
query = f"SELECT * FROM users WHERE id = {id};"
|
||||
conn = con3()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(query)
|
||||
user = cursor.fetchone()
|
||||
conn.close()
|
||||
return user
|
||||
|
||||
|
||||
def get_user_by_email(email: str):
|
||||
query = f"SELECT * FROM users WHERE email = '{email}';"
|
||||
conn = con3()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(query)
|
||||
|
||||
BIN
db/db.sqlite
BIN
db/db.sqlite
Binary file not shown.
@ -1,18 +1,26 @@
|
||||
from db.SQLiteClient import create_user, get_user
|
||||
from flask_login import UserMixin
|
||||
|
||||
from db.SQLiteClient import create_user, get_user, get_user_by_email
|
||||
|
||||
|
||||
class User:
|
||||
def __init__(self, id, name, email):
|
||||
class User(UserMixin):
|
||||
def __init__(self, id, name, email, password=None):
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.email = email
|
||||
self.password = password
|
||||
|
||||
@staticmethod
|
||||
def create(name, email, password):
|
||||
def create(name: str, email: str, password: str):
|
||||
id = create_user(name, email, password)
|
||||
return User(id, name, email)
|
||||
|
||||
@staticmethod
|
||||
def get(id):
|
||||
def get(id: int):
|
||||
user = get_user(id)
|
||||
return User(user[0], user[1], user[2]) if user else None
|
||||
return User(user[0], user[1], user[2], user[3]) if user else None
|
||||
|
||||
@staticmethod
|
||||
def get_by_email(email: str):
|
||||
user = get_user_by_email(email)
|
||||
return User(user[0], user[1], user[2], user[3]) if user else None
|
||||
|
||||
@ -8,19 +8,25 @@
|
||||
<div class="mb-3 row">
|
||||
<label for="email" class="col-sm-2 col-form-label">Email</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="email" class="form-control" id="email" placeholder="email@example.com">
|
||||
<input type="email" value="{{ email }}" class="form-control {% if errors.get('email') %} is-invalid {% endif %}" id="email" placeholder="email@example.com" name="email">
|
||||
<div class="invalid-feedback">
|
||||
{{ errors.get('email', '') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="password" class="col-sm-2 col-form-label">Passwort</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="email" class="form-control" id="password">
|
||||
<input type="password" value="{{ password }}" class="form-control {% if errors.get('password') %} is-invalid {% endif %}" id="password" name="password">
|
||||
<div class="invalid-feedback">
|
||||
{{ errors.get('password', '') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-auto">
|
||||
<button type="submit" class="btn btn-primary mb-3">Einloggen</button>
|
||||
<button type="submit" class="btn btn-primary mb-3">Login</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@ -36,12 +36,18 @@
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav mb-2 mb-lg-0">
|
||||
{% if not current_user.is_authenticated %}
|
||||
<li class="nav-item me-2">
|
||||
<a class="btn btn-primary" aria-current="page" href="{{ url_for('login') }}">Login</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="btn btn-outline-secondary" aria-current="page" href="{{ url_for('signup') }}">Signup</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item me-2">
|
||||
<a class="btn btn-primary" aria-current="page" href="{{ url_for('logout') }}">Logout</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
14
utils.py
Normal file
14
utils.py
Normal file
@ -0,0 +1,14 @@
|
||||
from functools import wraps
|
||||
|
||||
from flask import redirect, url_for
|
||||
from flask_login import current_user
|
||||
|
||||
|
||||
def anonymous_required(f):
|
||||
@wraps(f)
|
||||
def decorated_function(*args, **kwargs):
|
||||
if current_user.is_authenticated:
|
||||
return redirect(url_for('index'))
|
||||
return f(*args, **kwargs)
|
||||
|
||||
return decorated_function
|
||||
Loading…
x
Reference in New Issue
Block a user