# HG changeset patch # User Marcin Kuzminski # Date 2013-02-05 02:04:46 # Node ID 069884383cc794f290f03084a7034c956e0ad741 # Parent 92dfc033ee6f9dd32466adae61998368819c8927 Implemented #738 Giving a user WRITE+ permissions on folder should not allow repo creation in root folder. user can create repos only if he got explicitly permission for creating repos globally, or have WRITE+ permission on a group. Then he can create repositories inside this group diff --git a/rhodecode/controllers/admin/repos.py b/rhodecode/controllers/admin/repos.py --- a/rhodecode/controllers/admin/repos.py +++ b/rhodecode/controllers/admin/repos.py @@ -28,7 +28,7 @@ import traceback import formencode from formencode import htmlfill -from webob.exc import HTTPInternalServerError +from webob.exc import HTTPInternalServerError, HTTPForbidden from pylons import request, session, tmpl_context as c, url from pylons.controllers.util import redirect from pylons.i18n.translation import _ @@ -37,7 +37,8 @@ from sqlalchemy.exc import IntegrityErro import rhodecode from rhodecode.lib import helpers as h from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \ - HasPermissionAnyDecorator, HasRepoPermissionAllDecorator + HasPermissionAnyDecorator, HasRepoPermissionAllDecorator, NotAnonymous,\ + HasPermissionAny, HasReposGroupPermissionAny from rhodecode.lib.base import BaseRepoController, render from rhodecode.lib.utils import invalidate_cache, action_logger, repo_name_slug from rhodecode.lib.helpers import get_token @@ -61,7 +62,6 @@ class ReposController(BaseRepoController # map.resource('repo', 'repos') @LoginRequired() - @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository') def __before__(self): c.admin_user = session.get('admin_user') c.admin_username = session.get('admin_username') @@ -148,7 +148,7 @@ class ReposController(BaseRepoController return render('admin/repos/repos.html') - @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository') + @NotAnonymous() def create(self): """ POST /repos: Create a new item""" @@ -160,6 +160,20 @@ class ReposController(BaseRepoController form_result = RepoForm(repo_groups=c.repo_groups_choices, landing_revs=c.landing_revs_choices)()\ .to_python(dict(request.POST)) + #we check ACLs after form, since we want to display nicer errors + #if form forbids creation of repos inside a group we don't have + #perms for + if not HasPermissionAny('hg.admin', 'hg.create.repository')(): + #you're not super admin nor have global create permissions, + #but maybe you have at least write permission to a parent group ? + parent_group = request.POST.get('repo_group') + _gr = RepoGroup.get(parent_group) + gr_name = _gr.group_name if _gr else None + if not HasReposGroupPermissionAny('group.admin', 'group.write')(group_name=gr_name): + msg = _('no permission to create repository in root location') + raise formencode.Invalid('', form_result, None, + error_dict={'repo_group': msg}) + new_repo = RepoModel().create(form_result, self.rhodecode_user.user_id) if form_result['clone_uri']: @@ -181,16 +195,8 @@ class ReposController(BaseRepoController self.sa) Session().commit() except formencode.Invalid, errors: - - c.new_repo = errors.value['repo_name'] - - if request.POST.get('user_created'): - r = render('admin/repos/repo_add_create_repository.html') - else: - r = render('admin/repos/repo_add.html') - return htmlfill.render( - r, + render('admin/repos/repo_add.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, @@ -201,7 +207,9 @@ class ReposController(BaseRepoController msg = _('error occurred during creation of repository %s') \ % form_result.get('repo_name') h.flash(msg, category='error') - return redirect(url('repos')) + if c.rhodecode_user.is_admin: + return redirect(url('repos')) + return redirect(url('home')) #redirect to our new repo ! return redirect(url('summary_home', repo_name=new_repo.repo_name)) @@ -213,10 +221,7 @@ class ReposController(BaseRepoController GET /repos/new: Form to create a new item """ - new_repo = request.GET.get('repo', '') parent_group = request.GET.get('parent_group') - - c.new_repo = repo_name_slug(new_repo) self.__load_defaults() ## apply the defaults from defaults page defaults = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True) diff --git a/rhodecode/controllers/admin/settings.py b/rhodecode/controllers/admin/settings.py --- a/rhodecode/controllers/admin/settings.py +++ b/rhodecode/controllers/admin/settings.py @@ -37,7 +37,8 @@ from pylons.i18n.translation import _ from rhodecode.lib import helpers as h from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \ - HasPermissionAnyDecorator, NotAnonymous + HasPermissionAnyDecorator, NotAnonymous, HasPermissionAny,\ + HasReposGroupPermissionAll, HasReposGroupPermissionAny from rhodecode.lib.base import BaseController, render from rhodecode.lib.celerylib import tasks, run_task from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \ @@ -54,6 +55,7 @@ from rhodecode.model.notification import from rhodecode.model.meta import Session from rhodecode.lib.utils2 import str2bool, safe_unicode from rhodecode.lib.compat import json +from webob.exc import HTTPForbidden log = logging.getLogger(__name__) @@ -484,9 +486,17 @@ class SettingsController(BaseController) return render('admin/users/user_edit_my_account_pullrequests.html') @NotAnonymous() - @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository') def create_repository(self): """GET /_admin/create_repository: Form to create a new item""" + new_repo = request.GET.get('repo', '') + parent_group = request.GET.get('parent_group') + if not HasPermissionAny('hg.admin', 'hg.create.repository')(): + #you're not super admin nor have global create permissions, + #but maybe you have at least write permission to a parent group ? + _gr = RepoGroup.get(parent_group) + gr_name = _gr.group_name if _gr else None + if not HasReposGroupPermissionAny('group.admin', 'group.write')(group_name=gr_name): + raise HTTPForbidden acl_groups = GroupList(RepoGroup.query().all(), perm_set=['group.write', 'group.admin']) @@ -494,8 +504,6 @@ class SettingsController(BaseController) c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) choices, c.landing_revs = ScmModel().get_repo_landing_revs() - new_repo = request.GET.get('repo', '') - parent_group = request.GET.get('parent_group') c.new_repo = repo_name_slug(new_repo) ## apply the defaults from defaults page @@ -504,7 +512,7 @@ class SettingsController(BaseController) defaults.update({'repo_group': parent_group}) return htmlfill.render( - render('admin/repos/repo_add_create_repository.html'), + render('admin/repos/repo_add.html'), defaults=defaults, errors={}, prefix_error=False, diff --git a/rhodecode/templates/admin/repos/repo_add.html b/rhodecode/templates/admin/repos/repo_add.html --- a/rhodecode/templates/admin/repos/repo_add.html +++ b/rhodecode/templates/admin/repos/repo_add.html @@ -6,9 +6,15 @@ <%def name="breadcrumbs_links()"> + %if c.rhodecode_user.is_admin: ${h.link_to(_('Admin'),h.url('admin_home'))} » ${h.link_to(_('Repositories'),h.url('repos'))} + %else: + ${_('Admin')} + » + ${_('Repositories')} + %endif » ${_('add new')} diff --git a/rhodecode/templates/admin/repos/repo_add_base.html b/rhodecode/templates/admin/repos/repo_add_base.html --- a/rhodecode/templates/admin/repos/repo_add_base.html +++ b/rhodecode/templates/admin/repos/repo_add_base.html @@ -9,8 +9,8 @@
- ${h.text('repo_name',c.new_repo,class_="small")} - %if not h.HasPermissionAll('hg.admin')('repo create form'): + ${h.text('repo_name',class_="small")} + %if not c.rhodecode_user.is_admin: ${h.hidden('user_created',True)} %endif
diff --git a/rhodecode/templates/admin/repos/repo_add_create_repository.html b/rhodecode/templates/admin/repos/repo_add_create_repository.html deleted file mode 100644 --- a/rhodecode/templates/admin/repos/repo_add_create_repository.html +++ /dev/null @@ -1,24 +0,0 @@ -## -*- coding: utf-8 -*- -<%inherit file="/base/base.html"/> - -<%def name="title()"> - ${_('Add repository')} - ${c.rhodecode_name} - - -<%def name="breadcrumbs_links()"> - ${_('add new repository')} - - -<%def name="page_nav()"> - ${self.menu('admin')} - - -<%def name="main()"> -
- -
- ${self.breadcrumbs()} -
- <%include file="repo_add_base.html"/> -
- diff --git a/rhodecode/templates/index_base.html b/rhodecode/templates/index_base.html --- a/rhodecode/templates/index_base.html +++ b/rhodecode/templates/index_base.html @@ -7,12 +7,10 @@ %if c.rhodecode_user.username != 'default':