proxadmin/app/auth/routes.py
2017-03-09 03:09:49 +02:00

221 lines
8.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from flask import render_template, redirect, request, url_for, flash, session, abort, current_app
from flask_login import login_required, login_user, logout_user, current_user
from . import auth
from .. import db
from ..models import User
from ..email import send_email
from .forms import LoginForm, TwoFAForm, RegistrationForm, ChangePasswordForm,PasswordResetRequestForm, PasswordResetForm
from io import BytesIO
import pyqrcode
@auth.before_app_request
def before_request():
#print('session: %s' % str(session))
if current_user.is_authenticated:
current_user.ping()
#print('request for {} from {}#{}'.format(request.endpoint, current_user.email, current_user.pid))
if not current_user.confirmed and request.endpoint[:5] != 'auth.' and request.endpoint != 'static':
print(request.endpoint)
return redirect(url_for('auth.unconfirmed'))
@auth.route('/unconfirmed')
def unconfirmed():
if current_user.is_anonymous or current_user.confirmed:
return redirect(url_for('vmanager.index'))
return render_template('auth/unconfirmed.html')
@auth.route('/login', methods=['GET', 'POST'])
def login():
page = { 'title': 'Login' }
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user is not None and user.verify_password(form.password.data):
if user.twofactor:
# redirect to the two-factor auth page, passing username in session
session['email'] = user.email
session['memberberry'] = form.remember_me.data
return redirect(url_for('auth.twofactor'))
#print('remember: ' + str(form.remember_me.data))
login_user(user, form.remember_me.data)
if request.headers.getlist("X-Forwarded-For"):
lastip = request.headers.getlist("X-Forwarded-For")[0]
else:
lastip = request.remote_addr
user.last_ip = lastip
db.session.add(user)
db.session.commit()
#send_email(current_app.config['MAIL_USERNAME'], user.email + ' logged in.', 'auth/email/adm_loginnotify', user=user, ipaddr=lastip )
return redirect(request.args.get('next') or url_for('vmanager.dashboard'))
flash('Invalid username or password.')
return render_template('auth/login.html', page=page, form=form)
@auth.route('/twofactor', methods=['GET', 'POST'])
def twofactor():
if 'email' not in session:
abort(404)
if 'memberberry' not in session:
abort(404)
page = { 'title': '2-Factor Login' }
form = TwoFAForm()
if form.validate_on_submit():
user = User.query.filter_by(email=session['email']).first()
del session['email']
if user is not None and user.verify_totp(form.token.data):
print('remember: ' + str(session['memberberry']))
login_user(user, session['memberberry'])
del session['memberberry']
if request.headers.getlist("X-Forwarded-For"):
lastip = request.headers.getlist("X-Forwarded-For")[0]
else:
lastip = request.remote_addr
user.last_ip = lastip
db.session.add(user)
db.session.commit()
#send_email(current_app.config['MAIL_USERNAME'], user.email + ' logged in.', 'auth/email/adm_loginnotify', user=user, ipaddr=lastip )
return redirect(request.args.get('next') or url_for('vmanager.dashboard'))
return render_template('auth/2fa.html', page=page, form=form)
@auth.route('/qrcode')
@login_required
def qrcode():
#if 'email' not in session:
# abort(404)
#user = User.query.filter_by(email=session['email']).first()
#if user is None:
# abort(404)
# for added security, remove username from session
#del session['email']
# render qrcode for FreeTOTP
url = pyqrcode.create(current_user.get_totp_uri())
stream = BytesIO()
url.svg(stream, scale=6)
return stream.getvalue(), 200, {
'Content-Type': 'image/svg+xml',
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0'}
@auth.route("/logout", methods=['GET'])
@login_required
def logout():
logout_user()
flash('You have logged out')
return redirect(url_for('vmanager.index'))
@auth.route('/register', methods=['GET', 'POST'])
def register():
#print(current_app.secret_key)
page = { 'title': 'Register' }
form = RegistrationForm()
if form.validate_on_submit():
user = User(email=form.email.data, password=form.password.data)
db.session.add(user)
db.session.commit()
token = user.generate_confirmation_token()
send_email(user.email, 'Потвърдетеашият_акаунт', 'auth/email/confirm', user=user, token=token)
#notify admin
newip = request.remote_addr
if request.headers.getlist("X-Forwarded-For"):
newip = request.headers.getlist("X-Forwarded-For")[0]
else:
newip = request.remote_addr
send_email(current_app.config['MAIL_USERNAME'], user.email + ' registered!', 'auth/email/adm_regnotify', user=user, ipaddr=newip )
flash('Благодарим за регистрацията! Моля проверете вашият email за потвърждение')
return redirect(url_for('auth.login'))
return render_template('auth/register.html', page=page, form=form)
@auth.route('/confirm/<token>')
@login_required
def confirm(token):
if current_user.confirmed:
return redirect(url_for('vmanager.index'))
if current_user.confirm(token):
flash('Вашият акаунт е потвърден. Благодаря!')
else:
flash('Времето за потвърждение на вашият код изтече.')
return redirect(url_for('vmanager.index'))
@auth.route('/confirm')
@login_required
def resend_confirmation():
token = current_user.generate_confirmation_token()
send_email(current_user.email, 'Потвърдетеашият_акаунт',
'auth/email/confirm', user=current_user, token=token)
flash('Изпратен е нов код за потвърждение..')
return redirect(url_for('vmanager.index'))
@auth.route('/change-password', methods=['GET', 'POST'])
@login_required
def change_password():
form = ChangePasswordForm()
if form.validate_on_submit():
if current_user.verify_password(form.old_password.data):
current_user.password = form.password.data
db.session.add(current_user)
db.session.commit()
flash('Вашата парола беше променена.')
return redirect(url_for('vmanager.index'))
else:
flash('Грешна парола.')
return render_template("auth/change_password.html", form=form)
@auth.route('/reset', methods=['GET', 'POST'])
def password_reset_request():
if not current_user.is_anonymous:
return redirect(url_for('vmanager.index'))
form = PasswordResetRequestForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user:
token = user.generate_reset_token()
send_email(user.email, 'Reset Your Password',
'auth/email/reset_password',
user=user, token=token,
next=request.args.get('next'))
flash('An email with instructions to reset your password has been '
'sent to you.')
return redirect(url_for('auth.login'))
return render_template('auth/reset_password.html', form=form)
@auth.route('/reset/<token>', methods=['GET', 'POST'])
def password_reset(token):
if not current_user.is_anonymous:
return redirect(url_for('vmanager.index'))
form = PasswordResetForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user is None:
return redirect(url_for('vmanager.index'))
if user.reset_password(token, form.password.data):
flash('Your password has been updated.')
return redirect(url_for('auth.login'))
else:
return redirect(url_for('vmanager.index'))
return render_template('auth/reset_password.html', form=form)