##// END OF EJS Templates
API changes...
marcink -
r1989:0f87c784 beta
parent child Browse files
Show More
@@ -1,541 +1,571 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 web view in RhodeCode that is
16 API access can also be turned on for each web view in RhodeCode that is
17 decorated with `@LoginRequired` decorator. To enable API access simple change
17 decorated with `@LoginRequired` decorator. To enable API access simple change
18 the standard login decorator to `@LoginRequired(api_access=True)`.
18 the standard login decorator to `@LoginRequired(api_access=True)`.
19 After this change, a rhodecode view can be accessed without login by adding a
19 After this change, a rhodecode view can be accessed without login by adding a
20 GET parameter `?api_key=<api_key>` to url. By default this is only
20 GET parameter `?api_key=<api_key>` to url. By default this is only
21 enabled on RSS/ATOM feed views.
21 enabled on RSS/ATOM feed views.
22
22
23
23
24 API ACCESS
24 API ACCESS
25 ++++++++++
25 ++++++++++
26
26
27 All clients are required to send JSON-RPC spec JSON data::
27 All clients are required to send JSON-RPC spec JSON data::
28
28
29 {
29 {
30 "id:<id>,
30 "id:<id>,
31 "api_key":"<api_key>",
31 "api_key":"<api_key>",
32 "method":"<method_name>",
32 "method":"<method_name>",
33 "args":{"<arg_key>":"<arg_val>"}
33 "args":{"<arg_key>":"<arg_val>"}
34 }
34 }
35
35
36 Example call for autopulling remotes repos using curl::
36 Example call for autopulling remotes repos using curl::
37 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 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"}}'
38
38
39 Simply provide
39 Simply provide
40 - *id* A value of any type, which is used to match the response with the request that it is replying to.
40 - *id* A value of any type, which is used to match the response with the request that it is replying to.
41 - *api_key* for access and permission validation.
41 - *api_key* for access and permission validation.
42 - *method* is name of method to call
42 - *method* is name of method to call
43 - *args* is an key:value list of arguments to pass to method
43 - *args* is an key:value list of arguments to pass to method
44
44
45 .. note::
45 .. note::
46
46
47 api_key can be found in your user account page
47 api_key can be found in your user account page
48
48
49
49
50 RhodeCode API will return always a JSON-RPC response::
50 RhodeCode API will return always a JSON-RPC response::
51
51
52 {
52 {
53 "id":<id>,
53 "id":<id>,
54 "result": "<result>",
54 "result": "<result>",
55 "error": null
55 "error": null
56 }
56 }
57
57
58 All responses from API will be `HTTP/1.0 200 OK`, if there's an error while
58 All responses from API will be `HTTP/1.0 200 OK`, if there's an error while
59 calling api *error* key from response will contain failure description
59 calling api *error* key from response will contain failure description
60 and result will be null.
60 and result will be null.
61
61
62 API METHODS
62 API METHODS
63 +++++++++++
63 +++++++++++
64
64
65
65
66 pull
66 pull
67 ----
67 ----
68
68
69 Pulls given repo from remote location. Can be used to automatically keep
69 Pulls given repo from remote location. Can be used to automatically keep
70 remote repos up to date. This command can be executed only using api_key
70 remote repos up to date. This command can be executed only using api_key
71 belonging to user with admin rights
71 belonging to user with admin rights
72
72
73 INPUT::
73 INPUT::
74
74
75 api_key : "<api_key>"
75 api_key : "<api_key>"
76 method : "pull"
76 method : "pull"
77 args : {
77 args : {
78 "repo_name" : "<reponame>"
78 "repo_name" : "<reponame>"
79 }
79 }
80
80
81 OUTPUT::
81 OUTPUT::
82
82
83 result : "Pulled from <reponame>"
83 result : "Pulled from <reponame>"
84 error : null
84 error : null
85
85
86
86
87 get_user
87 get_user
88 --------
88 --------
89
89
90 Get's an user by username, Returns empty result if user is not found.
90 Get's an user by username, Returns empty result if user is not found.
91 This command can be executed only using api_key belonging to user with admin
91 This command can be executed only using api_key belonging to user with admin
92 rights.
92 rights.
93
93
94
94
95 INPUT::
95 INPUT::
96
96
97 api_key : "<api_key>"
97 api_key : "<api_key>"
98 method : "get_user"
98 method : "get_user"
99 args : {
99 args : {
100 "username" : "<username>"
100 "username" : "<username>"
101 }
101 }
102
102
103 OUTPUT::
103 OUTPUT::
104
104
105 result: None if user does not exist or
105 result: None if user does not exist or
106 {
106 {
107 "id" : "<id>",
107 "id" : "<id>",
108 "username" : "<username>",
108 "username" : "<username>",
109 "firstname": "<firstname>",
109 "firstname": "<firstname>",
110 "lastname" : "<lastname>",
110 "lastname" : "<lastname>",
111 "email" : "<email>",
111 "email" : "<email>",
112 "active" : "<bool>",
112 "active" : "<bool>",
113 "admin" :Β  "<bool>",
113 "admin" :Β  "<bool>",
114 "ldap" : "<ldap_dn>"
114 "ldap" : "<ldap_dn>"
115 }
115 }
116
116
117 error: null
117 error: null
118
118
119
119
120 get_users
120 get_users
121 ---------
121 ---------
122
122
123 Lists all existing users. This command can be executed only using api_key
123 Lists all existing users. This command can be executed only using api_key
124 belonging to user with admin rights.
124 belonging to user with admin rights.
125
125
126
126
127 INPUT::
127 INPUT::
128
128
129 api_key : "<api_key>"
129 api_key : "<api_key>"
130 method : "get_users"
130 method : "get_users"
131 args : { }
131 args : { }
132
132
133 OUTPUT::
133 OUTPUT::
134
134
135 result: [
135 result: [
136 {
136 {
137 "id" : "<id>",
137 "id" : "<id>",
138 "username" : "<username>",
138 "username" : "<username>",
139 "firstname": "<firstname>",
139 "firstname": "<firstname>",
140 "lastname" : "<lastname>",
140 "lastname" : "<lastname>",
141 "email" : "<email>",
141 "email" : "<email>",
142 "active" : "<bool>",
142 "active" : "<bool>",
143 "admin" :Β  "<bool>",
143 "admin" :Β  "<bool>",
144 "ldap" : "<ldap_dn>"
144 "ldap" : "<ldap_dn>"
145 },
145 },
146 …
146 …
147 ]
147 ]
148 error: null
148 error: null
149
149
150
150
151 create_user
151 create_user
152 -----------
152 -----------
153
153
154 Creates new user or updates current one if such user exists. This command can
154 Creates new user or updates current one if such user exists. This command can
155 be executed only using api_key belonging to user with admin rights.
155 be executed only using api_key belonging to user with admin rights.
156
156
157
157
158 INPUT::
158 INPUT::
159
159
160 api_key : "<api_key>"
160 api_key : "<api_key>"
161 method : "create_user"
161 method : "create_user"
162 args : {
162 args : {
163 "username" : "<username>",
163 "username" : "<username>",
164 "password" : "<password>",
164 "password" : "<password>",
165 "email" : "<useremail>",
165 "email" : "<useremail>",
166 "firstname" : "<firstname> = None",
166 "firstname" : "<firstname> = None",
167 "lastname" : "<lastname> = None",
167 "lastname" : "<lastname> = None",
168 "active" : "<bool> = True",
168 "active" : "<bool> = True",
169 "admin" : "<bool> = False",
169 "admin" : "<bool> = False",
170 "ldap_dn" : "<ldap_dn> = None"
170 "ldap_dn" : "<ldap_dn> = None"
171 }
171 }
172
172
173 OUTPUT::
173 OUTPUT::
174
174
175 result: {
175 result: {
176 "id" : "<new_user_id>",
176 "id" : "<new_user_id>",
177 "msg" : "created new user <username>"
177 "msg" : "created new user <username>"
178 }
178 }
179 error: null
179 error: null
180
180
181
181
182 get_users_group
182 get_users_group
183 ---------------
183 ---------------
184
184
185 Gets an existing users group. This command can be executed only using api_key
185 Gets an existing users group. This command can be executed only using api_key
186 belonging to user with admin rights.
186 belonging to user with admin rights.
187
187
188
188
189 INPUT::
189 INPUT::
190
190
191 api_key : "<api_key>"
191 api_key : "<api_key>"
192 method : "get_users_group"
192 method : "get_users_group"
193 args : {
193 args : {
194 "group_name" : "<name>"
194 "group_name" : "<name>"
195 }
195 }
196
196
197 OUTPUT::
197 OUTPUT::
198
198
199 result : None if group not exist
199 result : None if group not exist
200 {
200 {
201 "id" : "<id>",
201 "id" : "<id>",
202 "group_name" : "<groupname>",
202 "group_name" : "<groupname>",
203 "active": "<bool>",
203 "active": "<bool>",
204 "members" : [
204 "members" : [
205 { "id" : "<userid>",
205 { "id" : "<userid>",
206 "username" : "<username>",
206 "username" : "<username>",
207 "firstname": "<firstname>",
207 "firstname": "<firstname>",
208 "lastname" : "<lastname>",
208 "lastname" : "<lastname>",
209 "email" : "<email>",
209 "email" : "<email>",
210 "active" : "<bool>",
210 "active" : "<bool>",
211 "admin" :Β  "<bool>",
211 "admin" :Β  "<bool>",
212 "ldap" : "<ldap_dn>"
212 "ldap" : "<ldap_dn>"
213 },
213 },
214 …
214 …
215 ]
215 ]
216 }
216 }
217 error : null
217 error : null
218
218
219
219
220 get_users_groups
220 get_users_groups
221 ----------------
221 ----------------
222
222
223 Lists all existing users groups. This command can be executed only using
223 Lists all existing users groups. This command can be executed only using
224 api_key belonging to user with admin rights.
224 api_key belonging to user with admin rights.
225
225
226
226
227 INPUT::
227 INPUT::
228
228
229 api_key : "<api_key>"
229 api_key : "<api_key>"
230 method : "get_users_groups"
230 method : "get_users_groups"
231 args : { }
231 args : { }
232
232
233 OUTPUT::
233 OUTPUT::
234
234
235 result : [
235 result : [
236 {
236 {
237 "id" : "<id>",
237 "id" : "<id>",
238 "group_name" : "<groupname>",
238 "group_name" : "<groupname>",
239 "active": "<bool>",
239 "active": "<bool>",
240 "members" : [
240 "members" : [
241 {
241 {
242 "id" : "<userid>",
242 "id" : "<userid>",
243 "username" : "<username>",
243 "username" : "<username>",
244 "firstname": "<firstname>",
244 "firstname": "<firstname>",
245 "lastname" : "<lastname>",
245 "lastname" : "<lastname>",
246 "email" : "<email>",
246 "email" : "<email>",
247 "active" : "<bool>",
247 "active" : "<bool>",
248 "admin" :Β  "<bool>",
248 "admin" :Β  "<bool>",
249 "ldap" : "<ldap_dn>"
249 "ldap" : "<ldap_dn>"
250 },
250 },
251 …
251 …
252 ]
252 ]
253 }
253 }
254 ]
254 ]
255 error : null
255 error : null
256
256
257
257
258 create_users_group
258 create_users_group
259 ------------------
259 ------------------
260
260
261 Creates new users group. This command can be executed only using api_key
261 Creates new users group. This command can be executed only using api_key
262 belonging to user with admin rights
262 belonging to user with admin rights
263
263
264
264
265 INPUT::
265 INPUT::
266
266
267 api_key : "<api_key>"
267 api_key : "<api_key>"
268 method : "create_users_group"
268 method : "create_users_group"
269 args: {
269 args: {
270 "group_name": "<groupname>",
270 "group_name": "<groupname>",
271 "active":"<bool> = True"
271 "active":"<bool> = True"
272 }
272 }
273
273
274 OUTPUT::
274 OUTPUT::
275
275
276 result: {
276 result: {
277 "id": "<newusersgroupid>",
277 "id": "<newusersgroupid>",
278 "msg": "created new users group <groupname>"
278 "msg": "created new users group <groupname>"
279 }
279 }
280 error: null
280 error: null
281
281
282
282
283 add_user_to_users_group
283 add_user_to_users_group
284 -----------------------
284 -----------------------
285
285
286 Adds a user to a users group. This command can be executed only using api_key
286 Adds a user to a users group. If user exists in that group success will be
287 `false`. This command can be executed only using api_key
287 belonging to user with admin rights
288 belonging to user with admin rights
288
289
289
290
290 INPUT::
291 INPUT::
291
292
292 api_key : "<api_key>"
293 api_key : "<api_key>"
293 method : "add_user_users_group"
294 method : "add_user_users_group"
294 args: {
295 args: {
295 "group_name" : "<groupname>",
296 "group_name" : "<groupname>",
296 "username" : "<username>"
297 "username" : "<username>"
297 }
298 }
298
299
299 OUTPUT::
300 OUTPUT::
300
301
301 result: {
302 result: {
302 "id": "<newusersgroupmemberid>",
303 "id": "<newusersgroupmemberid>",
303 "msg": "created new users group member"
304 "success": True|False # depends on if member is in group
305 "msg": "added member <username> to users group <groupname> |
306 User is already in that group"
307 }
308 error: null
309
310
311 remove_user_from_users_group
312 ----------------------------
313
314 Removes a user from a users group. If user is not in given group success will
315 be `false`. This command can be executed only
316 using api_key belonging to user with admin rights
317
318
319 INPUT::
320
321 api_key : "<api_key>"
322 method : "remove_user_from_users_group"
323 args: {
324 "group_name" : "<groupname>",
325 "username" : "<username>"
326 }
327
328 OUTPUT::
329
330 result: {
331 "success": True|False, # depends on if member is in group
332 "msg": "removed member <username> from users group <groupname> |
333 User wasn't in group"
304 }
334 }
305 error: null
335 error: null
306
336
307
337
308 get_repo
338 get_repo
309 --------
339 --------
310
340
311 Gets an existing repository. This command can be executed only using api_key
341 Gets an existing repository. This command can be executed only using api_key
312 belonging to user with admin rights
342 belonging to user with admin rights
313
343
314
344
315 INPUT::
345 INPUT::
316
346
317 api_key : "<api_key>"
347 api_key : "<api_key>"
318 method : "get_repo"
348 method : "get_repo"
319 args: {
349 args: {
320 "repo_name" : "<reponame>"
350 "repo_name" : "<reponame>"
321 }
351 }
322
352
323 OUTPUT::
353 OUTPUT::
324
354
325 result: None if repository does not exist or
355 result: None if repository does not exist or
326 {
356 {
327 "id" : "<id>",
357 "id" : "<id>",
328 "repo_name" : "<reponame>"
358 "repo_name" : "<reponame>"
329 "type" : "<type>",
359 "type" : "<type>",
330 "description" : "<description>",
360 "description" : "<description>",
331 "members" : [
361 "members" : [
332 { "id" : "<userid>",
362 { "id" : "<userid>",
333 "username" : "<username>",
363 "username" : "<username>",
334 "firstname": "<firstname>",
364 "firstname": "<firstname>",
335 "lastname" : "<lastname>",
365 "lastname" : "<lastname>",
336 "email" : "<email>",
366 "email" : "<email>",
337 "active" : "<bool>",
367 "active" : "<bool>",
338 "admin" :Β  "<bool>",
368 "admin" :Β  "<bool>",
339 "ldap" : "<ldap_dn>",
369 "ldap" : "<ldap_dn>",
340 "permission" : "repository.(read|write|admin)"
370 "permission" : "repository.(read|write|admin)"
341 },
371 },
342 …
372 …
343 {
373 {
344 "id" : "<usersgroupid>",
374 "id" : "<usersgroupid>",
345 "name" : "<usersgroupname>",
375 "name" : "<usersgroupname>",
346 "active": "<bool>",
376 "active": "<bool>",
347 "permission" : "repository.(read|write|admin)"
377 "permission" : "repository.(read|write|admin)"
348 },
378 },
349 …
379 …
350 ]
380 ]
351 }
381 }
352 error: null
382 error: null
353
383
354
384
355 get_repos
385 get_repos
356 ---------
386 ---------
357
387
358 Lists all existing repositories. This command can be executed only using api_key
388 Lists all existing repositories. This command can be executed only using api_key
359 belonging to user with admin rights
389 belonging to user with admin rights
360
390
361
391
362 INPUT::
392 INPUT::
363
393
364 api_key : "<api_key>"
394 api_key : "<api_key>"
365 method : "get_repos"
395 method : "get_repos"
366 args: { }
396 args: { }
367
397
368 OUTPUT::
398 OUTPUT::
369
399
370 result: [
400 result: [
371 {
401 {
372 "id" : "<id>",
402 "id" : "<id>",
373 "repo_name" : "<reponame>"
403 "repo_name" : "<reponame>"
374 "type" : "<type>",
404 "type" : "<type>",
375 "description" : "<description>"
405 "description" : "<description>"
376 },
406 },
377 …
407 …
378 ]
408 ]
379 error: null
409 error: null
380
410
381
411
382 get_repo_nodes
412 get_repo_nodes
383 --------------
413 --------------
384
414
385 returns a list of nodes and it's children in a flat list for a given path
415 returns a list of nodes and it's children in a flat list for a given path
386 at given revision. It's possible to specify ret_type to show only `files` or
416 at given revision. It's possible to specify ret_type to show only `files` or
387 `dirs`. This command can be executed only using api_key belonging to user
417 `dirs`. This command can be executed only using api_key belonging to user
388 with admin rights
418 with admin rights
389
419
390
420
391 INPUT::
421 INPUT::
392
422
393 api_key : "<api_key>"
423 api_key : "<api_key>"
394 method : "get_repo_nodes"
424 method : "get_repo_nodes"
395 args: {
425 args: {
396 "repo_name" : "<reponame>",
426 "repo_name" : "<reponame>",
397 "revision" : "<revision>",
427 "revision" : "<revision>",
398 "root_path" : "<root_path>",
428 "root_path" : "<root_path>",
399 "ret_type" : "<ret_type>" = 'all'
429 "ret_type" : "<ret_type>" = 'all'
400 }
430 }
401
431
402 OUTPUT::
432 OUTPUT::
403
433
404 result: [
434 result: [
405 {
435 {
406 "name" : "<name>"
436 "name" : "<name>"
407 "type" : "<type>",
437 "type" : "<type>",
408 },
438 },
409 …
439 …
410 ]
440 ]
411 error: null
441 error: null
412
442
413
443
414 create_repo
444 create_repo
415 -----------
445 -----------
416
446
417 Creates a repository. This command can be executed only using api_key
447 Creates a repository. This command can be executed only using api_key
418 belonging to user with admin rights.
448 belonging to user with admin rights.
419 If repository name contains "/", all needed repository groups will be created.
449 If repository name contains "/", all needed repository groups will be created.
420 For example "foo/bar/baz" will create groups "foo", "bar" (with "foo" as parent),
450 For example "foo/bar/baz" will create groups "foo", "bar" (with "foo" as parent),
421 and create "baz" repository with "bar" as group.
451 and create "baz" repository with "bar" as group.
422
452
423
453
424 INPUT::
454 INPUT::
425
455
426 api_key : "<api_key>"
456 api_key : "<api_key>"
427 method : "create_repo"
457 method : "create_repo"
428 args: {
458 args: {
429 "repo_name" : "<reponame>",
459 "repo_name" : "<reponame>",
430 "owner_name" : "<ownername>",
460 "owner_name" : "<ownername>",
431 "description" : "<description> = ''",
461 "description" : "<description> = ''",
432 "repo_type" : "<type> = 'hg'",
462 "repo_type" : "<type> = 'hg'",
433 "private" : "<bool> = False"
463 "private" : "<bool> = False"
434 }
464 }
435
465
436 OUTPUT::
466 OUTPUT::
437
467
438 result: {
468 result: {
439 "id": "<newrepoid>",
469 "id": "<newrepoid>",
440 "msg": "Created new repository <reponame>",
470 "msg": "Created new repository <reponame>",
441 }
471 }
442 error: null
472 error: null
443
473
444
474
445 grant_user_permission
475 grant_user_permission
446 ---------------------
476 ---------------------
447
477
448 Grant permission for user on given repository, or update existing one
478 Grant permission for user on given repository, or update existing one
449 if found. This command can be executed only using api_key belonging to user
479 if found. This command can be executed only using api_key belonging to user
450 with admin rights.
480 with admin rights.
451
481
452
482
453 INPUT::
483 INPUT::
454
484
455 api_key : "<api_key>"
485 api_key : "<api_key>"
456 method : "grant_user_permission"
486 method : "grant_user_permission"
457 args: {
487 args: {
458 "repo_name" : "<reponame>",
488 "repo_name" : "<reponame>",
459 "username" : "<username>",
489 "username" : "<username>",
460 "perm" : "(repository.(none|read|write|admin))",
490 "perm" : "(repository.(none|read|write|admin))",
461 }
491 }
462
492
463 OUTPUT::
493 OUTPUT::
464
494
465 result: {
495 result: {
466 "msg" : "Granted perm: <perm> for user: <username> in repo: <reponame>"
496 "msg" : "Granted perm: <perm> for user: <username> in repo: <reponame>"
467 }
497 }
468 error: null
498 error: null
469
499
470
500
471 revoke_user_permission
501 revoke_user_permission
472 ----------------------
502 ----------------------
473
503
474 Revoke permission for user on given repository. This command can be executed
504 Revoke permission for user on given repository. This command can be executed
475 only using api_key belonging to user with admin rights.
505 only using api_key belonging to user with admin rights.
476
506
477
507
478 INPUT::
508 INPUT::
479
509
480 api_key : "<api_key>"
510 api_key : "<api_key>"
481 method : "revoke_user_permission"
511 method : "revoke_user_permission"
482 args: {
512 args: {
483 "repo_name" : "<reponame>",
513 "repo_name" : "<reponame>",
484 "username" : "<username>",
514 "username" : "<username>",
485 }
515 }
486
516
487 OUTPUT::
517 OUTPUT::
488
518
489 result: {
519 result: {
490 "msg" : "Revoked perm for user: <suername> in repo: <reponame>"
520 "msg" : "Revoked perm for user: <suername> in repo: <reponame>"
491 }
521 }
492 error: null
522 error: null
493
523
494
524
495 grant_users_group_permission
525 grant_users_group_permission
496 ----------------------------
526 ----------------------------
497
527
498 Grant permission for users group on given repository, or update
528 Grant permission for users group on given repository, or update
499 existing one if found. This command can be executed only using
529 existing one if found. This command can be executed only using
500 api_key belonging to user with admin rights.
530 api_key belonging to user with admin rights.
501
531
502
532
503 INPUT::
533 INPUT::
504
534
505 api_key : "<api_key>"
535 api_key : "<api_key>"
506 method : "grant_users_group_permission"
536 method : "grant_users_group_permission"
507 args: {
537 args: {
508 "repo_name" : "<reponame>",
538 "repo_name" : "<reponame>",
509 "group_name" : "<usersgroupname>",
539 "group_name" : "<usersgroupname>",
510 "perm" : "(repository.(none|read|write|admin))",
540 "perm" : "(repository.(none|read|write|admin))",
511 }
541 }
512
542
513 OUTPUT::
543 OUTPUT::
514
544
515 result: {
545 result: {
516 "msg" : "Granted perm: <perm> for group: <usersgroupname> in repo: <reponame>"
546 "msg" : "Granted perm: <perm> for group: <usersgroupname> in repo: <reponame>"
517 }
547 }
518 error: null
548 error: null
519
549
520
550
521 revoke_users_group_permission
551 revoke_users_group_permission
522 -----------------------------
552 -----------------------------
523
553
524 Revoke permission for users group on given repository.This command can be
554 Revoke permission for users group on given repository.This command can be
525 executed only using api_key belonging to user with admin rights.
555 executed only using api_key belonging to user with admin rights.
526
556
527 INPUT::
557 INPUT::
528
558
529 api_key : "<api_key>"
559 api_key : "<api_key>"
530 method : "revoke_users_group_permission"
560 method : "revoke_users_group_permission"
531 args: {
561 args: {
532 "repo_name" : "<reponame>",
562 "repo_name" : "<reponame>",
533 "users_group" : "<usersgroupname>",
563 "users_group" : "<usersgroupname>",
534 }
564 }
535
565
536 OUTPUT::
566 OUTPUT::
537
567
538 result: {
568 result: {
539 "msg" : "Revoked perm for group: <usersgroupname> in repo: <reponame>"
569 "msg" : "Revoked perm for group: <usersgroupname> in repo: <reponame>"
540 }
570 }
541 error: null No newline at end of file
571 error: null
@@ -1,571 +1,604 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_name):
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_name:
73 :param repo_name:
74 """
74 """
75
75
76 if Repository.is_valid(repo_name) is False:
76 if Repository.is_valid(repo_name) is False:
77 raise JSONRPCError('Unknown repo "%s"' % repo_name)
77 raise JSONRPCError('Unknown repo "%s"' % repo_name)
78
78
79 try:
79 try:
80 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
80 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
81 return 'Pulled from %s' % repo_name
81 return 'Pulled from %s' % repo_name
82 except Exception:
82 except Exception:
83 raise JSONRPCError('Unable to pull changes from "%s"' % repo_name)
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 user is None:
96 return None
96 return user
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, email, firstname=None,
134 def create_user(self, apiuser, username, password, email, firstname=None,
135 lastname=None, active=True, admin=False, ldap_dn=None):
135 lastname=None, active=True, admin=False, ldap_dn=None):
136 """
136 """
137 Create new user or updates current one
137 Create new user or updates current one
138
138
139 :param apiuser:
139 :param apiuser:
140 :param username:
140 :param username:
141 :param password:
141 :param password:
142 :param email:
142 :param email:
143 :param name:
143 :param name:
144 :param lastname:
144 :param lastname:
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 usr = UserModel().create_or_update(
154 usr = UserModel().create_or_update(
155 username, password, email, firstname,
155 username, password, email, firstname,
156 lastname, active, admin, ldap_dn
156 lastname, active, admin, ldap_dn
157 )
157 )
158 Session.commit()
158 Session.commit()
159 return dict(
159 return dict(
160 id=usr.user_id,
160 id=usr.user_id,
161 msg='created new user %s' % username
161 msg='created new user %s' % username
162 )
162 )
163 except Exception:
163 except Exception:
164 log.error(traceback.format_exc())
164 log.error(traceback.format_exc())
165 raise JSONRPCError('failed to create user %s' % username)
165 raise JSONRPCError('failed to create user %s' % username)
166
166
167 @HasPermissionAllDecorator('hg.admin')
167 @HasPermissionAllDecorator('hg.admin')
168 def get_users_group(self, apiuser, group_name):
168 def get_users_group(self, apiuser, group_name):
169 """"
169 """"
170 Get users group by name
170 Get users group by name
171
171
172 :param apiuser:
172 :param apiuser:
173 :param group_name:
173 :param group_name:
174 """
174 """
175
175
176 users_group = UsersGroup.get_by_group_name(group_name)
176 users_group = UsersGroup.get_by_group_name(group_name)
177 if not users_group:
177 if not users_group:
178 return None
178 return None
179
179
180 members = []
180 members = []
181 for user in users_group.members:
181 for user in users_group.members:
182 user = user.user
182 user = user.user
183 members.append(dict(id=user.user_id,
183 members.append(dict(id=user.user_id,
184 username=user.username,
184 username=user.username,
185 firstname=user.name,
185 firstname=user.name,
186 lastname=user.lastname,
186 lastname=user.lastname,
187 email=user.email,
187 email=user.email,
188 active=user.active,
188 active=user.active,
189 admin=user.admin,
189 admin=user.admin,
190 ldap=user.ldap_dn))
190 ldap=user.ldap_dn))
191
191
192 return dict(id=users_group.users_group_id,
192 return dict(id=users_group.users_group_id,
193 group_name=users_group.users_group_name,
193 group_name=users_group.users_group_name,
194 active=users_group.users_group_active,
194 active=users_group.users_group_active,
195 members=members)
195 members=members)
196
196
197 @HasPermissionAllDecorator('hg.admin')
197 @HasPermissionAllDecorator('hg.admin')
198 def get_users_groups(self, apiuser):
198 def get_users_groups(self, apiuser):
199 """"
199 """"
200 Get all users groups
200 Get all users groups
201
201
202 :param apiuser:
202 :param apiuser:
203 """
203 """
204
204
205 result = []
205 result = []
206 for users_group in UsersGroup.getAll():
206 for users_group in UsersGroup.getAll():
207 members = []
207 members = []
208 for user in users_group.members:
208 for user in users_group.members:
209 user = user.user
209 user = user.user
210 members.append(dict(id=user.user_id,
210 members.append(dict(id=user.user_id,
211 username=user.username,
211 username=user.username,
212 firstname=user.name,
212 firstname=user.name,
213 lastname=user.lastname,
213 lastname=user.lastname,
214 email=user.email,
214 email=user.email,
215 active=user.active,
215 active=user.active,
216 admin=user.admin,
216 admin=user.admin,
217 ldap=user.ldap_dn))
217 ldap=user.ldap_dn))
218
218
219 result.append(dict(id=users_group.users_group_id,
219 result.append(dict(id=users_group.users_group_id,
220 group_name=users_group.users_group_name,
220 group_name=users_group.users_group_name,
221 active=users_group.users_group_active,
221 active=users_group.users_group_active,
222 members=members))
222 members=members))
223 return result
223 return result
224
224
225 @HasPermissionAllDecorator('hg.admin')
225 @HasPermissionAllDecorator('hg.admin')
226 def create_users_group(self, apiuser, group_name, active=True):
226 def create_users_group(self, apiuser, group_name, active=True):
227 """
227 """
228 Creates an new usergroup
228 Creates an new usergroup
229
229
230 :param group_name:
230 :param group_name:
231 :param active:
231 :param active:
232 """
232 """
233
233
234 if self.get_users_group(apiuser, group_name):
234 if self.get_users_group(apiuser, group_name):
235 raise JSONRPCError("users group %s already exist" % group_name)
235 raise JSONRPCError("users group %s already exist" % group_name)
236
236
237 try:
237 try:
238 ug = UsersGroupModel().create(name=group_name, active=active)
238 ug = UsersGroupModel().create(name=group_name, active=active)
239 Session.commit()
239 Session.commit()
240 return dict(id=ug.users_group_id,
240 return dict(id=ug.users_group_id,
241 msg='created new users group %s' % group_name)
241 msg='created new users group %s' % group_name)
242 except Exception:
242 except Exception:
243 log.error(traceback.format_exc())
243 log.error(traceback.format_exc())
244 raise JSONRPCError('failed to create group %s' % group_name)
244 raise JSONRPCError('failed to create group %s' % group_name)
245
245
246 @HasPermissionAllDecorator('hg.admin')
246 @HasPermissionAllDecorator('hg.admin')
247 def add_user_to_users_group(self, apiuser, group_name, username):
247 def add_user_to_users_group(self, apiuser, group_name, username):
248 """"
248 """"
249 Add a user to a group
249 Add a user to a group
250
250
251 :param apiuser:
251 :param apiuser:
252 :param group_name:
252 :param group_name:
253 :param username:
253 :param username:
254 """
254 """
255
255
256 try:
256 try:
257 users_group = UsersGroup.get_by_group_name(group_name)
257 users_group = UsersGroup.get_by_group_name(group_name)
258 if not users_group:
258 if not users_group:
259 raise JSONRPCError('unknown users group %s' % group_name)
259 raise JSONRPCError('unknown users group %s' % group_name)
260
260
261 try:
261 user = User.get_by_username(username)
262 user = User.get_by_username(username)
262 if user is None:
263 except NoResultFound:
264 raise JSONRPCError('unknown user %s' % username)
263 raise JSONRPCError('unknown user %s' % username)
265
264
266 ugm = UsersGroupModel().add_user_to_group(users_group, user)
265 ugm = UsersGroupModel().add_user_to_group(users_group, user)
266 success = True if ugm != True else False
267 msg = 'added member %s to users group %s' % (username, group_name)
268 msg = msg if success else 'User is already in that group'
267 Session.commit()
269 Session.commit()
268 return dict(id=ugm.users_group_member_id,
270
269 msg='created new users group member')
271 return dict(
272 id=ugm.users_group_member_id if ugm != True else None,
273 success=success,
274 msg=msg
275 )
270 except Exception:
276 except Exception:
271 log.error(traceback.format_exc())
277 log.error(traceback.format_exc())
272 raise JSONRPCError('failed to create users group member')
278 raise JSONRPCError('failed to add users group member')
279
280 @HasPermissionAllDecorator('hg.admin')
281 def remove_user_from_users_group(self, apiuser, group_name, username):
282 """
283 Remove user from a group
284
285 :param apiuser
286 :param group_name
287 :param username
288 """
289
290 try:
291 users_group = UsersGroup.get_by_group_name(group_name)
292 if not users_group:
293 raise JSONRPCError('unknown users group %s' % group_name)
294
295 user = User.get_by_username(username)
296 if user is None:
297 raise JSONRPCError('unknown user %s' % username)
298
299 success = UsersGroupModel().remove_user_from_group(users_group, user)
300 msg = 'removed member %s from users group %s' % (username, group_name)
301 msg = msg if success else "User wasn't in group"
302 Session.commit()
303 return dict(success=success, msg=msg)
304 except Exception:
305 log.error(traceback.format_exc())
306 raise JSONRPCError('failed to remove user from group')
273
307
274 @HasPermissionAnyDecorator('hg.admin')
308 @HasPermissionAnyDecorator('hg.admin')
275 def get_repo(self, apiuser, repo_name):
309 def get_repo(self, apiuser, repo_name):
276 """"
310 """"
277 Get repository by name
311 Get repository by name
278
312
279 :param apiuser:
313 :param apiuser:
280 :param repo_name:
314 :param repo_name:
281 """
315 """
282
316
283 repo = Repository.get_by_repo_name(repo_name)
317 repo = Repository.get_by_repo_name(repo_name)
284 if repo is None:
318 if repo is None:
285 raise JSONRPCError('unknown repository %s' % repo)
319 raise JSONRPCError('unknown repository %s' % repo)
286
320
287 members = []
321 members = []
288 for user in repo.repo_to_perm:
322 for user in repo.repo_to_perm:
289 perm = user.permission.permission_name
323 perm = user.permission.permission_name
290 user = user.user
324 user = user.user
291 members.append(
325 members.append(
292 dict(
326 dict(
293 type_="user",
327 type_="user",
294 id=user.user_id,
328 id=user.user_id,
295 username=user.username,
329 username=user.username,
296 firstname=user.name,
330 firstname=user.name,
297 lastname=user.lastname,
331 lastname=user.lastname,
298 email=user.email,
332 email=user.email,
299 active=user.active,
333 active=user.active,
300 admin=user.admin,
334 admin=user.admin,
301 ldap=user.ldap_dn,
335 ldap=user.ldap_dn,
302 permission=perm
336 permission=perm
303 )
337 )
304 )
338 )
305 for users_group in repo.users_group_to_perm:
339 for users_group in repo.users_group_to_perm:
306 perm = users_group.permission.permission_name
340 perm = users_group.permission.permission_name
307 users_group = users_group.users_group
341 users_group = users_group.users_group
308 members.append(
342 members.append(
309 dict(
343 dict(
310 type_="users_group",
344 type_="users_group",
311 id=users_group.users_group_id,
345 id=users_group.users_group_id,
312 name=users_group.users_group_name,
346 name=users_group.users_group_name,
313 active=users_group.users_group_active,
347 active=users_group.users_group_active,
314 permission=perm
348 permission=perm
315 )
349 )
316 )
350 )
317
351
318 return dict(
352 return dict(
319 id=repo.repo_id,
353 id=repo.repo_id,
320 repo_name=repo.repo_name,
354 repo_name=repo.repo_name,
321 type=repo.repo_type,
355 type=repo.repo_type,
322 description=repo.description,
356 description=repo.description,
323 members=members
357 members=members
324 )
358 )
325
359
326 @HasPermissionAnyDecorator('hg.admin')
360 @HasPermissionAnyDecorator('hg.admin')
327 def get_repos(self, apiuser):
361 def get_repos(self, apiuser):
328 """"
362 """"
329 Get all repositories
363 Get all repositories
330
364
331 :param apiuser:
365 :param apiuser:
332 """
366 """
333
367
334 result = []
368 result = []
335 for repository in Repository.getAll():
369 for repository in Repository.getAll():
336 result.append(
370 result.append(
337 dict(
371 dict(
338 id=repository.repo_id,
372 id=repository.repo_id,
339 repo_name=repository.repo_name,
373 repo_name=repository.repo_name,
340 type=repository.repo_type,
374 type=repository.repo_type,
341 description=repository.description
375 description=repository.description
342 )
376 )
343 )
377 )
344 return result
378 return result
345
379
346 @HasPermissionAnyDecorator('hg.admin')
380 @HasPermissionAnyDecorator('hg.admin')
347 def get_repo_nodes(self, apiuser, repo_name, revision, root_path,
381 def get_repo_nodes(self, apiuser, repo_name, revision, root_path,
348 ret_type='all'):
382 ret_type='all'):
349 """
383 """
350 returns a list of nodes and it's children
384 returns a list of nodes and it's children
351 for a given path at given revision. It's possible to specify ret_type
385 for a given path at given revision. It's possible to specify ret_type
352 to show only files or dirs
386 to show only files or dirs
353
387
354 :param apiuser:
388 :param apiuser:
355 :param repo_name: name of repository
389 :param repo_name: name of repository
356 :param revision: revision for which listing should be done
390 :param revision: revision for which listing should be done
357 :param root_path: path from which start displaying
391 :param root_path: path from which start displaying
358 :param ret_type: return type 'all|files|dirs' nodes
392 :param ret_type: return type 'all|files|dirs' nodes
359 """
393 """
360 try:
394 try:
361 _d, _f = ScmModel().get_nodes(repo_name, revision, root_path,
395 _d, _f = ScmModel().get_nodes(repo_name, revision, root_path,
362 flat=False)
396 flat=False)
363 _map = {
397 _map = {
364 'all': _d + _f,
398 'all': _d + _f,
365 'files': _f,
399 'files': _f,
366 'dirs': _d,
400 'dirs': _d,
367 }
401 }
368 return _map[ret_type]
402 return _map[ret_type]
369 except KeyError:
403 except KeyError:
370 raise JSONRPCError('ret_type must be one of %s' % _map.keys())
404 raise JSONRPCError('ret_type must be one of %s' % _map.keys())
371 except Exception, e:
405 except Exception, e:
372 raise JSONRPCError(e)
406 raise JSONRPCError(e)
373
407
374 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
408 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
375 def create_repo(self, apiuser, repo_name, owner_name, description='',
409 def create_repo(self, apiuser, repo_name, owner_name, description='',
376 repo_type='hg', private=False):
410 repo_type='hg', private=False):
377 """
411 """
378 Create a repository
412 Create a repository
379
413
380 :param apiuser:
414 :param apiuser:
381 :param repo_name:
415 :param repo_name:
382 :param description:
416 :param description:
383 :param type:
417 :param type:
384 :param private:
418 :param private:
385 :param owner_name:
419 :param owner_name:
386 """
420 """
387
421
388 try:
422 try:
389 try:
423 owner = User.get_by_username(owner_name)
390 owner = User.get_by_username(owner_name)
424 if owner is None:
391 except NoResultFound:
425 raise JSONRPCError('unknown user %s' % owner_name)
392 raise JSONRPCError('unknown user %s' % owner)
393
426
394 if Repository.get_by_repo_name(repo_name):
427 if Repository.get_by_repo_name(repo_name):
395 raise JSONRPCError("repo %s already exist" % repo_name)
428 raise JSONRPCError("repo %s already exist" % repo_name)
396
429
397 groups = repo_name.split('/')
430 groups = repo_name.split('/')
398 real_name = groups[-1]
431 real_name = groups[-1]
399 groups = groups[:-1]
432 groups = groups[:-1]
400 parent_id = None
433 parent_id = None
401 for g in groups:
434 for g in groups:
402 group = RepoGroup.get_by_group_name(g)
435 group = RepoGroup.get_by_group_name(g)
403 if not group:
436 if not group:
404 group = ReposGroupModel().create(g, '', parent_id)
437 group = ReposGroupModel().create(g, '', parent_id)
405 parent_id = group.group_id
438 parent_id = group.group_id
406
439
407 repo = RepoModel().create(
440 repo = RepoModel().create(
408 dict(
441 dict(
409 repo_name=real_name,
442 repo_name=real_name,
410 repo_name_full=repo_name,
443 repo_name_full=repo_name,
411 description=description,
444 description=description,
412 private=private,
445 private=private,
413 repo_type=repo_type,
446 repo_type=repo_type,
414 repo_group=parent_id,
447 repo_group=parent_id,
415 clone_uri=None
448 clone_uri=None
416 ),
449 ),
417 owner
450 owner
418 )
451 )
419 Session.commit()
452 Session.commit()
420
453
421 return dict(
454 return dict(
422 id=repo.repo_id,
455 id=repo.repo_id,
423 msg="Created new repository %s" % repo.repo_name
456 msg="Created new repository %s" % repo.repo_name
424 )
457 )
425
458
426 except Exception:
459 except Exception:
427 log.error(traceback.format_exc())
460 log.error(traceback.format_exc())
428 raise JSONRPCError('failed to create repository %s' % repo_name)
461 raise JSONRPCError('failed to create repository %s' % repo_name)
429
462
430 @HasPermissionAnyDecorator('hg.admin')
463 @HasPermissionAnyDecorator('hg.admin')
431 def grant_user_permission(self, repo_name, username, perm):
464 def grant_user_permission(self, repo_name, username, perm):
432 """
465 """
433 Grant permission for user on given repository, or update existing one
466 Grant permission for user on given repository, or update existing one
434 if found
467 if found
435
468
436 :param repo_name:
469 :param repo_name:
437 :param username:
470 :param username:
438 :param perm:
471 :param perm:
439 """
472 """
440
473
441 try:
474 try:
442 repo = Repository.get_by_repo_name(repo_name)
475 repo = Repository.get_by_repo_name(repo_name)
443 if repo is None:
476 if repo is None:
444 raise JSONRPCError('unknown repository %s' % repo)
477 raise JSONRPCError('unknown repository %s' % repo)
445
478
446 user = User.get_by_username(username)
479 user = User.get_by_username(username)
447 if user is None:
480 if user is None:
448 raise JSONRPCError('unknown user %s' % username)
481 raise JSONRPCError('unknown user %s' % username)
449
482
450 RepoModel().grant_user_permission(repo=repo, user=user, perm=perm)
483 RepoModel().grant_user_permission(repo=repo, user=user, perm=perm)
451
484
452 Session.commit()
485 Session.commit()
453 return dict(
486 return dict(
454 msg='Granted perm: %s for user: %s in repo: %s' % (
487 msg='Granted perm: %s for user: %s in repo: %s' % (
455 perm, username, repo_name
488 perm, username, repo_name
456 )
489 )
457 )
490 )
458 except Exception:
491 except Exception:
459 log.error(traceback.format_exc())
492 log.error(traceback.format_exc())
460 raise JSONRPCError(
493 raise JSONRPCError(
461 'failed to edit permission %(repo)s for %(user)s' % dict(
494 'failed to edit permission %(repo)s for %(user)s' % dict(
462 user=username, repo=repo_name
495 user=username, repo=repo_name
463 )
496 )
464 )
497 )
465
498
466 @HasPermissionAnyDecorator('hg.admin')
499 @HasPermissionAnyDecorator('hg.admin')
467 def revoke_user_permission(self, repo_name, username):
500 def revoke_user_permission(self, repo_name, username):
468 """
501 """
469 Revoke permission for user on given repository
502 Revoke permission for user on given repository
470
503
471 :param repo_name:
504 :param repo_name:
472 :param username:
505 :param username:
473 """
506 """
474
507
475 try:
508 try:
476 repo = Repository.get_by_repo_name(repo_name)
509 repo = Repository.get_by_repo_name(repo_name)
477 if repo is None:
510 if repo is None:
478 raise JSONRPCError('unknown repository %s' % repo)
511 raise JSONRPCError('unknown repository %s' % repo)
479
512
480 user = User.get_by_username(username)
513 user = User.get_by_username(username)
481 if user is None:
514 if user is None:
482 raise JSONRPCError('unknown user %s' % username)
515 raise JSONRPCError('unknown user %s' % username)
483
516
484 RepoModel().revoke_user_permission(repo=repo_name, user=username)
517 RepoModel().revoke_user_permission(repo=repo_name, user=username)
485
518
486 Session.commit()
519 Session.commit()
487 return dict(
520 return dict(
488 msg='Revoked perm for user: %s in repo: %s' % (
521 msg='Revoked perm for user: %s in repo: %s' % (
489 username, repo_name
522 username, repo_name
490 )
523 )
491 )
524 )
492 except Exception:
525 except Exception:
493 log.error(traceback.format_exc())
526 log.error(traceback.format_exc())
494 raise JSONRPCError(
527 raise JSONRPCError(
495 'failed to edit permission %(repo)s for %(user)s' % dict(
528 'failed to edit permission %(repo)s for %(user)s' % dict(
496 user=username, repo=repo_name
529 user=username, repo=repo_name
497 )
530 )
498 )
531 )
499
532
500 @HasPermissionAnyDecorator('hg.admin')
533 @HasPermissionAnyDecorator('hg.admin')
501 def grant_users_group_permission(self, repo_name, group_name, perm):
534 def grant_users_group_permission(self, repo_name, group_name, perm):
502 """
535 """
503 Grant permission for users group on given repository, or update
536 Grant permission for users group on given repository, or update
504 existing one if found
537 existing one if found
505
538
506 :param repo_name:
539 :param repo_name:
507 :param group_name:
540 :param group_name:
508 :param perm:
541 :param perm:
509 """
542 """
510
543
511 try:
544 try:
512 repo = Repository.get_by_repo_name(repo_name)
545 repo = Repository.get_by_repo_name(repo_name)
513 if repo is None:
546 if repo is None:
514 raise JSONRPCError('unknown repository %s' % repo)
547 raise JSONRPCError('unknown repository %s' % repo)
515
548
516 user_group = UsersGroup.get_by_group_name(group_name)
549 user_group = UsersGroup.get_by_group_name(group_name)
517 if user_group is None:
550 if user_group is None:
518 raise JSONRPCError('unknown users group %s' % user_group)
551 raise JSONRPCError('unknown users group %s' % user_group)
519
552
520 RepoModel().grant_users_group_permission(repo=repo_name,
553 RepoModel().grant_users_group_permission(repo=repo_name,
521 group_name=group_name,
554 group_name=group_name,
522 perm=perm)
555 perm=perm)
523
556
524 Session.commit()
557 Session.commit()
525 return dict(
558 return dict(
526 msg='Granted perm: %s for group: %s in repo: %s' % (
559 msg='Granted perm: %s for group: %s in repo: %s' % (
527 perm, group_name, repo_name
560 perm, group_name, repo_name
528 )
561 )
529 )
562 )
530 except Exception:
563 except Exception:
531 log.error(traceback.format_exc())
564 log.error(traceback.format_exc())
532 raise JSONRPCError(
565 raise JSONRPCError(
533 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
566 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
534 usersgr=group_name, repo=repo_name
567 usersgr=group_name, repo=repo_name
535 )
568 )
536 )
569 )
537
570
538 @HasPermissionAnyDecorator('hg.admin')
571 @HasPermissionAnyDecorator('hg.admin')
539 def revoke_users_group_permission(self, repo_name, group_name):
572 def revoke_users_group_permission(self, repo_name, group_name):
540 """
573 """
541 Revoke permission for users group on given repository
574 Revoke permission for users group on given repository
542
575
543 :param repo_name:
576 :param repo_name:
544 :param group_name:
577 :param group_name:
545 """
578 """
546
579
547 try:
580 try:
548 repo = Repository.get_by_repo_name(repo_name)
581 repo = Repository.get_by_repo_name(repo_name)
549 if repo is None:
582 if repo is None:
550 raise JSONRPCError('unknown repository %s' % repo)
583 raise JSONRPCError('unknown repository %s' % repo)
551
584
552 user_group = UsersGroup.get_by_group_name(group_name)
585 user_group = UsersGroup.get_by_group_name(group_name)
553 if user_group is None:
586 if user_group is None:
554 raise JSONRPCError('unknown users group %s' % user_group)
587 raise JSONRPCError('unknown users group %s' % user_group)
555
588
556 RepoModel().revoke_users_group_permission(repo=repo_name,
589 RepoModel().revoke_users_group_permission(repo=repo_name,
557 group_name=group_name)
590 group_name=group_name)
558
591
559 Session.commit()
592 Session.commit()
560 return dict(
593 return dict(
561 msg='Revoked perm for group: %s in repo: %s' % (
594 msg='Revoked perm for group: %s in repo: %s' % (
562 group_name, repo_name
595 group_name, repo_name
563 )
596 )
564 )
597 )
565 except Exception:
598 except Exception:
566 log.error(traceback.format_exc())
599 log.error(traceback.format_exc())
567 raise JSONRPCError(
600 raise JSONRPCError(
568 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
601 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
569 usersgr=group_name, repo=repo_name
602 usersgr=group_name, repo=repo_name
570 )
603 )
571 )
604 )
@@ -1,160 +1,188 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.model.users_group
3 rhodecode.model.users_group
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 users group model for RhodeCode
6 users group model for RhodeCode
7
7
8 :created_on: Oct 1, 2011
8 :created_on: Oct 1, 2011
9 :author: nvinot
9 :author: nvinot
10 :copyright: (C) 2011-2011 Nicolas Vinot <aeris@imirhil.fr>
10 :copyright: (C) 2011-2011 Nicolas Vinot <aeris@imirhil.fr>
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
12 :license: GPLv3, see COPYING for more details.
12 :license: GPLv3, see COPYING for more details.
13 """
13 """
14 # This program is free software: you can redistribute it and/or modify
14 # This program is free software: you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation, either version 3 of the License, or
16 # the Free Software Foundation, either version 3 of the License, or
17 # (at your option) any later version.
17 # (at your option) any later version.
18 #
18 #
19 # This program is distributed in the hope that it will be useful,
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
22 # GNU General Public License for more details.
23 #
23 #
24 # You should have received a copy of the GNU General Public License
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26
26
27 import logging
27 import logging
28 import traceback
28 import traceback
29
29
30 from rhodecode.model import BaseModel
30 from rhodecode.model import BaseModel
31 from rhodecode.model.db import UsersGroupMember, UsersGroup,\
31 from rhodecode.model.db import UsersGroupMember, UsersGroup,\
32 UsersGroupRepoToPerm, Permission, UsersGroupToPerm
32 UsersGroupRepoToPerm, Permission, UsersGroupToPerm, User
33 from rhodecode.lib.exceptions import UsersGroupsAssignedException
33 from rhodecode.lib.exceptions import UsersGroupsAssignedException
34
34
35 log = logging.getLogger(__name__)
35 log = logging.getLogger(__name__)
36
36
37
37
38 class UsersGroupModel(BaseModel):
38 class UsersGroupModel(BaseModel):
39
39
40 def __get_user(self, user):
41 return self._get_instance(User, user, callback=User.get_by_username)
42
40 def __get_users_group(self, users_group):
43 def __get_users_group(self, users_group):
41 return self._get_instance(UsersGroup, users_group,
44 return self._get_instance(UsersGroup, users_group,
42 callback=UsersGroup.get_by_group_name)
45 callback=UsersGroup.get_by_group_name)
43
46
44 def __get_perm(self, permission):
47 def __get_perm(self, permission):
45 return self._get_instance(Permission, permission,
48 return self._get_instance(Permission, permission,
46 callback=Permission.get_by_key)
49 callback=Permission.get_by_key)
47
50
48 def get(self, users_group_id, cache=False):
51 def get(self, users_group_id, cache=False):
49 return UsersGroup.get(users_group_id)
52 return UsersGroup.get(users_group_id)
50
53
51 def get_by_name(self, name, cache=False, case_insensitive=False):
54 def get_by_name(self, name, cache=False, case_insensitive=False):
52 return UsersGroup.get_by_group_name(name, cache, case_insensitive)
55 return UsersGroup.get_by_group_name(name, cache, case_insensitive)
53
56
54 def create(self, name, active=True):
57 def create(self, name, active=True):
55 try:
58 try:
56 new = UsersGroup()
59 new = UsersGroup()
57 new.users_group_name = name
60 new.users_group_name = name
58 new.users_group_active = active
61 new.users_group_active = active
59 self.sa.add(new)
62 self.sa.add(new)
60 return new
63 return new
61 except:
64 except:
62 log.error(traceback.format_exc())
65 log.error(traceback.format_exc())
63 raise
66 raise
64
67
65 def update(self, users_group, form_data):
68 def update(self, users_group, form_data):
66
69
67 try:
70 try:
68 users_group = self.__get_users_group(users_group)
71 users_group = self.__get_users_group(users_group)
69
72
70 for k, v in form_data.items():
73 for k, v in form_data.items():
71 if k == 'users_group_members':
74 if k == 'users_group_members':
72 users_group.members = []
75 users_group.members = []
73 self.sa.flush()
76 self.sa.flush()
74 members_list = []
77 members_list = []
75 if v:
78 if v:
76 v = [v] if isinstance(v, basestring) else v
79 v = [v] if isinstance(v, basestring) else v
77 for u_id in set(v):
80 for u_id in set(v):
78 member = UsersGroupMember(users_group.users_group_id, u_id)
81 member = UsersGroupMember(users_group.users_group_id, u_id)
79 members_list.append(member)
82 members_list.append(member)
80 setattr(users_group, 'members', members_list)
83 setattr(users_group, 'members', members_list)
81 setattr(users_group, k, v)
84 setattr(users_group, k, v)
82
85
83 self.sa.add(users_group)
86 self.sa.add(users_group)
84 except:
87 except:
85 log.error(traceback.format_exc())
88 log.error(traceback.format_exc())
86 raise
89 raise
87
90
88 def delete(self, users_group, force=False):
91 def delete(self, users_group, force=False):
89 """
92 """
90 Deletes repos group, unless force flag is used
93 Deletes repos group, unless force flag is used
91 raises exception if there are members in that group, else deletes
94 raises exception if there are members in that group, else deletes
92 group and users
95 group and users
93
96
94 :param users_group:
97 :param users_group:
95 :param force:
98 :param force:
96 """
99 """
97 try:
100 try:
98 users_group = self.__get_users_group(users_group)
101 users_group = self.__get_users_group(users_group)
99
102
100 # check if this group is not assigned to repo
103 # check if this group is not assigned to repo
101 assigned_groups = UsersGroupRepoToPerm.query()\
104 assigned_groups = UsersGroupRepoToPerm.query()\
102 .filter(UsersGroupRepoToPerm.users_group == users_group).all()
105 .filter(UsersGroupRepoToPerm.users_group == users_group).all()
103
106
104 if assigned_groups and force is False:
107 if assigned_groups and force is False:
105 raise UsersGroupsAssignedException('RepoGroup assigned to %s' %
108 raise UsersGroupsAssignedException('RepoGroup assigned to %s' %
106 assigned_groups)
109 assigned_groups)
107
110
108 self.sa.delete(users_group)
111 self.sa.delete(users_group)
109 except:
112 except:
110 log.error(traceback.format_exc())
113 log.error(traceback.format_exc())
111 raise
114 raise
112
115
113 def add_user_to_group(self, users_group, user):
116 def add_user_to_group(self, users_group, user):
117 users_group = self.__get_users_group(users_group)
118 user = self.__get_user(user)
119
114 for m in users_group.members:
120 for m in users_group.members:
115 u = m.user
121 u = m.user
116 if u.user_id == user.user_id:
122 if u.user_id == user.user_id:
117 return m
123 return True
118
124
119 try:
125 try:
120 users_group_member = UsersGroupMember()
126 users_group_member = UsersGroupMember()
121 users_group_member.user = user
127 users_group_member.user = user
122 users_group_member.users_group = users_group
128 users_group_member.users_group = users_group
123
129
124 users_group.members.append(users_group_member)
130 users_group.members.append(users_group_member)
125 user.group_member.append(users_group_member)
131 user.group_member.append(users_group_member)
126
132
127 self.sa.add(users_group_member)
133 self.sa.add(users_group_member)
128 return users_group_member
134 return users_group_member
129 except:
135 except:
130 log.error(traceback.format_exc())
136 log.error(traceback.format_exc())
131 raise
137 raise
132
138
139 def remove_user_from_group(self, users_group, user):
140 users_group = self.__get_users_group(users_group)
141 user = self.__get_user(user)
142
143 users_group_member = None
144 for m in users_group.members:
145 if m.user.user_id == user.user_id:
146 # Found this user's membership row
147 users_group_member = m
148 break
149
150 if users_group_member:
151 try:
152 self.sa.delete(users_group_member)
153 return True
154 except:
155 log.error(traceback.format_exc())
156 raise
157 else:
158 # User isn't in that group
159 return False
160
133 def has_perm(self, users_group, perm):
161 def has_perm(self, users_group, perm):
134 users_group = self.__get_users_group(users_group)
162 users_group = self.__get_users_group(users_group)
135 perm = self.__get_perm(perm)
163 perm = self.__get_perm(perm)
136
164
137 return UsersGroupToPerm.query()\
165 return UsersGroupToPerm.query()\
138 .filter(UsersGroupToPerm.users_group == users_group)\
166 .filter(UsersGroupToPerm.users_group == users_group)\
139 .filter(UsersGroupToPerm.permission == perm).scalar() is not None
167 .filter(UsersGroupToPerm.permission == perm).scalar() is not None
140
168
141 def grant_perm(self, users_group, perm):
169 def grant_perm(self, users_group, perm):
142 if not isinstance(perm, Permission):
170 if not isinstance(perm, Permission):
143 raise Exception('perm needs to be an instance of Permission class')
171 raise Exception('perm needs to be an instance of Permission class')
144
172
145 users_group = self.__get_users_group(users_group)
173 users_group = self.__get_users_group(users_group)
146
174
147 new = UsersGroupToPerm()
175 new = UsersGroupToPerm()
148 new.users_group = users_group
176 new.users_group = users_group
149 new.permission = perm
177 new.permission = perm
150 self.sa.add(new)
178 self.sa.add(new)
151
179
152 def revoke_perm(self, users_group, perm):
180 def revoke_perm(self, users_group, perm):
153 users_group = self.__get_users_group(users_group)
181 users_group = self.__get_users_group(users_group)
154 perm = self.__get_perm(perm)
182 perm = self.__get_perm(perm)
155
183
156 obj = UsersGroupToPerm.query()\
184 obj = UsersGroupToPerm.query()\
157 .filter(UsersGroupToPerm.users_group == users_group)\
185 .filter(UsersGroupToPerm.users_group == users_group)\
158 .filter(UsersGroupToPerm.permission == perm).scalar()
186 .filter(UsersGroupToPerm.permission == perm).scalar()
159 if obj:
187 if obj:
160 self.sa.delete(obj)
188 self.sa.delete(obj)
General Comments 0
You need to be logged in to leave comments. Login now