Reworked login and register

This commit is contained in:
Emily 2019-05-12 18:31:26 +01:00
parent 3a1137561d
commit 81dbaceb46
5 changed files with 195 additions and 98 deletions

View File

@ -5,6 +5,10 @@ from flask_login import UserMixin
from objects import glob
FORM_RENDER_KW = {
"class_": "form-control"
}
class BillForm(Form):
payment_to = StringField("Payment to", [validators.DataRequired()])
description = TextAreaField("Description", render_kw = {
@ -19,35 +23,41 @@ class LoginForm(Form):
email = StringField("Email", [
validators.DataRequired(),
validators.Length(min=6, max=254)
])
],
render_kw = FORM_RENDER_KW)
password = PasswordField("Password", [
validators.DataRequired(),
validators.Length(min=4, max=127)
])
],
render_kw = FORM_RENDER_KW)
class RegisterForm(Form):
email = StringField("Email", [
validators.DataRequired(),
validators.Length(min=6, max=254)
])
],
render_kw = FORM_RENDER_KW)
password = PasswordField("Password", [
validators.DataRequired(),
validators.Length(min=4, max=127),
validators.EqualTo("confirm_password", message = "Passwords must match")
])
confirm_password = PasswordField("Repeat Password")
],
render_kw = FORM_RENDER_KW)
confirm_password = PasswordField("Repeat Password", render_kw = FORM_RENDER_KW)
firstname = StringField("Firstname", [
validators.DataRequired(),
validators.Length(min=2, max=30)
])
],
render_kw = FORM_RENDER_KW)
surname = StringField("Surname", [
validators.DataRequired(),
validators.Length(min=2, max=30)
])
],
render_kw = FORM_RENDER_KW)
accept_tos = BooleanField("I accept the TOS", [validators.DataRequired()])

View File

@ -70,20 +70,31 @@ def login():
flash(gettext("Already logged in"), "info")
return redirect(url_for("dashboard"))
form = LoginForm(request.form)
if request.method == "POST" and form.validate():
try:
user = User((form.email.data, form.password.data))
except Exception as e:
flash(gettext(str(e)), "danger")
return render_template("login.html", form=form)
form_login = LoginForm(request.form)
form_register = RegisterForm(request.form)
flask_login.login_user(user)
logged_in_users.append(user)
flash(gettext("Logged in"), "success")
return redirect(url_for("dashboard"))
return render_template("login.html", form=form)
if request.method == "POST":
if form_register.validate():
try:
register_account(form_register.email.data, form_register.password.data, form_register.firstname.data, form_register.surname.data)
flash(gettext("User registered"), "success")
except Exception as e:
flash(gettext(str(e)), "danger")
return redirect(url_for("login"))
elif form_login.validate():
try:
user = User((form_login.email.data, form_login.password.data))
flask_login.login_user(user)
logged_in_users.append(user)
flash(gettext("Logged in"), "success")
except Exception as e:
flash(gettext(str(e)), "danger")
return redirect(url_for("login"))
return redirect(url_for("dashboard")) # Valid login > Redirect to dashboard as user is logged in
return render_template("login.html", form = {
"login": form_login,
"register": form_register
})
@glob.app.route("/register", methods = ["GET", "POST"])
def register():

BIN
static/img/login-bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

View File

