changeset 3333:069884383cc7 beta

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
author Marcin Kuzminski <marcin@python-works.com>
date Tue, 05 Feb 2013 03:04:46 +0100
parents 92dfc033ee6f
children 968b28545f93
files rhodecode/controllers/admin/repos.py rhodecode/controllers/admin/settings.py rhodecode/templates/admin/repos/repo_add.html rhodecode/templates/admin/repos/repo_add_base.html rhodecode/templates/admin/repos/repo_add_create_repository.html rhodecode/templates/index_base.html
diffstat 6 files changed, 44 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/controllers/admin/repos.py	Tue Feb 05 01:57:37 2013 +0100
+++ b/rhodecode/controllers/admin/repos.py	Tue Feb 05 03:04:46 2013 +0100
@@ -28,7 +28,7 @@
 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 @@
 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 @@
     #     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 @@
 
         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 @@
             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 @@
                               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 @@
             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 @@
         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)
--- a/rhodecode/controllers/admin/settings.py	Tue Feb 05 01:57:37 2013 +0100
+++ b/rhodecode/controllers/admin/settings.py	Tue Feb 05 03:04:46 2013 +0100
@@ -37,7 +37,8 @@
 
 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.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 @@
         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 @@
         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 @@
             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,
--- a/rhodecode/templates/admin/repos/repo_add.html	Tue Feb 05 01:57:37 2013 +0100
+++ b/rhodecode/templates/admin/repos/repo_add.html	Tue Feb 05 03:04:46 2013 +0100
@@ -6,9 +6,15 @@
 </%def>
 
 <%def name="breadcrumbs_links()">
+    %if c.rhodecode_user.is_admin:
     ${h.link_to(_('Admin'),h.url('admin_home'))}
     &raquo;
     ${h.link_to(_('Repositories'),h.url('repos'))}
+    %else:
+    ${_('Admin')}
+    &raquo;
+    ${_('Repositories')}    
+    %endif
     &raquo;
     ${_('add new')}
 </%def>
--- a/rhodecode/templates/admin/repos/repo_add_base.html	Tue Feb 05 01:57:37 2013 +0100
+++ b/rhodecode/templates/admin/repos/repo_add_base.html	Tue Feb 05 03:04:46 2013 +0100
@@ -9,8 +9,8 @@
                 <label for="repo_name">${_('Name')}:</label>
             </div>
             <div class="input">
-                ${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
             </div>
--- a/rhodecode/templates/admin/repos/repo_add_create_repository.html	Tue Feb 05 01:57:37 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-## -*- coding: utf-8 -*-
-<%inherit file="/base/base.html"/>
-
-<%def name="title()">
-    ${_('Add repository')} - ${c.rhodecode_name}
-</%def>
-
-<%def name="breadcrumbs_links()">
-    ${_('add new repository')}
-</%def>
-
-<%def name="page_nav()">
-    ${self.menu('admin')}
-</%def>
-
-<%def name="main()">
-    <div class="box">
-        <!-- box / title -->
-        <div class="title">
-            ${self.breadcrumbs()}
-        </div>
-        <%include file="repo_add_base.html"/>
-    </div>
-</%def>
--- a/rhodecode/templates/index_base.html	Tue Feb 05 01:57:37 2013 +0100
+++ b/rhodecode/templates/index_base.html	Tue Feb 05 03:04:46 2013 +0100
@@ -7,12 +7,10 @@
             </h5>
             %if c.rhodecode_user.username != 'default':
               <ul class="links">
-                %if h.HasPermissionAny('hg.admin','hg.create.repository')():
+                %if h.HasPermissionAny('hg.admin','hg.create.repository')() or h.HasReposGroupPermissionAny('group.write', 'group.admin')(c.group.group_name if c.group else None):
                   <li>
                   %if c.group:
-                    %if h.HasReposGroupPermissionAny('group.write', 'group.admin')(c.group.group_name):
                         <span>${h.link_to(_('Add repository'),h.url('admin_settings_create_repository',parent_group=c.group.group_id))}</span>
-                    %endif
                   %else:
                     <span>${h.link_to(_('Add repository'),h.url('admin_settings_create_repository'))}</span>
                   %endif