##// END OF EJS Templates
api review...
marcink -
r1843:0771f0f5 beta
parent child Browse files
Show More
@@ -1,426 +1,472 b''
1 .. _api:
1 .. _api:
2
2
3
3
4 API
4 API
5 ===
5 ===
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 a single 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 API ACCESS FOR WEB VIEWS
13 API ACCESS FOR WEB VIEWS
14 ++++++++++++++++++++++++
14 ++++++++++++++++++++++++
15
15
16 API access can also be turned on for each view decorated with `@LoginRequired`
16 API access can also be turned on for each view decorated with `@LoginRequired`
17 decorator. To enable API access simple change standard login decorator into
17 decorator. To enable API access simple change standard login decorator into
18 `@LoginRequired(api_access=True)`. After such a change view can be accessed
18 `@LoginRequired(api_access=True)`. After such a change view can be accessed
19 by adding a GET parameter to url `?api_key=<api_key>`. By default it's only
19 by adding a GET parameter to url `?api_key=<api_key>`. By default it's only
20 enabled on RSS/ATOM feed views.
20 enabled on RSS/ATOM feed views.
21
21
22
22
23 API ACCESS
23 API ACCESS
24 ++++++++++
24 ++++++++++
25
25
26 All clients are required to send JSON-RPC spec JSON data::
26 All clients are required to send JSON-RPC spec JSON data::
27
27
28 {
28 {
29 "id:<id>,
29 "id:<id>,
30 "api_key":"<api_key>",
30 "api_key":"<api_key>",
31 "method":"<method_name>",
31 "method":"<method_name>",
32 "args":{"<arg_key>":"<arg_val>"}
32 "args":{"<arg_key>":"<arg_val>"}
33 }
33 }
34
34
35 Example call for autopulling remotes repos using curl::
35 Example call for autopulling remotes repos using curl::
36 curl https://server.com/_admin/api -X POST -H 'content-type:text/plain' --data-binary '{"id":1,"api_key":"xe7cdb2v278e4evbdf5vs04v832v0efvcbcve4a3","method":"pull","args":{"repo":"CPython"}}'
36 curl https://server.com/_admin/api -X POST -H 'content-type:text/plain' --data-binary '{"id":1,"api_key":"xe7cdb2v278e4evbdf5vs04v832v0efvcbcve4a3","method":"pull","args":{"repo":"CPython"}}'
37
37
38 Simply provide
38 Simply provide
39 - *id* A value of any type, which is used to match the response with the request that it is replying to.
39 - *id* A value of any type, which is used to match the response with the request that it is replying to.
40 - *api_key* for access and permission validation.
40 - *api_key* for access and permission validation.
41 - *method* is name of method to call
41 - *method* is name of method to call
42 - *args* is an key:value list of arguments to pass to method
42 - *args* is an key:value list of arguments to pass to method
43
43
44 .. note::
44 .. note::
45
45
46 api_key can be found in your user account page
46 api_key can be found in your user account page
47
47
48
48
49 RhodeCode API will return always a JSON-RPC response::
49 RhodeCode API will return always a JSON-RPC response::
50
50
51 {
51 {
52 "id":<id>,
52 "id":<id>,
53 "result": "<result>",
53 "result": "<result>",
54 "error": null
54 "error": null
55 }
55 }
56
56
57 All responses from API will be `HTTP/1.0 200 OK`, if there's an error while
57 All responses from API will be `HTTP/1.0 200 OK`, if there's an error while
58 calling api *error* key from response will contain failure description
58 calling api *error* key from response will contain failure description
59 and result will be null.
59 and result will be null.
60
60
61 API METHODS
61 API METHODS
62 +++++++++++
62 +++++++++++
63
63
64
64
65 pull
65 pull
66 ----
66 ----
67
67
68 Pulls given repo from remote location. Can be used to automatically keep
68 Pulls given repo from remote location. Can be used to automatically keep
69 remote repos up to date. This command can be executed only using api_key
69 remote repos up to date. This command can be executed only using api_key
70 belonging to user with admin rights
70 belonging to user with admin rights
71
71
72 INPUT::
72 INPUT::
73
73
74 api_key : "<api_key>"
74 api_key : "<api_key>"
75 method : "pull"
75 method : "pull"
76 args : {
76 args : {
77 "repo" : "<repo_name>"
77 "repo_name" : "<reponame>"
78 }
78 }
79
79
80 OUTPUT::
80 OUTPUT::
81
81
82 result : "Pulled from <repo_name>"
82 result : "Pulled from <reponame>"
83 error : null
84
85
86 get_user
87 --------
88
89 Get's an user by username, Returns empty result if user is not found.
90 This command can be executed only using api_key belonging to user with admin
91 rights.
92
93 INPUT::
94
95 api_key : "<api_key>"
96 method : "get_user"
97 args : {
98 "username" : "<username>"
99 }
100
101 OUTPUT::
102
103 result: None if user does not exist or
104 {
105 "id" : "<id>",
106 "username" : "<username>",
107 "firstname": "<firstname>",
108 "lastname" : "<lastname>",
109 "email" : "<email>",
110 "active" : "<bool>",
111 "admin" :Β  "<bool>",
112 "ldap" : "<ldap_dn>"
113 }
114
83 error : null
115 error: null
84
116
85
117
86 get_users
118 get_users
87 ---------
119 ---------
88
120
89 Lists all existing users. This command can be executed only using api_key
121 Lists all existing users. This command can be executed only using api_key
90 belonging to user with admin rights.
122 belonging to user with admin rights.
91
123
92 INPUT::
124 INPUT::
93
125
94 api_key : "<api_key>"
126 api_key : "<api_key>"
95 method : "get_users"
127 method : "get_users"
96 args : { }
128 args : { }
97
129
98 OUTPUT::
130 OUTPUT::
99
131
100 result: [
132 result: [
101 {
133 {
102 "id" : "<id>",
134 "id" : "<id>",
103 "username" : "<username>",
135 "username" : "<username>",
104 "firstname": "<firstname>",
136 "firstname": "<firstname>",
105 "lastname" : "<lastname>",
137 "lastname" : "<lastname>",
106 "email" : "<email>",
138 "email" : "<email>",
107 "active" : "<bool>",
139 "active" : "<bool>",
108 "admin" :Β  "<bool>",
140 "admin" :Β  "<bool>",
109 "ldap" : "<ldap_dn>"
141 "ldap" : "<ldap_dn>"
110 },
142 },
111 …
143 …
112 ]
144 ]
113 error: null
145 error: null
114
146
115 create_user
147 create_user
116 -----------
148 -----------
117
149
118 Creates new user in RhodeCode. This command can be executed only using api_key
150 Creates new user in RhodeCode. This command can be executed only using api_key
119 belonging to user with admin rights.
151 belonging to user with admin rights.
120
152
121 INPUT::
153 INPUT::
122
154
123 api_key : "<api_key>"
155 api_key : "<api_key>"
124 method : "create_user"
156 method : "create_user"
125 args : {
157 args : {
126 "username" : "<username>",
158 "username" : "<username>",
127 "password" : "<password>",
159 "password" : "<password>",
128 "firstname" : "<firstname>",
160 "firstname" : "<firstname>",
129 "lastname" : "<lastname>",
161 "lastname" : "<lastname>",
130 "email" : "<useremail>"
162 "email" : "<useremail>"
131 "active" : "<bool> = True",
163 "active" : "<bool> = True",
132 "admin" : "<bool> = False",
164 "admin" : "<bool> = False",
133 "ldap_dn" : "<ldap_dn> = None"
165 "ldap_dn" : "<ldap_dn> = None"
134 }
166 }
135
167
136 OUTPUT::
168 OUTPUT::
137
169
138 result: {
170 result: {
171 "id" : "<new_user_id>",
139 "msg" : "created new user <username>"
172 "msg" : "created new user <username>"
140 }
173 }
141 error: null
174 error: null
142
175
143 get_users_groups
144 ----------------
145
146 Lists all existing users groups. This command can be executed only using api_key
147 belonging to user with admin rights.
148
149 INPUT::
150
151 api_key : "<api_key>"
152 method : "get_users_groups"
153 args : { }
154
155 OUTPUT::
156
157 result : [
158 {
159 "id" : "<id>",
160 "name" : "<name>",
161 "active": "<bool>",
162 "members" : [
163 {
164 "id" : "<userid>",
165 "username" : "<username>",
166 "firstname": "<firstname>",
167 "lastname" : "<lastname>",
168 "email" : "<email>",
169 "active" : "<bool>",
170 "admin" :Β  "<bool>",
171 "ldap" : "<ldap_dn>"
172 },
173 …
174 ]
175 }
176 ]
177 error : null
178
179 get_users_group
176 get_users_group
180 ---------------
177 ---------------
181
178
182 Gets an existing users group. This command can be executed only using api_key
179 Gets an existing users group. This command can be executed only using api_key
183 belonging to user with admin rights.
180 belonging to user with admin rights.
184
181
185 INPUT::
182 INPUT::
186
183
187 api_key : "<api_key>"
184 api_key : "<api_key>"
188 method : "get_users_group"
185 method : "get_users_group"
189 args : {
186 args : {
190 "group_name" : "<name>"
187 "group_name" : "<name>"
191 }
188 }
192
189
193 OUTPUT::
190 OUTPUT::
194
191
195 result : None if group not exist
192 result : None if group not exist
196 {
193 {
197 "id" : "<id>",
194 "id" : "<id>",
198 "name" : "<name>",
195 "group_name" : "<groupname>",
199 "active": "<bool>",
196 "active": "<bool>",
200 "members" : [
197 "members" : [
201 { "id" : "<userid>",
198 { "id" : "<userid>",
202 "username" : "<username>",
199 "username" : "<username>",
203 "firstname": "<firstname>",
200 "firstname": "<firstname>",
204 "lastname" : "<lastname>",
201 "lastname" : "<lastname>",
205 "email" : "<email>",
202 "email" : "<email>",
206 "active" : "<bool>",
203 "active" : "<bool>",
207 "admin" :Β  "<bool>",
204 "admin" :Β  "<bool>",
208 "ldap" : "<ldap_dn>"
205 "ldap" : "<ldap_dn>"
209 },
206 },
210 …
207 …
211 ]
208 ]
212 }
209 }
213 error : null
210 error : null
214
211
212 get_users_groups
213 ----------------
214
215 Lists all existing users groups. This command can be executed only using
216 api_key belonging to user with admin rights.
217
218 INPUT::
219
220 api_key : "<api_key>"
221 method : "get_users_groups"
222 args : { }
223
224 OUTPUT::
225
226 result : [
227 {
228 "id" : "<id>",
229 "group_name" : "<groupname>",
230 "active": "<bool>",
231 "members" : [
232 {
233 "id" : "<userid>",
234 "username" : "<username>",
235 "firstname": "<firstname>",
236 "lastname" : "<lastname>",
237 "email" : "<email>",
238 "active" : "<bool>",
239 "admin" :Β  "<bool>",
240 "ldap" : "<ldap_dn>"
241 },
242 …
243 ]
244 }
245 ]
246 error : null
247
248
215 create_users_group
249 create_users_group
216 ------------------
250 ------------------
217
251
218 Creates new users group. This command can be executed only using api_key
252 Creates new users group. This command can be executed only using api_key
219 belonging to user with admin rights
253 belonging to user with admin rights
220
254
221 INPUT::
255 INPUT::
222
256
223 api_key : "<api_key>"
257 api_key : "<api_key>"
224 method : "create_users_group"
258 method : "create_users_group"
225 args: {
259 args: {
226 "name": "<name>",
260 "group_name": "<groupname>",
227 "active":"<bool> = True"
261 "active":"<bool> = True"
228 }
262 }
229
263
230 OUTPUT::
264 OUTPUT::
231
265
232 result: {
266 result: {
233 "id": "<newusersgroupid>",
267 "id": "<newusersgroupid>",
234 "msg": "created new users group <name>"
268 "msg": "created new users group <groupname>"
235 }
269 }
236 error: null
270 error: null
237
271
238 add_user_to_users_group
272 add_user_to_users_group
239 -----------------------
273 -----------------------
240
274
241 Adds a user to a users group. This command can be executed only using api_key
275 Adds a user to a users group. This command can be executed only using api_key
242 belonging to user with admin rights
276 belonging to user with admin rights
243
277
244 INPUT::
278 INPUT::
245
279
246 api_key : "<api_key>"
280 api_key : "<api_key>"
247 method : "add_user_users_group"
281 method : "add_user_users_group"
248 args: {
282 args: {
249 "group_name" : "<groupname>",
283 "group_name" : "<groupname>",
250 "username" : "<username>"
284 "username" : "<username>"
251 }
285 }
252
286
253 OUTPUT::
287 OUTPUT::
254
288
255 result: {
289 result: {
256 "id": "<newusersgroupmemberid>",
290 "id": "<newusersgroupmemberid>",
257 "msg": "created new users group member"
291 "msg": "created new users group member"
258 }
292 }
259 error: null
293 error: null
260
294
261 get_repos
262 ---------
263
264 Lists all existing repositories. This command can be executed only using api_key
265 belonging to user with admin rights
266
267 INPUT::
268
269 api_key : "<api_key>"
270 method : "get_repos"
271 args: { }
272
273 OUTPUT::
274
275 result: [
276 {
277 "id" : "<id>",
278 "name" : "<name>"
279 "type" : "<type>",
280 "description" : "<description>"
281 },
282 …
283 ]
284 error: null
285
286 get_repo
295 get_repo
287 --------
296 --------
288
297
289 Gets an existing repository. This command can be executed only using api_key
298 Gets an existing repository. This command can be executed only using api_key
290 belonging to user with admin rights
299 belonging to user with admin rights
291
300
292 INPUT::
301 INPUT::
293
302
294 api_key : "<api_key>"
303 api_key : "<api_key>"
295 method : "get_repo"
304 method : "get_repo"
296 args: {
305 args: {
297 "name" : "<name>"
306 "repo_name" : "<reponame>"
298 }
307 }
299
308
300 OUTPUT::
309 OUTPUT::
301
310
302 result: None if repository not exist
311 result: None if repository does not exist or
303 {
312 {
304 "id" : "<id>",
313 "id" : "<id>",
305 "name" : "<name>"
314 "repo_name" : "<reponame>"
306 "type" : "<type>",
315 "type" : "<type>",
307 "description" : "<description>",
316 "description" : "<description>",
308 "members" : [
317 "members" : [
309 { "id" : "<userid>",
318 { "id" : "<userid>",
310 "username" : "<username>",
319 "username" : "<username>",
311 "firstname": "<firstname>",
320 "firstname": "<firstname>",
312 "lastname" : "<lastname>",
321 "lastname" : "<lastname>",
313 "email" : "<email>",
322 "email" : "<email>",
314 "active" : "<bool>",
323 "active" : "<bool>",
315 "admin" :Β  "<bool>",
324 "admin" :Β  "<bool>",
316 "ldap" : "<ldap_dn>",
325 "ldap" : "<ldap_dn>",
317 "permission" : "repository.(read|write|admin)"
326 "permission" : "repository.(read|write|admin)"
318 },
327 },
319 …
328 …
320 {
329 {
321 "id" : "<usersgroupid>",
330 "id" : "<usersgroupid>",
322 "name" : "<usersgroupname>",
331 "name" : "<usersgroupname>",
323 "active": "<bool>",
332 "active": "<bool>",
324 "permission" : "repository.(read|write|admin)"
333 "permission" : "repository.(read|write|admin)"
325 },
334 },
326 …
335 …
327 ]
336 ]
328 }
337 }
329 error: null
338 error: null
330
339
340 get_repos
341 ---------
342
343 Lists all existing repositories. This command can be executed only using api_key
344 belonging to user with admin rights
345
346 INPUT::
347
348 api_key : "<api_key>"
349 method : "get_repos"
350 args: { }
351
352 OUTPUT::
353
354 result: [
355 {
356 "id" : "<id>",
357 "repo_name" : "<reponame>"
358 "type" : "<type>",
359 "description" : "<description>"
360 },
361 …
362 ]
363 error: null
364
365
331 get_repo_nodes
366 get_repo_nodes
332 --------------
367 --------------
333
368
334 returns a list of nodes and it's children in a flat list for a given path
369 returns a list of nodes and it's children in a flat list for a given path
335 at given revision. It's possible to specify ret_type to show only files or
370 at given revision. It's possible to specify ret_type to show only `files` or
336 dirs. This command can be executed only using api_key belonging to user
371 `dirs`. This command can be executed only using api_key belonging to user
337 with admin rights
372 with admin rights
338
373
339 INPUT::
374 INPUT::
340
375
341 api_key : "<api_key>"
376 api_key : "<api_key>"
342 method : "get_repo_nodes"
377 method : "get_repo_nodes"
343 args: {
378 args: {
344 "repo_name" : "<name>",
379 "repo_name" : "<reponame>",
345 "revision" : "<revision>",
380 "revision" : "<revision>",
346 "root_path" : "<root_path>",
381 "root_path" : "<root_path>",
347 "ret_type" : "<ret_type>" = 'all'
382 "ret_type" : "<ret_type>" = 'all'
348 }
383 }
349
384
350 OUTPUT::
385 OUTPUT::
351
386
352 result: [
387 result: [
353 {
388 {
354 "name" : "<name>"
389 "name" : "<name>"
355 "type" : "<type>",
390 "type" : "<type>",
356 },
391 },
357 …
392 …
358 ]
393 ]
359 error: null
394 error: null
360
395
361
396
362
397
363 create_repo
398 create_repo
364 -----------
399 -----------
365
400
366 Creates a repository. This command can be executed only using api_key
401 Creates a repository. This command can be executed only using api_key
367 belonging to user with admin rights.
402 belonging to user with admin rights.
368 If repository name contains "/", all needed repository groups will be created.
403 If repository name contains "/", all needed repository groups will be created.
369 For example "foo/bar/baz" will create groups "foo", "bar" (with "foo" as parent),
404 For example "foo/bar/baz" will create groups "foo", "bar" (with "foo" as parent),
370 and create "baz" repository with "bar" as group.
405 and create "baz" repository with "bar" as group.
371
406
372 INPUT::
407 INPUT::
373
408
374 api_key : "<api_key>"
409 api_key : "<api_key>"
375 method : "create_repo"
410 method : "create_repo"
376 args: {
411 args: {
377 "name" : "<name>",
412 "repo_name" : "<reponame>",
378 "owner_name" : "<ownername>",
413 "owner_name" : "<ownername>",
379 "description" : "<description> = ''",
414 "description" : "<description> = ''",
380 "repo_type" : "<type> = 'hg'",
415 "repo_type" : "<type> = 'hg'",
381 "private" : "<bool> = False"
416 "private" : "<bool> = False"
382 }
417 }
383
418
384 OUTPUT::
419 OUTPUT::
385
420
386 result: None
421 result: {
422 "id": "<newrepoid>",
423 "msg": "Created new repository <reponame>",
424 }
387 error: null
425 error: null
388
426
389 add_user_to_repo
427 add_user_to_repo
390 ----------------
428 ----------------
391
429
392 Add a user to a repository. This command can be executed only using api_key
430 Add a user to a repository. This command can be executed only using api_key
393 belonging to user with admin rights.
431 belonging to user with admin rights.
394 If "perm" is None, user will be removed from the repository.
432 If "perm" is None, user will be removed from the repository.
395
433
396 INPUT::
434 INPUT::
397
435
398 api_key : "<api_key>"
436 api_key : "<api_key>"
399 method : "add_user_to_repo"
437 method : "add_user_to_repo"
400 args: {
438 args: {
401 "repo_name" : "<reponame>",
439 "repo_name" : "<reponame>",
402 "username" : "<username>",
440 "username" : "<username>",
403 "perm" : "(None|repository.(read|write|admin))",
441 "perm" : "(None|repository.(read|write|admin))",
404 }
442 }
405
443
406 OUTPUT::
444 OUTPUT::
407
445
408 result: None
446 result: {
447 "msg" : "Added perm: <perm> for <username> in repo: <reponame>"
448 }
409 error: null
449 error: null
410
450
411 add_users_group_to_repo
451 add_users_group_to_repo
412 -----------------------
452 -----------------------
413
453
414 Add a users group to a repository. This command can be executed only using
454 Add a users group to a repository. This command can be executed only using
415 api_key belonging to user with admin rights. If "perm" is None, group will
455 api_key belonging to user with admin rights. If "perm" is None, group will
416 be removed from the repository.
456 be removed from the repository.
417
457
418 INPUT::
458 INPUT::
419
459
420 api_key : "<api_key>"
460 api_key : "<api_key>"
421 method : "add_users_group_to_repo"
461 method : "add_users_group_to_repo"
422 args: {
462 args: {
423 "repo_name" : "<reponame>",
463 "repo_name" : "<reponame>",
424 "group_name" : "<groupname>",
464 "group_name" : "<groupname>",
425 "perm" : "(None|repository.(read|write|admin))",
465 "perm" : "(None|repository.(read|write|admin))",
426 } No newline at end of file
466 }
467 OUTPUT::
468
469 result: {
470 "msg" : Added perm: <perm> for <groupname> in repo: <reponame>"
471 }
472
@@ -1,499 +1,510 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.api
3 rhodecode.controllers.api
4 ~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 API controller for RhodeCode
6 API controller for RhodeCode
7
7
8 :created_on: Aug 20, 2011
8 :created_on: Aug 20, 2011
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software; you can redistribute it and/or
13 # This program is free software; you can redistribute it and/or
14 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
15 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
16 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
27
27
28 import traceback
28 import traceback
29 import logging
29 import logging
30
30
31 from sqlalchemy.orm.exc import NoResultFound
31 from sqlalchemy.orm.exc import NoResultFound
32
32
33 from rhodecode.controllers.api import JSONRPCController, JSONRPCError
33 from rhodecode.controllers.api import JSONRPCController, JSONRPCError
34 from rhodecode.lib.auth import HasPermissionAllDecorator, \
34 from rhodecode.lib.auth import HasPermissionAllDecorator, \
35 HasPermissionAnyDecorator
35 HasPermissionAnyDecorator
36
36
37 from rhodecode.model.meta import Session
37 from rhodecode.model.meta import Session
38 from rhodecode.model.scm import ScmModel
38 from rhodecode.model.scm import ScmModel
39 from rhodecode.model.db import User, UsersGroup, RepoGroup, Repository
39 from rhodecode.model.db import User, UsersGroup, RepoGroup, Repository
40 from rhodecode.model.repo import RepoModel
40 from rhodecode.model.repo import RepoModel
41 from rhodecode.model.user import UserModel
41 from rhodecode.model.user import UserModel
42 from rhodecode.model.repo_permission import RepositoryPermissionModel
42 from rhodecode.model.repo_permission import RepositoryPermissionModel
43 from rhodecode.model.users_group import UsersGroupModel
43 from rhodecode.model.users_group import UsersGroupModel
44 from rhodecode.model.repos_group import ReposGroupModel
44 from rhodecode.model.repos_group import ReposGroupModel
45
45
46
46
47 log = logging.getLogger(__name__)
47 log = logging.getLogger(__name__)
48
48
49
49
50 class ApiController(JSONRPCController):
50 class ApiController(JSONRPCController):
51 """
51 """
52 API Controller
52 API Controller
53
53
54
54
55 Each method needs to have USER as argument this is then based on given
55 Each method needs to have USER as argument this is then based on given
56 API_KEY propagated as instance of user object
56 API_KEY propagated as instance of user object
57
57
58 Preferably this should be first argument also
58 Preferably this should be first argument also
59
59
60
60
61 Each function should also **raise** JSONRPCError for any
61 Each function should also **raise** JSONRPCError for any
62 errors that happens
62 errors that happens
63
63
64 """
64 """
65
65
66 @HasPermissionAllDecorator('hg.admin')
66 @HasPermissionAllDecorator('hg.admin')
67 def pull(self, apiuser, repo):
67 def pull(self, apiuser, repo_name):
68 """
68 """
69 Dispatch pull action on given repo
69 Dispatch pull action on given repo
70
70
71
71
72 :param user:
72 :param user:
73 :param repo:
73 :param repo_name:
74 """
74 """
75
75
76 if Repository.is_valid(repo) is False:
76 if Repository.is_valid(repo_name) is False:
77 raise JSONRPCError('Unknown repo "%s"' % repo)
77 raise JSONRPCError('Unknown repo "%s"' % repo_name)
78
78
79 try:
79 try:
80 ScmModel().pull_changes(repo, self.rhodecode_user.username)
80 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
81 return 'Pulled from %s' % repo
81 return 'Pulled from %s' % repo_name
82 except Exception:
82 except Exception:
83 raise JSONRPCError('Unable to pull changes from "%s"' % repo)
83 raise JSONRPCError('Unable to pull changes from "%s"' % repo_name)
84
84
85 @HasPermissionAllDecorator('hg.admin')
85 @HasPermissionAllDecorator('hg.admin')
86 def get_user(self, apiuser, username):
86 def get_user(self, apiuser, username):
87 """"
87 """"
88 Get a user by username
88 Get a user by username
89
89
90 :param apiuser:
90 :param apiuser:
91 :param username:
91 :param username:
92 """
92 """
93
93
94 user = User.get_by_username(username)
94 user = User.get_by_username(username)
95 if not user:
95 if not user:
96 return None
96 return None
97
97
98 return dict(
98 return dict(
99 id=user.user_id,
99 id=user.user_id,
100 username=user.username,
100 username=user.username,
101 firstname=user.name,
101 firstname=user.name,
102 lastname=user.lastname,
102 lastname=user.lastname,
103 email=user.email,
103 email=user.email,
104 active=user.active,
104 active=user.active,
105 admin=user.admin,
105 admin=user.admin,
106 ldap=user.ldap_dn
106 ldap=user.ldap_dn
107 )
107 )
108
108
109 @HasPermissionAllDecorator('hg.admin')
109 @HasPermissionAllDecorator('hg.admin')
110 def get_users(self, apiuser):
110 def get_users(self, apiuser):
111 """"
111 """"
112 Get all users
112 Get all users
113
113
114 :param apiuser:
114 :param apiuser:
115 """
115 """
116
116
117 result = []
117 result = []
118 for user in User.getAll():
118 for user in User.getAll():
119 result.append(
119 result.append(
120 dict(
120 dict(
121 id=user.user_id,
121 id=user.user_id,
122 username=user.username,
122 username=user.username,
123 firstname=user.name,
123 firstname=user.name,
124 lastname=user.lastname,
124 lastname=user.lastname,
125 email=user.email,
125 email=user.email,
126 active=user.active,
126 active=user.active,
127 admin=user.admin,
127 admin=user.admin,
128 ldap=user.ldap_dn
128 ldap=user.ldap_dn
129 )
129 )
130 )
130 )
131 return result
131 return result
132
132
133 @HasPermissionAllDecorator('hg.admin')
133 @HasPermissionAllDecorator('hg.admin')
134 def create_user(self, apiuser, username, password, firstname,
134 def create_user(self, apiuser, username, password, firstname,
135 lastname, email, active=True, admin=False, ldap_dn=None):
135 lastname, email, active=True, admin=False, ldap_dn=None):
136 """
136 """
137 Create new user
137 Create new user
138
138
139 :param apiuser:
139 :param apiuser:
140 :param username:
140 :param username:
141 :param password:
141 :param password:
142 :param name:
142 :param name:
143 :param lastname:
143 :param lastname:
144 :param email:
144 :param email:
145 :param active:
145 :param active:
146 :param admin:
146 :param admin:
147 :param ldap_dn:
147 :param ldap_dn:
148 """
148 """
149
149
150 if User.get_by_username(username):
150 if User.get_by_username(username):
151 raise JSONRPCError("user %s already exist" % username)
151 raise JSONRPCError("user %s already exist" % username)
152
152
153 try:
153 try:
154 UserModel().create_or_update(username, password, email, firstname,
154 usr = UserModel().create_or_update(
155 lastname, active, admin, ldap_dn)
155 username, password, email, firstname,
156 lastname, active, admin, ldap_dn
157 )
156 Session.commit()
158 Session.commit()
157 return dict(msg='created new user %s' % username)
159 return dict(
160 id=usr.user_id,
161 msg='created new user %s' % username
162 )
158 except Exception:
163 except Exception:
159 log.error(traceback.format_exc())
164 log.error(traceback.format_exc())
160 raise JSONRPCError('failed to create user %s' % username)
165 raise JSONRPCError('failed to create user %s' % username)
161
166
162 @HasPermissionAllDecorator('hg.admin')
167 @HasPermissionAllDecorator('hg.admin')
163 def get_users_group(self, apiuser, group_name):
168 def get_users_group(self, apiuser, group_name):
164 """"
169 """"
165 Get users group by name
170 Get users group by name
166
171
167 :param apiuser:
172 :param apiuser:
168 :param group_name:
173 :param group_name:
169 """
174 """
170
175
171 users_group = UsersGroup.get_by_group_name(group_name)
176 users_group = UsersGroup.get_by_group_name(group_name)
172 if not users_group:
177 if not users_group:
173 return None
178 return None
174
179
175 members = []
180 members = []
176 for user in users_group.members:
181 for user in users_group.members:
177 user = user.user
182 user = user.user
178 members.append(dict(id=user.user_id,
183 members.append(dict(id=user.user_id,
179 username=user.username,
184 username=user.username,
180 firstname=user.name,
185 firstname=user.name,
181 lastname=user.lastname,
186 lastname=user.lastname,
182 email=user.email,
187 email=user.email,
183 active=user.active,
188 active=user.active,
184 admin=user.admin,
189 admin=user.admin,
185 ldap=user.ldap_dn))
190 ldap=user.ldap_dn))
186
191
187 return dict(id=users_group.users_group_id,
192 return dict(id=users_group.users_group_id,
188 name=users_group.users_group_name,
193 group_name=users_group.users_group_name,
189 active=users_group.users_group_active,
194 active=users_group.users_group_active,
190 members=members)
195 members=members)
191
196
192 @HasPermissionAllDecorator('hg.admin')
197 @HasPermissionAllDecorator('hg.admin')
193 def get_users_groups(self, apiuser):
198 def get_users_groups(self, apiuser):
194 """"
199 """"
195 Get all users groups
200 Get all users groups
196
201
197 :param apiuser:
202 :param apiuser:
198 """
203 """
199
204
200 result = []
205 result = []
201 for users_group in UsersGroup.getAll():
206 for users_group in UsersGroup.getAll():
202 members = []
207 members = []
203 for user in users_group.members:
208 for user in users_group.members:
204 user = user.user
209 user = user.user
205 members.append(dict(id=user.user_id,
210 members.append(dict(id=user.user_id,
206 username=user.username,
211 username=user.username,
207 firstname=user.name,
212 firstname=user.name,
208 lastname=user.lastname,
213 lastname=user.lastname,
209 email=user.email,
214 email=user.email,
210 active=user.active,
215 active=user.active,
211 admin=user.admin,
216 admin=user.admin,
212 ldap=user.ldap_dn))
217 ldap=user.ldap_dn))
213
218
214 result.append(dict(id=users_group.users_group_id,
219 result.append(dict(id=users_group.users_group_id,
215 name=users_group.users_group_name,
220 group_name=users_group.users_group_name,
216 active=users_group.users_group_active,
221 active=users_group.users_group_active,
217 members=members))
222 members=members))
218 return result
223 return result
219
224
220 @HasPermissionAllDecorator('hg.admin')
225 @HasPermissionAllDecorator('hg.admin')
221 def create_users_group(self, apiuser, name, active=True):
226 def create_users_group(self, apiuser, group_name, active=True):
222 """
227 """
223 Creates an new usergroup
228 Creates an new usergroup
224
229
225 :param name:
230 :param group_name:
226 :param active:
231 :param active:
227 """
232 """
228
233
229 if self.get_users_group(apiuser, name):
234 if self.get_users_group(apiuser, group_name):
230 raise JSONRPCError("users group %s already exist" % name)
235 raise JSONRPCError("users group %s already exist" % group_name)
231
236
232 try:
237 try:
233 ug = UsersGroupModel().create(name=name, active=active)
238 ug = UsersGroupModel().create(name=group_name, active=active)
234 Session.commit()
239 Session.commit()
235 return dict(id=ug.users_group_id,
240 return dict(id=ug.users_group_id,
236 msg='created new users group %s' % name)
241 msg='created new users group %s' % group_name)
237 except Exception:
242 except Exception:
238 log.error(traceback.format_exc())
243 log.error(traceback.format_exc())
239 raise JSONRPCError('failed to create group %s' % name)
244 raise JSONRPCError('failed to create group %s' % group_name)
240
245
241 @HasPermissionAllDecorator('hg.admin')
246 @HasPermissionAllDecorator('hg.admin')
242 def add_user_to_users_group(self, apiuser, group_name, username):
247 def add_user_to_users_group(self, apiuser, group_name, username):
243 """"
248 """"
244 Add a user to a group
249 Add a user to a group
245
250
246 :param apiuser:
251 :param apiuser:
247 :param group_name:
252 :param group_name:
248 :param username:
253 :param username:
249 """
254 """
250
255
251 try:
256 try:
252 users_group = UsersGroup.get_by_group_name(group_name)
257 users_group = UsersGroup.get_by_group_name(group_name)
253 if not users_group:
258 if not users_group:
254 raise JSONRPCError('unknown users group %s' % group_name)
259 raise JSONRPCError('unknown users group %s' % group_name)
255
260
256 try:
261 try:
257 user = User.get_by_username(username)
262 user = User.get_by_username(username)
258 except NoResultFound:
263 except NoResultFound:
259 raise JSONRPCError('unknown user %s' % username)
264 raise JSONRPCError('unknown user %s' % username)
260
265
261 ugm = UsersGroupModel().add_user_to_group(users_group, user)
266 ugm = UsersGroupModel().add_user_to_group(users_group, user)
262 Session.commit()
267 Session.commit()
263 return dict(id=ugm.users_group_member_id,
268 return dict(id=ugm.users_group_member_id,
264 msg='created new users group member')
269 msg='created new users group member')
265 except Exception:
270 except Exception:
266 log.error(traceback.format_exc())
271 log.error(traceback.format_exc())
267 raise JSONRPCError('failed to create users group member')
272 raise JSONRPCError('failed to create users group member')
268
273
269 @HasPermissionAnyDecorator('hg.admin')
274 @HasPermissionAnyDecorator('hg.admin')
270 def get_repo(self, apiuser, repo_name):
275 def get_repo(self, apiuser, repo_name):
271 """"
276 """"
272 Get repository by name
277 Get repository by name
273
278
274 :param apiuser:
279 :param apiuser:
275 :param repo_name:
280 :param repo_name:
276 """
281 """
277
282
278 repo = Repository.get_by_repo_name(repo_name)
283 repo = Repository.get_by_repo_name(repo_name)
279 if repo is None:
284 if repo is None:
280 raise JSONRPCError('unknown repository %s' % repo)
285 raise JSONRPCError('unknown repository %s' % repo)
281
286
282 members = []
287 members = []
283 for user in repo.repo_to_perm:
288 for user in repo.repo_to_perm:
284 perm = user.permission.permission_name
289 perm = user.permission.permission_name
285 user = user.user
290 user = user.user
286 members.append(
291 members.append(
287 dict(
292 dict(
288 type_="user",
293 type_="user",
289 id=user.user_id,
294 id=user.user_id,
290 username=user.username,
295 username=user.username,
291 firstname=user.name,
296 firstname=user.name,
292 lastname=user.lastname,
297 lastname=user.lastname,
293 email=user.email,
298 email=user.email,
294 active=user.active,
299 active=user.active,
295 admin=user.admin,
300 admin=user.admin,
296 ldap=user.ldap_dn,
301 ldap=user.ldap_dn,
297 permission=perm
302 permission=perm
298 )
303 )
299 )
304 )
300 for users_group in repo.users_group_to_perm:
305 for users_group in repo.users_group_to_perm:
301 perm = users_group.permission.permission_name
306 perm = users_group.permission.permission_name
302 users_group = users_group.users_group
307 users_group = users_group.users_group
303 members.append(
308 members.append(
304 dict(
309 dict(
305 type_="users_group",
310 type_="users_group",
306 id=users_group.users_group_id,
311 id=users_group.users_group_id,
307 name=users_group.users_group_name,
312 name=users_group.users_group_name,
308 active=users_group.users_group_active,
313 active=users_group.users_group_active,
309 permission=perm
314 permission=perm
310 )
315 )
311 )
316 )
312
317
313 return dict(
318 return dict(
314 id=repo.repo_id,
319 id=repo.repo_id,
315 name=repo.repo_name,
320 repo_name=repo.repo_name,
316 type=repo.repo_type,
321 type=repo.repo_type,
317 description=repo.description,
322 description=repo.description,
318 members=members
323 members=members
319 )
324 )
320
325
321 @HasPermissionAnyDecorator('hg.admin')
326 @HasPermissionAnyDecorator('hg.admin')
322 def get_repos(self, apiuser):
327 def get_repos(self, apiuser):
323 """"
328 """"
324 Get all repositories
329 Get all repositories
325
330
326 :param apiuser:
331 :param apiuser:
327 """
332 """
328
333
329 result = []
334 result = []
330 for repository in Repository.getAll():
335 for repository in Repository.getAll():
331 result.append(
336 result.append(
332 dict(
337 dict(
333 id=repository.repo_id,
338 id=repository.repo_id,
334 name=repository.repo_name,
339 repo_name=repository.repo_name,
335 type=repository.repo_type,
340 type=repository.repo_type,
336 description=repository.description
341 description=repository.description
337 )
342 )
338 )
343 )
339 return result
344 return result
340
345
341 @HasPermissionAnyDecorator('hg.admin')
346 @HasPermissionAnyDecorator('hg.admin')
342 def get_repo_nodes(self, apiuser, repo_name, revision, root_path,
347 def get_repo_nodes(self, apiuser, repo_name, revision, root_path,
343 ret_type='all'):
348 ret_type='all'):
344 """
349 """
345 returns a list of nodes and it's children
350 returns a list of nodes and it's children
346 for a given path at given revision. It's possible to specify ret_type
351 for a given path at given revision. It's possible to specify ret_type
347 to show only files or dirs
352 to show only files or dirs
348
353
349 :param apiuser:
354 :param apiuser:
350 :param repo_name: name of repository
355 :param repo_name: name of repository
351 :param revision: revision for which listing should be done
356 :param revision: revision for which listing should be done
352 :param root_path: path from which start displaying
357 :param root_path: path from which start displaying
353 :param ret_type: return type 'all|files|dirs' nodes
358 :param ret_type: return type 'all|files|dirs' nodes
354 """
359 """
355 try:
360 try:
356 _d, _f = ScmModel().get_nodes(repo_name, revision, root_path,
361 _d, _f = ScmModel().get_nodes(repo_name, revision, root_path,
357 flat=False)
362 flat=False)
358 _map = {
363 _map = {
359 'all': _d + _f,
364 'all': _d + _f,
360 'files': _f,
365 'files': _f,
361 'dirs': _d,
366 'dirs': _d,
362 }
367 }
363 return _map[ret_type]
368 return _map[ret_type]
364 except KeyError:
369 except KeyError:
365 raise JSONRPCError('ret_type must be one of %s' % _map.keys())
370 raise JSONRPCError('ret_type must be one of %s' % _map.keys())
366 except Exception, e:
371 except Exception, e:
367 raise JSONRPCError(e)
372 raise JSONRPCError(e)
368
373
369 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
374 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
370 def create_repo(self, apiuser, name, owner_name, description='',
375 def create_repo(self, apiuser, repo_name, owner_name, description='',
371 repo_type='hg', private=False):
376 repo_type='hg', private=False):
372 """
377 """
373 Create a repository
378 Create a repository
374
379
375 :param apiuser:
380 :param apiuser:
376 :param name:
381 :param repo_name:
377 :param description:
382 :param description:
378 :param type:
383 :param type:
379 :param private:
384 :param private:
380 :param owner_name:
385 :param owner_name:
381 """
386 """
382
387
383 try:
388 try:
384 try:
389 try:
385 owner = User.get_by_username(owner_name)
390 owner = User.get_by_username(owner_name)
386 except NoResultFound:
391 except NoResultFound:
387 raise JSONRPCError('unknown user %s' % owner)
392 raise JSONRPCError('unknown user %s' % owner)
388
393
389 if self.get_repo(apiuser, name):
394 if Repository.get_by_repo_name(repo_name):
390 raise JSONRPCError("repo %s already exist" % name)
395 raise JSONRPCError("repo %s already exist" % repo_name)
391
396
392 groups = name.split('/')
397 groups = repo_name.split('/')
393 real_name = groups[-1]
398 real_name = groups[-1]
394 groups = groups[:-1]
399 groups = groups[:-1]
395 parent_id = None
400 parent_id = None
396 for g in groups:
401 for g in groups:
397 group = RepoGroup.get_by_group_name(g)
402 group = RepoGroup.get_by_group_name(g)
398 if not group:
403 if not group:
399 group = ReposGroupModel().create(
404 group = ReposGroupModel().create(
400 dict(
405 dict(
401 group_name=g,
406 group_name=g,
402 group_description='',
407 group_description='',
403 group_parent_id=parent_id
408 group_parent_id=parent_id
404 )
409 )
405 )
410 )
406 parent_id = group.group_id
411 parent_id = group.group_id
407
412
408 RepoModel().create(
413 repo = RepoModel().create(
409 dict(
414 dict(
410 repo_name=real_name,
415 repo_name=real_name,
411 repo_name_full=name,
416 repo_name_full=repo_name,
412 description=description,
417 description=description,
413 private=private,
418 private=private,
414 repo_type=repo_type,
419 repo_type=repo_type,
415 repo_group=parent_id,
420 repo_group=parent_id,
416 clone_uri=None
421 clone_uri=None
417 ),
422 ),
418 owner
423 owner
419 )
424 )
420 Session.commit()
425 Session.commit()
426
427 return dict(
428 id=repo.repo_id,
429 msg="Created new repository %s" % repo.repo_name
430 )
431
421 except Exception:
432 except Exception:
422 log.error(traceback.format_exc())
433 log.error(traceback.format_exc())
423 raise JSONRPCError('failed to create repository %s' % name)
434 raise JSONRPCError('failed to create repository %s' % repo_name)
424
435
425 @HasPermissionAnyDecorator('hg.admin')
436 @HasPermissionAnyDecorator('hg.admin')
426 def add_user_to_repo(self, apiuser, repo_name, username, perm):
437 def add_user_to_repo(self, apiuser, repo_name, username, perm):
427 """
438 """
428 Add permission for a user to a repository
439 Add permission for a user to a repository
429
440
430 :param apiuser:
441 :param apiuser:
431 :param repo_name:
442 :param repo_name:
432 :param username:
443 :param username:
433 :param perm:
444 :param perm:
434 """
445 """
435
446
436 try:
447 try:
437 repo = Repository.get_by_repo_name(repo_name)
448 repo = Repository.get_by_repo_name(repo_name)
438 if repo is None:
449 if repo is None:
439 raise JSONRPCError('unknown repository %s' % repo)
450 raise JSONRPCError('unknown repository %s' % repo)
440
451
441 try:
452 try:
442 user = User.get_by_username(username)
453 user = User.get_by_username(username)
443 except NoResultFound:
454 except NoResultFound:
444 raise JSONRPCError('unknown user %s' % user)
455 raise JSONRPCError('unknown user %s' % user)
445
456
446 RepositoryPermissionModel()\
457 RepositoryPermissionModel()\
447 .update_or_delete_user_permission(repo, user, perm)
458 .update_or_delete_user_permission(repo, user, perm)
448 Session.commit()
459 Session.commit()
449
460
450 return dict(
461 return dict(
451 msg='Added perm: %s for %s in repo: %s' % (
462 msg='Added perm: %s for %s in repo: %s' % (
452 perm, username, repo_name
463 perm, username, repo_name
453 )
464 )
454 )
465 )
455 except Exception:
466 except Exception:
456 log.error(traceback.format_exc())
467 log.error(traceback.format_exc())
457 raise JSONRPCError(
468 raise JSONRPCError(
458 'failed to edit permission %(repo)s for %(user)s' % dict(
469 'failed to edit permission %(repo)s for %(user)s' % dict(
459 user=username, repo=repo_name
470 user=username, repo=repo_name
460 )
471 )
461 )
472 )
462
473
463 @HasPermissionAnyDecorator('hg.admin')
474 @HasPermissionAnyDecorator('hg.admin')
464 def add_users_group_to_repo(self, apiuser, repo_name, group_name, perm):
475 def add_users_group_to_repo(self, apiuser, repo_name, group_name, perm):
465 """
476 """
466 Add permission for a users group to a repository
477 Add permission for a users group to a repository
467
478
468 :param apiuser:
479 :param apiuser:
469 :param repo_name:
480 :param repo_name:
470 :param group_name:
481 :param group_name:
471 :param perm:
482 :param perm:
472 """
483 """
473
484
474 try:
485 try:
475 repo = Repository.get_by_repo_name(repo_name)
486 repo = Repository.get_by_repo_name(repo_name)
476 if repo is None:
487 if repo is None:
477 raise JSONRPCError('unknown repository %s' % repo)
488 raise JSONRPCError('unknown repository %s' % repo)
478
489
479 try:
490 try:
480 user_group = UsersGroup.get_by_group_name(group_name)
491 user_group = UsersGroup.get_by_group_name(group_name)
481 except NoResultFound:
492 except NoResultFound:
482 raise JSONRPCError('unknown users group %s' % user_group)
493 raise JSONRPCError('unknown users group %s' % user_group)
483
494
484 RepositoryPermissionModel()\
495 RepositoryPermissionModel()\
485 .update_or_delete_users_group_permission(repo, user_group,
496 .update_or_delete_users_group_permission(repo, user_group,
486 perm)
497 perm)
487 Session.commit()
498 Session.commit()
488 return dict(
499 return dict(
489 msg='Added perm: %s for %s in repo: %s' % (
500 msg='Added perm: %s for %s in repo: %s' % (
490 perm, group_name, repo_name
501 perm, group_name, repo_name
491 )
502 )
492 )
503 )
493 except Exception:
504 except Exception:
494 log.error(traceback.format_exc())
505 log.error(traceback.format_exc())
495 raise JSONRPCError(
506 raise JSONRPCError(
496 'failed to edit permission %(repo)s for %(usergr)s' % dict(
507 'failed to edit permission %(repo)s for %(usergr)s' % dict(
497 usergr=group_name, repo=repo_name
508 usergr=group_name, repo=repo_name
498 )
509 )
499 )
510 )
General Comments 0
You need to be logged in to leave comments. Login now