blob: b37a6b3aeac9ac24c36edcf7dcb75d13d2d31199 [file] [log] [blame]
from datetime import datetime, timedelta
from flask import current_app, flash, redirect, render_template, request, url_for
from flask_login import current_user, login_user, logout_user, login_required
from werkzeug.urls import url_parse
from app import db
from app.email import send_email, notify_admins
from app.user import bp
from app.user.forms import LoginForm, RegistrationForm, ProfileForm, \
RequestPasswordResetForm, PasswordResetForm
from app.user.decorators import check_confirmed, check_sshkey
from app.user.token import generate_token, confirm_token
from app.models import User, UserRole, UserOrganization
@bp.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
return redirect(url_for('main.index'))
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user is None or not user.check_password(form.password.data):
flash('Invalid email or password', 'danger')
return redirect(url_for('user.login'))
login_user(user, remember=form.remember_me.data)
next_page = request.args.get('next')
if not next_page or url_parse(next_page).netloc != '':
next_page = url_for('main.index')
return redirect(next_page)
return render_template('user/login.html', title='[nolabs] | Login', form=form)
@bp.route('/logout')
def logout():
logout_user()
return redirect(url_for('main.index'))
@bp.route('/register', methods=['GET', 'POST'])
def register():
if current_user.is_authenticated:
return redirect(url_for('main.index'))
form = RegistrationForm()
if form.validate_on_submit():
role_id = UserRole.query.filter_by(role_name='regular').first().id
org_id = UserOrganization.query.filter_by(org_name='nordix').first().id
user = User(username=form.email.data, email=form.email.data, role_id=role_id, org_id=org_id)
user.set_password(form.password.data)
db.session.add(user)
db.session.commit()
token = generate_token(form.email.data)
flash('Congratulations, you are now a registered user!', 'success')
confirm_url = url_for('user.confirm', token=token, _external=True)
email_body_html = render_template('user/activation_mail.html', confirm_url=confirm_url)
send_email('Please confirm your Nordix Open Labs email', form.email.data, email_body_html)
notify_admins('[nolabs] User Registered', form.email.data)
flash('A confirmation email has been sent to your email adddress. Please check your spam mail folder as well.', 'success')
flash('Please confirm your mail address within 24 hours.', 'warning')
return redirect(url_for('user.login'))
return render_template('user/register.html', title='[nolabs] | Register', form=form)
@bp.route('/request_password_reset', methods=['GET', 'POST'])
def request_password_reset():
if current_user.is_authenticated:
return redirect(url_for('main.index'))
form = RequestPasswordResetForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user is None:
flash('There is no user with the provided email address!', 'danger')
return redirect(url_for('user.request_password_reset'))
token = generate_token(form.email.data)
password_reset_url = url_for('user.password_reset', token=token, _external=True)
email_body_html = render_template('user/password_reset_mail.html', password_reset_url=password_reset_url)
send_email('Reset your Nordix Open Labs password', form.email.data, email_body_html)
flash('An email with instructions has been sent to your email address.', 'success')
next_page = request.args.get('next')
if not next_page or url_parse(next_page).netloc != '':
next_page = url_for('user.login')
return redirect(next_page)
return render_template('user/request_password_reset.html', title='[nolabs] | Password Reset', form=form)
@bp.route('/password_reset/<token>', methods=['GET', 'POST'])
def password_reset(token):
if current_user.is_authenticated:
return redirect(url_for('main.index'))
email = confirm_token(token)
user = User.query.filter_by(email=email).first()
if user is None or user.email != email:
flash('The password reset link is either invalid or has expired.', 'danger')
return redirect(url_for('user.request_password_reset'))
form = PasswordResetForm()
if form.validate_on_submit():
if form.email.data != email:
flash('Invalid email!', 'danger')
return redirect(url_for('user.login'))
user.set_password(form.password.data)
db.session.commit()
flash('Your password is now changed. Please use your new password when you login next time.', 'success')
email_body_html = render_template('user/notify_password_reset.html', request_password_reset=request_password_reset)
send_email('Your Nordix Open Labs password is reset', form.email.data, email_body_html)
return redirect(url_for('user.login'))
return render_template('user/password_reset.html', title='[nolabs] | Password Reset', form=form)
@bp.route('/confirm/<token>', methods=['GET', 'POST'])
@login_required
def confirm(token):
if current_user.confirmed:
flash('Account already confirmed!', 'success')
return render_template('index.html', title='[nolabs] | Nordix Open Labs', text=current_app.news_content)
email = confirm_token(token)
user = User.query.filter_by(email=email).first()
if user.email == email:
user.confirmed = 1
user.confirmed_on = datetime.utcnow().isoformat()
db.session.commit()
flash('You have confirmed your account now. Enjoy!', 'success')
notify_admins('[nolabs] User Confirmed', user.email)
else:
flash('The confirmation link is either invalid or has expired.', 'danger')
return render_template('index.html', title='[nolabs] | Nordix Open Labs', text=current_app.news_content)
@bp.route('/unconfirmed', methods=['GET'])
@login_required
def unconfirmed():
if current_user.confirmed:
next_page = request.args.get('next')
if not next_page or url_parse(next_page).netloc != '':
next_page = url_for('main.index')
return redirect(next_page)
flash('Your mail address is not confirmed yet. Please confirm it to access full functionality!', 'danger')
return render_template('user/unconfirmed.html')
@bp.route('/profile', methods=['GET', 'POST'])
@login_required
@check_confirmed
def profile():
form = ProfileForm(current_user.email)
if not current_user.confirmed:
flash('Your mail address is not confirmed yet. Please confirm it to access full functionality.', 'danger')
if current_user.ssh_public_key is None or not current_user.ssh_public_key:
flash("You either haven't registered your SSH Public Key or it is invalid. Please register your SSH Public Key in order to be able to make a new booking!", 'danger')
if form.validate_on_submit():
current_user.fullname = form.fullname.data
current_user.ssh_public_key = form.ssh_public_key.data
db.session.commit()
db.session.flush()
flash('Your changes have been saved.', 'success')
return redirect(url_for('user.profile'))
elif request.method == 'GET':
form.email.data = current_user.email
form.fullname.data = current_user.fullname
form.organization.data = UserOrganization.query.filter_by(id=current_user.org_id).first().org_name
form.role.data = UserRole.query.filter_by(id=current_user.role_id).first().role_name
form.email.data = current_user.email
form.ssh_public_key.data = current_user.ssh_public_key
form.registered_on.data = current_user.registered_on
form.confirmed_on.data = current_user.confirmed_on
form.last_logged_in.data = current_user.last_logged_in
return render_template('user/profile.html', title = '[nolabs] | Profile', form=form)