def test_remove_repo_detach_forks(self): repo = fixture.create_repo(name='test-repo-1') Session().commit() fork = fixture.create_fork(repo.repo_name, 'test-repo-fork-1') Session().commit() #fork of fork fixture.create_fork(fork.repo_name, 'test-repo-fork-fork-1') Session().commit() RepoModel().delete(repo=repo, forks='detach') Session().commit() try: self.assertEqual( None, Repository.get_by_repo_name(repo_name='test-repo-1')) self.assertNotEqual( None, Repository.get_by_repo_name(repo_name='test-repo-fork-1')) self.assertNotEqual( None, Repository.get_by_repo_name(repo_name='test-repo-fork-fork-1')) finally: RepoModel().delete(repo='test-repo-fork-fork-1') RepoModel().delete(repo='test-repo-fork-1') Session().commit()
def delete(self, repo_name): """ DELETE /repos/repo_name: 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('repo', repo_name=ID), # method='delete') # url('repo', repo_name=ID) repo_model = RepoModel() repo = repo_model.get_by_repo_name(repo_name) if not repo: h.not_mapped_error(repo_name) return redirect(url('repos')) try: action_logger(self.rhodecode_user, 'admin_deleted_repo', repo_name, self.ip_addr, self.sa) repo_model.delete(repo) invalidate_cache('get_repo_cached_%s' % repo_name) h.flash(_('deleted repository %s') % repo_name, category='success') Session().commit() except IntegrityError, e: if e.message.find('repositories_fork_id_fkey') != -1: log.error(traceback.format_exc()) h.flash(_('Cannot delete %s it still contains attached ' 'forks') % repo_name, category='warning') else: log.error(traceback.format_exc()) h.flash(_('An error occurred during ' 'deletion of %s') % repo_name, category='error')
def test_api_get_repo_nodes_by_regular_user(self, name, ret_type, grant_perm, backend): RepoModel().grant_user_permission(repo=backend.repo_name, user=self.TEST_USER_LOGIN, perm=grant_perm) Session().commit() commit_id = 'tip' path = '/' id_, params = build_data(self.apikey_regular, 'get_repo_nodes', repoid=backend.repo_name, revision=commit_id, root_path=path, ret_type=ret_type) response = api_call(self.app, params) # we don't the actual return types here since it's tested somewhere # else expected = response.json['result'] try: assert_ok(id_, expected, given=response.body) finally: RepoModel().revoke_user_permission(backend.repo_name, self.TEST_USER_LOGIN)
def delete(self, repo_name): """DELETE /repos/repo_name: 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('repo_settings_delete', repo_name=ID), # method='delete') # url('repo_settings_delete', repo_name=ID) repo_model = RepoModel() repo = repo_model.get_by_repo_name(repo_name) if not repo: h.flash(_('%s repository is not mapped to db perhaps' ' it was moved or renamed from the filesystem' ' please run the application again' ' in order to rescan repositories') % repo_name, category='error') return redirect(url('home')) try: action_logger(self.rhodecode_user, 'user_deleted_repo', repo_name, '', self.sa) repo_model.delete(repo) invalidate_cache('get_repo_cached_%s' % repo_name) h.flash(_('deleted repository %s') % repo_name, category='success') except Exception: log.error(traceback.format_exc()) h.flash(_('An error occurred during deletion of %s') % repo_name, category='error') return redirect(url('home'))
def __load_defaults(self): c.repo_groups = RepoGroup.groups_choices() c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) repo_model = RepoModel() c.users_array = repo_model.get_users_js() c.users_groups_array = repo_model.get_users_groups_js()
def delete(self, repo_name): """DELETE /repos/repo_name: 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('repo_settings_delete', repo_name=ID), # method='delete') # url('repo_settings_delete', repo_name=ID) repo_model = RepoModel() repo = repo_model.get_by_repo_name(repo_name) if not repo: h.not_mapped_error(repo_name) return redirect(url('home')) try: action_logger(self.rhodecode_user, 'user_deleted_repo', repo_name, self.ip_addr, self.sa) repo_model.delete(repo) invalidate_cache('get_repo_cached_%s' % repo_name) h.flash(_('deleted repository %s') % repo_name, category='success') Session().commit() except Exception: log.error(traceback.format_exc()) h.flash(_('An error occurred during deletion of %s') % repo_name, category='error') return redirect(url('admin_settings_my_account', anchor='my'))
def set_repo_perm_member(self, repo_name): form = RepoPermsForm()().to_python(request.POST) perms_new = form['perms_new'] perms_updates = form['perms_updates'] cur_repo = repo_name # update permissions for member, perm, member_type in perms_updates: if member_type == 'user': # this updates existing one RepoModel().grant_user_permission(repo=cur_repo, user=member, perm=perm) else: RepoModel().grant_users_group_permission(repo=cur_repo, group_name=member, perm=perm) # set new permissions for member, perm, member_type in perms_new: if member_type == 'user': RepoModel().grant_user_permission(repo=cur_repo, user=member, perm=perm) else: RepoModel().grant_users_group_permission(repo=cur_repo, group_name=member, perm=perm) #TODO: implement this #action_logger(self.rhodecode_user, 'admin_changed_repo_permissions', # repo_name, self.ip_addr, self.sa) Session().commit() h.flash(_('Repository permissions updated'), category='success') return redirect(url('edit_repo', repo_name=repo_name))
def delete(self, repo_name): """DELETE /repos/repo_name: 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('repo_settings_delete', repo_name=ID), # method='delete') # url('repo_settings_delete', repo_name=ID) repo_model = RepoModel() repo = repo_model.get_by_repo_name(repo_name) if not repo: h.flash(_('%s repository is not mapped to db perhaps' ' it was moved or renamed from the filesystem' ' please run the application again' ' in order to rescan repositories') % repo_name, category='error') return redirect(url('home')) try: action_logger(self.rhodecode_user, 'user_deleted_repo', repo_name, '', self.sa) repo_model.delete(repo) invalidate_cache('get_repo_cached_%s' % repo_name) h.flash(_('deleted repository %s') % repo_name, category='success') Session.commit() except Exception: log.error(traceback.format_exc()) h.flash(_('An error occurred during deletion of %s') % repo_name, category='error') return redirect(url('home'))
def __load_data(self, user_group_id): permissions = {'repositories': {}, 'repositories_groups': {}} ugroup_repo_perms = UserGroupRepoToPerm.query()\ .options(joinedload(UserGroupRepoToPerm.permission))\ .options(joinedload(UserGroupRepoToPerm.repository))\ .filter(UserGroupRepoToPerm.users_group_id == user_group_id)\ .all() for gr in ugroup_repo_perms: permissions['repositories'][gr.repository.repo_name] \ = gr.permission.permission_name ugroup_group_perms = UserGroupRepoGroupToPerm.query()\ .options(joinedload(UserGroupRepoGroupToPerm.permission))\ .options(joinedload(UserGroupRepoGroupToPerm.group))\ .filter(UserGroupRepoGroupToPerm.users_group_id == user_group_id)\ .all() for gr in ugroup_group_perms: permissions['repositories_groups'][gr.group.group_name] \ = gr.permission.permission_name c.permissions = permissions c.group_members_obj = sorted((x.user for x in c.users_group.members), key=lambda u: u.username.lower()) c.group_members = [(x.user_id, x.username) for x in c.group_members_obj] c.available_members = sorted( ((x.user_id, x.username) for x in User.query().all()), key=lambda u: u[1].lower()) repo_model = RepoModel() c.users_array = repo_model.get_users_js() c.users_groups_array = repo_model.get_users_groups_js() c.available_permissions = config['available_permissions']
def update(self, repo_name): repo_model = RepoModel() changed_name = repo_name self.__load_defaults() _form = RepoSettingsForm(edit=True, old_data={'repo_name': repo_name}, repo_groups=c.repo_groups_choices)() try: form_result = _form.to_python(dict(request.POST)) repo_model.update(repo_name, form_result) invalidate_cache('get_repo_cached_%s' % repo_name) h.flash(_('Repository %s updated successfully' % repo_name), category='success') changed_name = form_result['repo_name_full'] action_logger(self.rhodecode_user, 'user_updated_repo', changed_name, '', self.sa) Session.commit() except formencode.Invalid, errors: c.repo_info = repo_model.get_by_repo_name(repo_name) c.users_array = repo_model.get_users_js() errors.value.update({'user': c.repo_info.user.username}) return htmlfill.render( render('settings/repo_settings.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
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_defaults() repo_model = RepoModel() changed_name = repo_name _form = RepoForm(edit=True, old_data={'repo_name': repo_name}, repo_groups=c.repo_groups_choices)() try: form_result = _form.to_python(dict(request.POST)) repo = repo_model.update(repo_name, form_result) invalidate_cache('get_repo_cached_%s' % repo_name) h.flash(_('Repository %s updated successfully' % repo_name), category='success') changed_name = repo.repo_name action_logger(self.rhodecode_user, 'admin_updated_repo', changed_name, '', self.sa) Session.commit() except formencode.Invalid, 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")
def fork_create(self, repo_name): repo_model = RepoModel() c.repo_info = repo_model.get_by_repo_name(repo_name) _form = RepoForkForm(old_data={'repo_type': c.repo_info.repo_type})() form_result = {} try: form_result = _form.to_python(dict(request.POST)) form_result.update({'repo_name': repo_name}) repo_model.create_fork(form_result, self.rhodecode_user) h.flash(_('forked %s repository as %s') \ % (repo_name, form_result['fork_name']), category='success') action_logger(self.rhodecode_user, 'user_forked_repo:%s' % form_result['fork_name'], repo_name, '', self.sa) except formencode.Invalid, errors: c.new_repo = errors.value['fork_name'] r = render('settings/repo_fork.html') return htmlfill.render( r, defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def create_test_repo(force=True): print 'creating test repo' from rhodecode.model.repo import RepoModel sa = get_session() user = sa.query(User).filter(User.username == USER).scalar() if user is None: raise Exception('user not found') repo = sa.query(Repository).filter( Repository.repo_name == HG_REPO).scalar() if repo is None: print 'repo not found creating' form_data = { 'repo_name': HG_REPO, 'repo_type': 'hg', 'private': False, 'clone_uri': '' } rm = RepoModel(sa) rm.base_path = '/home/hg' rm.create(form_data, user) print 'done'
def update(self, repo_name): self.__load_defaults() repo_model = RepoModel() changed_name = repo_name #override the choices with extracted revisions ! choices, c.landing_revs = ScmModel().get_repo_landing_revs(repo_name) c.landing_revs_choices = choices _form = RepoSettingsForm(edit=True, old_data={'repo_name': repo_name}, repo_groups=c.repo_groups_choices, landing_revs=c.landing_revs_choices)() try: form_result = _form.to_python(dict(request.POST)) repo_model.update(repo_name, **form_result) invalidate_cache('get_repo_cached_%s' % repo_name) h.flash(_('Repository %s updated successfully') % repo_name, category='success') changed_name = form_result['repo_name_full'] action_logger(self.rhodecode_user, 'user_updated_repo', changed_name, self.ip_addr, self.sa) Session().commit() except formencode.Invalid, errors: defaults = self.__load_data(repo_name) defaults.update(errors.value) return htmlfill.render( render('settings/repo_settings.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def delete_repo_perm_member(self, repo_name): """ DELETE an existing repository permission user :param repo_name: """ try: obj_type = request.POST.get('obj_type') obj_id = None if obj_type == 'user': obj_id = safe_int(request.POST.get('user_id')) elif obj_type == 'user_group': obj_id = safe_int(request.POST.get('user_group_id')) if obj_type == 'user': RepoModel().revoke_user_permission(repo=repo_name, user=obj_id) elif obj_type == 'user_group': RepoModel().revoke_users_group_permission(repo=repo_name, group_name=obj_id) #TODO: implement this #action_logger(self.rhodecode_user, 'admin_revoked_repo_permissions', # repo_name, self.ip_addr, self.sa) Session().commit() except Exception: log.error(traceback.format_exc()) h.flash(_('An error occurred during revoking of permission'), category='error') raise HTTPInternalServerError()
def test_subgrouping_with_repo(self): g1 = _make_group('g1') g2 = _make_group('g2') # create new repo form_data = dict(repo_name='john', repo_name_full='john', fork_name=None, description=None, repo_group=None, private=False, repo_type='hg', clone_uri=None) cur_user = User.get_by_username(TEST_USER_ADMIN_LOGIN) r = RepoModel().create(form_data, cur_user) self.assertEqual(r.repo_name, 'john') # put repo into group form_data = form_data form_data['repo_group'] = g1.group_id form_data['perms_new'] = [] form_data['perms_updates'] = [] RepoModel().update(r.repo_name, form_data) self.assertEqual(r.repo_name, 'g1/john') self.__update_group(g1.group_id, 'g1', parent_id=g2.group_id) self.assertTrue(self.__check_path('g2', 'g1')) # test repo self.assertEqual(r.repo_name, RepoGroup.url_sep().join(['g2', 'g1', r.just_name]))
def tearDown(self): if self.r2_id: RepoModel().delete(self.r2_id) if self.r1_id: RepoModel().delete(self.r1_id) Session().commit() Session.remove()
def fork_repo(self, apiuser, repoid, fork_name, owner=Optional(OAttr('apiuser')), description=Optional(''), copy_permissions=Optional(False), private=Optional(False), landing_rev=Optional('tip')): repo = get_repo_or_error(repoid) repo_name = repo.repo_name _repo = RepoModel().get_by_repo_name(fork_name) if _repo: type_ = 'fork' if _repo.fork else 'repo' raise JSONRPCError("%s `%s` already exist" % (type_, fork_name)) if HasPermissionAnyApi('hg.admin')(user=apiuser): pass elif HasRepoPermissionAnyApi('repository.admin', 'repository.write', 'repository.read')(user=apiuser, repo_name=repo.repo_name): if not isinstance(owner, Optional): #forbid setting owner for non-admins raise JSONRPCError( 'Only RhodeCode admin can specify `owner` param' ) else: raise JSONRPCError('repository `%s` does not exist' % (repoid)) if isinstance(owner, Optional): owner = apiuser.user_id owner = get_user_or_error(owner) try: # create structure of groups and return the last group group = map_groups(fork_name) form_data = dict( repo_name=fork_name, repo_name_full=fork_name, repo_group=group, repo_type=repo.repo_type, description=Optional.extract(description), private=Optional.extract(private), copy_permissions=Optional.extract(copy_permissions), landing_rev=Optional.extract(landing_rev), update_after_clone=False, fork_parent_id=repo.repo_id, ) RepoModel().create_fork(form_data, cur_user=owner) return dict( msg='Created fork of `%s` as `%s`' % (repo.repo_name, fork_name), success=True # cannot return the repo data here since fork # cann be done async ) except Exception: log.error(traceback.format_exc()) raise JSONRPCError( 'failed to fork repository `%s` as `%s`' % (repo_name, fork_name) )
def show(self, repo_name, pull_request_id): repo_model = RepoModel() c.users_array = repo_model.get_users_js() c.users_groups_array = repo_model.get_users_groups_js() c.pull_request = PullRequest.get_or_404(pull_request_id) c.allowed_to_change_status = self._get_is_allowed_change_status(c.pull_request) cc_model = ChangesetCommentsModel() cs_model = ChangesetStatusModel() _cs_statuses = cs_model.get_statuses(c.pull_request.org_repo, pull_request=c.pull_request, with_revisions=True) cs_statuses = defaultdict(list) for st in _cs_statuses: cs_statuses[st.author.username] += [st] c.pull_request_reviewers = [] c.pull_request_pending_reviewers = [] for o in c.pull_request.reviewers: st = cs_statuses.get(o.user.username, None) if st: sorter = lambda k: k.version st = [(x, list(y)[0]) for x, y in (groupby(sorted(st, key=sorter), sorter))] else: c.pull_request_pending_reviewers.append(o.user) c.pull_request_reviewers.append([o.user, st]) # pull_requests repo_name we opened it against # ie. other_repo must match if repo_name != c.pull_request.other_repo.repo_name: raise HTTPNotFound # load compare data into template context enable_comments = not c.pull_request.is_closed() self._load_compare_data(c.pull_request, enable_comments=enable_comments) # inline comments c.inline_cnt = 0 c.inline_comments = cc_model.get_inline_comments( c.rhodecode_db_repo.repo_id, pull_request=pull_request_id) # count inline comments for __, lines in c.inline_comments: for comments in lines.values(): c.inline_cnt += len(comments) # comments c.comments = cc_model.get_comments(c.rhodecode_db_repo.repo_id, pull_request=pull_request_id) # (badly named) pull-request status calculation based on reviewer votes c.current_changeset_status = cs_model.calculate_status( c.pull_request_reviewers, ) c.changeset_statuses = ChangesetStatus.STATUSES c.as_form = False c.ancestor = None # there is one - but right here we don't know which return render('/pullrequests/pullrequest_show.html')
def show(self, repo_name, pull_request_id): repo_model = RepoModel() c.users_array = repo_model.get_users_js() c.users_groups_array = repo_model.get_users_groups_js() c.pull_request = PullRequest.get_or_404(pull_request_id) c.allowed_to_change_status = self._get_is_allowed_change_status( c.pull_request) cc_model = ChangesetCommentsModel() cs_model = ChangesetStatusModel() _cs_statuses = cs_model.get_statuses(c.pull_request.org_repo, pull_request=c.pull_request, with_revisions=True) cs_statuses = defaultdict(list) for st in _cs_statuses: cs_statuses[st.author.username] += [st] c.pull_request_reviewers = [] c.pull_request_pending_reviewers = [] for o in c.pull_request.reviewers: st = cs_statuses.get(o.user.username, None) if st: sorter = lambda k: k.version st = [(x, list(y)[0]) for x, y in (groupby(sorted(st, key=sorter), sorter))] else: c.pull_request_pending_reviewers.append(o.user) c.pull_request_reviewers.append([o.user, st]) # pull_requests repo_name we opened it against # ie. other_repo must match if repo_name != c.pull_request.other_repo.repo_name: raise HTTPNotFound # load compare data into template context enable_comments = not c.pull_request.is_closed() self._load_compare_data(c.pull_request, enable_comments=enable_comments) # inline comments c.inline_cnt = 0 c.inline_comments = cc_model.get_inline_comments( c.rhodecode_db_repo.repo_id, pull_request=pull_request_id) # count inline comments for __, lines in c.inline_comments: for comments in lines.values(): c.inline_cnt += len(comments) # comments c.comments = cc_model.get_comments(c.rhodecode_db_repo.repo_id, pull_request=pull_request_id) # (badly named) pull-request status calculation based on reviewer votes c.current_changeset_status = cs_model.calculate_status( c.pull_request_reviewers, ) c.changeset_statuses = ChangesetStatus.STATUSES c.as_form = False c.ancestor = None # there is one - but right here we don't know which return render('/pullrequests/pullrequest_show.html')
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): c.repo_groups = RepoGroup.groups_choices(check_perms=True) c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) repo_model = RepoModel() c.users_array = repo_model.get_users_js() c.users_groups_array = repo_model.get_users_groups_js() choices, c.landing_revs = ScmModel().get_repo_landing_revs() c.landing_revs_choices = choices
def __load_defaults(self): acl_groups = GroupList(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) repo_model = RepoModel() c.users_array = repo_model.get_users_js() c.users_groups_array = repo_model.get_users_groups_js() choices, c.landing_revs = ScmModel().get_repo_landing_revs() c.landing_revs_choices = choices
def test_create_fails_when_no_permissions(self, backend): data = self._prepare_data(backend) RepoModel().revoke_user_permission(self.source.repo_name, User.DEFAULT_USER) RepoModel().revoke_user_permission(self.source.repo_name, self.test_user) id_, params = build_data(self.apikey_regular, 'create_pull_request', **data) response = api_call(self.app, params) expected_message = 'repository `{}` does not exist'.format( self.source.repo_name) assert_error(id_, expected_message, given=response.body)
def action_logger(user, action, repo, ipaddr='', sa=None): """ Action logger for various actions made by users :param user: user that made this action, can be a unique username string or object containing user_id attribute :param action: action to log, should be on of predefined unique actions for easy translations :param repo: string name of repository or object containing repo_id, that action was made on :param ipaddr: optional ip address from what the action was made :param sa: optional sqlalchemy session """ if not sa: sa = meta.Session() try: um = UserModel() if hasattr(user, 'user_id'): user_obj = user elif isinstance(user, basestring): user_obj = um.get_by_username(user, cache=False) else: raise Exception('You have to provide user object or username') rm = RepoModel() if hasattr(repo, 'repo_id'): repo_obj = rm.get(repo.repo_id, cache=False) repo_name = repo_obj.repo_name elif isinstance(repo, basestring): repo_name = repo.lstrip('/') repo_obj = rm.get_by_repo_name(repo_name, cache=False) else: raise Exception('You have to provide repository to action logger') user_log = UserLog() user_log.user_id = user_obj.user_id user_log.action = action user_log.repository_id = repo_obj.repo_id user_log.repository_name = repo_name user_log.action_date = datetime.datetime.now() user_log.user_ip = ipaddr sa.add(user_log) sa.commit() log.info('Adding user %s, action %s on %s', user_obj, action, repo) except: log.error(traceback.format_exc()) sa.rollback()
def create_repo(self, apiuser, repo_name, owner, repo_type, description=Optional(''), private=Optional(False), clone_uri=Optional(None), landing_rev=Optional('tip')): """ Create repository, if clone_url is given it makes a remote clone if repo_name is withina group name the groups will be created automatically if they aren't present :param apiuser: :param repo_name: :param onwer: :param repo_type: :param description: :param private: :param clone_uri: :param landing_rev: """ owner = get_user_or_error(owner) if RepoModel().get_by_repo_name(repo_name): raise JSONRPCError("repo `%s` already exist" % repo_name) private = Optional.extract(private) clone_uri = Optional.extract(clone_uri) description = Optional.extract(description) landing_rev = Optional.extract(landing_rev) try: # create structure of groups and return the last group group = map_groups(repo_name) repo = RepoModel().create_repo( repo_name=repo_name, repo_type=repo_type, description=description, owner=owner, private=private, clone_uri=clone_uri, repos_group=group, landing_rev=landing_rev, ) Session().commit() return dict( msg="Created new repository `%s`" % (repo.repo_name), repo=repo.get_api_data() ) except Exception: log.error(traceback.format_exc()) raise JSONRPCError('failed to create repository `%s`' % repo_name)
def fork(self, repo_name): repo_model = RepoModel() c.repo_info = repo = repo_model.get_by_repo_name(repo_name) if not repo: h.flash(_('%s repository is not mapped to db perhaps' ' it was created or renamed from the file system' ' please run the application again' ' in order to rescan repositories') % repo_name, category='error') return redirect(url('home')) return render('settings/repo_fork.html')
def repo_stats(self, repo_name): """ DELETE an existing repository statistics :param repo_name: """ try: repo_model = RepoModel() repo_model.delete_stats(repo_name) except Exception, e: h.flash(_('An error occurred during deletion of repository stats'), category='error')
def test_manual_delete(self, autologin_user, backend, suffix, csrf_token): repo = backend.create_repo(name_suffix=suffix) repo_name = repo.repo_name # delete from file system RepoModel()._delete_filesystem_repo(repo) # test if the repo is still in the database new_repo = RepoModel().get_by_repo_name(repo_name) assert new_repo.repo_name == repo_name # check if repo is not in the filesystem assert not repo_on_filesystem(repo_name) self.assert_repo_not_found_redirect(repo_name)
def delete_perm_users_group(self, repo_name): """ DELETE an existing repository permission users group :param repo_name: """ try: repo_model = RepoModel() repo_model.delete_perm_users_group(request.POST, repo_name) except Exception, e: h.flash(_('An error occurred during deletion of repository' ' users groups'), category='error') raise HTTPInternalServerError()
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 check 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 sa = meta.Session rm = RepoModel() user = sa.query(User).filter(User.admin == True).first() if user is None: raise Exception('Missing administrative account !') added = [] for name, repo in initial_repo_list.items(): group = map_groups(name) if not rm.get_by_repo_name(name, cache=False): log.info('repository %s not found creating default' % name) added.append(name) form_data = { 'repo_name': name, 'repo_name_full': name, 'repo_type': repo.alias, 'description': repo.description \ if repo.description != 'unknown' else '%s repository' % name, 'private': False, 'group_id': getattr(group, 'group_id', None) } rm.create(form_data, user, just_db=True) sa.commit() 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) removed.append(repo.repo_name) sa.delete(repo) sa.commit() # clear cache keys log.debug("Clearing cache keys now...") CacheInvalidation.clear_cache() sa.commit() return added, removed
def get_repos(self, apiuser): """" Get all repositories :param apiuser: """ result = [] if HasPermissionAnyApi('hg.admin')(user=apiuser) is False: repos = RepoModel().get_all_user_repos(user=apiuser) else: repos = RepoModel().get_all() for repo in repos: result.append(repo.get_api_data()) return result
def test_per_repo_config_is_generated_during_filesystem_repo_creation( self, tmpdir, backend, use_global_config, repo_name_passed): repo_name = 'test-{}-repo-{}'.format(backend.alias, use_global_config) config = make_db_config() model = RepoModel() with mock.patch('rhodecode.model.repo.make_db_config') as config_mock: config_mock.return_value = config model._create_filesystem_repo(repo_name, backend.alias, repo_group='', clone_uri=None, use_global_config=use_global_config) expected_repo_name = repo_name if repo_name_passed else None expected_call = mock.call(clear_session=False, repo=expected_repo_name) assert expected_call in config_mock.call_args_list
def test_create_repo_with_extra_slashes_in_name(self, backend, user_util): existing_repo_group = user_util.create_repo_group() dirty_repo_name = '//{}/repo_name//'.format( existing_repo_group.group_name) cleaned_repo_name = '{}/repo_name'.format( existing_repo_group.group_name) id_, params = build_data( self.apikey, 'create_repo', repo_name=dirty_repo_name, repo_type=backend.alias, owner=TEST_USER_ADMIN_LOGIN, ) response = api_call(self.app, params) repo = RepoModel().get_by_repo_name(cleaned_repo_name) assert repo is not None expected = { 'msg': 'Created new repository `%s`' % (cleaned_repo_name, ), 'success': True, 'task': None, } assert_ok(id_, expected, given=response.body) fixture.destroy_repo(cleaned_repo_name)
def revoke_users_group_permission(self, apiuser, repo_name, group_name): """ Revoke permission for users group on given repository :param repo_name: :param group_name: """ try: repo = Repository.get_by_repo_name(repo_name) if repo is None: raise JSONRPCError('unknown repository %s' % repo) user_group = UsersGroup.get_by_group_name(group_name) if user_group is None: raise JSONRPCError('unknown users group %s' % user_group) RepoModel().revoke_users_group_permission(repo=repo_name, group_name=group_name) Session.commit() return dict( msg='Revoked perm for group: %s in repo: %s' % ( group_name, repo_name ) ) except Exception: log.error(traceback.format_exc()) raise JSONRPCError( 'failed to edit permission %(repo)s for %(usersgr)s' % dict( usersgr=group_name, repo=repo_name ) )
def test_api_create_repo_in_group(self, backend): repo_group_name = 'my_gr' # create the parent fixture.create_repo_group(repo_group_name) repo_name = '%s/api-repo-gr' % (repo_group_name, ) id_, params = build_data( self.apikey, 'create_repo', repo_name=repo_name, owner=TEST_USER_ADMIN_LOGIN, repo_type=backend.alias, ) response = api_call(self.app, params) repo = RepoModel().get_by_repo_name(repo_name) assert repo is not None assert repo.group is not None ret = { 'msg': 'Created new repository `%s`' % (repo_name, ), 'success': True, 'task': None, } expected = ret assert_ok(id_, expected, given=response.body) fixture.destroy_repo(repo_name) fixture.destroy_repo_group(repo_group_name)
def test_propagated_permission_from_users_group(self): # make group self.ug1 = UserGroupModel().create('G1') # add user to group UserGroupModel().add_user_to_group(self.ug1, self.u3) # grant perm for group this should override default permission from user new_perm_gr = 'repository.write' RepoModel().grant_users_group_permission(repo=HG_REPO, group_name=self.ug1, perm=new_perm_gr) # check perms u3_auth = AuthUser(user_id=self.u3.user_id) perms = { 'repositories_groups': {}, 'global': set([ u'hg.create.repository', u'repository.read', u'hg.register.manual_activate' ]), 'repositories': { u'vcs_test_hg': u'repository.read' } } self.assertEqual(u3_auth.permissions['repositories'][HG_REPO], new_perm_gr) self.assertEqual(u3_auth.permissions['repositories_groups'], perms['repositories_groups'])
def test_api_create_restricted_repo_type(self, backend): repo_name = 'api-repo-type-{0}'.format(backend.alias) id_, params = build_data( self.apikey, 'create_repo', repo_name=repo_name, owner=TEST_USER_ADMIN_LOGIN, repo_type=backend.alias, ) git_backend = settings.BACKENDS['git'] with mock.patch('rhodecode.lib.vcs.settings.BACKENDS', {'git': git_backend}): response = api_call(self.app, params) repo = RepoModel().get_by_repo_name(repo_name) if backend.alias == 'git': assert repo is not None expected = { 'msg': 'Created new repository `{0}`'.format(repo_name, ), 'success': True, 'task': None, } assert_ok(id_, expected, given=response.body) else: assert repo is None fixture.destroy_repo(repo_name)
def test_api_create_repo_with_booleans(self, backend): repo_name = 'api-repo-2' id_, params = build_data(self.apikey, 'create_repo', repo_name=repo_name, owner=TEST_USER_ADMIN_LOGIN, repo_type=backend.alias, enable_statistics=True, enable_locking=True, enable_downloads=True) response = api_call(self.app, params) repo = RepoModel().get_by_repo_name(repo_name) assert repo is not None ret = { 'msg': 'Created new repository `%s`' % (repo_name, ), 'success': True, 'task': None, } expected = ret assert_ok(id_, expected, given=response.body) id_, params = build_data(self.apikey, 'get_repo', repoid=repo_name) response = api_call(self.app, params) body = json.loads(response.body) assert body['result']['enable_downloads'] is True assert body['result']['enable_locking'] is True assert body['result']['enable_statistics'] is True fixture.destroy_repo(repo_name)
def fork_create(self, repo_name): self.__load_defaults() c.repo_info = Repository.get_by_repo_name(repo_name) _form = RepoForkForm(old_data={'repo_type': c.repo_info.repo_type}, repo_groups=c.repo_groups_choices, landing_revs=c.landing_revs_choices)() form_result = {} try: form_result = _form.to_python(dict(request.POST)) # an approximation that is better than nothing if not RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_UPDATE).ui_active: form_result['update_after_clone'] = False # create fork is done sometimes async on celery, db transaction # management is handled there. RepoModel().create_fork(form_result, self.rhodecode_user.user_id) fork_url = h.link_to( form_result['repo_name_full'], h.url('summary_home', repo_name=form_result['repo_name_full'])) h.flash(h.literal(_('Forked repository %s as %s') \ % (repo_name, fork_url)), category='success') except formencode.Invalid, errors: c.new_repo = errors.value['repo_name'] return htmlfill.render(render('forks/fork.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def show(self, group_name, format='html'): """GET /repos_groups/group_name: Show a specific item""" # url('repos_group', group_name=GROUP_NAME) c.group = c.repos_group = ReposGroupModel()._get_repo_group(group_name) c.group_repos = c.group.repositories.all() #overwrite our cached list with current filter gr_filter = c.group_repos c.repo_cnt = 0 groups = RepoGroup.query().order_by(RepoGroup.group_name)\ .filter(RepoGroup.group_parent_id == c.group.group_id).all() c.groups = self.scm_model.get_repos_groups(groups) c.repos_list = Repository.query()\ .filter(Repository.group_id == c.group.group_id)\ .order_by(func.lower(Repository.repo_name))\ .all() repos_data = RepoModel().get_repos_as_dict(repos_list=c.repos_list, admin=False) #json used to render the grid c.data = json.dumps(repos_data) return render('admin/repos_groups/repos_groups.html')
def step_14(self): # fix nullable columns on last_update for r in RepoModel().get_all(): if r.updated_on is None: r.updated_on = datetime.datetime.fromtimestamp(0) Session().add(r) Session().commit()
def command(self): logging.config.fileConfig(self.path_to_ini_file) #get SqlAlchemy session self._init_session() from pylons import config index_location = config['index_dir'] load_rcextensions(config['here']) repo_location = self.options.repo_location \ if self.options.repo_location else RepoModel().repos_path repo_list = map(strip, self.options.repo_list.split(',')) \ if self.options.repo_list else None repo_update_list = map(strip, self.options.repo_update_list.split(',')) \ if self.options.repo_update_list else None #====================================================================== # WHOOSH DAEMON #====================================================================== from rhodecode.lib.pidlock import LockHeld, DaemonLock from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon try: l = DaemonLock( file_=os.path.join(dn(dn(index_location)), 'make_index.lock')) WhooshIndexingDaemon(index_location=index_location, repo_location=repo_location, repo_list=repo_list, repo_update_list=repo_update_list)\ .run(full_index=self.options.full_index) l.release() except LockHeld: sys.exit(1)
def _prepare_data(self, backend, source_head='change', target_head='initial'): commits = [ { 'message': 'initial' }, { 'message': 'change' }, { 'message': 'new-feature', 'parents': ['initial'] }, ] self.commit_ids = backend.create_master_repo(commits) self.source = backend.create_repo(heads=[source_head]) self.target = backend.create_repo(heads=[target_head]) data = { 'source_repo': self.source.repo_name, 'target_repo': self.target.repo_name, 'source_ref': self._get_full_ref(backend, self.commit_ids[source_head]), 'target_ref': self._get_full_ref(backend, self.commit_ids[target_head]), 'title': 'Test PR 1', 'description': 'Test' } RepoModel().grant_user_permission(self.source.repo_name, self.TEST_USER_LOGIN, 'repository.read') return data
def test_api_create_repo(self): repo_name = 'api-repo' id_, params = _build_data(self.apikey, 'create_repo', repo_name=repo_name, owner=TEST_USER_ADMIN_LOGIN, repo_type='hg', ) response = api_call(self, params) repo = RepoModel().get_by_repo_name(repo_name) ret = { 'msg': 'Created new repository `%s`' % repo_name, 'repo': jsonify(repo.get_api_data()) } expected = ret self._compare_ok(id_, expected, given=response.body) destroy_repo(repo_name)
def __load_defaults(self): repo_model = RepoModel() c.repo_groups = [('', '')] parents_link = lambda k: h.literal('»'.join( map(lambda k: k.group_name, k.parents + [k]) ) ) c.repo_groups.extend([(x.group_id, parents_link(x)) for \ x in self.sa.query(Group).all()]) c.repo_groups = sorted(c.repo_groups, key=lambda t: t[1].split('»')[0]) c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) c.users_array = repo_model.get_users_js() c.users_groups_array = repo_model.get_users_groups_js()
def __load_defaults(self, allow_empty_group=False, exclude_group_ids=[]): if HasPermissionAll('hg.admin')('group edit'): #we're global admin, we're ok and we can create TOP level groups allow_empty_group = True #override the choices for this form, we need to filter choices #and display only those we have ADMIN right groups_with_admin_rights = RepoGroupList(RepoGroup.query().all(), perm_set=['group.admin']) c.repo_groups = RepoGroup.groups_choices(groups=groups_with_admin_rights, show_empty_group=allow_empty_group) # exclude filtered ids c.repo_groups = filter(lambda x: x[0] not in exclude_group_ids, c.repo_groups) c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) repo_model = RepoModel() c.users_array = repo_model.get_users_js() c.users_groups_array = repo_model.get_users_groups_js()
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_defaults() repo_model = RepoModel() changed_name = repo_name #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) 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)() 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(self.rhodecode_user, 'admin_updated_repo', changed_name, self.ip_addr, self.sa) Session().commit() except formencode.Invalid, 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")
def create_repo_fork(form_data, cur_user): from rhodecode.model.repo import RepoModel try: log = create_repo_fork.get_logger() except: log = logging.getLogger(__name__) repo_model = RepoModel(get_session()) repo_model.create(form_data, cur_user, just_db=True, fork=True) repo_name = form_data['repo_name'] repos_path = get_repos_path() repo_path = os.path.join(repos_path, repo_name) repo_fork_path = os.path.join(repos_path, form_data['fork_name']) alias = form_data['repo_type'] log.info('creating repo fork %s as %s', repo_name, repo_path) backend = get_backend(alias) backend(str(repo_fork_path), create=True, src_url=str(repo_path))
def command(self): # get SqlAlchemy session self._init_session() repo_update_list = ( map(string.strip, self.options.repo_update_list.split(",")) if self.options.repo_update_list else None ) if repo_update_list: repo_list = Repository.query().filter(Repository.repo_name.in_(repo_update_list)) else: repo_list = Repository.getAll() RepoModel.update_repoinfo(repositories=repo_list) Session().commit() if self.options.invalidate_cache: for r in repo_list: r.set_invalidate() log.info("Updated cache for %s repositories" % (len(repo_list)))
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 check 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 """ sa = meta.Session() rm = RepoModel() user = sa.query(User).filter(User.admin == True).first() added = [] # fixup groups paths to new format on the fly # TODO: remove this in future for g in Group.query().all(): g.group_name = g.get_new_name(g.name) sa.add(g) for name, repo in initial_repo_list.items(): group = map_groups(name.split(Repository.url_sep())) if not rm.get_by_repo_name(name, cache=False): log.info("repository %s not found creating default", name) added.append(name) form_data = { "repo_name": name, "repo_name_full": name, "repo_type": repo.alias, "description": repo.description if repo.description != "unknown" else "%s repository" % name, "private": False, "group_id": getattr(group, "group_id", None), } rm.create(form_data, user, just_db=True) 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(): removed.append(repo.repo_name) sa.delete(repo) sa.commit() return added, removed
def create(self): """ POST /repos: Create a new item""" # url('repos') repo_model = RepoModel() self.__load_defaults() form_result = {} try: form_result = RepoForm(repo_groups=c.repo_groups_choices)()\ .to_python(dict(request.POST)) repo_model.create(form_result, self.rhodecode_user) if form_result['clone_uri']: h.flash(_('created repository %s from %s') \ % (form_result['repo_name'], form_result['clone_uri']), category='success') else: h.flash(_('created repository %s') % form_result['repo_name'], category='success') if request.POST.get('user_created'): #created by regular non admin user action_logger(self.rhodecode_user, 'user_created_repo', form_result['repo_name_full'], '', self.sa) else: action_logger(self.rhodecode_user, 'admin_created_repo', form_result['repo_name_full'], '', self.sa) 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, defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def delete(self, repo_name): """ DELETE /repos/repo_name: 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('repo', repo_name=ID), # method='delete') # url('repo', repo_name=ID) repo_model = RepoModel() repo = repo_model.get_by_repo_name(repo_name) if not repo: h.not_mapped_error(repo_name) return redirect(url('repos')) try: _forks = repo.forks.count() handle_forks = None if _forks and request.POST.get('forks'): do = request.POST['forks'] if do == 'detach_forks': handle_forks = 'detach' h.flash(_('Detached %s forks') % _forks, category='success') elif do == 'delete_forks': handle_forks = 'delete' h.flash(_('Deleted %s forks') % _forks, category='success') repo_model.delete(repo, forks=handle_forks) action_logger(self.rhodecode_user, 'admin_deleted_repo', repo_name, self.ip_addr, self.sa) invalidate_cache('get_repo_cached_%s' % repo_name) h.flash(_('Deleted repository %s') % repo_name, category='success') Session().commit() except AttachedForksError: h.flash(_('Cannot delete %s it still contains attached forks') % repo_name, category='warning') except Exception: log.error(traceback.format_exc()) h.flash(_('An error occurred during deletion of %s') % repo_name, category='error') return redirect(url('repos'))
def create_test_repo(force=True): from rhodecode.model.repo import RepoModel user = User.get_by_username(USER) if user is None: raise Exception('user not found') repo = sa.query(Repository).filter(Repository.repo_name == HG_REPO).scalar() if repo is None: print '\trepo not found creating' form_data = {'repo_name':HG_REPO, 'repo_type':'hg', 'private':False, 'clone_uri':'' } rm = RepoModel(sa) rm.base_path = '/home/hg' rm.create(form_data, user)
def index(self, repo_name): repo_model = RepoModel() c.repo_info = repo = repo_model.get_by_repo_name(repo_name) if not repo: h.flash(_('%s repository is not mapped to db perhaps' ' it was created or renamed from the file system' ' please run the application again' ' in order to rescan repositories') % repo_name, category='error') return redirect(url('home')) c.users_array = repo_model.get_users_js() c.users_groups_array = repo_model.get_users_groups_js() defaults = c.repo_info.get_dict() #fill owner if c.repo_info.user: defaults.update({'user': c.repo_info.user.username}) else: replacement_user = self.sa.query(User)\ .filter(User.admin == True).first().username defaults.update({'user': replacement_user}) #fill repository users for p in c.repo_info.repo_to_perm: defaults.update({'u_perm_%s' % p.user.username: p.permission.permission_name}) #fill repository groups for p in c.repo_info.users_group_to_perm: defaults.update({'g_perm_%s' % p.users_group.users_group_name: p.permission.permission_name}) return htmlfill.render( render('settings/repo_settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False )
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 check 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 """ sa = meta.Session() rm = RepoModel() user = sa.query(User).filter(User.admin == True).first() added = [] for name, repo in initial_repo_list.items(): group = map_groups(name.split(os.sep)) if not rm.get_by_repo_name(name, cache=False): log.info('repository %s not found creating default', name) added.append(name) form_data = { 'repo_name': name, 'repo_name_full': name, 'repo_type': repo.alias, 'description': repo.description \ if repo.description != 'unknown' else \ '%s repository' % name, 'private': False, 'group_id': getattr(group, 'group_id', None) } rm.create(form_data, user, just_db=True) 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(): removed.append(repo.repo_name) sa.delete(repo) sa.commit() return added, removed
def create_repo_fork(form_data, cur_user): """ Creates a fork of repository using interval VCS methods :param form_data: :param cur_user: """ from rhodecode.model.repo import RepoModel log = get_logger(create_repo_fork) DBS = get_session() base_path = Repository.base_path() fork_repo = RepoModel(DBS).create(form_data, cur_user, just_db=True, fork=True) alias = form_data['repo_type'] org_repo_name = form_data['org_path'] fork_name = form_data['repo_name_full'] update_after_clone = form_data['update_after_clone'] source_repo_path = os.path.join(base_path, org_repo_name) destination_fork_path = os.path.join(base_path, fork_name) log.info('creating fork of %s as %s', source_repo_path, destination_fork_path) backend = get_backend(alias) backend(safe_str(destination_fork_path), create=True, src_url=safe_str(source_repo_path), update_after_clone=update_after_clone) log_create_repository(fork_repo.get_dict(), created_by=cur_user.username) action_logger(cur_user, 'user_forked_repo:%s' % fork_name, org_repo_name, '', DBS) action_logger(cur_user, 'user_created_fork:%s' % fork_name, fork_name, '', DBS) # finally commit at latest possible stage DBS.commit()