@@ -11,7 +11,7 @@ with JSON protocol both ways. An url to
<your_server>/_admin/api
All clients need to send JSON data in such format::
All clients are required to send JSON-RPC spec JSON data::
{
"api_key":"<api_key>",
@@ -32,7 +32,7 @@ Simply provide
api_key can be found in your user account page
RhodeCode API will return always a JSON formatted answer::
RhodeCode API will return always a JSON-RPC response::
"result": "<result>",
@@ -220,8 +220,8 @@ OUTPUT::
}
error: null
add_user_to_users_groups
------------------------
add_user_to_users_group
-----------------------
Adds a user to a users group. This command can be executed only using api_key
belonging to user with admin rights
@@ -299,14 +299,14 @@ OUTPUT::
"active" : "<bool>",
"admin" : "<bool>",
"ldap" : "<ldap_dn>",
"permission" : "repository_(read|write|admin)"
"permission" : "repository.(read|write|admin)"
},
…
"id" : "<usersgroupid>",
"name" : "<usersgroupname>",
"active": "<bool>",
]
@@ -353,10 +353,27 @@ INPUT::
args: {
"repo_name" : "<reponame>",
"user_name" : "<username>",
"perm" : "(None|repository_(read|write|admin))",
"perm" : "(None|repository.(read|write|admin))",
OUTPUT::
result: None
add_users_group_to_repo
Add a users group to a repository. This command can be executed only using
api_key belonging to user with admin rights. If "perm" is None, group will
be removed from the repository.
INPUT::
api_key : "<api_key>"
method : "add_users_group_to_repo"
"group_name" : "<groupname>",
\ No newline at end of file
@@ -36,7 +36,7 @@ from rhodecode.lib.compat import izip_lo
from paste.response import replace_header
from pylons.controllers import WSGIController
from pylons.controllers.util import Response
from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError, \
HTTPBadRequest, HTTPError
@@ -46,19 +46,26 @@ from rhodecode.lib.auth import AuthUser
log = logging.getLogger('JSONRPC')
class JSONRPCError(BaseException):
def __init__(self, message):
self.message = message
super(JSONRPCError, self).__init__()
def __str__(self):
return str(self.message)
def jsonrpc_error(message, code=None):
"""Generate a Response object with a JSON-RPC error body"""
return Response(body=json.dumps(dict(result=None,
error=message)))
"""
Generate a Response object with a JSON-RPC error body
resp = Response(body=json.dumps(dict(result=None, error=message)),
status=code,
content_type='application/json')
return resp
class JSONRPCController(WSGIController):
@@ -111,17 +118,20 @@ class JSONRPCController(WSGIController):
#check AUTH based on API KEY
try:
self._req_api_key = json_body['api_key']
self._req_id = json_body['id']
self._req_method = json_body['method']
self._req_params = json_body['args']
self._request_params = json_body['args']
log.debug('method: %s, params: %s',
self._req_method,
self._req_params)
self._request_params)
except KeyError, e:
return jsonrpc_error(message='Incorrect JSON query missing %s' % e)
#check if we can find this session using api_key
u = User.get_by_api_key(self._req_api_key)
if u is None:
return jsonrpc_error(message='Invalid API KEY')
auth_u = AuthUser(u.user_id, self._req_api_key)
except Exception, e:
@@ -136,10 +146,11 @@ class JSONRPCController(WSGIController):
# self.kargs and dispatch control to WGIController
argspec = inspect.getargspec(self._func)
arglist = argspec[0][1:]
defaults = argspec[3] or []
defaults = map(type, argspec[3] or [])
default_empty = types.NotImplementedType
kwarglist = list(izip_longest(reversed(arglist), reversed(defaults),
# kw arguments required by this method
func_kwargs = dict(izip_longest(reversed(arglist), reversed(defaults),
fillvalue=default_empty))
# this is little trick to inject logged in user for
@@ -157,7 +168,7 @@ class JSONRPCController(WSGIController):
(self._func.__name__, USER_SESSION_ATTR))
# get our arglist and check if we provided them as args
for arg, default in kwarglist:
for arg, default in func_kwargs.iteritems():
if arg == USER_SESSION_ATTR:
# USER_SESSION_ATTR is something translated from api key and
# this is checked before so we don't need validate it
@@ -165,13 +176,15 @@ class JSONRPCController(WSGIController):
# skip the required param check if it's default value is
# NotImplementedType (default_empty)
if not self._req_params or (type(default) == default_empty
and arg not in self._req_params):
return jsonrpc_error(message=('Missing non optional %s arg '
'in JSON DATA') % arg)
if (default == default_empty and arg not in self._request_params):
return jsonrpc_error(
message=(
'Missing non optional `%s` arg in JSON DATA' % arg
)
self._rpc_args = {USER_SESSION_ATTR:u}
self._rpc_args.update(self._req_params)
self._rpc_args.update(self._request_params)
self._rpc_args['action'] = self._req_method
self._rpc_args['environ'] = environ
@@ -180,6 +193,7 @@ class JSONRPCController(WSGIController):
status = []
headers = []
exc_info = []
def change_content(new_status, new_headers, new_exc_info=None):
status.append(new_status)
headers.extend(new_headers)
@@ -212,7 +226,8 @@ class JSONRPCController(WSGIController):
if self._error is not None:
raw_response = None
response = dict(result=raw_response, error=self._error)
response = dict(result=raw_response,
error=self._error)
return json.dumps(response)
@@ -6,8 +6,9 @@
repository permission model for RhodeCode
:created_on: Oct 1, 2011
:author: nvinot
:author: nvinot, marcink
:copyright: (C) 2011-2011 Nicolas Vinot <aeris@imirhil.fr>
:copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
:license: GPLv3, see COPYING for more details.
# This program is free software: you can redistribute it and/or modify
@@ -24,11 +25,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from rhodecode.model.db import BaseModel, RepoToPerm, Permission
from rhodecode.model.db import BaseModel, RepoToPerm, Permission,\
UsersGroupRepoToPerm
from rhodecode.model.meta import Session
log = logging.getLogger(__name__)
class RepositoryPermissionModel(BaseModel):
def get_user_permission(self, repository, user):
return RepoToPerm.query() \
@@ -56,8 +59,43 @@ class RepositoryPermissionModel(BaseMode
Session.delete(current)
Session.commit()
def get_users_group_permission(self, repository, users_group):
return UsersGroupRepoToPerm.query() \
.filter(UsersGroupRepoToPerm.users_group == users_group) \
.filter(UsersGroupRepoToPerm.repository == repository) \
.scalar()
def update_users_group_permission(self, repository, users_group,
permission):
permission = Permission.get_by_key(permission)
current = self.get_users_group_permission(repository, users_group)
if current:
if not current.permission is permission:
current.permission = permission
else:
p = UsersGroupRepoToPerm()
p.users_group = users_group
p.repository = repository
p.permission = permission
self.sa.add(p)
def delete_users_group_permission(self, repository, users_group):
self.sa.delete(current)
def update_or_delete_user_permission(self, repository, user, permission):
if permission:
self.update_user_permission(repository, user, permission)
self.delete_user_permission(repository, user)
def update_or_delete_users_group_permission(self, repository, user_group,
self.update_users_group_permission(repository, user_group,
permission)
self.delete_users_group_permission(repository, user_group)
Status change: