| 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) |