@@ -1630,99 +1630,100 @@ class ApiController(JSONRPCController):
"private": "<bool>",
"landing_rev": "<landing_rev>"
}
OUTPUT::
id : <id_given_in_input>
result: {
"msg": "Created fork of `<reponame>` as `<forkname>`",
"success": true,
"task": "<celery task id or None if done sync>"
error: null
"""
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 Kallithea admin can specify `owner` param'
)
if not HasPermissionAnyApi('hg.create.repository')(user=apiuser):
raise JSONRPCError('no permission to create repositories')
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)
fork_base_name = fork_name.rsplit('/', 1)[-1]
form_data = dict(
repo_name=fork_name,
repo_name=fork_base_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,
task = RepoModel().create_fork(form_data, cur_user=owner)
# no commit, it's done in RepoModel, or async via celery
from celery.result import BaseAsyncResult
task_id = None
if isinstance(task, BaseAsyncResult):
task_id = task.task_id
return dict(
msg='Created fork of `%s` as `%s`' % (repo.repo_name,
fork_name),
success=True, # cannot return the repo data here since fork
# can be done async
task=task_id
except Exception:
log.error(traceback.format_exc())
'failed to fork repository `%s` as `%s`' % (repo_name,
fork_name)
# permission check inside
def delete_repo(self, apiuser, repoid, forks=Optional('')):
Deletes a repository. This command can be executed only using api_key belonging
to user with admin rights or regular user that have admin access to repository.
When `forks` param is set it's possible to detach or delete forks of deleting
repository
:param apiuser: filled automatically from apikey
:type apiuser: AuthUser
:param repoid: repository name or repository id
:type repoid: str or int
:param forks: `detach` or `delete`, what do do with attached forks for repo
:type forks: Optional(str)
@@ -1346,98 +1346,101 @@ class _BaseTestApi(object):
finally:
fixture.destroy_repo(repo_name)
def test_api_delete_repo_by_non_admin_no_permission(self):
repo_name = 'api_delete_me'
fixture.create_repo(repo_name, repo_type=self.REPO_TYPE)
id_, params = _build_data(self.apikey_regular, 'delete_repo',
repoid=repo_name, )
response = api_call(self, params)
expected = 'repository `%s` does not exist' % (repo_name)
self._compare_error(id_, expected, given=response.body)
def test_api_delete_repo_exception_occurred(self):
with mock.patch.object(RepoModel, 'delete', crash):
id_, params = _build_data(self.apikey, 'delete_repo',
expected = 'failed to delete repository `%s`' % repo_name
def test_api_fork_repo(self):
fork_name = 'api-repo-fork'
id_, params = _build_data(self.apikey, 'fork_repo',
repoid=self.REPO,
fork_name=fork_name,
owner=TEST_USER_ADMIN_LOGIN,
ret = {
'msg': 'Created fork of `%s` as `%s`' % (self.REPO,
'success': True,
'task': None,
expected = ret
self._compare_ok(id_, expected, given=response.body)
fixture.destroy_repo(fork_name)
def test_api_fork_repo_non_admin(self):
@parameterized.expand([
(u'api-repo-fork',),
(u'%s/api-repo-fork' % TEST_REPO_GROUP,),
])
def test_api_fork_repo_non_admin(self, fork_name):
id_, params = _build_data(self.apikey_regular, 'fork_repo',
def test_api_fork_repo_non_admin_specify_owner(self):
expected = 'Only Kallithea admin can specify `owner` param'
def test_api_fork_repo_non_admin_no_permission_to_fork(self):
RepoModel().grant_user_permission(repo=self.REPO,
user=self.TEST_USER_LOGIN,
perm='repository.none')
expected = 'repository `%s` does not exist' % (self.REPO)
@parameterized.expand([('read', 'repository.read'),
('write', 'repository.write'),
('admin', 'repository.admin')])
def test_api_fork_repo_non_admin_no_create_repo_permission(self, name, perm):
# regardless of base repository permission, forking is disallowed
Status change: