# HG changeset patch # User Søren Løvborg # Date 1436875199 -7200 # Node ID c5ff0bfefdf8a9730513fb8672bce90250cfe9e9 # Parent ad70180effaf8b8e67f730a8261c18133c30493e log_in_user: extract user session setup from LoginController The next changeset will need to set up a user login session outside LoginController. 'log_in_user' extracted and added as a top-level function in kallithea.lib.base since the code doesn't need access to the current controller. Code refactored to take a User object instead of a username, to allow callers flexibility in how the user should be looked up. diff -r ad70180effaf -r c5ff0bfefdf8 kallithea/controllers/login.py --- a/kallithea/controllers/login.py Tue Jul 14 13:59:59 2015 +0200 +++ b/kallithea/controllers/login.py Tue Jul 14 13:59:59 2015 +0200 @@ -28,7 +28,6 @@ import logging import formencode -import datetime import urlparse from formencode import htmlfill @@ -40,7 +39,7 @@ import kallithea.lib.helpers as h from kallithea.lib.auth import AuthUser, HasPermissionAnyDecorator from kallithea.lib.auth_modules import importplugin -from kallithea.lib.base import BaseController, render +from kallithea.lib.base import BaseController, log_in_user, render from kallithea.lib.exceptions import UserCreationError from kallithea.lib.utils2 import safe_str from kallithea.model.db import User, Setting @@ -57,29 +56,6 @@ def __before__(self): super(LoginController, self).__before__() - def _store_user_in_session(self, username, remember=False): - user = User.get_by_username(username, case_insensitive=True) - auth_user = AuthUser(user.user_id) - auth_user.set_authenticated() - cs = auth_user.get_cookie_store() - session['authuser'] = cs - user.update_lastlogin() - Session().commit() - - # If they want to be remembered, update the cookie - if remember: - _year = (datetime.datetime.now() + - datetime.timedelta(seconds=60 * 60 * 24 * 365)) - session._set_cookie_expires(_year) - - session.save() - - log.info('user %s is now authenticated and stored in ' - 'session, session attrs %s' % (username, cs)) - - # dumps session attrs back to cookie - session._update_cookie_out() - def _validate_came_from(self, came_from): """Return True if came_from is valid and can and should be used""" if not came_from: @@ -119,14 +95,10 @@ # import Login Form validator class login_form = LoginForm() try: - session.invalidate() c.form_result = login_form.to_python(dict(request.POST)) # form checks for username/password, now we're authenticated - self._store_user_in_session( - username=c.form_result['username'], - remember=c.form_result['remember']) - return self._redirect_to_origin(c.came_from) - + username = c.form_result['username'] + user = User.get_by_username(username, case_insensitive=True) except formencode.Invalid, errors: defaults = errors.value # remove password from filling in form again @@ -144,6 +116,9 @@ # with user creation, explanation should be provided in # Exception itself h.flash(e, 'error') + else: + log_in_user(user, c.form_result['remember']) + return self._redirect_to_origin(c.came_from) # check if we use container plugin, and try to login using it. auth_plugins = Setting.get_auth_plugins() @@ -158,7 +133,9 @@ return render('/login.html') if auth_info: - self._store_user_in_session(auth_info.get('username')) + username = auth_info.get('username') + user = User.get_by_username(username, case_insensitive=True) + log_in_user(user, remember=False) return self._redirect_to_origin(c.came_from) return render('/login.html') diff -r ad70180effaf -r c5ff0bfefdf8 kallithea/lib/base.py --- a/kallithea/lib/base.py Tue Jul 14 13:59:59 2015 +0200 +++ b/kallithea/lib/base.py Tue Jul 14 13:59:59 2015 +0200 @@ -28,6 +28,7 @@ :license: GPLv3, see LICENSE.md for more details. """ +import datetime import logging import time import traceback @@ -103,6 +104,37 @@ return path +def log_in_user(user, remember): + """ + Log a `User` in and update session and cookies. If `remember` is True, + the session cookie is set to expire in a year; otherwise, it expires at + the end of the browser session. + """ + user.update_lastlogin() + meta.Session().commit() + + auth_user = AuthUser(user_id=user.user_id) + auth_user.set_authenticated() + + # Start new session to prevent session fixation attacks. + session.invalidate() + cs = auth_user.get_cookie_store() + session['authuser'] = cs + + # If they want to be remembered, update the cookie + if remember: + t = datetime.datetime.now() + datetime.timedelta(days=365) + session._set_cookie_expires(t) + + session.save() + + log.info('user %s is now authenticated and stored in ' + 'session, session attrs %s', user.username, cs) + + # dumps session attrs back to cookie + session._update_cookie_out() + + class BasicAuth(paste.auth.basic.AuthBasicAuthenticator): def __init__(self, realm, authfunc, auth_http_code=None):