Changeset - d66a7fa7689b
[Not reviewed]
default
0 6 0
Marcin Kuzminski - 15 years ago 2010-09-01 23:32:47
marcin@python-works.com
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
6 files changed with 50 insertions and 33 deletions:
0 comments (0 inline, 0 general)
production.ini
Show inline comments
 
@@ -53,13 +53,13 @@ beaker.cache.super_short_term.type=memor
 
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
 

	
 
beaker.session.key = hg-app
 
beaker.session.secret = g654dcno0-9873jhgfreyu
pylons_app/controllers/login.py
Show inline comments
 
@@ -27,13 +27,15 @@ from formencode import htmlfill
 
from pylons import request, response, session, tmpl_context as c, url
 
from pylons.controllers.util import abort, redirect
 
from pylons_app.lib.auth import AuthUser, HasPermissionAnyDecorator
 
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__)
 

	
 
class LoginController(BaseController):
 

	
 
@@ -49,12 +51,27 @@ class LoginController(BaseController):
 
        
 
        if request.POST:
 
            #import Login Form validator class
 
            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:
 
                    return redirect(url('hg_home'))
 
                               
 
            except formencode.Invalid as errors:
 
@@ -64,13 +81,14 @@ class LoginController(BaseController):
 
                    errors=errors.error_dict or {},
 
                    prefix_error=False,
 
                    encoding="UTF-8")
 
                        
 
        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
 
        for perm in user_model.get_default().user_perms:
 
            if perm.permission.permission_name == 'hg.register.auto_activate':
 
                c.auto_active = True
pylons_app/lib/auth.py
Show inline comments
 
@@ -229,13 +229,13 @@ class LoginRequired(object):
 
        else:
 
            log.warn('user %s not authenticated', user.username)
 

	
 
            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):
 
    """Base class for decorators"""
 
    
 
    def __init__(self, *required_perms):
pylons_app/model/db.py
Show inline comments
 
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'
 
    __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True})
 
    app_settings_id = Column("app_settings_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
 
    app_settings_name = Column("app_settings_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
@@ -40,12 +44,26 @@ class User(Base):
 
    def full_contact(self):
 
        return '%s %s <%s>' % (self.name, self.lastname, self.email)
 
        
 
    def __repr__(self):
 
        return "<User('id:%s:%s')>" % (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'
 
    __table_args__ = {'useexisting':True}
 
    user_log_id = Column("user_log_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
 
    user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
 
    user_ip = Column("user_ip", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) 
pylons_app/model/forms.py
Show inline comments
 
@@ -23,17 +23,17 @@ from formencode import All
 
from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \
 
    Email, Bool, StringBoolean
 
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
 
import pylons_app.lib.helpers as h
 
log = logging.getLogger(__name__)
 

	
 
@@ -90,46 +90,26 @@ class ValidAuth(formencode.validators.Fa
 
    #error mapping
 
    e_dict = {'username':messages['invalid_login'],
 
              'password':messages['invalid_password']}
 
    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
 
            raise formencode.Invalid(self.message('invalid_password',
 
                                     state=State_obj), value, state,
 
                                     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)
 
                    raise formencode.Invalid(self.message('invalid_password',
 
                                             state=State_obj), value, state,
 
                                             error_dict=self.e_dict)
 
@@ -137,27 +117,25 @@ class ValidAuth(formencode.validators.Fa
 
                log.warning('user %s is disabled', username)
 
                raise formencode.Invalid(self.message('disabled_account',
 
                                         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)
 
        finally:
 
        meta.Session.remove()            
 
                        
 
        return self.user_db.user_id
 

	
 
def ValidRepoName(edit, old_data):    
 
    class _ValidRepoName(formencode.validators.FancyValidator):
 
            
 
        def to_python(self, value, state):
pylons_app/model/user_model.py
Show inline comments
 
@@ -40,12 +40,15 @@ class UserModel(object):
 
    def get_default(self):
 
        return self.sa.query(User).filter(User.username == 'default').scalar()
 
    
 
    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()
 
            for k, v in form_data.items():
 
                setattr(new_user, k, v)
 
                
0 comments (0 inline, 0 general)