Changeset - 29370bb76fa6
[Not reviewed]
default
0 6 0
Marcin Kuzminski - 15 years ago 2010-06-25 02:09:33
marcin@python-works.com
first permissions commit: added permission managment on repository edit. Changed db rmissions, validators.
6 files changed with 196 insertions and 24 deletions:
0 comments (0 inline, 0 general)
pylons_app/controllers/repos.py
Show inline comments
 
@@ -104,16 +104,17 @@ class ReposController(BaseController):
 
        repo_model = RepoModel()
 
        _form = RepoForm(edit=True)()
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            repo_model.update(id, form_result)
 
            invalidate_cache('cached_repo_list')
 
            h.flash(_('Repository updated succesfully'), category='success')
 
            h.flash(_('Repository %s updated succesfully' % id), category='success')
 
                           
 
        except formencode.Invalid as errors:
 
            c.repo_info = repo_model.get(id)
 
            errors.value.update({'user':c.repo_info.user.username})
 
            c.form_errors = errors.error_dict
 
            return htmlfill.render(
 
                 render('admin/repos/repo_edit.html'),
 
                defaults=errors.value,
 
                encoding="UTF-8")
 
        except Exception:
 
@@ -164,12 +165,17 @@ class ReposController(BaseController):
 
                      ' please run the application again'
 
                      ' in order to rescan repositories') % id, category='error')
 
        
 
            return redirect(url('repos'))        
 
        defaults = c.repo_info.__dict__
 
        defaults.update({'user':c.repo_info.user.username})        
 
        
 
        for p in c.repo_info.repo2perm:
 
            defaults.update({'perm_%s' % p.user.username: 
 
                             p.permission.permission_name})
 
                
 
        return htmlfill.render(
 
            render('admin/repos/repo_edit.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
            force_defaults=False
 
        )          
pylons_app/lib/db_manage.py
Show inline comments
 
@@ -77,18 +77,31 @@ class DbManage(object):
 
        import getpass
 
        username = raw_input('Specify admin username:')
 
        password = getpass.getpass('Specify admin password:')
 
        self.create_user(username, password, True)
 
        
 
    def create_user(self, username, password, admin=False):
 
        
 
        log.info('creating default user')
 
        #create default user for handling default permissions.
 
        def_user = User()
 
        def_user.username = 'default'
 
        def_user.password = 'default'
 
        def_user.name = 'default'
 
        def_user.lastname = 'default'
 
        def_user.email = 'default@default'
 
        def_user.admin = False
 
        def_user.active = False
 
        
 
        self.sa.add(def_user)
 
        
 
        log.info('creating administrator user %s', username)
 
        
 
        new_user = User()
 
        new_user.username = username
 
        new_user.password = get_crypt_password(password)
 
        new_user.name = 'Admin'
 
        new_user.name = 'Hg'
 
        new_user.lastname = 'Admin'
 
        new_user.email = 'admin@localhost'
 
        new_user.admin = admin
 
        new_user.active = True
 
        
 
        try:
 
@@ -97,14 +110,17 @@ class DbManage(object):
 
        except:
 
            self.sa.rollback()
 
            raise
 
    
 
    def create_permissions(self):
 
        #module.(access|create|change|delete)_[name]
 
        perms = [('admin.access_home', 'Access to admin user view'),
 
                 
 
        #module.(read|write|owner)
 
        perms = [('repository.none', 'Repository no access'),
 
                 ('repository.read', 'Repository read access'),
 
                 ('repository.write', 'Repository write access'),
 
                 ('repository.admin', 'Repository admin access'),
 
                 ]
 
        
 
        for p in perms:
 
            new_perm = Permission()
 
            new_perm.permission_name = p[0]
 
            new_perm.permission_longname = p[1]
pylons_app/model/db.py
Show inline comments
 
@@ -25,31 +25,47 @@ class User(Base):
 
    def __repr__(self):
 
        return "<User('%s:%s')>" % (self.user_id, self.username)
 
      
 
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=1)
 
    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)
 
    repository = Column("repository", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    user_ip = Column("user_ip", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) 
 
    repository = Column("repository", TEXT(length=None, convert_unicode=False, assert_unicode=None), ForeignKey(u'repositories.repo_name'), nullable=False, unique=None, default=None)
 
    action = Column("action", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    action_date = Column("action_date", DATETIME(timezone=False), nullable=True, unique=None, default=None)
 
    
 
    user = relation('User')
 

	
 
class Repository(Base):
 
    __tablename__ = 'repositories'
 
    __table_args__ = {'useexisting':True}
 
    repo_name = Column("repo_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None, primary_key=True)
 
    user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=False, default=None)
 
    private = Column("private", BOOLEAN(), nullable=True, unique=None, default=None)
 
    description = Column("description", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    
 
    user = relation('User')
 
    repo2perm = relation('Repo2Perm', cascade='all')
 
    
 
class Permission(Base):
 
    __tablename__ = 'permissions'
 
    __table_args__ = {'useexisting':True}
 
    permission_id = Column("id", INTEGER(), nullable=False, unique=True, default=None, primary_key=1)
 
    permission_id = Column("permission_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
 
    permission_name = Column("permission_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    permission_longname = Column("permission_longname", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    
 
    def __repr__(self):
 
        return "<Permission('%s:%s')>" % (self.permission_id, self.permission_name)
 

	
 
class Repo2Perm(Base):
 
    __tablename__ = 'repo_to_perm'
 
    __table_args__ = (UniqueConstraint('user_id', 'permission_id', 'repository'), {'useexisting':True})
 
    repo2perm_id = Column("repo2perm_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)
 
    permission_id = Column("permission_id", INTEGER(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None)
 
    repository = Column("repository", TEXT(length=None, convert_unicode=False, assert_unicode=None), ForeignKey(u'repositories.repo_name'), nullable=False, unique=None, default=None) 
 
    
 
    user = relation('User')
 
    permission = relation('Permission')
 
    
pylons_app/model/forms.py
Show inline comments
 
@@ -52,13 +52,14 @@ class ValidAuthToken(formencode.validato
 
        if value != authentication_token():
 
            raise formencode.Invalid(self.message('invalid_token', state,
 
                                            search_number=value), value, state)
 
class ValidUsername(formencode.validators.FancyValidator):
 

	
 
    def validate_python(self, value, state):
 
        pass
 
        if value in ['default', 'new_user']:
 
            raise formencode.Invalid(_('Invalid username'), value, state)
 
    
 
class ValidPassword(formencode.validators.FancyValidator):
 
    
 
    def to_python(self, value, state):
 
        return get_crypt_password(value)
 
        
 
@@ -142,12 +143,45 @@ def ValidRepoName(edit=False):
 
            if sa.query(Repository).get(slug) and not edit:
 
                raise formencode.Invalid(_('This repository already exists'),
 
                                         value, state)
 
                        
 
            return slug 
 
    return _ValidRepoName
 

	
 
class ValidPerms(formencode.validators.FancyValidator):
 
    messages = {'perm_new_user_name':_('This username is not valid')}
 
    
 
    def to_python(self, value, state):
 
        perms_update = []
 
        perms_new = []
 
        #build a list of permission to update and new permission to create
 
        for k, v in value.items():
 
            print k, v
 
            if k.startswith('perm_'):
 
                if  k.startswith('perm_new_user'):
 
                    new_perm = value.get('perm_new_user', False)
 
                    new_user = value.get('perm_new_user_name', False)
 
                    if new_user and new_perm:
 
                        if (new_user, new_perm) not in perms_new:
 
                            perms_new.append((new_user, new_perm))
 
                else:
 
                    perms_update.append((k[5:], v))
 
                #clear from form list
 
                #del value[k]
 
        value['perms_updates'] = perms_update
 
        value['perms_new'] = perms_new
 
        sa = meta.Session
 
        for k, v in perms_new:
 
            try:
 
                self.user_db = sa.query(User).filter(User.username == k).one()
 
            except Exception:
 
                msg = self.message('perm_new_user_name',
 
                                     state=State_obj)
 
                raise formencode.Invalid(msg, value, state, error_dict={'perm_new_user_name':msg})            
 
        return value
 
                
 
#===============================================================================
 
# FORMS        
 
#===============================================================================
 
class LoginForm(formencode.Schema):
 
    allow_extra_fields = True
 
    filter_extra_fields = True
 
@@ -189,15 +223,16 @@ def UserForm(edit=False):
 
        
 
    return _UserForm
 

	
 
def RepoForm(edit=False):
 
    class _RepoForm(formencode.Schema):
 
        allow_extra_fields = True
 
        filter_extra_fields = True
 
        filter_extra_fields = False
 
        repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit))
 
        description = UnicodeString(strip=True, min=3, not_empty=True)
 
        private = StringBoolean(if_missing=False)
 
        
 
        if edit:
 
            user = All(Int(not_empty=True), ValidRepoUser)
 
        
 
        chained_validators = [ValidPerms]
 
    return _RepoForm
pylons_app/model/repo_model.py
Show inline comments
 
@@ -20,70 +20,108 @@
 
"""
 
Created on Jun 5, 2010
 
model for handling repositories actions
 
@author: marcink
 
"""
 
from pylons_app.model.meta import Session
 
from pylons_app.model.db import Repository
 
from pylons_app.model.db import Repository, Repo2Perm, User, Permission
 
import shutil
 
import os
 
from datetime import datetime
 
from pylons_app.lib.utils import check_repo
 
from pylons import app_globals as g
 
import traceback
 
import logging
 
log = logging.getLogger(__name__)
 

	
 
class RepoModel(object):
 
    
 
    def __init__(self):
 
        self.sa = Session()
 
    
 
    def get(self, id):
 
        return self.sa.query(Repository).get(id)
 
        
 
    
 
    def update(self, id, form_data):
 
    def update(self, repo_id, form_data):
 
        try:
 
            if id != form_data['repo_name']:
 
                self.__rename_repo(id, form_data['repo_name'])
 
            cur_repo = self.sa.query(Repository).get(id)
 
            if repo_id != form_data['repo_name']:
 
                self.__rename_repo(repo_id, form_data['repo_name'])
 
            cur_repo = self.sa.query(Repository).get(repo_id)
 
            for k, v in form_data.items():
 
                if k == 'user':
 
                    cur_repo.user_id = v
 
                else:
 
                    setattr(cur_repo, k, v)
 
                
 
            #update permissions
 
            for username, perm in form_data['perms_updates']:
 
                r2p = self.sa.query(Repo2Perm)\
 
                        .filter(Repo2Perm.user == self.sa.query(User)\
 
                                .filter(User.username == username).one())\
 
                        .filter(Repo2Perm.repository == repo_id).one()
 
                
 
                r2p.permission_id = self.sa.query(Permission).filter(
 
                                                Permission.permission_name == 
 
                                                perm).one().permission_id
 
                self.sa.add(r2p)
 
            
 
            for username, perm in form_data['perms_new']:
 
                r2p = Repo2Perm()
 
                r2p.repository = repo_id
 
                r2p.user = self.sa.query(User)\
 
                                .filter(User.username == username).one()
 
                
 
                r2p.permission_id = self.sa.query(Permission).filter(
 
                                                Permission.permission_name == 
 
                                                perm).one().permission_id
 
                self.sa.add(r2p)
 
                                    
 
            self.sa.add(cur_repo)
 
            self.sa.commit()
 
        except Exception as e:
 
            log.error(e)
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise    
 
    
 
    def create(self, form_data, cur_user):
 
    def create(self, form_data, cur_user, just_db=False):
 
        try:
 
            repo_name = form_data['repo_name']
 
            new_repo = Repository()
 
            for k, v in form_data.items():
 
                setattr(new_repo, k, v)
 
                
 
            new_repo.user_id = cur_user.user_id
 
            self.sa.add(new_repo)
 

	
 
            #create default permission
 
            repo2perm = Repo2Perm()
 
            repo2perm.permission_id = self.sa.query(Permission)\
 
                    .filter(Permission.permission_name == 'repository.read')\
 
                    .one().permission_id
 
                        
 
            repo2perm.repository = repo_name
 
            repo2perm.user_id = self.sa.query(User)\
 
                    .filter(User.username == 'default').one().user_id 
 
            
 
            self.sa.add(repo2perm)
 
            self.sa.commit()
 
            self.__create_repo(form_data['repo_name'])
 
        except Exception as e:
 
            log.error(e)
 
            if not just_db:
 
                self.__create_repo(repo_name)
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise    
 
                     
 
    def delete(self, repo):
 
        try:
 
            self.sa.delete(repo)
 
            self.sa.commit()
 
            self.__delete_repo(repo.repo_name)
 
        except Exception as e:
 
            log.error(e)
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 
       
 
    def __create_repo(self, repo_name):        
 
        repo_path = os.path.join(g.base_path, repo_name)
 
        if check_repo(repo_name, g.base_path):
 
@@ -100,7 +138,8 @@ class RepoModel(object):
 
    def __delete_repo(self, name):
 
        rm_path = os.path.join(g.base_path, name)
 
        log.info("Removing %s", rm_path)
 
        #disable hg 
 
        shutil.move(os.path.join(rm_path, '.hg'), os.path.join(rm_path, 'rm__.hg'))
 
        #disable repo
 
        shutil.move(rm_path, os.path.join(g.base_path, 'rm__%s-%s' % (datetime.today(), id)))
 
        shutil.move(rm_path, os.path.join(g.base_path, 'rm__%s__%s' \
 
                                          % (datetime.today(), name)))
pylons_app/templates/admin/repos/repo_edit.html
Show inline comments
 
@@ -36,14 +36,74 @@
 
        	<tr>
 
        		<td>${_('Owner')}</td>
 
        		<td>${h.text('user')}</td>
 
        		<td>${self.get_form_error('user')}</td>
 
        	</tr>
 
        	<tr>
 
        		<td>${_('Permissions')}</td>
 
        		<td>
 
        			<table>
 
        				<tr>
 
        					<td>${_('none')}</td>
 
        					<td>${_('read')}</td>
 
        					<td>${_('write')}</td>
 
        					<td>${_('admin')}</td>
 
        					<td>${_('user')}</td>
 
        				</tr>
 
        				
 
        				%for r2p in c.repo_info.repo2perm:
 
	        				<tr>
 
	        					<td>${h.radio('perm_%s' % r2p.user.username,'repository.none')}</td>
 
	        					<td>${h.radio('perm_%s' % r2p.user.username,'repository.read')}</td>
 
	        					<td>${h.radio('perm_%s' % r2p.user.username,'repository.write')}</td>
 
	        					<td>${h.radio('perm_%s' % r2p.user.username,'repository.admin')}</td>
 
	        					<td>${r2p.user.username}</td>
 
	        				</tr>
 
						%endfor
 

	
 
						
 
						<%
 
							
 
							if not hasattr(c,'form_errors'):
 
								d = 'display:none;'
 
							else:
 
								d=''
 
						%>
 

	
 
        				<tr id="add_perm_input" style="${d}">
 
        					<td>${h.radio('perm_new_user','repository.none')}</td>
 
        					<td>${h.radio('perm_new_user','repository.read')}</td>
 
        					<td>${h.radio('perm_new_user','repository.write')}</td>
 
        					<td>${h.radio('perm_new_user','repository.admin')}</td>
 
        					<td>${h.text('perm_new_user_name',size=10)}</td>
 
        					<td>${self.get_form_error('perm_new_user_name')}</td>     					
 
        				</tr>
 
        				<tr>
 
        					<td colspan="4">
 
        						<span id="add_perm" class="add_icon" style="cursor: pointer;">
 
        						${_('Add another user')}
 
        						</span>
 
        					</td>
 
        				</tr>
 
        			</table>
 
        		</td>
 
        		
 
        	</tr>
 
        	<tr>
 
        		<td></td>
 
        		<td>${h.submit('update','update')}</td>
 
        	</tr>
 
        	        	        	
 
        </table>
 
        ${h.end_form()}
 
        <script type="text/javascript">
 
        	YAHOO.util.Event.onDOMReady(function(){
 
				var D = YAHOO.util.Dom;
 
				YAHOO.util.Event.addListener('add_perm','click',function(){
 
					D.setStyle('add_perm_input','display','');
 
					D.setStyle('add_perm','opacity','0.6');
 
					D.setStyle('add_perm','cursor','default');
 
				});
 
            });
 
        </script>
 
    </div>
 
</%def>   
0 comments (0 inline, 0 general)