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 @@ -231,8 +231,10 @@ class ReposController(BaseController): #override the choices with extracted revisions ! choices, c.landing_revs = ScmModel().get_repo_landing_revs(repo_name) c.landing_revs_choices = choices - - _form = RepoForm(edit=True, old_data={'repo_name': repo_name}, + repo = Repository.get_by_repo_name(repo_name) + _form = RepoForm(edit=True, old_data={'repo_name': repo_name, + 'repo_group': repo.group.get_dict() \ + if repo.group else {}}, repo_groups=c.repo_groups_choices, landing_revs=c.landing_revs_choices)() try: diff --git a/rhodecode/controllers/settings.py b/rhodecode/controllers/settings.py --- a/rhodecode/controllers/settings.py +++ b/rhodecode/controllers/settings.py @@ -107,9 +107,11 @@ class SettingsController(BaseRepoControl #override the choices with extracted revisions ! choices, c.landing_revs = ScmModel().get_repo_landing_revs(repo_name) c.landing_revs_choices = choices - + repo = Repository.get_by_repo_name(repo_name) _form = RepoSettingsForm(edit=True, - old_data={'repo_name': repo_name}, + old_data={'repo_name': repo_name, + 'repo_group': repo.group.get_dict() \ + if repo.group else {}}, repo_groups=c.repo_groups_choices, landing_revs=c.landing_revs_choices)() try: diff --git a/rhodecode/model/forms.py b/rhodecode/model/forms.py --- a/rhodecode/model/forms.py +++ b/rhodecode/model/forms.py @@ -176,7 +176,7 @@ def RepoForm(edit=False, old_data={}, su filter_extra_fields = False repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), v.SlugifyName()) - repo_group = All(v.CanWriteGroup(), + repo_group = All(v.CanWriteGroup(old_data), v.OneOf(repo_groups, hideList=True)) repo_type = v.OneOf(supported_backends) repo_description = v.UnicodeString(strip=True, min=1, not_empty=False) @@ -205,7 +205,7 @@ def RepoSettingsForm(edit=False, old_dat filter_extra_fields = False repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), v.SlugifyName()) - repo_group = All(v.CanWriteGroup(), + repo_group = All(v.CanWriteGroup(old_data), v.OneOf(repo_groups, hideList=True)) repo_description = v.UnicodeString(strip=True, min=1, not_empty=False) repo_private = v.StringBoolean(if_missing=False) diff --git a/rhodecode/model/validators.py b/rhodecode/model/validators.py --- a/rhodecode/model/validators.py +++ b/rhodecode/model/validators.py @@ -16,11 +16,12 @@ from formencode.validators import ( from rhodecode.lib.compat import OrderedSet from rhodecode.lib import ipaddr from rhodecode.lib.utils import repo_name_slug +from rhodecode.lib.utils2 import safe_int from rhodecode.model.db import RepoGroup, Repository, UsersGroup, User,\ ChangesetStatus from rhodecode.lib.exceptions import LdapImportError from rhodecode.config.routing import ADMIN_PREFIX -from rhodecode.lib.auth import HasReposGroupPermissionAny +from rhodecode.lib.auth import HasReposGroupPermissionAny, HasPermissionAny # silence warnings and pylint UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set, \ @@ -472,7 +473,7 @@ def ValidForkType(old_data={}): return _validator -def CanWriteGroup(): +def CanWriteGroup(old_data=None): class _validator(formencode.validators.FancyValidator): messages = { 'permission_denied': _(u"You don't have permissions " @@ -481,13 +482,58 @@ def CanWriteGroup(): def validate_python(self, value, state): gr = RepoGroup.get(value) - if not HasReposGroupPermissionAny( - 'group.write', 'group.admin' - )(gr.group_name, 'get group of repo form'): + gr_name = gr.group_name if gr else None # None means ROOT location + val = HasReposGroupPermissionAny('group.write', 'group.admin') + can_create_repos = HasPermissionAny('hg.admin', 'hg.create.repository') + forbidden = not val(gr_name, 'can write into group validator') + value_changed = old_data['repo_group'].get('group_id') != safe_int(value) + if value_changed: # do check if we changed the value + #parent group need to be existing + if gr and forbidden: + msg = M(self, 'permission_denied', state) + raise formencode.Invalid(msg, value, state, + error_dict=dict(repo_type=msg) + ) + ## check if we can write to root location ! + elif gr is None and can_create_repos() is False: + msg = M(self, 'permission_denied_root', state) + raise formencode.Invalid(msg, value, state, + error_dict=dict(repo_type=msg) + ) + + return _validator + + +def CanCreateGroup(can_create_in_root=False): + class _validator(formencode.validators.FancyValidator): + messages = { + 'permission_denied': _(u"You don't have permissions " + "to create a group in this location") + } + + def to_python(self, value, state): + #root location + if value in [-1, "-1"]: + return None + return value + + def validate_python(self, value, state): + gr = RepoGroup.get(value) + gr_name = gr.group_name if gr else None # None means ROOT location + + if can_create_in_root and gr is None: + #we can create in root, we're fine no validations required + return + + forbidden_in_root = gr is None and can_create_in_root is False + val = HasReposGroupPermissionAny('group.admin') + forbidden = not val(gr_name, 'can create group validator') + if forbidden_in_root or forbidden: msg = M(self, 'permission_denied', state) raise formencode.Invalid(msg, value, state, - error_dict=dict(repo_type=msg) + error_dict=dict(group_parent_id=msg) ) + return _validator