@ -3,89 +3,165 @@
{% extends "layout/bootstrap.html" %}
{% block content %}
<script src="{{ url_for('static', filename='js/alerts.js') }}"></script>
<div class="container pt-3">
<div class="row alert-section">
<div class="col-md-8 mx-auto">
<div class="card rounded-1">
<div class="card-header navbar topnav">
<h3 class="mb-0">Login Methods</h3>
<div class="my-2 my-lg-0 d-flex">
<a href="{{ url_for('register') }}">Register</a>
</div>
</div>
<div class="card-body row">
<div class="col-md-6">
<h5>Electronic ID</h5>
<p class="lead">
Secure login using Electronic ID allows Husstanden to show you banking details, bills and receipts.<br>
<a target="_blank" href="https://eid.difi.no/en/id-porten/how-obtain-electronic-id">How to obtain an Electronic ID</a>
</p>
</div>
<div class="col-md-6">
<h5>House Account</h5>
<p class="lead">
Accounts with less privileges and fast login to view non-sensitive information.<br>
Multiple house accounts can be created by logging in with house holder's verified <i>Electronic ID</i>.
</p>
</div>
</div>
<hr>
<div class="card-body row pt-2">
<div class="col-md-6 pb-2">
<a class="btn btn-primary btn-lg btn-block" href="#TODO_LOGIN_EID" onclick="alertAbove(this, 'warning', 'This should redirect the user to Electronic ID page (but due to phishing, we can not demo this)')">Electronic ID</a>
</div>
<div class="col-md-6">
<a class="btn btn-primary btn-lg btn-block" href="#" data-toggle="modal" data-target="#myModal">House Account</a>
</div>
</div>
</div>
</div>
<style>
html, body {
height: 100%;
}
.main-head{
height: 150px;
background: #FFF;
}
.sidenav {
height: 100%;
background-color: #000;
overflow-x: hidden;
padding-top: 20px;
}
.main {
padding: 0px 10px;
display: grid;
grid-template-rows: 25% auto;
grid-row-gap: 8px;
height: 100%;
}
.main > .col:nth-child(1n) {
grid-row-start: 1;
}
.main > .col:nth-child(2n) {
grid-row-start: 2;
}
@media screen and (max-height: 450px) {
.sidenav {padding-top: 15px;}
}
@media screen and (max-width: 450px) {
.login-form{
margin-top: 10%;
}
.register-form{
margin-top: 10%;
}
}
@media screen and (min-width: 768px){
.main{
margin-left: 40%;
}
.sidenav{
width: 40%;
position: fixed;
z-index: 1;
top: 0;
left: 0;
}
}
.login-main-text{
margin-top: 20%;
padding: 60px;
color: #fff;
}
.login-main-text h2{
font-weight: 300;
}
.btn-black{
background-color: #000 !important;
color: #fff;
}
.hidable[aria-expanded="true"] {
display: none;
}
.toggle-form > form:nth-child(2n) {
display: none;
}
.toggle-form.toggled > form:nth-child(1n) {
display: none;
}
.toggle-form.toggled > form:nth-child(2n) {
display: block;
}
</style>
<script>
function toggleform(caller) {
let selectedDOM = caller;
do {
if (selectedDOM.classList.contains("toggle-form")){
let classes = selectedDOM.classList;
classes[classes.contains("toggled") ? "remove" : "add"]("toggled");
return;
}
selectedDOM = selectedDOM.parentElement;
} while (selectedDOM != null);
throw Error("Missing toggle-form class for self/parent(s)");
}
</script>
<div class="sidenav">
<div class="login-main-text">
<h2>Husstanden<br>Login Page</h2>
<p>Login is required to use this service.</p>
</div>
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Login</h4>
<button type="button" class="close" data-dismiss="modal">&times;</button>
</div>
<div class="modal-body">
{% macro render_field(field) %}
<dt>{{ field.label }}
<dd>{{ field(**kwargs)|safe }}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
</div>
<div class="main">
<div class="col pt-4">
{% with messages = get_flashed_messages(with_categories = true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }} fade in show" role="alert" style="margin-bottom:0px;padding:6px;">
<a href="#" class="close" data-dismiss="alert" aria-label="close" style="margin-left:10px;">&times;</a>
{{ message }}
</div>
{% endfor %}
</ul>
{% endif %}
</dd>
{% endwith %}
</div>
<div class="col col-md-6 col-sm-12">
<div class="login-form">
{% macro render_field(field) %}
<div class="form-group">
{{ field.label }}
{{ field(**kwargs)|safe }}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endmacro %}
<form method=post>
<dl>
{{ render_field(form.email) }}
{{ render_field(form.password) }}
</dl>
<input type=submit value="Login">
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
<div class="toggle-form false">
<form method="post">
{{ render_field(form.login.email) }}
{{ render_field(form.login.password) }}
<button class="btn btn-black">Login</button>
<span class="btn btn-secondary" onclick="toggleform(this)">Register</span>
</form>
<form method="post">
{{ render_field(form.register.email) }}
{{ render_field(form.register.password) }}
{{ render_field(form.register.confirm_password) }}
{{ render_field(form.register.firstname) }}
{{ render_field(form.register.surname) }}
{{ render_field(form.register.accept_tos) }}
<span class="btn btn-secondary" onclick="toggleform(this)">Login</span>
<button class="btn btn-black">Register</button>
</form>
</div>
</div>
</div>
</div>
<script>
{% with messages = get_flashed_messages() %}
{% if messages %}
let alertArea = document.getElementsByClassName("alert-section")[0];
{% for message in messages %}
alertAbove(alertArea, "info", "{{ message }}");
{% endfor %}
{% endif %}
{% endwith %}
</script>
{% endblock %}

View File

@ -18,7 +18,7 @@
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Add bill</h4>
<h4 class="modal-title">{{ _("Add bill") }}</h4>
<button type="button" class="close" data-dismiss="modal">&times;</button>
</div>
<div class="modal-body">