register funktion

This commit is contained in:
Manuel Weiser 2024-08-08 11:55:21 +02:00
parent 41a1bb3530
commit 0fd7679ac7
11 changed files with 409 additions and 268 deletions

0
Icon Normal file
View File

View File

@ -1,6 +1,14 @@
from flask import Flask, request, session
from lernplattform import app
from flask import Flask, request, session, make_response, redirect, url_for
from werkzeug.security import generate_password_hash, check_password_hash
from lernplattform import app, db
from lernplattform.models import User
import random
import string
def generate_random_string(length=8):
characters = string.ascii_letters + string.digits
random_string = ''.join(random.choice(characters) for _ in range(length))
return random_string
class login():
"""
@ -14,19 +22,61 @@ class login():
check(user_name): A static method that checks if the provided user name is valid.
login(self): Prints "Login" to indicate that the login method has been called.
"""
def __init__(self, user_name=None):
def __init__(self, user_name=None, login_data=None):
self.user_name = user_name # Initialize the user name attribute for the login class
def check(user_name):
if user_name is None:
def check_logged_in():
if request.cookies.get('username') is None:
session['logged_in'] = False
session['user_name'] = 'Gast'
session['username'] = 'Gast'
return False # Return False if the user name is not provided
else:
session['logged_in'] = True
session['user_name'] = user_name
session['username'] = request.cookies.get('username')
session['userid'] = request.cookies.get('userid')
return True # Otherwise, return True indicating a valid user name
def login(self):
print("Login") # Print "Login" to indicate that the login method has been called
def login(login_data):
# get password from db
user = User.query.filter_by(username = login_data.get('username')).first()
if user and check_password_hash(user.password, login_data.get('password')):
if not user.email_check == "":
return False
session['userid'] = user.id
session['username'] = user.username
session['logged_in'] = True
if login_data['remember'] == 'on':
resp = make_response(redirect(url_for('index')))
resp.set_cookie('userid', user.id)
resp.set_cookie('username', user.username)
return True
else:
return False
def logout():
resp = make_response(redirect(url_for('index')))
resp.set_cookie('username', '', expires=0)
resp.set_cookie('userid', '', expires=0)
session['logged_in'] = False
return resp
def register(request):
username = request.form.get('username')
email = request.form.get('email')
password = request.form.get('password')
hashed_password = generate_password_hash(password, method='pbkdf2:sha256')
if User.query.filter_by(username = username).first():
return False # Return False if the user name is already in use
else:
random_string = generate_random_string()
user = User(username = username, email = email, password = hashed_password, email_check = random_string)
db.session.add(user)
db.session.commit()
return True

View File

@ -1,15 +1,28 @@
from lernplattform import db
from sqlalchemy.sql import func
# Define a User model that represents the user table in the database
class User(db.Model):
# Primary key column for the table, auto-incrementing integer
"""
A class representing the user table in the database.
Attributes:
id (int): The unique identifier for each user, set as the primary key.
username (str): The username of the user, must be unique and cannot be null.
email (str): The email address of the user, must be unique and cannot be null.
password (str): The hashed password of the user, cannot be null.
email_check (str): A string field to store email verification status.
register_date (datetime): The date and time when the user registered, defaults to the current timestamp.
Methods:
__repr__(): Returns a string representation of the User object in the format "User('username', 'email')".
"""
id = db.Column(db.Integer, primary_key=True)
# Username column with a maximum length of 20 characters, unique and not nullable
username = db.Column(db.String(20), unique=True, nullable=False)
# Email column with a maximum length of 120 characters, unique and not nullable
email = db.Column(db.String(120), unique=True, nullable=False)
# Password column with a maximum length of 60 characters, not nullable
password = db.Column(db.String(60), nullable=False)
email_check = db.Column(db.String(10), nullable=True)
register_date = db.Column(db.DateTime, nullable=False, default=func.now())
# Magic method to represent the object as a string when printed or used in string context
def __repr__(self):

View File

