from flask import request, url_for, render_template, redirect, flash, jsonify, make_response, current_app from flask_jwt_extended import current_user, jwt_required, create_access_token, get_jwt, create_refresh_token, set_access_cookies, unset_jwt_cookies from datetime import datetime from . import blueprint from .model import User, BlackListedJWT from .forms import LoginForm, RegisterForm, RequestPasswordResetForm, ResetPasswordForm, SendConfirmEmailFrom from app.auth.email import send_password_reset_email @blueprint.route('/login', methods=['GET', 'POST']) @jwt_required(optional=True, locations=['cookies']) def login(): if current_user: flash(f'Already logged in as {current_user.user_id}. Incorrect? logout') form = LoginForm(request.form) if request.method == 'POST': if form.validate(): user = User.objects(user_id=form.user_id.data).first() auth_token = create_access_token(user) user.last_login = datetime.utcnow() user.save() response = make_response(jsonify(redirect=url_for('main.index'))) set_access_cookies(response, auth_token) return response return render_template('auth/login_modal.html', form=form) @blueprint.route('/register', methods=['POST', 'GET']) @jwt_required(optional=True) def register(): if current_user: flash(f'Already logged in as {current_user.user_id}. Incorrect? logout') return redirect(url_for('main.index')) form = RegisterForm(request.form) if request.method == 'POST': if form.validate(): user = User(user_id=form.user_id.data, email=form.email.data, first_name=form.first_name.data, last_name=form.last_name.data, last_login=datetime.now(), join_date=datetime.now().date(), date_of_birth=form.get_date_of_birth, phone_number=form.phone_number.data, type='Occupant') user.set_password(form.password.data) user.last_login = datetime.utcnow() user.save() auth_token = create_access_token(user) response = make_response(jsonify(redirect=url_for('main.index'))) set_access_cookies(response, auth_token) return response return render_template('auth/register.html', form=form) @blueprint.route('/logout') @jwt_required(locations=['cookies']) def logout(): to_blacklist = BlackListedJWT(jti=get_jwt()['jti'], created_at=datetime.utcnow()) to_blacklist.save() response = redirect(url_for('main.index')) flash('Logged out successfully!') unset_jwt_cookies(response) return redirect(url_for('main.index')) @blueprint.route('/request_password_reset', methods=['GET', 'POST']) @jwt_required(optional=True) def request_password_reset(): if current_user: flash(f'You are already logged in as {current_user.user_id}. Incorrect? logout') return redirect(url_for('main.index')) form = RequestPasswordResetForm(request.form) if request.method == 'POST': if form.validate(): if form.user_id.data: user = User.objects(user_id=form.user_id.data).first() else: user = User.objects(email=form.email.data).first() send_password_reset_email(user) flash('Check your email for the password reset link') return jsonify(redirect=url_for('main.index')) return render_template('auth/request_password_reset.html', form=form) @blueprint.route('/reset_password/', methods=['GET', 'POST']) def reset_password(token): if current_user: flash(f'You are already logged in as {current_user.user_id}. Incorrect? logout') return redirect(url_for('main.index')) user = User.from_password_reset_token(token, secret_key=current_app.config['SECRET_KEY']) if not user: flash(f'The password reset link may have expired. Please reset your password again.') return redirect(url_for('main.index')) form = ResetPasswordForm(request.form) if request.method == 'POST': if form.validate(): flash('Password reset successfully!') user.set_password(form.password.data) return redirect(url_for('main.index')) return render_template('auth/reset_password.html', form=form) @blueprint.route('/account') @jwt_required() def account(): return render_template('auth/account.html', current_user=current_user) @blueprint.route('/confirm_email/') def confirm_email(token): form = SendConfirmEmailFrom() user, redirect_url = User.from_activation_token(token, secret_key=current_app.config['SECRET_KEY']) return render_template('auth/email_confirmation.html', token=token, form=form, redirect_url=redirect_url)