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 @@ -27,14 +27,14 @@ import traceback import logging -from pylons.controllers.util import abort from rhodecode.controllers.api import JSONRPCController, JSONRPCError from rhodecode.lib.auth import PasswordGenerator, AuthUser, \ HasPermissionAllDecorator, HasPermissionAnyDecorator, \ HasPermissionAnyApi, HasRepoPermissionAnyApi from rhodecode.lib.utils import map_groups, repo2db_mapper -from rhodecode.lib.utils2 import str2bool +from rhodecode.lib.utils2 import str2bool, time_to_datetime, safe_int +from rhodecode.lib import helpers as h from rhodecode.model.meta import Session from rhodecode.model.scm import ScmModel from rhodecode.model.repo import RepoModel @@ -42,6 +42,7 @@ from rhodecode.model.user import UserMod from rhodecode.model.users_group import UserGroupModel from rhodecode.model.permission import PermissionModel from rhodecode.model.db import Repository, RhodeCodeSetting, UserIpMap +from rhodecode.lib.compat import json log = logging.getLogger(__name__) @@ -229,7 +230,8 @@ class ApiController(JSONRPCController): 'Error occurred during cache invalidation action' ) - def lock(self, apiuser, repoid, locked, userid=Optional(OAttr('apiuser'))): + def lock(self, apiuser, repoid, locked=Optional(None), + userid=Optional(OAttr('apiuser'))): """ Set locking state on particular repository by given user, if this command is runned by non-admin account userid is set to user @@ -257,21 +259,77 @@ class ApiController(JSONRPCController): if isinstance(userid, Optional): userid = apiuser.user_id + user = get_user_or_error(userid) - locked = str2bool(locked) - try: - if locked: - Repository.lock(repo, user.user_id) + + if isinstance(locked, Optional): + lockobj = Repository.getlock(repo) + + if lockobj[0] is None: + return ('Repo `%s` not locked. Locked=`False`.' + % (repo.repo_name)) else: - Repository.unlock(repo) + userid, time_ = lockobj + user = get_user_or_error(userid) + + return ('Repo `%s` locked by `%s`. Locked=`True`. ' + 'Locked since: `%s`' + % (repo.repo_name, user.username, + json.dumps(time_to_datetime(time_)))) + + else: + locked = str2bool(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 + ) - 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 - ) + def get_locks(self, apiuser, userid=Optional(OAttr('apiuser'))): + """ + Get all locks for given userid, if + this command is runned by non-admin account userid is set to user + who is calling this method, thus returning locks for himself + + :param apiuser: + :param userid: + """ + if HasPermissionAnyApi('hg.admin')(user=apiuser): + pass + else: + #make sure normal user does not pass someone else userid, + #he is not allowed to do that + if not isinstance(userid, Optional) and userid != apiuser.user_id: + raise JSONRPCError( + 'userid is not the same as your user' + ) + ret = [] + if isinstance(userid, Optional): + user = None + else: + user = get_user_or_error(userid) + + #show all locks + for r in Repository.getAll(): + userid, time_ = r.locked + if time_: + _api_data = r.get_api_data() + # if we use userfilter just show the locks for this user + if user: + if safe_int(userid) == user.user_id: + ret.append(_api_data) + else: + ret.append(_api_data) + + return ret @HasPermissionAllDecorator('hg.admin') def show_ip(self, apiuser, userid):