Changeset - 62c04c5cc971
[Not reviewed]
beta
0 5 0
Marcin Kuzminski - 15 years ago 2010-12-29 17:50:47
marcin@python-works.com
Added some more details into user edit permissions view
5 files changed with 160 insertions and 29 deletions:
0 comments (0 inline, 0 general)
rhodecode/controllers/admin/users.py
Show inline comments
 
@@ -27,19 +27,20 @@
 

	
 
import logging
 
import traceback
 
import formencode
 

	
 
from formencode import htmlfill
 
from pylons import request, session, tmpl_context as c, url
 
from pylons import request, session, tmpl_context as c, url, config
 
from pylons.controllers.util import abort, redirect
 
from pylons.i18n.translation import _
 

	
 
from rhodecode.lib.exceptions import *
 
from rhodecode.lib.exceptions import DefaultUserException, UserOwnsReposException
 
from rhodecode.lib import helpers as h
 
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
 
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
 
    fill_perms
 
from rhodecode.lib.base import BaseController, render
 

	
 
from rhodecode.model.db import User
 
from rhodecode.model.forms import UserForm
 
from rhodecode.model.user import UserModel
 

	
 
@@ -54,13 +55,13 @@ class UsersController(BaseController):
 
    @LoginRequired()
 
    @HasPermissionAllDecorator('hg.admin')
 
    def __before__(self):
 
        c.admin_user = session.get('admin_user')
 
        c.admin_username = session.get('admin_username')
 
        super(UsersController, self).__before__()
 

	
 
        c.available_permissions = config['available_permissions']
 

	
 
    def index(self, format='html'):
 
        """GET /users: All items in the collection"""
 
        # url('users')
 

	
 
        c.users_list = self.sa.query(User).all()
 
@@ -137,13 +138,13 @@ class UsersController(BaseController):
 
        #    h.form(url('user', id=ID),
 
        #           method='delete')
 
        # url('user', id=ID)
 
        user_model = UserModel()
 
        try:
 
            user_model.delete(id)
 
            h.flash(_('sucessfully deleted user'), category='success')
 
            h.flash(_('successfully deleted user'), category='success')
 
        except (UserOwnsReposException, DefaultUserException), e:
 
            h.flash(str(e), category='warning')
 
        except Exception:
 
            h.flash(_('An error occurred during deletion of user'),
 
                    category='error')
 
        return redirect(url('users'))
 
