Refactor login_user and logout_user to be a utility method, thus it can be reused if necessary

This commit is contained in:
Matt Wright
2012-07-23 18:28:13 -04:00
parent 39670ac84e
commit a9727ceaa6
6 changed files with 73 additions and 423 deletions
+1 -2
View File
@@ -10,8 +10,6 @@
:license: MIT, see LICENSE for more details.
"""
from flask.ext.login import login_user, logout_user
from .core import Security, RoleMixin, UserMixin, AnonymousUser, \
AuthenticationProvider, current_user
from .datastore import SQLAlchemyUserDatastore, MongoEngineUserDatastore
@@ -22,3 +20,4 @@ from .forms import ForgotPasswordForm, LoginForm, RegisterForm, \
from .signals import confirm_instructions_sent, password_reset, \
password_reset_requested, reset_instructions_sent, user_confirmed, \
user_registered
from .utils import login_user, logout_user
-51
View File
@@ -1,51 +0,0 @@
# -*- coding: utf-8 -*-
"""
flask.ext.security.tokens
~~~~~~~~~~~~~~~~~~~~~~~~~
Flask-Security tokens module
:copyright: (c) 2012 by Matt Wright.
:license: MIT, see LICENSE for more details.
"""
from flask import current_app as app
from werkzeug.local import LocalProxy
from .utils import md5
# Convenient references
_security = LocalProxy(lambda: app.extensions['security'])
_datastore = LocalProxy(lambda: _security.datastore)
def generate_authentication_token(user):
"""Generates a unique authentication token for the specified user.
:param user: The user to work with
"""
data = [str(user.id), md5(user.email)]
return _security.token_auth_serializer.dumps(data)
def reset_authentication_token(user):
"""Resets a user's authentication token and returns the new token value.
:param user: The user to work with
"""
token = generate_authentication_token(user)
user.authentication_token = token
_datastore._save_model(user)
return token
def ensure_authentication_token(user):
"""Ensures that a user has an authentication token. If the user has an
authentication token already, nothing is performed.
:param user: The user to work with
"""
if not user.authentication_token:
return reset_authentication_token(user)
+60 -1
View File
@@ -17,7 +17,9 @@ from contextlib import contextmanager
from datetime import datetime, timedelta
from flask import url_for, flash, current_app, request, session, render_template
from flask.ext.login import make_secure_token
from flask.ext.login import make_secure_token, login_user as _login_user, \
logout_user as _logout_user
from flask.ext.principal import Identity, AnonymousIdentity, identity_changed
from werkzeug.local import LocalProxy
from .signals import user_registered, password_reset_requested
@@ -26,8 +28,56 @@ from .signals import user_registered, password_reset_requested
# Convenient references
_security = LocalProxy(lambda: current_app.extensions['security'])
_datastore = LocalProxy(lambda: _security.datastore)
_pwd_context = LocalProxy(lambda: _security.pwd_context)
_logger = LocalProxy(lambda: current_app.logger)
def login_user(user, remember=True):
"""Performs the login and sends the appropriate signal."""
if not _login_user(user, remember):
return False
if user.authentication_token is None:
from .tokens import generate_authentication_token
user.authentication_token = generate_authentication_token(user)
if remember:
user.remember_token = get_remember_token(user.email, user.password)
if _security.trackable:
old_current, new_current = user.current_login_at, datetime.utcnow()
user.last_login_at = old_current or new_current
user.current_login_at = new_current
old_current, new_current = user.current_login_ip, request.remote_addr
user.last_login_ip = old_current or new_current
user.current_login_ip = new_current
user.login_count = user.login_count + 1 if user.login_count else 0
_datastore._save_model(user)
identity_changed.send(current_app._get_current_object(),
identity=Identity(user.id))
_logger.debug('User %s logged in' % user)
return True
def logout_user():
for key in ('identity.name', 'identity.auth_type'):
session.pop(key, None)
identity_changed.send(current_app._get_current_object(),
identity=AnonymousIdentity())
_logout_user()
def get_hmac(msg, salt=None, digestmod=None):
digestmod = digestmod or hashlib.sha512
@@ -44,6 +94,15 @@ def encrypt_password(password, salt=None, use_hmac=False):
return _pwd_context.encrypt(hmac_value)
def generate_authentication_token(user):
"""Generates a unique authentication token for the specified user.
:param user: The user to work with
"""
data = [str(user.id), md5(user.email)]
return _security.token_auth_serializer.dumps(data)
def md5(data):
return hashlib.md5(data).hexdigest()
+5 -46
View File
@@ -9,12 +9,9 @@
:license: MIT, see LICENSE for more details.
"""
from datetime import datetime
from flask import current_app as app, redirect, request, session, \
render_template, jsonify, Blueprint
from flask.ext.login import login_user, logout_user
from flask.ext.principal import Identity, AnonymousIdentity, identity_changed
from flask.ext.principal import AnonymousIdentity, identity_changed
from werkzeug.datastructures import MultiDict
from werkzeug.local import LocalProxy
@@ -27,9 +24,8 @@ from flask_security.forms import LoginForm, RegisterForm, ForgotPasswordForm, \
from flask_security.recoverable import reset_by_token, \
reset_password_reset_token
from flask_security.signals import user_registered
from flask_security.tokens import generate_authentication_token
from flask_security.utils import get_url, get_post_login_redirect, do_flash, \
get_remember_token, get_message, config_value
get_message, config_value, login_user, logout_user
# Convenient references
@@ -40,38 +36,6 @@ _datastore = LocalProxy(lambda: _security.datastore)
_logger = LocalProxy(lambda: app.logger)
def _do_login(user, remember=True):
"""Performs the login and sends the appropriate signal."""
if not login_user(user, remember):
return False
if user.authentication_token is None:
user.authentication_token = generate_authentication_token(user)
if remember:
user.remember_token = get_remember_token(user.email, user.password)
if _security.trackable:
old_current, new_current = user.current_login_at, datetime.utcnow()
user.last_login_at = old_current or new_current
user.current_login_at = new_current
old_current, new_current = user.current_login_ip, request.remote_addr
user.last_login_ip = old_current or new_current
user.current_login_ip = new_current
user.login_count = user.login_count + 1 if user.login_count else 0
_datastore._save_model(user)
identity_changed.send(app._get_current_object(),
identity=Identity(user.id))
_logger.debug('User %s logged in' % user)
return True
def _json_auth_ok(user):
return jsonify({
"meta": {
@@ -107,7 +71,7 @@ def authenticate():
try:
user = _security.auth_provider.authenticate(form)
if _do_login(user, remember=form.remember.data):
if login_user(user, remember=form.remember.data):
if request.json:
return _json_auth_ok(user)
@@ -131,13 +95,8 @@ def authenticate():
def logout():
"""View function which handles a logout request."""
for key in ('identity.name', 'identity.auth_type'):
session.pop(key, None)
identity_changed.send(app._get_current_object(),
identity=AnonymousIdentity())
logout_user()
_logger.debug('User logged out')
return redirect(request.args.get('next', None) or
@@ -163,7 +122,7 @@ def register_user():
# Login the user if allowed
if not _security.confirmable or _security.login_without_confirmation:
_do_login(u)
login_user(u)
return redirect(_security.post_register_view or
_security.post_login_view)