changeset 484:c3e28b44454b demo

Merge with 0668919c307c0aa9de7f4befe189aad3783c6fbe
author Marcin Kuzminski <marcin@python-works.com>
date Thu, 02 Sep 2010 20:08:00 +0200
parents 492b4940750b (current diff) 0668919c307c (diff)
children a977818fbc6d
files pylons_app/model/user_model.py
diffstat 10 files changed, 89 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/production.ini	Sun Aug 29 22:02:42 2010 +0200
+++ b/production.ini	Thu Sep 02 20:08:00 2010 +0200
@@ -56,7 +56,7 @@
 ###       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
--- a/pylons_app/controllers/login.py	Sun Aug 29 22:02:42 2010 +0200
+++ b/pylons_app/controllers/login.py	Thu Sep 02 20:08:00 2010 +0200
@@ -30,7 +30,9 @@
 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 @@
             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 @@
                         
         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
--- a/pylons_app/controllers/summary.py	Sun Aug 29 22:02:42 2010 +0200
+++ b/pylons_app/controllers/summary.py	Thu Sep 02 20:08:00 2010 +0200
@@ -74,13 +74,10 @@
         
         #graph range
         td = datetime.today() + timedelta(days=1) 
-        y = td.year
-        m = td.month
-        d = td.day
-        c.ts_min = mktime((y, (td - timedelta(days=calendar.mdays[m] - 1)).month,
+        y, m, d = td.year, td.month, td.day
+        c.ts_min = mktime((y, (td - timedelta(days=calendar.mdays[m])).month,
                             d, 0, 0, 0, 0, 0, 0,))
         c.ts_max = mktime((y, m, d, 0, 0, 0, 0, 0, 0,))
-
         
         def author_key_cleaner(k):
             k = person(k)
--- a/pylons_app/lib/auth.py	Sun Aug 29 22:02:42 2010 +0200
+++ b/pylons_app/lib/auth.py	Thu Sep 02 20:08:00 2010 +0200
@@ -232,7 +232,7 @@
             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):
--- a/pylons_app/lib/backup_manager.py	Sun Aug 29 22:02:42 2010 +0200
+++ b/pylons_app/lib/backup_manager.py	Thu Sep 02 20:08:00 2010 +0200
@@ -53,7 +53,8 @@
         if not os.path.isfile(rsa_key):
             logging.error('Could not load id_rsa key file in %s', rsa_key)
             sys.exit()
-
+        return rsa_key
+    
     def get_repos_path(self, path):
         if not os.path.isdir(path):
             logging.error('Wrong location for repositories in %s', path)
--- a/pylons_app/lib/helpers.py	Sun Aug 29 22:02:42 2010 +0200
+++ b/pylons_app/lib/helpers.py	Thu Sep 02 20:08:00 2010 +0200
@@ -75,8 +75,8 @@
         @param tooltip_title:
         """
         
-        return literal(wrap_paragraphs(tooltip_title, trim_at)\
-                       .replace('\n', '<br/>')) 
+        return wrap_paragraphs(escape(tooltip_title), trim_at)\
+                       .replace('\n', '<br/>')
     
     def activate(self):
         """
@@ -336,3 +336,19 @@
     gravatar_url += urllib.urlencode({'d':default, 's':str(size)})
 
     return gravatar_url
+
+def safe_unicode(str):
+    """safe unicode function. In case of UnicodeDecode error we try to return
+    unicode with errors replace, if this failes we return unicode with 
+    string_escape decoding """
+    
+    try:
+        u_str = unicode(str)
+    except UnicodeDecodeError:
+        try:
+            u_str = unicode(str, 'utf-8', 'replace')
+        except UnicodeDecodeError:
+            #incase we have a decode error just represent as byte string
+            u_str = unicode(str(str).encode('string_escape'))
+        
+    return u_str
\ No newline at end of file
--- a/pylons_app/lib/indexers/daemon.py	Sun Aug 29 22:02:42 2010 +0200
+++ b/pylons_app/lib/indexers/daemon.py	Thu Sep 02 20:08:00 2010 +0200
@@ -36,6 +36,7 @@
 import traceback
 from pylons_app.config.environment import load_environment
 from pylons_app.model.hg_model import HgModel
+from pylons_app.lib.helpers import safe_unicode
 from whoosh.index import create_in, open_dir
 from shutil import rmtree
 from pylons_app.lib.indexers import ANALYZER, INDEX_EXTENSIONS, IDX_LOCATION, \
@@ -77,22 +78,29 @@
             fobj = open(path, 'rb')
             content = fobj.read()
             fobj.close()
-            try:
-                u_content = unicode(content)
-            except UnicodeDecodeError:
-                #incase we have a decode error just represent as byte string
-                u_content = unicode(str(content).encode('string_escape'))
+            u_content = safe_unicode(content)
         else:
             log.debug('    >> %s' % path)
             #just index file name without it's content
             u_content = u''
-                
-        writer.add_document(owner=unicode(repo.contact),
+        
+        
+        
+        try:
+            os.stat(path)
+            writer.add_document(owner=unicode(repo.contact),
                             repository=u"%s" % repo.name,
                             path=u"%s" % path,
                             content=u_content,
                             modtime=os.path.getmtime(path),
-                            extension=ext) 
+                            extension=ext)             
+        except OSError, e:
+            import errno
+            if e.errno == errno.ENOENT:
+                log.debug('path %s does not exist or is a broken symlink' % path)
+            else:
+                raise e                 
+
     
     def build_index(self):
         if os.path.exists(IDX_LOCATION):
--- a/pylons_app/model/db.py	Sun Aug 29 22:02:42 2010 +0200
+++ b/pylons_app/model/db.py	Thu Sep 02 20:08:00 2010 +0200
@@ -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 @@
         
     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'
--- a/pylons_app/model/forms.py	Sun Aug 29 22:02:42 2010 +0200
+++ b/pylons_app/model/forms.py	Thu Sep 02 20:08:00 2010 +0200
@@ -26,11 +26,11 @@
 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 @@
     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 @@
                                      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 @@
                                          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):    
--- a/pylons_app/model/user_model.py	Sun Aug 29 22:02:42 2010 +0200
+++ b/pylons_app/model/user_model.py	Thu Sep 02 20:08:00 2010 +0200
@@ -43,6 +43,9 @@
     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()