@ -16,38 +16,38 @@ def index():
Returns:
A rendered HTML template with the current username.
"""
login.check(request.cookies.get('user_name'))
login.check_logged_in()
# Render the main page with the current username
return render_template('index.html', user_name=session['user_name'])
return render_template('index.html', page='index', user_name=session['username'])
@app.route('/users', methods=['GET'])
def get_users():
# Query all users from the database
users = User.query.all()
# Create a list of dictionaries with user information
user_list = [
{
"id": user.id,
"username": user.username,
"email": user.email,
"password": user.password
}
for user in users
]
# Return the list of users as a JSON response
return jsonify(user_list)
#return user_list[0]['username']
@app.route('/users', methods=['POST'])
def create_user():
# Get the JSON data from the request body
data = request.get_json()
# Create a new User object with the provided username, email, and password
new_user = User(username=data['username'], email=data['email'], password=data['password'])
# Add the new user to the database session
db.session.add(new_user)
# Commit the transaction to save the new user in the database
db.session.commit()
# Return a success message with status code 201 (Created)
return jsonify({'message': 'User created'}), 201
@app.route('/login', methods=['GET', 'POST'])
def userlogin():
if request.method == 'POST':
#data = request.form
if request.form.get('form_id') == 'login':
if login.login(request.form):
# get username, password, remember from form
flash('Login erfolgreich!', 'login')
return redirect(url_for('index'))
else:
flash('Ungültiger Benutzername, Passwort oder Registrierung noch nicht bestätigt.', 'login')
# Render the main page with the current username
return render_template('index.html', page='index', user_name=session['username'])
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
if login.register(request):
flash('''
Du erhältst in den nächsten Minuten eine eMail mit einem Bestätigungslink.
Bitte klicke auf diesen Link, um deine Registrierung abzuschließen.
''', 'register')
return redirect(url_for('index'))
return render_template('index.html', page='register', user_name=session['username'])

View File

@ -0,0 +1,20 @@
function validateForm() {
var username = document.forms["loginForm"]["username"].value;
var password = document.forms["loginForm"]["password"].value;
if (username == "" || password == "") {
alert("Benutzername und Passwort müssen ausgefüllt werden.");
return false;
}
return true;
}
function checkPasswords() {
var password = document.forms["registerForm"]["password"].value;
var confirmPassword = document.forms["registerForm"]["password_repeat"].value;
if (password != confirmPassword) {
alert("Passwörter stimmen nicht überein.");
return false;
}
return true;
}

View File

@ -0,0 +1,103 @@
:root {
--primary-color: #102037; /* Definieren Sie die primäre Farbe */
--secondary-color: #f78b47; /* Definieren Sie die sekundäre Farbe */
--link-default-color: #ffffff; /* Definieren Sie die Link-Hover-Farbe */
--link-hover-color: #ffcc00; /* Definieren Sie die Link-Hover-Farbe */
--link-active-color: #ffcc00; /* Definieren Sie die Link-Hover-Farbe */
--background-color: #d4c4c4; /* Definieren Sie die Hintergrundfarbe */
--nav-background-color: #102037; /* Definieren Sie die Hintergrundfarbe */
--box-background-color: #102037;
}
body {
color: #ffffff;
background-color: var(--background-color);
}
.light {
color: #cdcdcd;
font-weight: 400;
font-size: small;
}
.sidebar {
height: 100%;
position: sticky;
top: 0;
background-color: var(--background-color);
}
.main-content {
background-color: var(--background-color);
}
.profile-card,
.story,
.post,
.who-to-follow,
.news {
background-color: var(--box-background-color);
padding: 20px;
border-radius: 15px;
margin-bottom: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}
.headbar {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}
.profile-card img,
.who-to-follow img {
width: 60px;
height: 60px;
object-fit: cover;
border-radius: 50%;
}
.story input {
border-radius: 30px;
}
.story button {
border-radius: 20px;
}
.post img {
width: 100%;
border-radius: 15px;
margin-top: 10px;
}
.who-to-follow button {
border-radius: 20px;
}
.navbar {
background-color: var(--nav-background-color);
padding: 0;
}
.navbar-nav .nav-link {
color: var(--link-default-color)
}
.navbar-nav .nav-link:hover {
color: var(--link-hover-color);
}
.navbar-nav .nav-link.active {
color: var(--link-active-color);
}
a {
color: #ffcc00;
}
a:hover {
color: #c07427;
}
.logo {
display:inline;
width: 50px;
margin: 0;
padding: 0;
}
.footer {
background-color: var(--nav-background-color);
padding: 0;
box-shadow: 0 -4px 8px rgba(0, 0, 0, 0.3);
}
.errormsg {
color: red;
font-size: 15px;
}

View File

@ -0,0 +1,48 @@
<!-- Post a Story -->
<!--
<div class="story p-3">
<div class="d-flex align-items-center">
<img
src="https://via.placeholder.com/50"
class="rounded-circle me-3"
alt="Profile Picture" />
<input type="text" class="form-control" placeholder="Share your thoughts..." />
</div>
<div class="d-flex justify-content-around mt-3">
<button class="btn btn-outline-primary">Photo</button>
<button class="btn btn-outline-primary">Video</button>
<button class="btn btn-outline-primary">Event</button>
<button class="btn btn-outline-primary">Feeling/Activity</button>
</div>
</div>
-->
<!-- Posts -->
<div class="post p-3">
<div class="d-flex">
<img
src="../static/images/logo.png"
class="rounded-circle me-3"
style="width: 300px; height: 300px;"
alt="Profile Picture" />
<div class="my-3">
<h6>Lernplattform für <br>Rettungs- und Notfallsanitäter</h6>
<p class="light" style="text-align: justify;">
Willkommen auf unserer Lernplattform für Rettungssanitäter und Notfallsanitäter,
basierend auf dem bewährten Kartensystem nach Leitner.
Unsere Plattform bietet Dir die Möglichkeit,
Deine Kenntnisse und Fähigkeiten effektiv zu vertiefen und zu erweitern. <br><br>
Bei Interesse bist Du herzlich eingeladen, an der Entwicklung von Fragen und Aufgaben mitzuwirken.
Unsere Plattform ist und bleibt kostenlos, um alle Mitarbeiter im Rettungsdienst bestmöglich zu unterstützen.
</p>
</div>
</div>
<p class="mt-3">
I'm thrilled to share that I've completed a graduate certificate course in project
management with the president's honor roll.
</p>
<img src="https://via.placeholder.com/600x300" alt="Post Image" />
</div>

View File

@ -0,0 +1,39 @@
<div class="who-to-follow p-3">
<h6>Lernfelder</h6>
<div class="d-flex align-items-center my-2">
<img
src="https://via.placeholder.com/50"
class="rounded-circle me-3"
alt="Profile Picture" />
<div>
<h6 class="mb-0">Anatomie</h6>
<small class="light">RettSan</small>
</div>
<button class="btn btn-outline-primary ms-auto">+</button>
</div>
<div class="d-flex align-items-center my-2">
<img
src="https://via.placeholder.com/50"
class="rounded-circle me-3"
alt="Profile Picture" />
<div>
<h6 class="mb-0">Medikamente</h6>
<small class="light">NotSan</small>
</div>
<button class="btn btn-outline-primary ms-auto">+</button>
</div>
<div class="d-flex align-items-center my-2">
<img
src="https://via.placeholder.com/50"
class="rounded-circle me-3"
alt="Profile Picture" />
<div>
<h6 class="mb-0">Herzkreislauf</h6>
<small class="light">RettSan</small>
</div>
<button class="btn btn-outline-primary ms-auto">+</button>
</div>
<div class="text-center mt-3">
<button class="btn btn-link">Mehr Lernfelder</button>
</div>
</div>

View File

@ -0,0 +1,54 @@
<!-- wenn logged out -->
{% if not session['logged_in'] %}
<h5>{{ user_name }}</h5>
<p>Login oder <a href="/register">Registrieren</a></p>
<p class="light">Warum registrieren? Zum Schutz der Daten und dem Speichern deines Lernfortschrittes.</p>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
{% if category == 'login' %}
<p class="errormsg">{{message}}</p>
{% endif %}
{% endfor %}
{% endif %}
{% endwith %}
<form name="loginForm" action="/login" method="post" onsubmit="return validateForm()">
<div class="row mb-3">
<label for="inputEmail3" class="col-sm-3 col-form-label">Benutzer</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="username" name="username">
</div>
</div>
<div class="row mb-3">
<label for="inputPassword3" class="col-sm-3 col-form-label">Password</label>
<div class="col-sm-8">
<input type="password" class="form-control" id="password" name="password">
</div>
</div>
<div class="row mb-3">
<div class="col-sm-8 offset-2">
<input type="checkbox" name="remember" id="remember">
<label for="remember">Eingeloggt bleiben</label>
</div>
</div>
<input type="hidden" name="form_id" value="login">
<button type="submit" class="btn btn-primary">Einloggen</button>
</form>
{% endif %}
<!-- wenn logged out -->
<!-- wenn logged in -->
{% if session['logged_in'] %}
<!--<img src="https://via.placeholder.com/100" alt="Profile Picture" />-->
<h5>{{ user_name }}</h5>
<p>Web Developer at Webestica</p>
<p class="light">I'd love to change the world, but they wont give me the source code.</p>
<div class="d-flex justify-content-around">
<span>256 Posts</span>
<span>2.5K Followers</span>
<span>365 Following</span>
</div>
{% endif %}
<!-- wenn logged in -->

View File

@ -0,0 +1,28 @@
<div class="story p-3 shadow-sm">
<div>
<h5>Registrierung</h5>
<p>Registriere dich, um die Plattform zu nutzen. Deine Daten werden nicht an Dritte weitergegeben oder anderweitig anderweitig
verarbeitet. Die dienen lediglich zur Authentifizierung und Speicherung deines Lernfortschrittes.</p>
</div>
<form name="registerForm" method="post" onsubmit="return checkPasswords()">
<div>
<div class="row">
<div class="col py-3">
Benutzername: <input type="text" name="username" class="form-control" placeholder="Benutzername" tabindex="1" required />
<br>
Passwort: <input type="password" id="password" name="password" class="form-control" placeholder="Passwort" tabindex="3" required />
</div>
<div class="col py-3">
EMail: <input type="email" name="email" class="form-control" placeholder="EMail" tabindex="2" required />
<br>
Passwort wiederholen: <input type="password" id="password_repeat" name="password_repeat" class="form-control" tabindex="4" placeholder="Passwort wiederholen" required />
</div>
</div>
</div>
<div class="d-flex justify-content-around mt-3">
<button type="submit" class="btn btn-outline-primary">Registrieren</button>
</div>
</form>
</div>

View File

@ -5,106 +5,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Lernplattform EMT/Paramedic</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
<style>
:root {
--primary-color: #102037; /* Definieren Sie die primäre Farbe */
--secondary-color: #f78b47; /* Definieren Sie die sekundäre Farbe */
--link-default-color: #ffffff; /* Definieren Sie die Link-Hover-Farbe */
--link-hover-color: #ffcc00; /* Definieren Sie die Link-Hover-Farbe */
--link-active-color: #ffcc00; /* Definieren Sie die Link-Hover-Farbe */
--background-color: #d4c4c4; /* Definieren Sie die Hintergrundfarbe */
--nav-background-color: #102037; /* Definieren Sie die Hintergrundfarbe */
--box-background-color: #102037;
}
body {
color: #ffffff;
background-color: var(--background-color);
}
.light {
color: #cdcdcd;
font-weight: 400;
font-size: small;
}
.sidebar {
height: 100%;
position: sticky;
top: 0;
background-color: var(--background-color);
}
.main-content {
background-color: var(--background-color);
}
.profile-card,
.story,
.post,
.who-to-follow,
.news {
background-color: var(--box-background-color);
padding: 20px;
border-radius: 15px;
margin-bottom: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}
.headbar {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}
.profile-card img,
.who-to-follow img {
width: 60px;
height: 60px;
object-fit: cover;
border-radius: 50%;
}
.story input {
border-radius: 30px;
}
.story button {
border-radius: 20px;
}
.post img {
width: 100%;
border-radius: 15px;
margin-top: 10px;
}
.who-to-follow button {
border-radius: 20px;
}
.navbar {
background-color: var(--nav-background-color);
padding: 0;
}
.navbar-nav .nav-link {
color: var(--link-default-color)
}
.navbar-nav .nav-link:hover {
color: var(--link-hover-color);
}
.navbar-nav .nav-link.active {
color: var(--link-active-color);
}
a {
color: #ffcc00;
}
a:hover {
color: #c07427;
}
.logo {
display:inline;
width: 50px;
margin: 0;
padding: 0;
}
.footer {
background-color: var(--nav-background-color);
padding: 0;
box-shadow: 0 -4px 8px rgba(0, 0, 0, 0.3);
}
</style>
<link href="../static/style.css" rel="stylesheet"/>
<script src="../static/javascript.js"></script>
</head>
<body>
@ -116,44 +18,7 @@
<div class="col-12 col-md-3 sidebar mb-3">
<div class="profile-card text-center p-3">
<!-- wenn logged out -->
{% if not session['logged_in'] %}
<h5>{{ user_name }}</h5>
<p>Login oder <a href="#">Registrieren</a></p>
<p class="light">Warum registrieren? Zum Schutz der Daten und dem Speichern deines Lernfortschrittes.</p>
<form>
<div class="row mb-3">
<label for="inputEmail3" class="col-sm-3 col-form-label">Benutzer</label>
<div class="col-sm-8">
<input type="email" class="form-control" id="inputEmail3">
</div>
</div>
<div class="row mb-3">
<label for="inputPassword3" class="col-sm-3 col-form-label">Password</label>
<div class="col-sm-8">
<input type="password" class="form-control" id="inputPassword3">
</div>
</div>
<button type="submit" class="btn btn-primary">Einloggen</button>
</form>
{% endif %}
<!-- wenn logged out -->
<!-- wenn logged in -->
{% if session['logged_in'] %}
<!--<img src="https://via.placeholder.com/100" alt="Profile Picture" />-->
<h5>{{ user_name }}</h5>
<p>Web Developer at Webestica</p>
<p class="light">I'd love to change the world, but they wont give me the source code.</p>
<div class="d-flex justify-content-around">
<span>256 Posts</span>
<span>2.5K Followers</span>
<span>365 Following</span>
</div>
{% endif %}
<!-- wenn logged in -->
{% include 'block_login.html' %}
</div>
<!--
@ -172,97 +37,18 @@
<!-- Main Content -->
<div class="col-12 col-md-6 main-content mb-3">
<!-- Post a Story -->
<!--
<div class="story p-3">
<div class="d-flex align-items-center">
<img
src="https://via.placeholder.com/50"
class="rounded-circle me-3"
alt="Profile Picture" />
<input type="text" class="form-control" placeholder="Share your thoughts..." />
</div>
<div class="d-flex justify-content-around mt-3">
<button class="btn btn-outline-primary">Photo</button>
<button class="btn btn-outline-primary">Video</button>
<button class="btn btn-outline-primary">Event</button>
<button class="btn btn-outline-primary">Feeling/Activity</button>
</div>
</div>
-->
{% if not page or page == '' or page == 'index' %}
{% include 'block_content_index.html' %}
{% elif page == 'register' %}
{% include 'block_register.html' %}
{% endif %}
<!-- Posts -->
<div class="post p-3">
<div class="d-flex">
<img
src="../static/images/logo.png"
class="rounded-circle me-3"
style="width: 300px; height: 300px;"
alt="Profile Picture" />
<div class="my-3">
<h6>Lernplattform für <br>Rettungs- und Notfallsanitäter</h6>
<p class="light" style="text-align: justify;">
Willkommen auf unserer Lernplattform für Rettungssanitäter und Notfallsanitäter,
basierend auf dem bewährten Kartensystem nach Leitner.
Unsere Plattform bietet Dir die Möglichkeit,
Deine Kenntnisse und Fähigkeiten effektiv zu vertiefen und zu erweitern. <br><br>
Bei Interesse bist Du herzlich eingeladen, an der Entwicklung von Fragen und Aufgaben mitzuwirken.
Unsere Plattform ist und bleibt kostenlos, um alle Mitarbeiter im Rettungsdienst bestmöglich zu unterstützen.
</p>
</div>
</div>
<p class="mt-3">
I'm thrilled to share that I've completed a graduate certificate course in project
management with the president's honor roll.
</p>
<img src="https://via.placeholder.com/600x300" alt="Post Image" />
</div>
</div>
<!-- Right Sidebar -->
<div class="col-12 col-md-3 mb-3">
<!-- Who to Follow -->
<div class="who-to-follow p-3">
<h6>Lernfelder</h6>
<div class="d-flex align-items-center my-2">
<img
src="https://via.placeholder.com/50"
class="rounded-circle me-3"
alt="Profile Picture" />
<div>
<h6 class="mb-0">Anatomie</h6>
<small class="light">RettSan</small>
</div>
<button class="btn btn-outline-primary ms-auto">+</button>
</div>
<div class="d-flex align-items-center my-2">
<img
src="https://via.placeholder.com/50"
class="rounded-circle me-3"
alt="Profile Picture" />
<div>
<h6 class="mb-0">Medikamente</h6>
<small class="light">NotSan</small>
</div>
<button class="btn btn-outline-primary ms-auto">+</button>
</div>
<div class="d-flex align-items-center my-2">
<img
src="https://via.placeholder.com/50"
class="rounded-circle me-3"
alt="Profile Picture" />
<div>
<h6 class="mb-0">Herzkreislauf</h6>
<small class="light">RettSan</small>
</div>
<button class="btn btn-outline-primary ms-auto">+</button>
</div>
<div class="text-center mt-3">
<button class="btn btn-link">Mehr Lernfelder</button>
</div>
</div>
{% include 'block_lernfelder.html' %}
<!-- Today's News -->
<div class="news p-3">