##// END OF EJS Templates
Extended API...
marcink -
r1500:256e729a beta
parent child Browse files
Show More
@@ -6,12 +6,12 b' API'
6
6
7
7
8 Starting from RhodeCode version 1.2 a simple API was implemented.
8 Starting from RhodeCode version 1.2 a simple API was implemented.
9 There's one schema for calling all api methods. API is implemented
9 There's a single schema for calling all api methods. API is implemented
10 with JSON protocol both ways. An url to send API request in RhodeCode is
10 with JSON protocol both ways. An url to send API request in RhodeCode is
11 <your-server>/_admin/api
11 <your_server>/_admin/api
12
12
13
13
14 Clients need to send JSON data in such format::
14 All clients need to send JSON data in such format::
15
15
16 {
16 {
17 "api_key":"<api_key>",
17 "api_key":"<api_key>",
@@ -19,16 +19,20 b' Clients need to send JSON data in such f'
19 "args":{"<arg_key>":"<arg_val>"}
19 "args":{"<arg_key>":"<arg_val>"}
20 }
20 }
21
21
22 Simply provide api_key for access and permission validation
22 Example call for autopulling remotes repos using curl::
23 method is name of method to call
23 curl https://server.com/_admin/api -X POST -H 'content-type:text/plain' --data-binary '{"api_key":"xe7cdb2v278e4evbdf5vs04v832v0efvcbcve4a3","method":"pull","args":{"repo":"CPython"}}'
24 and args is an key:value list of arguments to pass to method
24
25 Simply provide
26 - *api_key* for access and permission validation.
27 - *method* is name of method to call
28 - *args* is an key:value list of arguments to pass to method
25
29
26 .. note::
30 .. note::
27
31
28 api_key can be found in your user account page
32 api_key can be found in your user account page
29
33
30
34
31 And will receive JSON formatted answer::
35 RhodeCode API will return always a JSON formatted answer::
32
36
33 {
37 {
34 "result": "<result>",
38 "result": "<result>",
@@ -36,7 +40,7 b' And will receive JSON formatted answer::'
36 }
40 }
37
41
38 All responses from API will be `HTTP/1.0 200 OK`, if there's an error while
42 All responses from API will be `HTTP/1.0 200 OK`, if there's an error while
39 calling api **error** key from response will contain failure description
43 calling api *error* key from response will contain failure description
40 and result will be null.
44 and result will be null.
41
45
42 API METHODS
46 API METHODS
@@ -47,11 +51,61 b' pull'
47 ----
51 ----
48
52
49 Pulls given repo from remote location. Can be used to automatically keep
53 Pulls given repo from remote location. Can be used to automatically keep
50 remote repos upto date. This command can be executed only using admin users
54 remote repos up to date. This command can be executed only using api_key
51 api_key
55 belonging to user with admin rights
52
56
53 ::
57 INPUT::
58
54 api_key:"<api_key>"
59 api_key:"<api_key>"
55 method: "pull"
60 method: "pull"
56 args: {"repo":<repo_name>}
61 args: {"repo":<repo_name>}
57
62
63 OUTPUT::
64
65 result:"Pulled from <repo_name>"
66 error:null
67
68
69 create_user
70 -----------
71
72 Creates new user in RhodeCode. This command can be executed only using api_key
73 belonging to user with admin rights
74
75 INPUT::
76
77 api_key:"<api_key>"
78 method: "create_user"
79 args: {"username": "<username>",
80 "password": "<password>",
81 "active": "<bool>",
82 "admin": "<bool>",
83 "name": "<firstname>",
84 "lastname": "<lastname>",
85 "email": "<useremail>"}
86
87 OUTPUT::
88
89 result:{"id": <newuserid>,
90 "msg":"created new user <username>"}
91 error:null
92
93
94 create_users_group
95 ------------------
96
97 creates new users group. This command can be executed only using api_key
98 belonging to user with admin rights
99
100 INPUT::
101
102 api_key:"<api_key>"
103 method: "create_user"
104 args: {"name": "<groupname>",
105 "active":"<bool>"}
106
107 OUTPUT::
108
109 result:{"id": <newusersgroupid>,
110 "msg":"created new users group <groupname>"}
111 error:null
@@ -136,25 +136,29 b' class JSONRPCController(WSGIController):'
136
136
137 # this is little trick to inject logged in user for
137 # this is little trick to inject logged in user for
138 # perms decorators to work they expect the controller class to have
138 # perms decorators to work they expect the controller class to have
139 # rhodecode_user set
139 # rhodecode_user attribute set
140 self.rhodecode_user = auth_u
140 self.rhodecode_user = auth_u
141
141
142 if 'user' not in arglist:
142 # This attribute will need to be first param of a method that uses
143 # api_key, which is translated to instance of user at that name
144 USER_SESSION_ATTR = 'apiuser'
145
146 if USER_SESSION_ATTR not in arglist:
143 return jsonrpc_error(message='This method [%s] does not support '
147 return jsonrpc_error(message='This method [%s] does not support '
144 'authentication (missing user param)' %
148 'authentication (missing %s param)' %
145 self._func.__name__)
149 (self._func.__name__, USER_SESSION_ATTR))
146
150
147 # get our arglist and check if we provided them as args
151 # get our arglist and check if we provided them as args
148 for arg in arglist:
152 for arg in arglist:
149 if arg == 'user':
153 if arg == USER_SESSION_ATTR:
150 # user is something translated from api key and this is
154 # USER_SESSION_ATTR is something translated from api key and
151 # checked before
155 # this is checked before so we don't need validate it
152 continue
156 continue
153
157
154 if not self._req_params or arg not in self._req_params:
158 if not self._req_params or arg not in self._req_params:
155 return jsonrpc_error(message='Missing %s arg in JSON DATA' % arg)
159 return jsonrpc_error(message='Missing %s arg in JSON DATA' % arg)
156
160
157 self._rpc_args = dict(user=u)
161 self._rpc_args = {USER_SESSION_ATTR:u}
158 self._rpc_args.update(self._req_params)
162 self._rpc_args.update(self._req_params)
159
163
160 self._rpc_args['action'] = self._req_method
164 self._rpc_args['action'] = self._req_method
@@ -183,7 +187,6 b' class JSONRPCController(WSGIController):'
183 """
187 """
184 try:
188 try:
185 raw_response = self._inspect_call(self._func)
189 raw_response = self._inspect_call(self._func)
186 print raw_response
187 if isinstance(raw_response, HTTPError):
190 if isinstance(raw_response, HTTPError):
188 self._error = str(raw_response)
191 self._error = str(raw_response)
189 except JSONRPCError as e:
192 except JSONRPCError as e:
@@ -223,3 +226,4 b' class JSONRPCController(WSGIController):'
223 return func
226 return func
224 else:
227 else:
225 raise AttributeError("No such method: %s" % self._req_method)
228 raise AttributeError("No such method: %s" % self._req_method)
229
@@ -1,7 +1,14 b''
1 import traceback
2 import logging
3
1 from rhodecode.controllers.api import JSONRPCController, JSONRPCError
4 from rhodecode.controllers.api import JSONRPCController, JSONRPCError
2 from rhodecode.lib.auth import HasPermissionAllDecorator
5 from rhodecode.lib.auth import HasPermissionAllDecorator
3 from rhodecode.model.scm import ScmModel
6 from rhodecode.model.scm import ScmModel
4
7
8 from rhodecode.model.db import User, UsersGroup
9
10 log = logging.getLogger(__name__)
11
5
12
6 class ApiController(JSONRPCController):
13 class ApiController(JSONRPCController):
7 """
14 """
@@ -20,13 +27,13 b' class ApiController(JSONRPCController):'
20 """
27 """
21
28
22 @HasPermissionAllDecorator('hg.admin')
29 @HasPermissionAllDecorator('hg.admin')
23 def pull(self, user, repo):
30 def pull(self, apiuser, repo):
24 """
31 """
25 Dispatch pull action on given repo
32 Dispatch pull action on given repo
26
33
27
34
28 param user:
35 :param user:
29 param repo:
36 :param repo:
30 """
37 """
31
38
32 try:
39 try:
@@ -36,5 +43,53 b' class ApiController(JSONRPCController):'
36 raise JSONRPCError('Unable to pull changes from "%s"' % repo)
43 raise JSONRPCError('Unable to pull changes from "%s"' % repo)
37
44
38
45
46 @HasPermissionAllDecorator('hg.admin')
47 def create_user(self, apiuser, username, password, active, admin, name,
48 lastname, email):
49 """
50 Creates new user
51
52 :param apiuser:
53 :param username:
54 :param password:
55 :param active:
56 :param admin:
57 :param name:
58 :param lastname:
59 :param email:
60 """
61
62 form_data = dict(username=username,
63 password=password,
64 active=active,
65 admin=admin,
66 name=name,
67 lastname=lastname,
68 email=email)
69 try:
70 u = User.create(form_data)
71 return {'id':u.user_id,
72 'msg':'created new user %s' % name}
73 except Exception:
74 log.error(traceback.format_exc())
75 raise JSONRPCError('failed to create user %s' % name)
39
76
40
77
78 @HasPermissionAllDecorator('hg.admin')
79 def create_users_group(self, apiuser, name, active):
80 """
81 Creates an new usergroup
82
83 :param name:
84 :param active:
85 """
86 form_data = {'users_group_name':name,
87 'users_group_active':active}
88 try:
89 ug = UsersGroup.create(form_data)
90 return {'id':ug.users_group_id,
91 'msg':'created new users group %s' % name}
92 except Exception:
93 log.error(traceback.format_exc())
94 raise JSONRPCError('failed to create group %s' % name)
95 No newline at end of file
@@ -38,12 +38,13 b' from beaker.cache import cache_region, r'
38
38
39 from vcs import get_backend
39 from vcs import get_backend
40 from vcs.utils.helpers import get_scm
40 from vcs.utils.helpers import get_scm
41 from vcs.exceptions import RepositoryError, VCSError
41 from vcs.exceptions import VCSError
42 from vcs.utils.lazy import LazyProperty
42 from vcs.utils.lazy import LazyProperty
43 from vcs.nodes import FileNode
44
43
45 from rhodecode.lib.exceptions import UsersGroupsAssignedException
44 from rhodecode.lib.exceptions import UsersGroupsAssignedException
46 from rhodecode.lib import str2bool, json, safe_str, get_changeset_safe
45 from rhodecode.lib import str2bool, json, safe_str, get_changeset_safe,\
46 generate_api_key
47
47 from rhodecode.model.meta import Base, Session
48 from rhodecode.model.meta import Base, Session
48 from rhodecode.model.caching_query import FromCache
49 from rhodecode.model.caching_query import FromCache
49
50
@@ -298,6 +299,25 b' class User(Base, BaseModel):'
298 Session.commit()
299 Session.commit()
299 log.debug('updated user %s lastlogin', self.username)
300 log.debug('updated user %s lastlogin', self.username)
300
301
302 @classmethod
303 def create(cls, form_data):
304 from rhodecode.lib.auth import get_crypt_password
305
306 try:
307 new_user = cls()
308 for k, v in form_data.items():
309 if k == 'password':
310 v = get_crypt_password(v)
311 setattr(new_user, k, v)
312
313 new_user.api_key = generate_api_key(form_data['username'])
314 Session.add(new_user)
315 Session.commit()
316 return new_user
317 except:
318 log.error(traceback.format_exc())
319 Session.rollback()
320 raise
301
321
302 class UserLog(Base, BaseModel):
322 class UserLog(Base, BaseModel):
303 __tablename__ = 'user_logs'
323 __tablename__ = 'user_logs'
@@ -362,6 +382,7 b' class UsersGroup(Base, BaseModel):'
362
382
363 Session.add(new_users_group)
383 Session.add(new_users_group)
364 Session.commit()
384 Session.commit()
385 return new_users_group
365 except:
386 except:
366 log.error(traceback.format_exc())
387 log.error(traceback.format_exc())
367 Session.rollback()
388 Session.rollback()
General Comments 0
You need to be logged in to leave comments. Login now