# HG changeset patch # User Marcin Kuzminski # Date 2010-09-01 21:32:47 # Node ID d66a7fa7689b4796f153fcf40331b81bdf5eb29b # Parent c59c4d4323e7ba54d5728233c149f48b13560562 moved loged in user propagation out of forms, update user model to get auto update last login. bugfix with redirect log fixed forms logic a little bit some other tweeks diff --git a/production.ini b/production.ini --- a/production.ini +++ b/production.ini @@ -56,7 +56,7 @@ beaker.cache.super_short_term.expire=10 ### BEAKER SESSION #### #################################### ## Type of storage used for the session, current types are -## “dbm”, “file”, “memcached”, “database”, and “memory”. +## dbm, file, memcached, database, and memory. ## The storage uses the Container API ##that is also used by the cache system. beaker.session.type = file diff --git a/pylons_app/controllers/login.py b/pylons_app/controllers/login.py --- a/pylons_app/controllers/login.py +++ b/pylons_app/controllers/login.py @@ -30,7 +30,9 @@ from pylons_app.lib.auth import AuthUser from pylons_app.lib.base import BaseController, render from pylons_app.model.forms import LoginForm, RegisterForm from pylons_app.model.user_model import UserModel +from sqlalchemy.exc import OperationalError import formencode +import datetime import logging log = logging.getLogger(__name__) @@ -52,6 +54,21 @@ class LoginController(BaseController): login_form = LoginForm() try: c.form_result = login_form.to_python(dict(request.POST)) + username = c.form_result['username'] + user = UserModel().get_user_by_name(username) + auth_user = AuthUser() + auth_user.username = user.username + auth_user.is_authenticated = True + auth_user.is_admin = user.admin + auth_user.user_id = user.user_id + auth_user.name = user.name + auth_user.lastname = user.lastname + session['hg_app_user'] = auth_user + session.save() + log.info('user %s is now authenticated', username) + + user.update_lastlogin() + if c.came_from: return redirect(c.came_from) else: @@ -67,7 +84,8 @@ class LoginController(BaseController): return render('/login.html') - @HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate') + @HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate', + 'hg.register.manual_activate') def register(self): user_model = UserModel() c.auto_active = False diff --git a/pylons_app/lib/auth.py b/pylons_app/lib/auth.py --- a/pylons_app/lib/auth.py +++ b/pylons_app/lib/auth.py @@ -232,7 +232,7 @@ class LoginRequired(object): p = request.environ.get('PATH_INFO') if request.environ.get('QUERY_STRING'): p+='?'+request.environ.get('QUERY_STRING') - log.debug('redirecting to login page with %',p) + log.debug('redirecting to login page with %s',p) return redirect(url('login_home',came_from=p)) class PermsDecorator(object): diff --git a/pylons_app/model/db.py b/pylons_app/model/db.py --- a/pylons_app/model/db.py +++ b/pylons_app/model/db.py @@ -1,7 +1,11 @@ from pylons_app.model.meta import Base +from sqlalchemy import * from sqlalchemy.orm import relation, backref -from sqlalchemy import * +from sqlalchemy.orm.session import Session from vcs.utils.lazy import LazyProperty +import logging + +log = logging.getLogger(__name__) class HgAppSettings(Base): __tablename__ = 'hg_app_settings' @@ -42,6 +46,20 @@ class User(Base): def __repr__(self): return "" % (self.user_id, self.username) + + def update_lastlogin(self): + """Update user lastlogin""" + import datetime + + try: + session = Session.object_session(self) + self.last_login = datetime.datetime.now() + session.add(self) + session.commit() + log.debug('updated user %s lastlogin',self) + except Exception: + session.rollback() + class UserLog(Base): __tablename__ = 'user_logs' diff --git a/pylons_app/model/forms.py b/pylons_app/model/forms.py --- a/pylons_app/model/forms.py +++ b/pylons_app/model/forms.py @@ -26,11 +26,11 @@ from pylons import session from pylons.i18n.translation import _ from pylons_app.lib.auth import check_password, get_crypt_password from pylons_app.model import meta +from pylons_app.model.user_model import UserModel from pylons_app.model.db import User, Repository from sqlalchemy.exc import OperationalError from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound from webhelpers.pylonslib.secure_form import authentication_token -import datetime import formencode import logging import os @@ -93,11 +93,10 @@ class ValidAuth(formencode.validators.Fa e_dict_disable = {'username':messages['disabled_account']} def validate_python(self, value, state): - sa = meta.Session password = value['password'] username = value['username'] try: - user = sa.query(User).filter(User.username == username).one() + user = UserModel().get_user_by_name(username) except (NoResultFound, MultipleResultsFound, OperationalError) as e: log.error(e) user = None @@ -106,27 +105,8 @@ class ValidAuth(formencode.validators.Fa error_dict=self.e_dict) if user: if user.active: - if user.username == username and check_password(password, user.password): - from pylons_app.lib.auth import AuthUser - auth_user = AuthUser() - auth_user.username = username - auth_user.is_authenticated = True - auth_user.is_admin = user.admin - auth_user.user_id = user.user_id - auth_user.name = user.name - auth_user.lastname = user.lastname - session['hg_app_user'] = auth_user - session.save() - log.info('user %s is now authenticated', username) - - try: - user.last_login = datetime.datetime.now() - sa.add(user) - sa.commit() - except (OperationalError) as e: - log.error(e) - sa.rollback() - + if user.username == username and check_password(password, + user.password): return value else: log.warning('user %s not authenticated', username) @@ -139,22 +119,20 @@ class ValidAuth(formencode.validators.Fa state=State_obj), value, state, error_dict=self.e_dict_disable) - - meta.Session.remove() - class ValidRepoUser(formencode.validators.FancyValidator): def to_python(self, value, state): - sa = meta.Session try: - self.user_db = sa.query(User)\ + self.user_db = meta.Session.query(User)\ .filter(User.active == True)\ .filter(User.username == value).one() except Exception: raise formencode.Invalid(_('This username is not valid'), value, state) - meta.Session.remove() + finally: + meta.Session.remove() + return self.user_db.user_id def ValidRepoName(edit, old_data): diff --git a/pylons_app/model/user_model.py b/pylons_app/model/user_model.py --- a/pylons_app/model/user_model.py +++ b/pylons_app/model/user_model.py @@ -43,6 +43,9 @@ class UserModel(object): def get_user(self, id): return self.sa.query(User).get(id) + def get_user_by_name(self,name): + return self.sa.query(User).filter(User.username == name).scalar() + def create(self, form_data): try: new_user = User()