@@ -159,14 +160,17 @@ class UsersController(BaseController):
 
        c.user = self.sa.query(User).get(id)
 
        if not c.user:
 
            return redirect(url('users'))
 
        if c.user.username == 'default':
 
            h.flash(_("You can't edit this user"), category='warning')
 
            return redirect(url('users'))
 
        c.user.permissions = {}
 
        c.granted_permissions = fill_perms(c.user).permissions['global']
 

	
 
        defaults = c.user.get_dict()
 

	
 
        return htmlfill.render(
 
            render('admin/users/user_edit.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
            force_defaults=False
 
        )
rhodecode/lib/auth.py
Show inline comments
 
#!/usr/bin/env python
 
# encoding: utf-8
 
# authentication and permission libraries
 
# Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
 
#
 
# -*- coding: utf-8 -*-
 
"""
 
    rhodecode.lib.auth
 
    ~~~~~~~~~~~~~~~~~~
 
    
 
    authentication and permission libraries
 
    
 
    :created_on: Apr 4, 2010
 
    :copyright: (c) 2010 by marcink.
 
    :license: LICENSE_NAME, see LICENSE_FILE for more details.
 
"""
 
# 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,
 
@@ -14,32 +20,32 @@
 
# 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 4, 2010
 

	
 
@author: marcink
 
"""
 
import bcrypt
 
import random
 
import logging
 
import traceback
 

	
 
from decorator import decorator
 

	
 
from pylons import config, session, url, request
 
from pylons.controllers.util import abort, redirect
 
from rhodecode.lib.exceptions import *
 

	
 
from rhodecode.lib.exceptions import LdapPasswordError, LdapUsernameError
 
from rhodecode.lib.utils import get_repo_slug
 
from rhodecode.lib.auth_ldap import AuthLdap
 

	
 
from rhodecode.model import meta
 
from rhodecode.model.user import UserModel
 
from rhodecode.model.caching_query import FromCache
 
from rhodecode.model.db import User, RepoToPerm, Repository, Permission, \
 
    UserToPerm
 
import bcrypt
 
from decorator import decorator
 
import logging
 
import random
 
import traceback
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 
class PasswordGenerator(object):
 
    """This is a simple class for generating password from
 
        different sets of characters
 
@@ -169,18 +175,19 @@ class  AuthUser(object):
 
        self.permissions = {}
 

	
 
    def __repr__(self):
 
        return "<AuthUser('id:%s:%s')>" % (self.user_id, self.username)
 

	
 
def set_available_permissions(config):
 
    """
 
    This function will propagate pylons globals with all available defined
 
    """This function will propagate pylons globals with all available defined
 
    permission given in db. We don't wannt to check each time from db for new 
 
    permissions since adding a new permission also requires application restart
 
    ie. to decorate new views with the newly created permission
 
    :param config:
 
    
 
    :param config: current pylons config instance
 
    
 
    """
 
    log.info('getting information about all available permissions')
 
    try:
 
        sa = meta.Session()
 
        all_perms = sa.query(Permission).all()
 
    except:
 
@@ -192,15 +199,16 @@ def set_available_permissions(config):
 

	
 
def set_base_path(config):
 
    config['base_path'] = config['pylons.app_globals'].base_path
 

	
 

	
 
def fill_perms(user):
 
    """
 
    Fills user permission attribute with permissions taken from database
 
    """Fills user permission attribute with permissions taken from database
 
    
 
    :param user:
 
    
 
    """
 

	
 
    sa = meta.Session()
 
    user.permissions['repositories'] = {}
 
    user.permissions['global'] = set()
 

	
rhodecode/model/db.py
Show inline comments
 
@@ -114,12 +114,17 @@ class User(Base, BaseModel):
 
    user_followers = relation('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all')
 

	
 
    @property
 
    def full_contact(self):
 
        return '%s %s <%s>' % (self.name, self.lastname, self.email)
 

	
 

	
 
    @property
 
    def is_admin(self):
 
        return self.admin
 

	
 
    def __repr__(self):
 
        return "<%s('id:%s:%s')>" % (self.__class__.__name__,
 
                                     self.user_id, self.username)
 

	
 
    def update_lastlogin(self):
 
        """Update user lastlogin"""
rhodecode/templates/admin/users/user_edit.html
Show inline comments
 
@@ -110,11 +110,125 @@
 
</div>
 
<div class="box box-right">
 
    <!-- box / title -->
 
    <div class="title">
 
        <h5>${_('Permissions')}</h5>       
 
    </div>
 
    <div class="table">
 
    Permissions settings goes here !
 
	<form id="map_form" method="post" action="{%url update_permissions %}">
 
	<div class="form">
 
	  <div class="fields">
 
	  
 
	  
 
	  
 
		<table> 
 
		        <tr>
 
		            <td class="label">${_('Permissions')}:</td>
 
		            <td>
 
		                <div>
 
		                    <div style="float:left">
 
		                    <div class="text">${_('Granted permissions')}</div>
 
		                        ${h.select('granted_permissions',[],c.granted_permissions,multiple=True,size=8,style="min-width:210px")}
 
		                    </div>
 
		                    <div style="float:left;width:20px;padding-top:50px">
 
		                        <img alt="add" id="add_element" 
 
		                            style="padding:2px;cursor:pointer" 
 
		                            src="/images/icons/arrow_left.png">
 
		                        <br />
 
		                        <img alt="remove" id="remove_element" 
 
		                            style="padding:2px;cursor:pointer" 
 
		                            src="/images/icons/arrow_right.png">
 
		                    </div>
 
		                    <div style="float:left">
 
		                        <div class="text">${_('Available permissions')}</div>
 
		                         ${h.select('available_permissions',[],c.available_permissions,multiple=True,size=8,style="min-width:210px")}
 
		                    </div>
 
		                </div>
 
		            </td>           
 
		        </tr>       
 

	
 
		</table>
 
        <div class="buttons">
 
         ${h.submit('Save','Save',class_="ui-button")}    
 
        </div>
 
    </div>
 
</div>
 
	</form>
 
    
 
    
 
<script type="text/javascript">
 
    YAHOO.util.Event.onDOMReady(function(){
 
     
 
            var D = YAHOO.util.Dom;
 
            var E = YAHOO.util.Event;
 
        
 
            //temp container for storage.
 
            var cache = new Array();
 
            var c =  D.get('id_granted_permissions');
 
            
 
            //get only selected options for further fullfilment
 
            for(var i = 0;node =c.options[i];i++){
 
                if(node.selected){
 
                    //push selected to my temp storage left overs :)
 
                    cache.push(node);
 
                }   
 
            }
 
            
 
            //clear select
 
            c.options.length = 0;
 

	
 
            //fill it with remembered options
 
            for(var i = 0;node = cache[i];i++){
 
                c.options[i]=new Option(node.text, node.value, false, false);
 
            }
 
            
 
            function target_callback(e){
 
                window.location='/admin/t4?g='+e.target.value;
 
            }
 

	
 
            function prompts_action_callback(e){
 
                
 
                var choosen = D.get('id_granted_permissions');  
 
                var availible = D.get('id_available_permissions');
 
        
 
                if (this.id=='add_element'){
 
                    for(var i=0; node = availible.options[i];i++){
 
                        if(node.selected){
 
                            choosen.appendChild(new Option(node.text, node.value, false, false));
 
                        }
 
                    }
 
                }
 
                else if (this.id=='remove_element'){
 

	
 
                    //temp container for storage.
 
                    cache = new Array();
 
                    
 
                    for(var i = 0;node = choosen.options[i];i++){
 
                        if(!node.selected){
 
                            //push left overs :)
 
                            cache.push(node);
 
                        }   
 
                    }
 
                    //clear select
 
                    choosen.options.length = 0;
 
                    for(var i = 0;node = cache[i];i++){
 
                        choosen.options[i]=new Option(node.text, node.value, false, false);
 
                    }               
 
                }                   
 
                else{
 
                    
 
                }
 
            }
 
            
 
            E.addListener('id_groups','change',target_callback);
 
    
 
            E.addListener(['add_element','remove_element'],'click',prompts_action_callback)
 

	
 
            E.addListener('map_form','submit',function(){
 
                var choosen = D.get('id_granted_permissions');
 
                for (var i = 0; i < choosen.options.length; i++) {
 
                    choosen.options[i].selected = 'selected';
 
                }
 
            })  
 
        });
 
</script>    
 
</div>
 
</%def>  
 
\ No newline at end of file
rhodecode/tests/functional/test_admin_users.py
Show inline comments
 
@@ -97,13 +97,13 @@ class TestAdminUsersController(TestContr
 

	
 
        response = response.follow()
 

	
 
        new_user = self.sa.query(User).filter(User.username == username).one()
 
        response = self.app.delete(url('user', id=new_user.user_id))
 

	
 
        assert """sucessfully deleted user""" in response.session['flash'][0], 'No info about user deletion'
 
        assert """successfully deleted user""" in response.session['flash'][0], 'No info about user deletion'
 

	
 

	
 
    def test_delete_browser_fakeout(self):
 
        response = self.app.post(url('user', id=1), params=dict(_method='delete'))
 

	
 
    def test_show(self):
0 comments (0 inline, 0 general)