##// END OF EJS Templates
#227 Initial version of repository groups permissions system...
#227 Initial version of repository groups permissions system - implemented none/read/write/admin permissions for groups - wrote more tests for permissions, and new permissions groups - a lot of code garden, splitted logic into proper models - permissions on groups doesn't propagate yet to repositories - deprecated some methods on api for managing permissions on repositories for users, and users groups

File last commit:

r1982:87f0800a beta
r1982:87f0800a beta
Show More
repos_groups.py
313 lines | 11.3 KiB | text/x-python | PythonLexer
2012 copyrights
r1824 # -*- coding: utf-8 -*-
"""
rhodecode.controllers.admin.repos_groups
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#227 Initial version of repository groups permissions system...
r1982 Repositories groups controller for RhodeCode
2012 copyrights
r1824
:created_on: Mar 23, 2010
:author: marcink
:copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
:license: GPLv3, see COPYING 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, either version 3 of the License, or
# (at your option) any later version.
#
# 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, see <http://www.gnu.org/licenses/>.
changes for #56
r1171 import logging
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 import traceback
import formencode
from formencode import htmlfill
changes for #56
r1171
#227 Initial version of repository groups permissions system...
r1982 from pylons import request, tmpl_context as c, url
from pylons.controllers.util import redirect
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 from pylons.i18n.translation import _
changes for #56
r1171
Added friendly message about removing a group that still contains subgroups....
r1543 from sqlalchemy.exc import IntegrityError
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 from rhodecode.lib import helpers as h
#227 Initial version of repository groups permissions system...
r1982 from rhodecode.lib.auth import LoginRequired, HasPermissionAnyDecorator,\
HasReposGroupPermissionAnyDecorator
changes for #56
r1171 from rhodecode.lib.base import BaseController, render
refactoring of models names for repoGroup permissions
r1633 from rhodecode.model.db import RepoGroup
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 from rhodecode.model.repos_group import ReposGroupModel
from rhodecode.model.forms import ReposGroupForm
another major refactoring with session management
r1734 from rhodecode.model.meta import Session
#227 Initial version of repository groups permissions system...
r1982 from rhodecode.model.repo import RepoModel
from webob.exc import HTTPInternalServerError
changes for #56
r1171
log = logging.getLogger(__name__)
PEP8ify - controllers
r1245
changes for #56
r1171 class ReposGroupsController(BaseController):
"""REST Controller styled on the Atom Publishing Protocol"""
# To properly map this controller, ensure your config/routing.py
# file has a resource setup:
# map.resource('repos_group', 'repos_groups')
#47 implemented basic edition of groups
r1347 @LoginRequired()
def __before__(self):
super(ReposGroupsController, self).__before__()
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 def __load_defaults(self):
refactoring of models names for repoGroup permissions
r1633 c.repo_groups = RepoGroup.groups_choices()
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
#227 Initial version of repository groups permissions system...
r1982 repo_model = RepoModel()
c.users_array = repo_model.get_users_js()
c.users_groups_array = repo_model.get_users_groups_js()
#47 implemented basic edition of groups
r1347 def __load_data(self, group_id):
"""
Load defaults settings for edit, and update
:param group_id:
"""
self.__load_defaults()
refactoring of models names for repoGroup permissions
r1633 repo_group = RepoGroup.get(group_id)
#47 implemented basic edition of groups
r1347
#47 added editing of groups, and moving them between. Added check constraint for groups...
r1349 data = repo_group.get_dict()
#47 implemented basic edition of groups
r1347
implements #226 repo groups available by path...
r1538 data['group_name'] = repo_group.name
#227 Initial version of repository groups permissions system...
r1982 # fill repository users
for p in repo_group.repo_group_to_perm:
data.update({'u_perm_%s' % p.user.username:
p.permission.permission_name})
# fill repository groups
for p in repo_group.users_group_to_perm:
data.update({'g_perm_%s' % p.users_group.users_group_name:
p.permission.permission_name})
#47 added editing of groups, and moving them between. Added check constraint for groups...
r1349 return data
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345
@HasPermissionAnyDecorator('hg.admin')
changes for #56
r1171 def index(self, format='html'):
"""GET /repos_groups: All items in the collection"""
# url('repos_groups')
added validation to repo groups to check for conflicting repository name fixes #337
r1898 sk = lambda g: g.parents[0].group_name if g.parents else g.group_name
refactoring of models names for repoGroup permissions
r1633 c.groups = sorted(RepoGroup.query().all(), key=sk)
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 return render('admin/repos_groups/repos_groups_show.html')
@HasPermissionAnyDecorator('hg.admin')
changes for #56
r1171 def create(self):
"""POST /repos_groups: Create a new item"""
# url('repos_groups')
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 self.__load_defaults()
added validation to repo groups to check for conflicting repository name fixes #337
r1898 repos_group_form = ReposGroupForm(available_groups =
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 c.repo_groups_choices)()
try:
form_result = repos_group_form.to_python(dict(request.POST))
#227 Initial version of repository groups permissions system...
r1982 ReposGroupModel().create(
group_name=form_result['group_name'],
group_description=form_result['group_description'],
parent=form_result['group_parent_id']
)
commit less models...
r1749 Session.commit()
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 h.flash(_('created repos group %s') \
#47 implemented basic edition of groups
r1347 % form_result['group_name'], category='success')
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 #TODO: in futureaction_logger(, '', '', '', self.sa)
except formencode.Invalid, errors:
changes for #56
r1171
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 return htmlfill.render(
render('admin/repos_groups/repos_groups_add.html'),
defaults=errors.value,
errors=errors.error_dict or {},
prefix_error=False,
encoding="UTF-8")
except Exception:
log.error(traceback.format_exc())
h.flash(_('error occurred during creation of repos group %s') \
#47 implemented basic edition of groups
r1347 % request.POST.get('group_name'), category='error')
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345
return redirect(url('repos_groups'))
@HasPermissionAnyDecorator('hg.admin')
changes for #56
r1171 def new(self, format='html'):
"""GET /repos_groups/new: Form to create a new item"""
# url('new_repos_group')
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 self.__load_defaults()
return render('admin/repos_groups/repos_groups_add.html')
changes for #56
r1171
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 @HasPermissionAnyDecorator('hg.admin')
changes for #56
r1171 def update(self, id):
"""PUT /repos_groups/id: Update an existing item"""
# Forms posted to this method should contain a hidden field:
# <input type="hidden" name="_method" value="PUT" />
# Or using helpers:
# h.form(url('repos_group', id=ID),
# method='put')
# url('repos_group', id=ID)
#47 implemented basic edition of groups
r1347 self.__load_defaults()
refactoring of models names for repoGroup permissions
r1633 c.repos_group = RepoGroup.get(id)
#47 implemented basic edition of groups
r1347
#227 Initial version of repository groups permissions system...
r1982 repos_group_form = ReposGroupForm(
edit=True,
old_data=c.repos_group.get_dict(),
available_groups=c.repo_groups_choices
)()
#47 implemented basic edition of groups
r1347 try:
form_result = repos_group_form.to_python(dict(request.POST))
another major refactoring with session management
r1734 ReposGroupModel().update(id, form_result)
commit less models...
r1749 Session.commit()
#47 implemented basic edition of groups
r1347 h.flash(_('updated repos group %s') \
% form_result['group_name'], category='success')
#TODO: in futureaction_logger(, '', '', '', self.sa)
except formencode.Invalid, errors:
return htmlfill.render(
render('admin/repos_groups/repos_groups_edit.html'),
defaults=errors.value,
errors=errors.error_dict or {},
prefix_error=False,
encoding="UTF-8")
except Exception:
log.error(traceback.format_exc())
#47 added editing of groups, and moving them between. Added check constraint for groups...
r1349 h.flash(_('error occurred during update of repos group %s') \
#47 implemented basic edition of groups
r1347 % request.POST.get('group_name'), category='error')
return redirect(url('repos_groups'))
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 @HasPermissionAnyDecorator('hg.admin')
changes for #56
r1171 def delete(self, id):
"""DELETE /repos_groups/id: Delete an existing item"""
# Forms posted to this method should contain a hidden field:
# <input type="hidden" name="_method" value="DELETE" />
# Or using helpers:
# h.form(url('repos_group', id=ID),
# method='delete')
# url('repos_group', id=ID)
refactoring of models names for repoGroup permissions
r1633 gr = RepoGroup.get(id)
#47 implemented deleting of empty groups. Fixed problem with full paths on nested groups
r1346 repos = gr.repositories.all()
if repos:
h.flash(_('This group contains %s repositores and cannot be '
'deleted' % len(repos)),
category='error')
return redirect(url('repos_groups'))
try:
another major refactoring with session management
r1734 ReposGroupModel().delete(id)
commit less models...
r1749 Session.commit()
#47 implemented deleting of empty groups. Fixed problem with full paths on nested groups
r1346 h.flash(_('removed repos group %s' % gr.group_name), category='success')
removed obsolete sort code
r1482 #TODO: in future action_logger(, '', '', '', self.sa)
Added friendly message about removing a group that still contains subgroups....
r1543 except IntegrityError, e:
Added handling of ignore whitespace flag in changesets...
r1752 if e.message.find('groups_group_parent_id_fkey') != -1:
Added friendly message about removing a group that still contains subgroups....
r1543 log.error(traceback.format_exc())
h.flash(_('Cannot delete this group it still contains '
'subgroups'),
category='warning')
else:
log.error(traceback.format_exc())
h.flash(_('error occurred during deletion of repos '
'group %s' % gr.group_name), category='error')
#47 implemented deleting of empty groups. Fixed problem with full paths on nested groups
r1346 except Exception:
log.error(traceback.format_exc())
Added friendly message about removing a group that still contains subgroups....
r1543 h.flash(_('error occurred during deletion of repos '
'group %s' % gr.group_name), category='error')
#47 implemented deleting of empty groups. Fixed problem with full paths on nested groups
r1346
return redirect(url('repos_groups'))
#227 Initial version of repository groups permissions system...
r1982 @HasReposGroupPermissionAnyDecorator('group.admin')
def delete_repos_group_user_perm(self, group_name):
"""
DELETE an existing repositories group permission user
:param group_name:
"""
try:
ReposGroupModel().revoke_user_permission(
repos_group=group_name, user=request.POST['user_id']
)
Session.commit()
except Exception:
log.error(traceback.format_exc())
h.flash(_('An error occurred during deletion of group user'),
category='error')
raise HTTPInternalServerError()
@HasReposGroupPermissionAnyDecorator('group.admin')
def delete_repos_group_users_group_perm(self, group_name):
"""
DELETE an existing repositories group permission users group
:param group_name:
"""
try:
ReposGroupModel().revoke_users_group_permission(
repos_group=group_name,
group_name=request.POST['users_group_id']
)
Session.commit()
except Exception:
log.error(traceback.format_exc())
h.flash(_('An error occurred during deletion of group'
' users groups'),
category='error')
raise HTTPInternalServerError()
implements #226 repo groups available by path...
r1538 def show_by_name(self, group_name):
refactoring of models names for repoGroup permissions
r1633 id_ = RepoGroup.get_by_group_name(group_name).group_id
implements #226 repo groups available by path...
r1538 return self.show(id_)
#227 Initial version of repository groups permissions system...
r1982 @HasReposGroupPermissionAnyDecorator('group.read', 'group.write',
'group.admin')
changes for #56
r1171 def show(self, id, format='html'):
"""GET /repos_groups/id: Show a specific item"""
# url('repos_group', id=ID)
refactoring of models names for repoGroup permissions
r1633 c.group = RepoGroup.get(id)
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366
Added repo group page showing what reposiories are inside a group
r1193 if c.group:
#47 implemented basic gui for browsing repo groups
r1343 c.group_repos = c.group.repositories.all()
Added repo group page showing what reposiories are inside a group
r1193 else:
fixed improper redirect for repos groups
r1394 return redirect(url('home'))
Added repo group page showing what reposiories are inside a group
r1193
#overwrite our cached list with current filter
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 gr_filter = c.group_repos
Added repo group page showing what reposiories are inside a group
r1193 c.cached_repo_list = self.scm_model.get_repos(all_repos=gr_filter)
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 c.repos_list = c.cached_repo_list
Added repo group page showing what reposiories are inside a group
r1193
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 c.repo_cnt = 0
#47 implemented basic gui for browsing repo groups
r1343
refactoring of models names for repoGroup permissions
r1633 c.groups = self.sa.query(RepoGroup).order_by(RepoGroup.group_name)\
.filter(RepoGroup.group_parent_id == id).all()
#47 implemented basic gui for browsing repo groups
r1343
Added repo group page showing what reposiories are inside a group
r1193 return render('admin/repos_groups/repos_groups.html')
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 @HasPermissionAnyDecorator('hg.admin')
changes for #56
r1171 def edit(self, id, format='html'):
"""GET /repos_groups/id/edit: Form to edit an existing item"""
# url('edit_repos_group', id=ID)
#47 added editing of groups, and moving them between. Added check constraint for groups...
r1349
removed obsolete sort code
r1482 id_ = int(id)
#47 added editing of groups, and moving them between. Added check constraint for groups...
r1349
refactoring of models names for repoGroup permissions
r1633 c.repos_group = RepoGroup.get(id_)
removed obsolete sort code
r1482 defaults = self.__load_data(id_)
#47 implemented basic edition of groups
r1347
#47 added editing of groups, and moving them between. Added check constraint for groups...
r1349 # we need to exclude this group from the group list for editing
#227 Initial version of repository groups permissions system...
r1982 c.repo_groups = filter(lambda x: x[0] != id_, c.repo_groups)
#47 added editing of groups, and moving them between. Added check constraint for groups...
r1349
#47 implemented basic edition of groups
r1347 return htmlfill.render(
render('admin/repos_groups/repos_groups_edit.html'),
defaults=defaults,
encoding="UTF-8",
force_defaults=False
)