diff --git a/docs/api/api.rst b/docs/api/api.rst --- a/docs/api/api.rst +++ b/docs/api/api.rst @@ -152,6 +152,32 @@ OUTPUT:: error : null +lock +---- + +Set locking state on given repository by given user. +This command can be executed only using api_key belonging to user with admin +rights. + +INPUT:: + + id : + api_key : "" + method : "lock" + args : { + "repoid" : "" + "userid" : "", + "locked" : "" + + } + +OUTPUT:: + + id : + result : "User `` set lock state for repo `` to `true|false`" + error : null + + get_user -------- diff --git a/rhodecode/controllers/api/api.py b/rhodecode/controllers/api/api.py --- a/rhodecode/controllers/api/api.py +++ b/rhodecode/controllers/api/api.py @@ -38,6 +38,7 @@ from rhodecode.model.repo import RepoMod from rhodecode.model.user import UserModel from rhodecode.model.users_group import UsersGroupModel from rhodecode.model.permission import PermissionModel +from rhodecode.model.db import Repository log = logging.getLogger(__name__) @@ -180,7 +181,34 @@ class ApiController(JSONRPCController): except Exception: log.error(traceback.format_exc()) raise JSONRPCError( - 'Unable to rescan repositories' + 'Error occurred during rescan repositories action' + ) + + @HasPermissionAllDecorator('hg.admin') + def lock(self, apiuser, repoid, userid, locked): + """ + Set locking state on particular repository by given user + + :param apiuser: + :param repoid: + :param userid: + :param locked: + """ + repo = get_repo_or_error(repoid) + user = get_user_or_error(userid) + locked = bool(locked) + try: + if locked: + Repository.lock(repo, user.user_id) + else: + Repository.unlock(repo) + + return ('User `%s` set lock state for repo `%s` to `%s`' + % (user.username, repo.repo_name, locked)) + except Exception: + log.error(traceback.format_exc()) + raise JSONRPCError( + 'Error occurred locking repository `%s`' % repo.repo_name ) @HasPermissionAllDecorator('hg.admin') diff --git a/rhodecode/tests/api/api_base.py b/rhodecode/tests/api/api_base.py --- a/rhodecode/tests/api/api_base.py +++ b/rhodecode/tests/api/api_base.py @@ -10,6 +10,7 @@ from rhodecode.model.users_group import from rhodecode.model.repo import RepoModel from rhodecode.model.meta import Session from rhodecode.model.scm import ScmModel +from rhodecode.model.db import Repository API_URL = '/_admin/api' @@ -230,7 +231,41 @@ class BaseTestApi(object): response = self.app.post(API_URL, content_type='application/json', params=params) - expected = 'Unable to rescan repositories' + expected = 'Error occurred during rescan repositories action' + self._compare_error(id_, expected, given=response.body) + + def test_api_lock_repo_lock_aquire(self): + id_, params = _build_data(self.apikey, 'lock', + userid=TEST_USER_ADMIN_LOGIN, + repoid=self.REPO, + locked=True) + response = self.app.post(API_URL, content_type='application/json', + params=params) + expected = ('User `%s` set lock state for repo `%s` to `%s`' + % (TEST_USER_ADMIN_LOGIN, self.REPO, True)) + self._compare_ok(id_, expected, given=response.body) + + def test_api_lock_repo_lock_release(self): + id_, params = _build_data(self.apikey, 'lock', + userid=TEST_USER_ADMIN_LOGIN, + repoid=self.REPO, + locked=False) + response = self.app.post(API_URL, content_type='application/json', + params=params) + expected = ('User `%s` set lock state for repo `%s` to `%s`' + % (TEST_USER_ADMIN_LOGIN, self.REPO, False)) + self._compare_ok(id_, expected, given=response.body) + + @mock.patch.object(Repository, 'lock', crash) + def test_api_lock_error(self): + id_, params = _build_data(self.apikey, 'lock', + userid=TEST_USER_ADMIN_LOGIN, + repoid=self.REPO, + locked=True) + response = self.app.post(API_URL, content_type='application/json', + params=params) + + expected = 'Error occurred locking repository `%s`' % self.REPO self._compare_error(id_, expected, given=response.body) def test_api_create_existing_user(self):