Changeset - 556473ba0399
[Not reviewed]
default
0 2 2
Marcin Kuzminski - 15 years ago 2010-05-22 01:32:30
marcin@python-works.com
fixed menu in home page, and added login html with forms that validates username and password.
4 files changed with 154 insertions and 10 deletions:
0 comments (0 inline, 0 general)
pylons_app/controllers/login.py
Show inline comments
 
new file 100644
 
import logging
 
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.base import BaseController, render
 
import formencode
 
from pylons_app.model.forms import LoginForm
 
from pylons_app.lib.auth import AuthUser
 

	
 
log = logging.getLogger(__name__)
 

	
 
class LoginController(BaseController):
 

	
 
    def index(self):
 
        if session.get('hg_app_user', AuthUser()).is_authenticated:
 
            return redirect(url('hg_home'))
 
        
 
        if request.POST:
 
            #import Login Form validator class
 
            login_form = LoginForm()
 
            try:
 
                c.form_result = login_form.to_python(dict(request.POST))
 
                return redirect(url('hg_home'))
 
                               
 
            except formencode.Invalid as errors:
 
                c.form_errors = errors.error_dict
 
                return htmlfill.render(
 
                    render('/login.html'),
 
                    defaults=errors.value,
 
                    encoding="UTF-8")
 
                        
 
        return render('/login.html')
 
    
 
    def logout(self):
 
        session['hg_app_user'] = AuthUser()
 
        session.save()
 
        redirect(url('hg_home'))
pylons_app/model/forms.py
Show inline comments
 
@@ -16,24 +16,88 @@ ignore_key_missing      False     If Tru
 
<name> = formencode.validators.<name of validator>
 
<name> must equal form name
 
list=[1,2,3,4,5]
 
for select use formencode.All(OneOf(list), Int())
 
for SELECT use formencode.All(OneOf(list), Int())
 
    
 
"""
 

	
 
from formencode.validators import UnicodeString, OneOf, Int, Number, Regex
 
from pylons import session
 
from pylons.i18n.translation import _
 
from pylons_app.lib.auth import get_crypt_password
 
from pylons_app.model import meta
 
from pylons_app.model.db import Users
 
from sqlalchemy.exc import OperationalError
 
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
 
from webhelpers.pylonslib.secure_form import authentication_token
 
import formencode
 
from formencode.validators import UnicodeString, OneOf, Int, Number, Regex
 
from pylons.i18n.translation import _
 
from webhelpers.pylonslib.secure_form import authentication_token
 
import logging
 
log = logging.getLogger(__name__)
 

	
 

	
 
#this is needed to translate the messages using _() in validators
 
class State_obj(object):
 
    _ = staticmethod(_)
 
    
 
#===============================================================================
 
# VALIDATORS
 
#===============================================================================
 
class ValidAuthToken(formencode.validators.FancyValidator):
 
    messages = {'invalid_token':_('Token mismatch')}
 

	
 
    def validate_python(self, value, state):
 

	
 
        if value != authentication_token():
 
            raise formencode.Invalid(self.message('invalid_token', state, search_number=value), value, state)
 
            raise formencode.Invalid(self.message('invalid_token', state,
 
                                            search_number=value), value, state)
 

	
 
class ValidAuth(formencode.validators.FancyValidator):
 
    messages = {
 
            'invalid_password':_('invalid password'),
 
            'invalid_login':_('invalid user name'),
 
            'disabled_account':_('Your acccount is disabled')
 
            
 
            }
 
    #error mapping
 
    e_dict = {'username':messages['invalid_login'],
 
              'password':messages['invalid_password']}
 
    
 
    def validate_python(self, value, state):
 
        sa = meta.Session
 
        crypted_passwd = get_crypt_password(value['password'])
 
        username = value['username']
 
        try:
 
            user = sa.query(Users).filter(Users.username == username).one()
 
        except (NoResultFound, MultipleResultsFound, OperationalError) as e:
 
            log.error(e)
 
            user = None
 
        print value
 
        if user:
 
            if user.active:
 
                if user.username == username and user.password == crypted_passwd:
 
                    log.info('user %s authenticated correctly', username)
 
                    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
 
                    session['hg_app_user'] = auth_user
 
                    session.save()
 
                    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)
 
            else:
 
                log.warning('user %s is disabled', username)
 
                raise formencode.Invalid(self.message('disabled_account',
 
                                         state=State_obj),
 
                                         value, state, error_dict=self.e_dict)
 

	
 

	
 
        
 
#===============================================================================
 
# FORMS        
 
#===============================================================================
 
class LoginForm(formencode.Schema):
 
    allow_extra_fields = True
 
    filter_extra_fields = True
 
@@ -56,3 +120,7 @@ class LoginForm(formencode.Schema):
 
                                )
 

	
 

	
 
    #chained validators have access to all data
 
    chained_validators = [ValidAuth]
 
    
 

	
pylons_app/templates/index.html
Show inline comments
 
@@ -10,10 +10,7 @@ from pylons_app.lib import filters
 
	${c.repos_prefix} Mercurial Repositories
 
</%def>
 
<%def name="page_nav()">
 
	<ul class="page-nav">
 
		<li class="current">${_('Home')}</li>
 
		<li>${h.link_to(u'Admin',h.url('admin_home'))}</li>
 
	</ul>
 
	${self.menu('home')}
 
</%def>
 
<%def name="main()">
 
	<%def name="get_sort(name)">
pylons_app/templates/login.html
Show inline comments
 
new file 100644
 
## -*- coding: utf-8 -*-
 
<%!
 
from pylons_app.lib import filters
 
%>
 
<%inherit file="base/base.html"/>
 
<%def name="title()">
 
    ${c.repos_prefix} Mercurial Repositories
 
</%def>
 
<%def name="breadcrumbs()">
 
	${c.repos_prefix} Mercurial Repositories
 
</%def>
 
<%def name="page_nav()">
 
	${self.menu('home')}
 
</%def>
 
<%def name="main()">
 
        <div>
 
        <br />
 
        <h2>${_('Login')}</h2>
 
        ${h.form(h.url.current())}
 
        <table>
 
            <tr>
 
                <td>${_('Username')}</td>
 
                <td>${h.text('username')}</td>
 
                <td>${self.get_form_error('username')} 
 

	
 
                </td>
 
            </tr>
 
            <tr>
 
                <td>${_('Password')}</td>
 
                <td>${h.password('password')}</td>
 
                <td>${self.get_form_error('password')}</td> 
 
            </tr>
 
            <tr>
 
                <td></td>
 
                <td>${h.submit('login','login')}</td>
 
            </tr>            
 
        </table>
 
        ${h.end_form()}
 
        </div>
 
</%def>    
 

	
 

	
0 comments (0 inline, 0 general)