# HG changeset patch # User Marcin Kuzminski # Date 2010-06-25 00:09:33 # Node ID 29370bb76fa689dada511ca6e0dc5c6797926dc1 # Parent 248642ed19128c00b2e5ab8aecba8f48087914e8 first permissions commit: added permission managment on repository edit. Changed db rmissions, validators. diff --git a/pylons_app/controllers/repos.py b/pylons_app/controllers/repos.py --- a/pylons_app/controllers/repos.py +++ b/pylons_app/controllers/repos.py @@ -107,10 +107,11 @@ class ReposController(BaseController): 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'), @@ -166,7 +167,12 @@ class ReposController(BaseController): return redirect(url('repos')) defaults = c.repo_info.__dict__ - defaults.update({'user':c.repo_info.user.username}) + 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, diff --git a/pylons_app/lib/db_manage.py b/pylons_app/lib/db_manage.py --- a/pylons_app/lib/db_manage.py +++ b/pylons_app/lib/db_manage.py @@ -80,12 +80,25 @@ class DbManage(object): 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 @@ -100,8 +113,11 @@ class DbManage(object): 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: diff --git a/pylons_app/model/db.py b/pylons_app/model/db.py --- a/pylons_app/model/db.py +++ b/pylons_app/model/db.py @@ -28,28 +28,44 @@ class User(Base): 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 "" % (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') + diff --git a/pylons_app/model/forms.py b/pylons_app/model/forms.py --- a/pylons_app/model/forms.py +++ b/pylons_app/model/forms.py @@ -55,7 +55,8 @@ class ValidAuthToken(formencode.validato 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): @@ -145,6 +146,39 @@ def ValidRepoName(edit=False): 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 #=============================================================================== @@ -192,7 +226,7 @@ def UserForm(edit=False): 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) @@ -200,4 +234,5 @@ def RepoForm(edit=False): if edit: user = All(Int(not_empty=True), ValidRepoUser) + chained_validators = [ValidPerms] return _RepoForm diff --git a/pylons_app/model/repo_model.py b/pylons_app/model/repo_model.py --- a/pylons_app/model/repo_model.py +++ b/pylons_app/model/repo_model.py @@ -23,12 +23,13 @@ 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__) @@ -41,36 +42,73 @@ class RepoModel(object): 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 @@ -79,8 +117,8 @@ class RepoModel(object): 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 @@ -103,4 +141,5 @@ class RepoModel(object): #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))) diff --git a/pylons_app/templates/admin/repos/repo_edit.html b/pylons_app/templates/admin/repos/repo_edit.html --- a/pylons_app/templates/admin/repos/repo_edit.html +++ b/pylons_app/templates/admin/repos/repo_edit.html @@ -39,11 +39,71 @@ ${self.get_form_error('user')} + ${_('Permissions')} + + + + + + + + + + + %for r2p in c.repo_info.repo2perm: + + + + + + + + %endfor + + + <% + + if not hasattr(c,'form_errors'): + d = 'display:none;' + else: + d='' + %> + + + + + + + + + + + + +
${_('none')}${_('read')}${_('write')}${_('admin')}${_('user')}
${h.radio('perm_%s' % r2p.user.username,'repository.none')}${h.radio('perm_%s' % r2p.user.username,'repository.read')}${h.radio('perm_%s' % r2p.user.username,'repository.write')}${h.radio('perm_%s' % r2p.user.username,'repository.admin')}${r2p.user.username}
${h.radio('perm_new_user','repository.none')}${h.radio('perm_new_user','repository.read')}${h.radio('perm_new_user','repository.write')}${h.radio('perm_new_user','repository.admin')}${h.text('perm_new_user_name',size=10)}${self.get_form_error('perm_new_user_name')}
+ + ${_('Add another user')} + +
+ + + + ${h.submit('update','update')} ${h.end_form()} +