flask-base/auth/views.py
2018-03-31 18:26:40 +02:00

81 lines
2.4 KiB
Python

from flask import Blueprint, render_template, \
redirect, url_for, session, abort
from flask import current_app as app
from flask_security import login_user
from flask_security.confirmable import confirm_user
from flask_social import connection_created, login_completed, login_failed
from flask_social.utils import get_connection_values_from_oauth_response, \
get_provider_or_404
from flask_social.views import connect_handler
from werkzeug.local import LocalProxy
from flaskbase.extensions import db
from auth.forms import SocialLoginConfirmForm
blueprint = Blueprint('auth', __name__)
_security = LocalProxy(lambda: app.extensions['security'])
@connection_created.connect
@login_completed.connect
def on_connection_created(app, connection=None, user=None, provider=None):
if not connection:
connection = provider.get_connection()
if not connection.user and user:
connection.user = user
db.session.commit()
@login_failed.connect
def on_login_failed(app, provider, oauth_response):
session['failed_login_connection'] = \
get_connection_values_from_oauth_response(provider, oauth_response)
abort(redirect(url_for('auth.confirm_social')))
@blueprint.route('/confirm_social', methods=['GET', 'POST'])
def confirm_social():
connection_values = session.get('failed_login_connection', None)
if not connection_values:
return redirect('/')
form = SocialLoginConfirmForm(
email=connection_values.get('email', ''),
)
if form.validate_on_submit():
# Prevent Flask-Security form sending confirmation email
_security.confirmable = False
kwargs = {'email': form.email.data}
if connection_values.get('full_name'):
kwargs['display_name'] = connection_values['full_name']
# Create and login user
user = _security.datastore.create_user(**kwargs)
confirm_user(user)
_security.datastore.commit()
login_user(user)
# TODO: possibly move it to user_logged_in signal handler?
# Process pending social connection
connection_values = session.pop('failed_login_connection', None)
connection_values['user_id'] = user.id
connect_handler(
connection_values,
get_provider_or_404(connection_values['provider_id']))
_security.datastore.commit()
return redirect('/')
return render_template('security/confirm_social.html', form=form)