Changeset - 930f8182a884
[Not reviewed]
default
0 3 0
Marcin Kuzminski - 15 years ago 2010-08-29 00:11:28
marcin@python-works.com
Added redirection to page that request came from, after login in
3 files changed with 12 insertions and 3 deletions:
0 comments (0 inline, 0 general)
pylons_app/controllers/login.py
Show inline comments
 
#!/usr/bin/env python
 
# encoding: utf-8
 
# login controller for pylons
 
# Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
 
# 
 
# This program is free software; you can redistribute it and/or
 
# modify it under the terms of the GNU General Public License
 
# as published by the Free Software Foundation; version 2
 
# of the License or (at your opinion) any later version of the license.
 
# 
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
# 
 
# You should have received a copy of the GNU General Public License
 
# along with this program; if not, write to the Free Software
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
# MA  02110-1301, USA.
 

	
 
"""
 
Created on April 22, 2010
 
login controller for pylons
 
@author: marcink
 
"""
 
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
 
import formencode
 
import logging
 

	
 
log = logging.getLogger(__name__)
 

	
 
class LoginController(BaseController):
 

	
 
    def __before__(self):
 
        super(LoginController, self).__before__()
 

	
 
    def index(self):
 
        #redirect if already logged in
 
        c.came_from = request.GET.get('came_from',None)
 
        
 
        if c.hg_app_user.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))
 
                if c.came_from:
 
                    return redirect(c.came_from)
 
                else:
 
                return redirect(url('hg_home'))
 
                               
 
            except formencode.Invalid as errors:
 
                return htmlfill.render(
 
                    render('/login.html'),
 
                    defaults=errors.value,
 
                    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')
 
    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
 
                break
 
                        
 
        if request.POST:
 
                
 
            register_form = RegisterForm()()
 
            try:
 
                form_result = register_form.to_python(dict(request.POST))
 
                form_result['active'] = c.auto_active
 
                user_model.create_registration(form_result)
 
                return redirect(url('login_home'))
 
                               
 
            except formencode.Invalid as errors:
 
                return htmlfill.render(
 
                    render('/register.html'),
 
                    defaults=errors.value,
 
                    errors=errors.error_dict or {},
 
                    prefix_error=False,
 
                    encoding="UTF-8")
 
        
 
        return render('/register.html')
 
    
 
    def logout(self):
 
        session['hg_app_user'] = AuthUser()
 
        session.save()
 
        log.info('Logging out and setting user as Empty')
 
        redirect(url('hg_home'))
pylons_app/lib/auth.py
Show inline comments
 
@@ -183,98 +183,102 @@ def fill_perms(user):
 
                                                
 
        #=======================================================================
 
        # #overwrite default with user permissions if any
 
        #=======================================================================
 
        user_perms = sa.query(RepoToPerm, Permission, Repository)\
 
            .join((Repository, RepoToPerm.repository_id == Repository.repo_id))\
 
            .join((Permission, RepoToPerm.permission_id == Permission.permission_id))\
 
            .filter(RepoToPerm.user_id == user.user_id).all()
 
            
 
        for perm in user_perms:
 
            if perm.Repository.user_id == user.user_id:#set admin if owner
 
                p = 'repository.admin'
 
            else:
 
                p = perm.Permission.permission_name
 
            user.permissions['repositories'][perm.RepoToPerm.repository.repo_name] = p
 
    meta.Session.remove()         
 
    return user
 
    
 
def get_user(session):
 
    """
 
    Gets user from session, and wraps permissions into user
 
    @param session:
 
    """
 
    user = session.get('hg_app_user', AuthUser())
 
    if user.is_authenticated:
 
        user = fill_data(user)
 
    user = fill_perms(user)
 
    session['hg_app_user'] = user
 
    session.save()
 
    return user
 
        
 
#===============================================================================
 
# CHECK DECORATORS
 
#===============================================================================
 
class LoginRequired(object):
 
    """Must be logged in to execute this function else redirect to login page"""
 
   
 
    def __call__(self, func):
 
        return decorator(self.__wrapper, func)
 
    
 
    def __wrapper(self, func, *fargs, **fkwargs):
 
        user = session.get('hg_app_user', AuthUser())
 
        log.debug('Checking login required for user:%s', user.username)
 
        if user.is_authenticated:
 
            log.debug('user %s is authenticated', user.username)
 
            return func(*fargs, **fkwargs)
 
        else:
 
            log.warn('user %s not authenticated', user.username)
 
            log.debug('redirecting to login page')
 
            return redirect(url('login_home'))
 

	
 
            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)                
 
            return redirect(url('login_home',came_from=p))
 

	
 
