Restyled Login Container and removed unnessecery code
This commit is contained in:
@ -1,14 +1,17 @@
|
||||
from flask import Blueprint, request, redirect, url_for, flash, render_template
|
||||
from flask_login import login_user, logout_user
|
||||
from app.models.users import User
|
||||
from datetime import datetime, timedelta
|
||||
from app.models import db
|
||||
|
||||
import sys
|
||||
|
||||
auth = Blueprint('auth', __name__)
|
||||
|
||||
|
||||
def _authenticate(username, password):
|
||||
user = User.query.filter_by(username=username).first()
|
||||
if user and user.password == password:
|
||||
print(sys.version)
|
||||
return user
|
||||
return None
|
||||
|
||||
@ -16,11 +19,22 @@ def login():
|
||||
if request.method == 'POST':
|
||||
username = request.form.get('username')
|
||||
password = request.form.get('password')
|
||||
user = _authenticate(username, password)
|
||||
user = User.query.filter_by(username=username).first()
|
||||
if user:
|
||||
if user.failed_login_attempts is not None and user.failed_login_attempts >= 10:
|
||||
cooldown_expires = user.last_failed_login_attempt + timedelta(minutes=10)
|
||||
if datetime.now() < cooldown_expires:
|
||||
flash('You have exceeded the maximum number of failed login attempts. Please try again in {} minutes.'.format((cooldown_expires - datetime.now()).seconds // 60), 'danger')
|
||||
return render_template('login.html')
|
||||
if user.password == password:
|
||||
user.failed_login_attempts = 0
|
||||
login_user(user)
|
||||
flash('Logged in successfully!', 'success')
|
||||
return redirect(url_for('main.users_route'))
|
||||
return redirect(url_for('main.wines_route'))
|
||||
else:
|
||||
user.failed_login_attempts = (user.failed_login_attempts or 0) + 1
|
||||
user.last_failed_login_attempt = datetime.now()
|
||||
db.session.commit()
|
||||
flash('Invalid username or password.', 'danger')
|
||||
else:
|
||||
flash('Invalid username or password.', 'danger')
|
||||
return render_template('login.html')
|
||||
|
@ -1,7 +0,0 @@
|
||||
from flask import render_template
|
||||
from app.models.users import User
|
||||
|
||||
def get_users():
|
||||
users = User.query.all()
|
||||
return render_template('users.html', users=users)
|
||||
|
@ -1,14 +1,12 @@
|
||||
from flask import Blueprint
|
||||
from flask_login import login_required
|
||||
from app.controllers.user_controller import get_users
|
||||
from app.controllers.auth_controller import login, logout
|
||||
|
||||
main = Blueprint('main', __name__)
|
||||
|
||||
@main.route('/users')
|
||||
@login_required
|
||||
def users_route():
|
||||
return get_users()
|
||||
@main.route('/')
|
||||
def index():
|
||||
return login()
|
||||
|
||||
@main.route('/login', methods=['GET', 'POST'])
|
||||
def login_route():
|
||||
|
@ -1,45 +1,110 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="nl">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
<link
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
|
||||
rel="stylesheet"
|
||||
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<title>{% block title %}Default{% endblock %}</title>
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #494949;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
header {
|
||||
padding-top: 20px;
|
||||
padding-left: 20px;
|
||||
color: #FDEFA8;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 90%;
|
||||
max-width: 1200px;
|
||||
margin: 20px auto;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.profile-dropdown {
|
||||
position: absolute;
|
||||
top: 13px;
|
||||
right: 100px;
|
||||
}
|
||||
|
||||
.profile-icon {
|
||||
color: #171717;
|
||||
font-size: 40px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
background-color: #1a1a1a;
|
||||
border: 1px solid #70120a;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
color: #70120a;
|
||||
}
|
||||
|
||||
.dropdown-item:hover {
|
||||
background-color: #2a2a2a;
|
||||
color: #70120a;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.profile-icon {
|
||||
font-size: 30px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.profile-dropdown {
|
||||
right: 15px;
|
||||
top: 17px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% block additional_styles %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="bg-primary text-white text-center py-">
|
||||
<header>
|
||||
<h1>Beacon</h1>
|
||||
{% if current_user.is_authenticated %}
|
||||
<div class="profile-dropdown">
|
||||
<div class="profile-icon" data-bs-toggle="dropdown">
|
||||
<i class="fas fa-user"></i>
|
||||
</div>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="{{ url_for('main.logout_route') }}">Logout</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</header>
|
||||
|
||||
<div class="container mt-4">
|
||||
<div class="container">
|
||||
{% block content %}
|
||||
<!-- Standaard Content -->
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
<footer class="bg-dark text-white text-center py-3 mt-4">
|
||||
<p>© 2023 My App. All rights reserved.</p>
|
||||
</footer>
|
||||
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
|
||||
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"
|
||||
integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"
|
||||
integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -2,19 +2,149 @@
|
||||
|
||||
{% block title %}Login{% endblock %}
|
||||
|
||||
{% block additional_styles %}
|
||||
<style>
|
||||
.container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: calc(100vh - 200px);
|
||||
}
|
||||
|
||||
.login-container {
|
||||
width: 90%;
|
||||
max-width: 400px;
|
||||
padding: 30px;
|
||||
background-color: #343434;
|
||||
border-radius: 20px;
|
||||
margin-top: -50px;
|
||||
}
|
||||
|
||||
.login-container h2 {
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 8px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.login-description {
|
||||
font-size: 14px;
|
||||
color: #8f8f8f;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
color: rgb(255, 255, 255);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.form-group input {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border: 1px solid #D9D9D9;
|
||||
border-radius: 6px;
|
||||
background-color: #D9D9D9;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-group input:focus {
|
||||
border-color: FDEFA8;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
button[type="submit"] {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
background-color: #97988C;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
button[type="submit"]:hover {
|
||||
background-color: #6f6f6b;
|
||||
}
|
||||
|
||||
.password-input {
|
||||
letter-spacing: 3px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.login-container {
|
||||
width: 95%;
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.error-message p {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.signup-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.signup {
|
||||
font-size: 14px;
|
||||
color: #8f8f8f;
|
||||
margin-top: 14px;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mt-4">
|
||||
<div class="container">
|
||||
<div class="login-signup-container">
|
||||
|
||||
</div>
|
||||
<div class="login-container">
|
||||
<h2>Login</h2>
|
||||
<p class="login-description">Enter your credentials below to login to your account</p>
|
||||
|
||||
<form method="POST" action="{{ url_for('main.login_route') }}">
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label">Username</label>
|
||||
<input type="text" class="form-control" id="username" name="username" required>
|
||||
<div class="form-group">
|
||||
<label for="username">Username</label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Password</label>
|
||||
<input type="password" class="form-control" id="password" name="password" required>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" name="password" required class="password-input">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Login</button>
|
||||
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
<div class="signup-container">
|
||||
<p class="signup">Dont have an account? <u>Sign up</u></p>
|
||||
</div>
|
||||
|
||||
|
||||
{% with messages = get_flashed_messages() %}
|
||||
{% if messages %}
|
||||
<div class="error-message">
|
||||
{% for message in messages %}
|
||||
<p class="text-danger">{{ message }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,13 +0,0 @@
|
||||
{% extends "layouts/app.html" %}
|
||||
|
||||
{% block title %}Users List{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<a href="{{ url_for('main.logout_route') }}">Logout</a>
|
||||
<h2>Users List</h2>
|
||||
<ul>
|
||||
{% for user in users %}
|
||||
<li>{{ user.username }} - {{ user.email }} - {{ user.password }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
Reference in New Issue
Block a user