def create_group(self, name, **kwargs): if 'skip_if_exists' in kwargs: del kwargs['skip_if_exists'] gr = RepoGroup.get_by_group_name(group_name=name) if gr: return gr form_data = self._get_group_create_params(group_name=name, **kwargs) owner = kwargs.get('cur_user', TEST_USER_ADMIN_LOGIN) gr = ReposGroupModel().create(group_name=form_data['group_name'], group_description=form_data['group_name'], owner=owner, parent=form_data['group_parent_id']) Session().commit() gr = RepoGroup.get_by_group_name(gr.group_name) return gr
def create_repo_group(self, name, **kwargs): if 'skip_if_exists' in kwargs: del kwargs['skip_if_exists'] gr = RepoGroup.get_by_group_name(group_name=name) if gr: return gr form_data = self._get_group_create_params(group_name=name, **kwargs) owner = kwargs.get('cur_user', TEST_USER_ADMIN_LOGIN) gr = RepoGroupModel().create( group_name=form_data['group_name'], group_description=form_data['group_name'], owner=owner) Session().commit() gr = RepoGroup.get_by_group_name(gr.group_name) return gr
def permissions_setup_func(group_name='g0', perm='group.read', recursive='all', user_id=None): """ Resets all permissions to perm attribute """ if not user_id: user_id = test_u1_id # called by the @with_setup decorator also reset the default user stuff permissions_setup_func(group_name, perm, recursive, user_id=User.get_default_user().user_id) # TODO: DRY, compare test_user_group:permissions_setup_func repo_group = RepoGroup.get_by_group_name(group_name=group_name) if not repo_group: raise Exception('Cannot get group %s' % group_name) perm_updates = [[user_id, perm, 'user']] RepoGroupModel().update_permissions(repo_group, perm_updates=perm_updates, recursive=recursive, check_perms=False) Session().commit()
def edit_advanced(self, user_id): user_id = safe_int(user_id) user = c.user = User.get_or_404(user_id) if user.username == User.DEFAULT_USER: h.flash(_("You can't edit this user"), category='warning') return redirect(url('users')) c.active = 'advanced' c.perm_user = AuthUser(user_id=user_id, ip_addr=self.ip_addr) c.personal_repo_group = RepoGroup.get_by_group_name(user.username) c.first_admin = User.get_first_super_admin() defaults = user.get_dict() # Interim workaround if the user participated on any pull requests as a # reviewer. has_review = bool(PullRequestReviewers.query().filter( PullRequestReviewers.user_id == user_id).first()) c.can_delete_user = not has_review c.can_delete_user_message = _( 'The user participates as reviewer in pull requests and ' 'cannot be deleted. You can set the user to ' '"inactive" instead of deleting it.') if has_review else '' return htmlfill.render(render('admin/users/user_edit.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def map_groups(path): """ Given a full path to a repository, create all nested groups that this repo is inside. This function creates parent-child relationships between groups and creates default perms for all new groups. :param paths: full path to repository """ sa = meta.Session() groups = path.split(Repository.url_sep()) parent = None group = None # last element is repo in nested groups structure groups = groups[:-1] rgm = ReposGroupModel(sa) for lvl, group_name in enumerate(groups): group_name = '/'.join(groups[:lvl] + [group_name]) group = RepoGroup.get_by_group_name(group_name) desc = '%s group' % group_name # skip folders that are now removed repos if REMOVED_REPO_PAT.match(group_name): break if group is None: log.debug('creating group level: %s group_name: %s' % (lvl, group_name)) group = RepoGroup(group_name, parent) group.group_description = desc sa.add(group) rgm._create_default_perms(group) sa.flush() parent = group return group
def test_update_group_parent(self): sg1 = _make_group('initial', parent_id=self.g1.group_id) new_sg1 = self.__update_group(sg1.group_id, 'after', parent_id=self.g1.group_id) self.assertTrue(self.__check_path('test1', 'after')) self.assertEqual(RepoGroup.get_by_group_name('test1/initial'), None) new_sg1 = self.__update_group(sg1.group_id, 'after', parent_id=self.g3.group_id) self.assertTrue(self.__check_path('test3', 'after')) self.assertEqual(RepoGroup.get_by_group_name('test3/initial'), None) new_sg1 = self.__update_group(sg1.group_id, 'hello') self.assertTrue(self.__check_path('hello')) self.assertEqual(RepoGroup.get_by_group_name('hello'), new_sg1)
def test_update_group_parent(self): sg1 = fixture.create_group("initial", group_parent_id=self.g1.group_id) new_sg1 = _update_group(sg1.group_id, "after", parent_id=self.g1.group_id) self.assertTrue(self.__check_path("test1", "after")) self.assertEqual(RepoGroup.get_by_group_name("test1/initial"), None) new_sg1 = _update_group(sg1.group_id, "after", parent_id=self.g3.group_id) self.assertTrue(self.__check_path("test3", "after")) self.assertEqual(RepoGroup.get_by_group_name("test3/initial"), None) new_sg1 = _update_group(sg1.group_id, "hello") self.assertTrue(self.__check_path("hello")) self.assertEqual(RepoGroup.get_by_group_name("hello"), new_sg1)
def validate_python(self, value, state): repo_name = value.get("repo_name") repo_name_full = value.get("repo_name_full") group_path = value.get("group_path") group_name = value.get("group_name") if repo_name in [ADMIN_PREFIX, ""]: msg = M(self, "invalid_repo_name", state, repo=repo_name) raise formencode.Invalid(msg, value, state, error_dict=dict(repo_name=msg)) rename = old_data.get("repo_name") != repo_name_full create = not edit if rename or create: if group_path != "": if Repository.get_by_repo_name(repo_name_full): msg = M(self, "repository_in_group_exists", state, repo=repo_name, group=group_name) raise formencode.Invalid(msg, value, state, error_dict=dict(repo_name=msg)) elif RepoGroup.get_by_group_name(repo_name_full): msg = M(self, "same_group_exists", state, repo=repo_name) raise formencode.Invalid(msg, value, state, error_dict=dict(repo_name=msg)) elif Repository.get_by_repo_name(repo_name_full): msg = M(self, "repository_exists", state, repo=repo_name) raise formencode.Invalid(msg, value, state, error_dict=dict(repo_name=msg)) return value
def test_update_group_parent(self): sg1 = fixture.create_repo_group('test1/initial') _update_group(sg1.group_id, 'after', parent_id=self.g1.group_id) assert self.__check_path('test1', 'after') assert RepoGroup.get_by_group_name('test1/initial') is None _update_group(sg1.group_id, 'after', parent_id=self.g3.group_id) assert self.__check_path('test3', 'after') assert RepoGroup.get_by_group_name('test3/initial') is None new_sg1 = _update_group(sg1.group_id, 'hello') assert self.__check_path('hello') assert RepoGroup.get_by_group_name('hello') == new_sg1
def create_personal_repo_group(self, user_id): """ Create personal repository group for this user :param user_id: """ from rhodecode.model.repo_group import RepoGroupModel user_id = safe_int(user_id) c.user = User.get_or_404(user_id) try: desc = RepoGroupModel.PERSONAL_GROUP_DESC % { 'username': c.user.username } if not RepoGroup.get_by_group_name(c.user.username): RepoGroupModel().create(group_name=c.user.username, group_description=desc, owner=c.user.username) msg = _('Created repository group `%s`' % (c.user.username, )) h.flash(msg, category='success') except Exception: log.exception("Exception during repository group creation") msg = _( 'An error occurred during repository group creation for user') h.flash(msg, category='error') return redirect(url('edit_user_advanced', user_id=user_id))
def _get_group_name_and_parent(self, group_name_full, repo_in_path=False): """ Get's the group name and a parent group name from given group name. If repo_in_path is set to truth, we asume the full path also includes repo name, in such case we clean the last element. :param group_name_full: """ split_paths = 1 if repo_in_path: split_paths = 2 _parts = group_name_full.rsplit(RepoGroup.url_sep(), split_paths) if repo_in_path and len(_parts) > 1: # such case last element is the repo_name _parts.pop(-1) group_name_cleaned = _parts[-1] # just the group name parent_repo_group_name = None if len(_parts) > 1: parent_repo_group_name = _parts[0] if parent_repo_group_name: parent_group = RepoGroup.get_by_group_name(parent_repo_group_name) return group_name_cleaned, parent_repo_group_name
def show_by_name(self, group_name): """ This is a proxy that does a lookup group_name -> id, and shows the group by id view instead """ group_name = group_name.rstrip('/') id_ = RepoGroup.get_by_group_name(group_name).group_id return self.show(id_)
def _make_group(path, desc='desc', parent_id=None, skip_if_exists=False): gr = RepoGroup.get_by_group_name(path) if gr and skip_if_exists: return gr gr = ReposGroupModel().create(path, desc, parent_id) return gr
def update(self, repo_name): """ PUT /repos/repo_name: 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('repo', repo_name=ID), # method='put') # url('repo', repo_name=ID) self.__load_data(repo_name) c.active = 'settings' c.repo_fields = RepositoryField.query()\ .filter(RepositoryField.repository == c.repo_info).all() repo_model = RepoModel() changed_name = repo_name # override the choices with extracted revisions ! c.personal_repo_group = RepoGroup.get_by_group_name( c.rhodecode_user.username) repo = Repository.get_by_repo_name(repo_name) old_data = { 'repo_name': repo_name, 'repo_group': repo.group.get_dict() if repo.group else {}, 'repo_type': repo.repo_type, } _form = RepoForm(edit=True, old_data=old_data, repo_groups=c.repo_groups_choices, landing_revs=c.landing_revs_choices, allow_disabled=True)() try: form_result = _form.to_python(dict(request.POST)) repo = repo_model.update(repo_name, **form_result) ScmModel().mark_for_invalidation(repo_name) h.flash(_('Repository %s updated successfully') % repo_name, category='success') changed_name = repo.repo_name action_logger(c.rhodecode_user, 'admin_updated_repo', changed_name, self.ip_addr, self.sa) Session().commit() except formencode.Invalid as errors: defaults = self.__load_data(repo_name) defaults.update(errors.value) return htmlfill.render(render('admin/repos/repo_edit.html'), defaults=defaults, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except Exception: log.exception("Exception during update of repository") h.flash(_('Error occurred during update of repository %s') \ % repo_name, category='error') return redirect(url('edit_repo', repo_name=changed_name))
def __load_defaults(self): acl_groups = RepoGroupList( RepoGroup.query().all(), perm_set=['group.write', 'group.admin']) c.repo_groups = RepoGroup.groups_choices(groups=acl_groups) c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) choices, c.landing_revs = ScmModel().get_repo_landing_revs() c.landing_revs_choices = choices c.personal_repo_group = RepoGroup.get_by_group_name( c.rhodecode_user.username)
def permissions_setup_func(group_name="g0", perm="group.read", recursive=True): """ Resets all permissions to perm attribute """ repos_group = RepoGroup.get_by_group_name(group_name=group_name) if not repos_group: raise Exception("Cannot get group %s" % group_name) perms_updates = [[test_u1_id, perm, "user"]] ReposGroupModel()._update_permissions(repos_group, perms_updates=perms_updates, recursive=recursive) Session().commit()
def _destroy_project_tree(test_u1_id): Session.remove() repos_group = RepoGroup.get_by_group_name(group_name='g0') for el in reversed(repos_group.recursive_groups_and_repos()): if isinstance(el, Repository): RepoModel().delete(el) elif isinstance(el, RepoGroup): ReposGroupModel().delete(el, force_delete=True) u = User.get(test_u1_id) Session().delete(u) Session().commit()
def permissions_setup_func(group_name='g0', perm='group.read', recursive=True): """ Resets all permissions to perm attribute """ repos_group = RepoGroup.get_by_group_name(group_name=group_name) if not repos_group: raise Exception('Cannot get group %s' % group_name) perms_updates = [[test_u2_gr_id, perm, 'users_group']] ReposGroupModel()._update_permissions(repos_group, perms_updates=perms_updates, recursive=recursive) Session().commit()
def permissions_setup_func(group_name='g0', perm='group.read', recursive=True): """ Resets all permissions to perm attribute """ repos_group = RepoGroup.get_by_group_name(group_name=group_name) if not repos_group: raise Exception('Cannot get group %s' % group_name) perms_updates = [[test_u1_id, perm, 'user']] ReposGroupModel()._update_permissions(repos_group, perms_updates=perms_updates, recursive=recursive) Session().commit()
def validate_python(self, value, state): repo_name = value.get('repo_name') repo_name_full = value.get('repo_name_full') group_path = value.get('group_path') group_name = value.get('group_name') if repo_name in [ADMIN_PREFIX, '']: msg = M(self, 'invalid_repo_name', state, repo=repo_name) raise formencode.Invalid( msg, value, state, error_dict={'repo_name': msg}) rename = old_data.get('repo_name') != repo_name_full create = not edit if rename or create: if group_path: if Repository.get_by_repo_name(repo_name_full): msg = M(self, 'repository_in_group_exists', state, repo=repo_name, group=group_name) raise formencode.Invalid( msg, value, state, error_dict={'repo_name': msg}) if RepoGroup.get_by_group_name(repo_name_full): msg = M(self, 'group_in_group_exists', state, repo=repo_name, group=group_name) raise formencode.Invalid( msg, value, state, error_dict={'repo_name': msg}) else: if RepoGroup.get_by_group_name(repo_name_full): msg = M(self, 'group_exists', state, repo=repo_name) raise formencode.Invalid( msg, value, state, error_dict={'repo_name': msg}) if Repository.get_by_repo_name(repo_name_full): msg = M( self, 'repository_exists', state, repo=repo_name) raise formencode.Invalid( msg, value, state, error_dict={'repo_name': msg}) return value
def to_python(self, value, state): repo_name = value.get('repo_name') slug = repo_name_slug(repo_name) if slug in [ADMIN_PREFIX, '']: e_dict = {'repo_name': _('This repository name is disallowed')} raise formencode.Invalid('', value, state, error_dict=e_dict) if value.get('repo_group'): gr = RepoGroup.get(value.get('repo_group')) group_path = gr.full_path # value needs to be aware of group name in order to check # db key This is an actual just the name to store in the # database repo_name_full = group_path + RepoGroup.url_sep() + repo_name else: group_path = '' repo_name_full = repo_name value['repo_name_full'] = repo_name_full rename = old_data.get('repo_name') != repo_name_full create = not edit if rename or create: if group_path != '': if Repository.get_by_repo_name(repo_name_full): e_dict = { 'repo_name': _('This repository already exists in ' 'a group "%s"') % gr.group_name } raise formencode.Invalid('', value, state, error_dict=e_dict) elif RepoGroup.get_by_group_name(repo_name_full): e_dict = { 'repo_name': _('There is a group with this name ' 'already "%s"') % repo_name_full } raise formencode.Invalid('', value, state, error_dict=e_dict) elif Repository.get_by_repo_name(repo_name_full): e_dict = {'repo_name': _('This repository ' 'already exists')} raise formencode.Invalid('', value, state, error_dict=e_dict) return value
def permissions_setup_func_orig(group_name='g0', perm='group.read', recursive='all'): """ Resets all permissions to perm attribute """ repo_group = RepoGroup.get_by_group_name(group_name=group_name) if not repo_group: raise Exception('Cannot get group %s' % group_name) perm_updates = [[test_u2_gr_id, perm, 'users_group']] RepoGroupModel().update_permissions(repo_group, perm_updates=perm_updates, recursive=recursive, check_perms=False) Session().commit()
def edit(self, repo_name): """GET /repo_name/settings: Form to edit an existing item""" # url('edit_repo', repo_name=ID) defaults = self.__load_data(repo_name) if 'clone_uri' in defaults: del defaults['clone_uri'] c.repo_fields = RepositoryField.query()\ .filter(RepositoryField.repository == c.repo_info).all() c.personal_repo_group = RepoGroup.get_by_group_name( c.rhodecode_user.username) c.active = 'settings' return htmlfill.render(render('admin/repos/repo_edit.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def permissions_setup_func(group_name='g0', perm='group.read', recursive=True, user_id=None): """ Resets all permissions to perm attribute """ if not user_id: user_id = test_u1_id repos_group = RepoGroup.get_by_group_name(group_name=group_name) if not repos_group: raise Exception('Cannot get group %s' % group_name) perms_updates = [[user_id, perm, 'user']] ReposGroupModel()._update_permissions(repos_group, perms_updates=perms_updates, recursive=recursive, check_perms=False) Session().commit()
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 # create repositories with write permission on group is set to true create_on_write = HasPermissionAny( 'hg.create.write_on_repogroup.true')() group_admin = HasRepoGroupPermissionAny('group.admin')( group_name=gr_name) group_write = HasRepoGroupPermissionAny('group.write')( group_name=gr_name) if not (group_admin or (group_write and create_on_write)): raise HTTPForbidden acl_groups = RepoGroupList(RepoGroup.query().all(), perm_set=['group.write', 'group.admin']) c.repo_groups = RepoGroup.groups_choices(groups=acl_groups) c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) choices, c.landing_revs = ScmModel().get_repo_landing_revs() c.personal_repo_group = RepoGroup.get_by_group_name( c.rhodecode_user.username) c.new_repo = repo_name_slug(new_repo) ## apply the defaults from defaults page defaults = SettingsModel().get_default_repo_settings(strip_prefix=True) # set checkbox to autochecked defaults['repo_copy_permissions'] = True if parent_group: defaults.update({'repo_group': parent_group}) return htmlfill.render(render('admin/repos/repo_add.html'), defaults=defaults, errors={}, prefix_error=False, encoding="UTF-8", force_defaults=False)
def create(self): """ POST /repos: Create a new item""" # url('repos') self.__load_defaults() form_result = {} task_id = None try: # CanWriteToGroup validators checks permissions of this POST form_result = RepoForm(repo_groups=c.repo_groups_choices, landing_revs=c.landing_revs_choices)()\ .to_python(dict(request.POST)) # create is done sometimes async on celery, db transaction # management is handled there. task = RepoModel().create(form_result, c.rhodecode_user.user_id) from celery.result import BaseAsyncResult if isinstance(task, BaseAsyncResult): task_id = task.task_id except formencode.Invalid as errors: c.personal_repo_group = RepoGroup.get_by_group_name( c.rhodecode_user.username) return htmlfill.render(render('admin/repos/repo_add.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except Exception as e: msg = self._log_creation_exception(e, form_result.get('repo_name')) h.flash(msg, category='error') return redirect(url('home')) return redirect( h.url('repo_creating_home', repo_name=form_result['repo_name_full'], task_id=task_id))
def validate_python(self, value, state): repo_name = value.get('repo_name') repo_name_full = value.get('repo_name_full') group_path = value.get('group_path') group_name = value.get('group_name') if repo_name in [ADMIN_PREFIX, '']: msg = M(self, 'invalid_repo_name', state, repo=repo_name) raise formencode.Invalid(msg, value, state, error_dict=dict(repo_name=msg) ) rename = old_data.get('repo_name') != repo_name_full create = not edit if rename or create: if group_path != '': if Repository.get_by_repo_name(repo_name_full): msg = M(self, 'repository_in_group_exists', state, repo=repo_name, group=group_name) raise formencode.Invalid(msg, value, state, error_dict=dict(repo_name=msg) ) elif RepoGroup.get_by_group_name(repo_name_full): msg = M(self, 'same_group_exists', state, repo=repo_name) raise formencode.Invalid(msg, value, state, error_dict=dict(repo_name=msg) ) elif Repository.get_by_repo_name(repo_name_full): msg = M(self, 'repository_exists', state, repo=repo_name) raise formencode.Invalid(msg, value, state, error_dict=dict(repo_name=msg) ) return value
def create(self, group_name, group_description, owner, just_db=False, copy_permissions=False, commit_early=True): (group_name_cleaned, parent_group_name) = RepoGroupModel()._get_group_name_and_parent(group_name) parent_group = None if parent_group_name: parent_group = self._get_repo_group(parent_group_name) # becase we are doing a cleanup, we need to check if such directory # already exists. If we don't do that we can accidentally delete existing # directory via cleanup that can cause data issues, since delete does a # folder rename to special syntax later cleanup functions can delete this cleanup_group = self.check_exist_filesystem(group_name, exc_on_failure=False) try: user = self._get_user(owner) new_repo_group = RepoGroup() new_repo_group.user = user new_repo_group.group_description = group_description or group_name new_repo_group.parent_group = parent_group new_repo_group.group_name = group_name self.sa.add(new_repo_group) # create an ADMIN permission for owner except if we're super admin, # later owner should go into the owner field of groups if not user.is_admin: self.grant_user_permission(repo_group=new_repo_group, user=owner, perm='group.admin') if parent_group and copy_permissions: # copy permissions from parent user_perms = UserRepoGroupToPerm.query() \ .filter(UserRepoGroupToPerm.group == parent_group).all() group_perms = UserGroupRepoGroupToPerm.query() \ .filter(UserGroupRepoGroupToPerm.group == parent_group).all() for perm in user_perms: # don't copy over the permission for user who is creating # this group, if he is not super admin he get's admin # permission set above if perm.user != user or user.is_admin: UserRepoGroupToPerm.create( perm.user, new_repo_group, perm.permission) for perm in group_perms: UserGroupRepoGroupToPerm.create( perm.users_group, new_repo_group, perm.permission) else: perm_obj = self._create_default_perms(new_repo_group) self.sa.add(perm_obj) # now commit the changes, earlier so we are sure everything is in # the database. if commit_early: self.sa.commit() if not just_db: self._create_group(new_repo_group.group_name) # trigger the post hook from rhodecode.lib.hooks_base import log_create_repository_group repo_group = RepoGroup.get_by_group_name(group_name) log_create_repository_group( created_by=user.username, **repo_group.get_dict()) return new_repo_group except Exception: self.sa.rollback() log.exception('Exception occurred when creating repository group, ' 'doing cleanup...') # rollback things manually ! repo_group = RepoGroup.get_by_group_name(group_name) if repo_group: RepoGroup.delete(repo_group.group_id) self.sa.commit() if cleanup_group: RepoGroupModel()._delete_filesystem_group(repo_group) raise
def expected_count(group_name, objects=False): repos_group = RepoGroup.get_by_group_name(group_name=group_name) objs = repos_group.recursive_groups_and_repos() if objects: return objs return len(objs)
def create_repo_group(request, apiuser, group_name, description=Optional(''), owner=Optional(OAttr('apiuser')), copy_permissions=Optional(False)): """ Creates a repository group. * If the repository group name contains "/", all the required repository groups will be created. For example "foo/bar/baz" will create |repo| groups "foo" and "bar" (with "foo" as parent). It will also create the "baz" repository with "bar" as |repo| group. This command can only be run using an |authtoken| with admin permissions. :param apiuser: This is filled automatically from the |authtoken|. :type apiuser: AuthUser :param group_name: Set the repository group name. :type group_name: str :param description: Set the |repo| group description. :type description: str :param owner: Set the |repo| group owner. :type owner: str :param copy_permissions: :type copy_permissions: Example output: .. code-block:: bash id : <id_given_in_input> result : { "msg": "Created new repo group `<repo_group_name>`" "repo_group": <repogroup_object> } error : null Example error output: .. code-block:: bash id : <id_given_in_input> result : null error : { failed to create repo group `<repogroupid>` } """ schema = RepoGroupSchema() try: data = schema.deserialize({ 'group_name': group_name }) except colander.Invalid as e: raise JSONRPCError("Validation failed: %s" % (e.asdict(),)) group_name = data['group_name'] if isinstance(owner, Optional): owner = apiuser.user_id group_description = Optional.extract(description) copy_permissions = Optional.extract(copy_permissions) # get by full name with parents, check if it already exist if RepoGroup.get_by_group_name(group_name): raise JSONRPCError("repo group `%s` already exist" % (group_name,)) (group_name_cleaned, parent_group_name) = RepoGroupModel()._get_group_name_and_parent( group_name) parent_group = None if parent_group_name: parent_group = get_repo_group_or_error(parent_group_name) if not HasPermissionAnyApi( 'hg.admin', 'hg.repogroup.create.true')(user=apiuser): # check if we have admin permission for this parent repo group ! # users without admin or hg.repogroup.create can only create other # groups in groups they own so this is a required, but can be empty parent_group = getattr(parent_group, 'group_name', '') _perms = ('group.admin',) if not HasRepoGroupPermissionAnyApi(*_perms)( user=apiuser, group_name=parent_group): raise JSONRPCForbidden() try: repo_group = RepoGroupModel().create( group_name=group_name, group_description=group_description, owner=owner, copy_permissions=copy_permissions) Session().commit() return { 'msg': 'Created new repo group `%s`' % group_name, 'repo_group': repo_group.get_api_data() } except Exception: log.exception("Exception occurred while trying create repo group") raise JSONRPCError( 'failed to create repo group `%s`' % (group_name,))
def test_rename_single_group(self): sg1 = fixture.create_repo_group('initial') _update_group(sg1.group_id, 'after') assert self.__check_path('after') assert RepoGroup.get_by_group_name('initial') is None
def test_rename_single_group(self): sg1 = fixture.create_group("initial") new_sg1 = _update_group(sg1.group_id, "after") self.assertTrue(self.__check_path("after")) self.assertEqual(RepoGroup.get_by_group_name("initial"), None)
def validate_python(self, value, state): old_group_name = None group_name = value.get('group_name') group_name_full = value.get('group_name_full') group_parent_id = safe_int(value.get('group_parent_id')) if group_parent_id == -1: group_parent_id = None group_obj = RepoGroup.get(old_data.get('group_id')) parent_group_changed = False if edit: old_group_name = group_obj.group_name old_group_parent_id = group_obj.group_parent_id if group_parent_id != old_group_parent_id: parent_group_changed = True # TODO: mikhail: the following if statement is not reached # since group_parent_id's OneOf validation fails before. # Can be removed. # check against setting a parent of self parent_of_self = ( old_data['group_id'] == group_parent_id if group_parent_id else False ) if parent_of_self: msg = M(self, 'group_parent_id', state) raise formencode.Invalid( msg, value, state, error_dict={'group_parent_id': msg} ) # group we're moving current group inside child_group = None if group_parent_id: child_group = RepoGroup.query().filter( RepoGroup.group_id == group_parent_id).scalar() # do a special check that we cannot move a group to one of # it's children if edit and child_group: parents = [x.group_id for x in child_group.parents] move_to_children = old_data['group_id'] in parents if move_to_children: msg = M(self, 'group_parent_id', state) raise formencode.Invalid( msg, value, state, error_dict={'group_parent_id': msg}) # Check if we have permission to store in the parent. # Only check if the parent group changed. if parent_group_changed: if child_group is None: if not can_create_in_root: msg = M(self, 'permission_denied_root', state) raise formencode.Invalid( msg, value, state, error_dict={'group_parent_id': msg}) else: valid = HasRepoGroupPermissionAny('group.admin') forbidden = not valid( child_group.group_name, 'can create group validator') if forbidden: msg = M(self, 'permission_denied', state) raise formencode.Invalid( msg, value, state, error_dict={'group_parent_id': msg}) # if we change the name or it's new group, check for existing names # or repositories with the same name if old_group_name != group_name_full or not edit: # check group gr = RepoGroup.get_by_group_name(group_name_full) if gr: msg = M(self, 'group_exists', state, group_name=group_name) raise formencode.Invalid( msg, value, state, error_dict={'group_name': msg}) # check for same repo repo = Repository.get_by_repo_name(group_name_full) if repo: msg = M(self, 'repo_exists', state, group_name=group_name) raise formencode.Invalid( msg, value, state, error_dict={'group_name': msg})
def repo2db_mapper(initial_repo_list, remove_obsolete=False): """ maps all repos given in initial_repo_list, non existing repositories are created, if remove_obsolete is True it also checks for db entries that are not in initial_repo_list and removes them. :param initial_repo_list: list of repositories found by scanning methods :param remove_obsolete: check for obsolete entries in database """ from rhodecode.model.repo import RepoModel from rhodecode.model.scm import ScmModel from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.settings import SettingsModel sa = meta.Session() repo_model = RepoModel() user = User.get_first_super_admin() added = [] # creation defaults defs = SettingsModel().get_default_repo_settings(strip_prefix=True) enable_statistics = defs.get('repo_enable_statistics') enable_locking = defs.get('repo_enable_locking') enable_downloads = defs.get('repo_enable_downloads') private = defs.get('repo_private') for name, repo in initial_repo_list.items(): group = map_groups(name) unicode_name = safe_unicode(name) db_repo = repo_model.get_by_repo_name(unicode_name) # found repo that is on filesystem not in RhodeCode database if not db_repo: log.info('repository %s not found, creating now', name) added.append(name) desc = (repo.description if repo.description != 'unknown' else '%s repository' % name) db_repo = repo_model._create_repo( repo_name=name, repo_type=repo.alias, description=desc, repo_group=getattr(group, 'group_id', None), owner=user, enable_locking=enable_locking, enable_downloads=enable_downloads, enable_statistics=enable_statistics, private=private, state=Repository.STATE_CREATED) sa.commit() # we added that repo just now, and make sure we updated server info if db_repo.repo_type == 'git': git_repo = db_repo.scm_instance() # update repository server-info log.debug('Running update server info') git_repo._update_server_info() db_repo.update_commit_cache() config = db_repo._config config.set('extensions', 'largefiles', '') ScmModel().install_hooks(db_repo.scm_instance(config=config), repo_type=db_repo.repo_type) removed = [] if remove_obsolete: # remove from database those repositories that are not in the filesystem for repo in sa.query(Repository).all(): if repo.repo_name not in initial_repo_list.keys(): log.debug("Removing non-existing repository found in db `%s`", repo.repo_name) try: RepoModel(sa).delete(repo, forks='detach', fs_remove=False) sa.commit() removed.append(repo.repo_name) except Exception: # don't hold further removals on error log.error(traceback.format_exc()) sa.rollback() def splitter(full_repo_name): _parts = full_repo_name.rsplit(RepoGroup.url_sep(), 1) gr_name = None if len(_parts) == 2: gr_name = _parts[0] return gr_name initial_repo_group_list = [ splitter(x) for x in initial_repo_list.keys() if splitter(x) ] # remove from database those repository groups that are not in the # filesystem due to parent child relationships we need to delete them # in a specific order of most nested first all_groups = [x.group_name for x in sa.query(RepoGroup).all()] nested_sort = lambda gr: len(gr.split('/')) for group_name in sorted(all_groups, key=nested_sort, reverse=True): if group_name not in initial_repo_group_list: repo_group = RepoGroup.get_by_group_name(group_name) if (repo_group.children.all() or not RepoGroupModel().check_exist_filesystem( group_name=group_name, exc_on_failure=False)): continue log.info( 'Removing non-existing repository group found in db `%s`', group_name) try: RepoGroupModel(sa).delete(group_name, fs_remove=False) sa.commit() removed.append(group_name) except Exception: # don't hold further removals on error log.exception('Unable to remove repository group `%s`', group_name) sa.rollback() raise return added, removed
def test_rename_single_group(self): sg1 = _make_group('initial') new_sg1 = self.__update_group(sg1.group_id, 'after') self.assertTrue(self.__check_path('after')) self.assertEqual(RepoGroup.get_by_group_name('initial'), None)