class PermsDecorator(object):
 
    """Base class for decorators"""
 
    
 
    def __init__(self, *required_perms):
 
        available_perms = config['available_permissions']
 
        for perm in required_perms:
 
            if perm not in available_perms:
 
                raise Exception("'%s' permission is not defined" % perm)
 
        self.required_perms = set(required_perms)
 
        self.user_perms = None
 
        
 
    def __call__(self, func):
 
        return decorator(self.__wrapper, func)
 
    
 
    
 
    def __wrapper(self, func, *fargs, **fkwargs):
 
#        _wrapper.__name__ = func.__name__
 
#        _wrapper.__dict__.update(func.__dict__)
 
#        _wrapper.__doc__ = func.__doc__
 

	
 
        self.user_perms = session.get('hg_app_user', AuthUser()).permissions
 
        log.debug('checking %s permissions %s for %s',
 
           self.__class__.__name__, self.required_perms, func.__name__)
 
        
 
        if self.check_permissions():
 
            log.debug('Permission granted for %s', func.__name__)
 
            
 
            return func(*fargs, **fkwargs)
 
        
 
        else:
 
            log.warning('Permission denied for %s', func.__name__)
 
            #redirect with forbidden ret code
 
            return abort(403)
 

	
 
        
 
        
 
    def check_permissions(self):
 
        """Dummy function for overriding"""
 
        raise Exception('You have to write this function in child class')
 

	
 
class HasPermissionAllDecorator(PermsDecorator):
 
    """Checks for access permission for all given predicates. All of them 
 
    have to be meet in order to fulfill the request
 
    """
 
        
 
    def check_permissions(self):
 
        if self.required_perms.issubset(self.user_perms.get('global')):
pylons_app/templates/login.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" id="mainhtml">
 
    <head>
 
        <title>${_('Sign In to hg-app')}</title>
 
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
 
        <link rel="icon" href="/images/hgicon.png" type="image/png" />
 
        <meta name="robots" content="index, nofollow"/>
 
            
 
        <!-- stylesheets -->
 
        <link rel="stylesheet" type="text/css" href="/css/reset.css" />
 
        <link rel="stylesheet" type="text/css" href="/css/style.css" media="screen" />
 
        <link id="color" rel="stylesheet" type="text/css" href="/css/colors/blue.css" />
 

	
 
        <!-- scripts -->
 

	
 
    </head>
 
    <body>
 
<div id="login">
 
            <!-- login -->
 
            <div class="title">
 
                <h5>${_('Sign In to hg-app')}</h5>
 
                <div class="corner tl"></div>
 
                <div class="corner tr"></div>
 
            </div>
 
            <div class="inner">            
 
                ${h.form(h.url.current())}
 
                ${h.form(h.url.current(came_from=c.came_from))}
 
                <div class="form">
 
                    <!-- fields -->
 

	
 
                    <div class="fields">
 
                        <div class="field">
 
                            <div class="label">
 
                                <label for="username">${_('Username')}:</label>
 
                            </div>
 
                            <div class="input">
 
                                ${h.text('username',class_='focus',size=40)}
 
                            </div>
 
                            
 
                        </div>                     
 
                        <div class="field">
 
                            <div class="label">
 
                                <label for="password">${_('Password')}:</label>
 
                            </div>
 
                            <div class="input">
 
                                ${h.password('password',class_='focus',size=40)}
 
                            </div>
 
                            
 
                        </div>
 
                        ##<div class="field">
 
                        ##    <div class="checkbox">
 
                        ##        <input type="checkbox" id="remember" name="remember" />
 
                        ##        <label for="remember">Remember me</label>
 
                        ##    </div>
 
                        ##</div>
 
                        <div class="buttons">
 
                            ${h.submit('sign_in','Sign In',class_="ui-button ui-widget ui-state-default ui-corner-all")}
 
                        </div>
 
                    </div>
 
                    <!-- end fields -->
 
                    <!-- links -->
 
                    <div class="links">
 
                        ${h.link_to(_('Forgot your password ?'),h.url('#'))}
 
                        %if h.HasPermissionAny('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')():
 
	                         / 
 
	                        ${h.link_to(_("Don't have an account ?"),h.url('register'))}
 
                        %endif
 
                    </div>
 

	
 
                    <!-- end links -->
 
                </div>
 
                ${h.end_form()}
 
            </div>
 
            <!-- end login -->
 
        </div>
0 comments (0 inline, 0 general)