##// END OF EJS Templates
API: update_user returns new updated user data
marcink -
r2507:374693af beta
parent child Browse files
Show More
@@ -1,753 +1,764 b''
1 1 .. _api:
2 2
3 3 ===
4 4 API
5 5 ===
6 6
7 7
8 8 Starting from RhodeCode version 1.2 a simple API was implemented.
9 9 There's a single schema for calling all api methods. API is implemented
10 10 with JSON protocol both ways. An url to send API request in RhodeCode is
11 11 <your_server>/_admin/api
12 12
13 13 API ACCESS FOR WEB VIEWS
14 14 ++++++++++++++++++++++++
15 15
16 16 API access can also be turned on for each web view in RhodeCode that is
17 17 decorated with `@LoginRequired` decorator. To enable API access simple change
18 18 the standard login decorator to `@LoginRequired(api_access=True)`.
19 19 After this change, a rhodecode view can be accessed without login by adding a
20 20 GET parameter `?api_key=<api_key>` to url. By default this is only
21 21 enabled on RSS/ATOM feed views.
22 22
23 23
24 24 API ACCESS
25 25 ++++++++++
26 26
27 27 All clients are required to send JSON-RPC spec JSON data::
28 28
29 29 {
30 30 "id:"<id>",
31 31 "api_key":"<api_key>",
32 32 "method":"<method_name>",
33 33 "args":{"<arg_key>":"<arg_val>"}
34 34 }
35 35
36 36 Example call for autopulling remotes repos using curl::
37 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 39 Simply provide
40 40 - *id* A value of any type, which is used to match the response with the request that it is replying to.
41 41 - *api_key* for access and permission validation.
42 42 - *method* is name of method to call
43 43 - *args* is an key:value list of arguments to pass to method
44 44
45 45 .. note::
46 46
47 47 api_key can be found in your user account page
48 48
49 49
50 50 RhodeCode API will return always a JSON-RPC response::
51 51
52 52 {
53 53 "id":<id>, # matching id sent by request
54 54 "result": "<result>"|null, # JSON formatted result, null if any errors
55 55 "error": "null"|<error_message> # JSON formatted error (if any)
56 56 }
57 57
58 58 All responses from API will be `HTTP/1.0 200 OK`, if there's an error while
59 59 calling api *error* key from response will contain failure description
60 60 and result will be null.
61 61
62 62
63 63 API CLIENT
64 64 ++++++++++
65 65
66 66 From version 1.4 RhodeCode adds a binary script that allows to easily
67 67 communicate with API. After installing RhodeCode a `rhodecode-api` script
68 68 will be available.
69 69
70 70 To get started quickly simply run::
71 71
72 72 rhodecode-api _create_config --apikey=<youapikey> --apihost=<rhodecode host>
73 73
74 74 This will create a file named .config in the directory you executed it storing
75 75 json config file with credentials. You can skip this step and always provide
76 76 both of the arguments to be able to communicate with server
77 77
78 78
79 79 after that simply run any api command for example get_repo::
80 80
81 81 rhodecode-api get_repo
82 82
83 83 calling {"api_key": "<apikey>", "id": 75, "args": {}, "method": "get_repo"} to http://127.0.0.1:5000
84 84 rhodecode said:
85 85 {'error': 'Missing non optional `repoid` arg in JSON DATA',
86 86 'id': 75,
87 87 'result': None}
88 88
89 89 Ups looks like we forgot to add an argument
90 90
91 91 Let's try again now giving the repoid as parameters::
92 92
93 93 rhodecode-api get_repo repoid:rhodecode
94 94
95 95 calling {"api_key": "<apikey>", "id": 39, "args": {"repoid": "rhodecode"}, "method": "get_repo"} to http://127.0.0.1:5000
96 96 rhodecode said:
97 97 {'error': None,
98 98 'id': 39,
99 99 'result': <json data...>}
100 100
101 101
102 102
103 103 API METHODS
104 104 +++++++++++
105 105
106 106
107 107 pull
108 108 ----
109 109
110 110 Pulls given repo from remote location. Can be used to automatically keep
111 111 remote repos up to date. This command can be executed only using api_key
112 112 belonging to user with admin rights
113 113
114 114 INPUT::
115 115
116 116 id : <id_for_response>
117 117 api_key : "<api_key>"
118 118 method : "pull"
119 119 args : {
120 120 "repo_name" : "<reponame>"
121 121 }
122 122
123 123 OUTPUT::
124 124
125 125 result : "Pulled from <reponame>"
126 126 error : null
127 127
128 128
129 129 get_user
130 130 --------
131 131
132 132 Get's an user by username or user_id, Returns empty result if user is not found.
133 133 This command can be executed only using api_key belonging to user with admin
134 134 rights.
135 135
136 136
137 137 INPUT::
138 138
139 139 id : <id_for_response>
140 140 api_key : "<api_key>"
141 141 method : "get_user"
142 142 args : {
143 143 "userid" : "<username or user_id>"
144 144 }
145 145
146 146 OUTPUT::
147 147
148 148 result: None if user does not exist or
149 149 {
150 150 "id" : "<id>",
151 151 "username" : "<username>",
152 152 "firstname": "<firstname>",
153 153 "lastname" : "<lastname>",
154 154 "email" : "<email>",
155 155 "emails": "<list_of_all_additional_emails>",
156 156 "active" : "<bool>",
157 157 "admin" :Β  "<bool>",
158 158 "ldap_dn" : "<ldap_dn>",
159 159 "last_login": "<last_login>",
160 160 "permissions": {
161 161 "global": ["hg.create.repository",
162 162 "repository.read",
163 163 "hg.register.manual_activate"],
164 164 "repositories": {"repo1": "repository.none"},
165 165 "repositories_groups": {"Group1": "group.read"}
166 166 },
167 167 }
168 168
169 169 error: null
170 170
171 171
172 172 get_users
173 173 ---------
174 174
175 175 Lists all existing users. This command can be executed only using api_key
176 176 belonging to user with admin rights.
177 177
178 178
179 179 INPUT::
180 180
181 181 id : <id_for_response>
182 182 api_key : "<api_key>"
183 183 method : "get_users"
184 184 args : { }
185 185
186 186 OUTPUT::
187 187
188 188 result: [
189 189 {
190 190 "id" : "<id>",
191 191 "username" : "<username>",
192 192 "firstname": "<firstname>",
193 193 "lastname" : "<lastname>",
194 194 "email" : "<email>",
195 195 "active" : "<bool>",
196 196 "admin" :Β  "<bool>",
197 197 "ldap_dn" : "<ldap_dn>",
198 198 "last_login": "<last_login>",
199 199 },
200 200 …
201 201 ]
202 202 error: null
203 203
204 204
205 205 create_user
206 206 -----------
207 207
208 208 Creates new user. This command can
209 209 be executed only using api_key belonging to user with admin rights.
210 210
211 211
212 212 INPUT::
213 213
214 214 id : <id_for_response>
215 215 api_key : "<api_key>"
216 216 method : "create_user"
217 217 args : {
218 218 "username" : "<username>",
219 219 "password" : "<password>",
220 220 "email" : "<useremail>",
221 221 "firstname" : "<firstname> = None",
222 222 "lastname" : "<lastname> = None",
223 223 "active" : "<bool> = True",
224 224 "admin" : "<bool> = False",
225 225 "ldap_dn" : "<ldap_dn> = None"
226 226 }
227 227
228 228 OUTPUT::
229 229
230 230 result: {
231 231 "id" : "<new_user_id>",
232 232 "msg" : "created new user <username>",
233 233 "user": {
234 234 "id" : "<id>",
235 235 "username" : "<username>",
236 236 "firstname": "<firstname>",
237 237 "lastname" : "<lastname>",
238 238 "email" : "<email>",
239 239 "active" : "<bool>",
240 240 "admin" :Β  "<bool>",
241 241 "ldap_dn" : "<ldap_dn>",
242 242 "last_login": "<last_login>",
243 243 },
244 244 }
245 245 error: null
246 246
247 247
248 248 update_user
249 249 -----------
250 250
251 251 updates given user if such user exists. This command can
252 252 be executed only using api_key belonging to user with admin rights.
253 253
254 254
255 255 INPUT::
256 256
257 257 id : <id_for_response>
258 258 api_key : "<api_key>"
259 259 method : "update_user"
260 260 args : {
261 261 "userid" : "<user_id or username>",
262 262 "username" : "<username>",
263 263 "password" : "<password>",
264 264 "email" : "<useremail>",
265 265 "firstname" : "<firstname>",
266 266 "lastname" : "<lastname>",
267 267 "active" : "<bool>",
268 268 "admin" : "<bool>",
269 269 "ldap_dn" : "<ldap_dn>"
270 270 }
271 271
272 272 OUTPUT::
273 273
274 274 result: {
275 275 "id" : "<edited_user_id>",
276 "msg" : "updated user ID:<userid> <username>"
276 "msg" : "updated user ID:<userid> <username>",
277 "user": {
278 "id" : "<id>",
279 "username" : "<username>",
280 "firstname": "<firstname>",
281 "lastname" : "<lastname>",
282 "email" : "<email>",
283 "active" : "<bool>",
284 "admin" :Β  "<bool>",
285 "ldap_dn" : "<ldap_dn>",
286 "last_login": "<last_login>",
287 },
277 288 }
278 289 error: null
279 290
280 291
281 292 delete_user
282 293 -----------
283 294
284 295
285 296 deletes givenuser if such user exists. This command can
286 297 be executed only using api_key belonging to user with admin rights.
287 298
288 299
289 300 INPUT::
290 301
291 302 id : <id_for_response>
292 303 api_key : "<api_key>"
293 304 method : "delete_user"
294 305 args : {
295 306 "userid" : "<user_id or username>",
296 307 }
297 308
298 309 OUTPUT::
299 310
300 311 result: {
301 312 "id" : "<edited_user_id>",
302 313 "msg" : "deleted user ID:<userid> <username>"
303 314 }
304 315 error: null
305 316
306 317
307 318 get_users_group
308 319 ---------------
309 320
310 321 Gets an existing users group. This command can be executed only using api_key
311 322 belonging to user with admin rights.
312 323
313 324
314 325 INPUT::
315 326
316 327 id : <id_for_response>
317 328 api_key : "<api_key>"
318 329 method : "get_users_group"
319 330 args : {
320 331 "group_name" : "<name>"
321 332 }
322 333
323 334 OUTPUT::
324 335
325 336 result : None if group not exist
326 337 {
327 338 "id" : "<id>",
328 339 "group_name" : "<groupname>",
329 340 "active": "<bool>",
330 341 "members" : [
331 342 { "id" : "<userid>",
332 343 "username" : "<username>",
333 344 "firstname": "<firstname>",
334 345 "lastname" : "<lastname>",
335 346 "email" : "<email>",
336 347 "active" : "<bool>",
337 348 "admin" :Β  "<bool>",
338 349 "ldap" : "<ldap_dn>"
339 350 },
340 351 …
341 352 ]
342 353 }
343 354 error : null
344 355
345 356
346 357 get_users_groups
347 358 ----------------
348 359
349 360 Lists all existing users groups. This command can be executed only using
350 361 api_key belonging to user with admin rights.
351 362
352 363
353 364 INPUT::
354 365
355 366 id : <id_for_response>
356 367 api_key : "<api_key>"
357 368 method : "get_users_groups"
358 369 args : { }
359 370
360 371 OUTPUT::
361 372
362 373 result : [
363 374 {
364 375 "id" : "<id>",
365 376 "group_name" : "<groupname>",
366 377 "active": "<bool>",
367 378 "members" : [
368 379 {
369 380 "id" : "<userid>",
370 381 "username" : "<username>",
371 382 "firstname": "<firstname>",
372 383 "lastname" : "<lastname>",
373 384 "email" : "<email>",
374 385 "active" : "<bool>",
375 386 "admin" :Β  "<bool>",
376 387 "ldap" : "<ldap_dn>"
377 388 },
378 389 …
379 390 ]
380 391 }
381 392 ]
382 393 error : null
383 394
384 395
385 396 create_users_group
386 397 ------------------
387 398
388 399 Creates new users group. This command can be executed only using api_key
389 400 belonging to user with admin rights
390 401
391 402
392 403 INPUT::
393 404
394 405 id : <id_for_response>
395 406 api_key : "<api_key>"
396 407 method : "create_users_group"
397 408 args: {
398 409 "group_name": "<groupname>",
399 410 "active":"<bool> = True"
400 411 }
401 412
402 413 OUTPUT::
403 414
404 415 result: {
405 416 "id": "<newusersgroupid>",
406 417 "msg": "created new users group <groupname>"
407 418 }
408 419 error: null
409 420
410 421
411 422 add_user_to_users_group
412 423 -----------------------
413 424
414 425 Adds a user to a users group. If user exists in that group success will be
415 426 `false`. This command can be executed only using api_key
416 427 belonging to user with admin rights
417 428
418 429
419 430 INPUT::
420 431
421 432 id : <id_for_response>
422 433 api_key : "<api_key>"
423 434 method : "add_user_users_group"
424 435 args: {
425 436 "group_name" : "<groupname>",
426 437 "username" : "<username>"
427 438 }
428 439
429 440 OUTPUT::
430 441
431 442 result: {
432 443 "id": "<newusersgroupmemberid>",
433 444 "success": True|False # depends on if member is in group
434 445 "msg": "added member <username> to users group <groupname> |
435 446 User is already in that group"
436 447 }
437 448 error: null
438 449
439 450
440 451 remove_user_from_users_group
441 452 ----------------------------
442 453
443 454 Removes a user from a users group. If user is not in given group success will
444 455 be `false`. This command can be executed only
445 456 using api_key belonging to user with admin rights
446 457
447 458
448 459 INPUT::
449 460
450 461 id : <id_for_response>
451 462 api_key : "<api_key>"
452 463 method : "remove_user_from_users_group"
453 464 args: {
454 465 "group_name" : "<groupname>",
455 466 "username" : "<username>"
456 467 }
457 468
458 469 OUTPUT::
459 470
460 471 result: {
461 472 "success": True|False, # depends on if member is in group
462 473 "msg": "removed member <username> from users group <groupname> |
463 474 User wasn't in group"
464 475 }
465 476 error: null
466 477
467 478
468 479 get_repo
469 480 --------
470 481
471 482 Gets an existing repository by it's name or repository_id. Members will return
472 483 either users_group or user associated to that repository. This command can
473 484 be executed only using api_key belonging to user with admin rights.
474 485
475 486
476 487 INPUT::
477 488
478 489 id : <id_for_response>
479 490 api_key : "<api_key>"
480 491 method : "get_repo"
481 492 args: {
482 493 "repoid" : "<reponame or repo_id>"
483 494 }
484 495
485 496 OUTPUT::
486 497
487 498 result: None if repository does not exist or
488 499 {
489 500 "id" : "<id>",
490 501 "repo_name" : "<reponame>"
491 502 "type" : "<type>",
492 503 "description" : "<description>",
493 504 "clone_uri" : "<clone_uri>",
494 505 "private": : "<bool>",
495 506 "created_on" : "<datetimecreated>",
496 507 "members" : [
497 508 {
498 509 "type": "user",
499 510 "id" : "<userid>",
500 511 "username" : "<username>",
501 512 "firstname": "<firstname>",
502 513 "lastname" : "<lastname>",
503 514 "email" : "<email>",
504 515 "active" : "<bool>",
505 516 "admin" :Β  "<bool>",
506 517 "ldap" : "<ldap_dn>",
507 518 "permission" : "repository.(read|write|admin)"
508 519 },
509 520 …
510 521 {
511 522 "type": "users_group",
512 523 "id" : "<usersgroupid>",
513 524 "name" : "<usersgroupname>",
514 525 "active": "<bool>",
515 526 "permission" : "repository.(read|write|admin)"
516 527 },
517 528 …
518 529 ]
519 530 }
520 531 error: null
521 532
522 533
523 534 get_repos
524 535 ---------
525 536
526 537 Lists all existing repositories. This command can be executed only using api_key
527 538 belonging to user with admin rights
528 539
529 540
530 541 INPUT::
531 542
532 543 id : <id_for_response>
533 544 api_key : "<api_key>"
534 545 method : "get_repos"
535 546 args: { }
536 547
537 548 OUTPUT::
538 549
539 550 result: [
540 551 {
541 552 "id" : "<id>",
542 553 "repo_name" : "<reponame>"
543 554 "type" : "<type>",
544 555 "description" : "<description>",
545 556 "clone_uri" : "<clone_uri>",
546 557 "private": : "<bool>",
547 558 "created_on" : "<datetimecreated>",
548 559 },
549 560 …
550 561 ]
551 562 error: null
552 563
553 564
554 565 get_repo_nodes
555 566 --------------
556 567
557 568 returns a list of nodes and it's children in a flat list for a given path
558 569 at given revision. It's possible to specify ret_type to show only `files` or
559 570 `dirs`. This command can be executed only using api_key belonging to user
560 571 with admin rights
561 572
562 573
563 574 INPUT::
564 575
565 576 id : <id_for_response>
566 577 api_key : "<api_key>"
567 578 method : "get_repo_nodes"
568 579 args: {
569 580 "repo_name" : "<reponame>",
570 581 "revision" : "<revision>",
571 582 "root_path" : "<root_path>",
572 583 "ret_type" : "<ret_type>" = 'all'
573 584 }
574 585
575 586 OUTPUT::
576 587
577 588 result: [
578 589 {
579 590 "name" : "<name>"
580 591 "type" : "<type>",
581 592 },
582 593 …
583 594 ]
584 595 error: null
585 596
586 597
587 598 create_repo
588 599 -----------
589 600
590 601 Creates a repository. This command can be executed only using api_key
591 602 belonging to user with admin rights.
592 603 If repository name contains "/", all needed repository groups will be created.
593 604 For example "foo/bar/baz" will create groups "foo", "bar" (with "foo" as parent),
594 605 and create "baz" repository with "bar" as group.
595 606
596 607
597 608 INPUT::
598 609
599 610 id : <id_for_response>
600 611 api_key : "<api_key>"
601 612 method : "create_repo"
602 613 args: {
603 614 "repo_name" : "<reponame>",
604 615 "owner_name" : "<ownername>",
605 616 "description" : "<description> = ''",
606 617 "repo_type" : "<type> = 'hg'",
607 618 "private" : "<bool> = False",
608 619 "clone_uri" : "<clone_uri> = None",
609 620 }
610 621
611 622 OUTPUT::
612 623
613 624 result: {
614 625 "id": "<newrepoid>",
615 626 "msg": "Created new repository <reponame>",
616 627 "repo": {
617 628 "id" : "<id>",
618 629 "repo_name" : "<reponame>"
619 630 "type" : "<type>",
620 631 "description" : "<description>",
621 632 "clone_uri" : "<clone_uri>",
622 633 "private": : "<bool>",
623 634 "created_on" : "<datetimecreated>",
624 635 },
625 636 }
626 637 error: null
627 638
628 639
629 640 delete_repo
630 641 -----------
631 642
632 643 Deletes a repository. This command can be executed only using api_key
633 644 belonging to user with admin rights.
634 645
635 646
636 647 INPUT::
637 648
638 649 id : <id_for_response>
639 650 api_key : "<api_key>"
640 651 method : "delete_repo"
641 652 args: {
642 653 "repo_name" : "<reponame>",
643 654 }
644 655
645 656 OUTPUT::
646 657
647 658 result: {
648 659 "msg": "Deleted repository <reponame>",
649 660 }
650 661 error: null
651 662
652 663
653 664 grant_user_permission
654 665 ---------------------
655 666
656 667 Grant permission for user on given repository, or update existing one
657 668 if found. This command can be executed only using api_key belonging to user
658 669 with admin rights.
659 670
660 671
661 672 INPUT::
662 673
663 674 id : <id_for_response>
664 675 api_key : "<api_key>"
665 676 method : "grant_user_permission"
666 677 args: {
667 678 "repo_name" : "<reponame>",
668 679 "username" : "<username>",
669 680 "perm" : "(repository.(none|read|write|admin))",
670 681 }
671 682
672 683 OUTPUT::
673 684
674 685 result: {
675 686 "msg" : "Granted perm: <perm> for user: <username> in repo: <reponame>"
676 687 }
677 688 error: null
678 689
679 690
680 691 revoke_user_permission
681 692 ----------------------
682 693
683 694 Revoke permission for user on given repository. This command can be executed
684 695 only using api_key belonging to user with admin rights.
685 696
686 697
687 698 INPUT::
688 699
689 700 id : <id_for_response>
690 701 api_key : "<api_key>"
691 702 method : "revoke_user_permission"
692 703 args: {
693 704 "repo_name" : "<reponame>",
694 705 "username" : "<username>",
695 706 }
696 707
697 708 OUTPUT::
698 709
699 710 result: {
700 711 "msg" : "Revoked perm for user: <suername> in repo: <reponame>"
701 712 }
702 713 error: null
703 714
704 715
705 716 grant_users_group_permission
706 717 ----------------------------
707 718
708 719 Grant permission for users group on given repository, or update
709 720 existing one if found. This command can be executed only using
710 721 api_key belonging to user with admin rights.
711 722
712 723
713 724 INPUT::
714 725
715 726 id : <id_for_response>
716 727 api_key : "<api_key>"
717 728 method : "grant_users_group_permission"
718 729 args: {
719 730 "repo_name" : "<reponame>",
720 731 "group_name" : "<usersgroupname>",
721 732 "perm" : "(repository.(none|read|write|admin))",
722 733 }
723 734
724 735 OUTPUT::
725 736
726 737 result: {
727 738 "msg" : "Granted perm: <perm> for group: <usersgroupname> in repo: <reponame>"
728 739 }
729 740 error: null
730 741
731 742
732 743 revoke_users_group_permission
733 744 -----------------------------
734 745
735 746 Revoke permission for users group on given repository.This command can be
736 747 executed only using api_key belonging to user with admin rights.
737 748
738 749 INPUT::
739 750
740 751 id : <id_for_response>
741 752 api_key : "<api_key>"
742 753 method : "revoke_users_group_permission"
743 754 args: {
744 755 "repo_name" : "<reponame>",
745 756 "users_group" : "<usersgroupname>",
746 757 }
747 758
748 759 OUTPUT::
749 760
750 761 result: {
751 762 "msg" : "Revoked perm for group: <usersgroupname> in repo: <reponame>"
752 763 }
753 764 error: null No newline at end of file
@@ -1,716 +1,727 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.api
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 API controller for RhodeCode
7 7
8 8 :created_on: Aug 20, 2011
9 9 :author: marcink
10 10 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software; you can redistribute it and/or
14 14 # modify it under the terms of the GNU General Public License
15 15 # as published by the Free Software Foundation; version 2
16 16 # of the License or (at your opinion) any later version of the license.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program; if not, write to the Free Software
25 25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 26 # MA 02110-1301, USA.
27 27
28 28 import traceback
29 29 import logging
30 30
31 31 from rhodecode.controllers.api import JSONRPCController, JSONRPCError
32 32 from rhodecode.lib.auth import HasPermissionAllDecorator, \
33 33 HasPermissionAnyDecorator, PasswordGenerator, AuthUser
34 34
35 35 from rhodecode.model.meta import Session
36 36 from rhodecode.model.scm import ScmModel
37 37 from rhodecode.model.db import User, UsersGroup, Repository
38 38 from rhodecode.model.repo import RepoModel
39 39 from rhodecode.model.user import UserModel
40 40 from rhodecode.model.users_group import UsersGroupModel
41 41 from rhodecode.lib.utils import map_groups
42 42
43 43 log = logging.getLogger(__name__)
44 44
45 45
46 46 class ApiController(JSONRPCController):
47 47 """
48 48 API Controller
49 49
50 50
51 51 Each method needs to have USER as argument this is then based on given
52 52 API_KEY propagated as instance of user object
53 53
54 54 Preferably this should be first argument also
55 55
56 56
57 57 Each function should also **raise** JSONRPCError for any
58 58 errors that happens
59 59
60 60 """
61 61
62 62 @HasPermissionAllDecorator('hg.admin')
63 63 def pull(self, apiuser, repo_name):
64 64 """
65 65 Dispatch pull action on given repo
66 66
67 67
68 68 :param user:
69 69 :param repo_name:
70 70 """
71 71
72 72 if Repository.is_valid(repo_name) is False:
73 73 raise JSONRPCError('Unknown repo "%s"' % repo_name)
74 74
75 75 try:
76 76 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
77 77 return 'Pulled from %s' % repo_name
78 78 except Exception:
79 79 raise JSONRPCError('Unable to pull changes from "%s"' % repo_name)
80 80
81 81 @HasPermissionAllDecorator('hg.admin')
82 82 def get_user(self, apiuser, userid):
83 83 """"
84 84 Get a user by username
85 85
86 86 :param apiuser:
87 87 :param username:
88 88 """
89 89
90 90 user = UserModel().get_user(userid)
91 91 if user is None:
92 92 return user
93 93
94 94 return dict(
95 95 id=user.user_id,
96 96 username=user.username,
97 97 firstname=user.name,
98 98 lastname=user.lastname,
99 99 email=user.email,
100 100 emails=user.emails,
101 101 active=user.active,
102 102 admin=user.admin,
103 103 ldap_dn=user.ldap_dn,
104 104 last_login=user.last_login,
105 105 permissions=AuthUser(user_id=user.user_id).permissions
106 106 )
107 107
108 108 @HasPermissionAllDecorator('hg.admin')
109 109 def get_users(self, apiuser):
110 110 """"
111 111 Get all users
112 112
113 113 :param apiuser:
114 114 """
115 115
116 116 result = []
117 117 for user in User.getAll():
118 118 result.append(
119 119 dict(
120 120 id=user.user_id,
121 121 username=user.username,
122 122 firstname=user.name,
123 123 lastname=user.lastname,
124 124 email=user.email,
125 125 active=user.active,
126 126 admin=user.admin,
127 127 ldap_dn=user.ldap_dn,
128 128 last_login=user.last_login,
129 129 )
130 130 )
131 131 return result
132 132
133 133 @HasPermissionAllDecorator('hg.admin')
134 134 def create_user(self, apiuser, username, email, password, firstname=None,
135 135 lastname=None, active=True, admin=False, ldap_dn=None):
136 136 """
137 137 Create new user
138 138
139 139 :param apiuser:
140 140 :param username:
141 141 :param password:
142 142 :param email:
143 143 :param name:
144 144 :param lastname:
145 145 :param active:
146 146 :param admin:
147 147 :param ldap_dn:
148 148 """
149 149 if User.get_by_username(username):
150 150 raise JSONRPCError("user %s already exist" % username)
151 151
152 152 if User.get_by_email(email, case_insensitive=True):
153 153 raise JSONRPCError("email %s already exist" % email)
154 154
155 155 if ldap_dn:
156 156 # generate temporary password if ldap_dn
157 157 password = PasswordGenerator().gen_password(length=8)
158 158
159 159 try:
160 160 user = UserModel().create_or_update(
161 161 username, password, email, firstname,
162 162 lastname, active, admin, ldap_dn
163 163 )
164 164 Session.commit()
165 165 return dict(
166 166 id=user.user_id,
167 167 msg='created new user %s' % username,
168 168 user=dict(
169 169 id=user.user_id,
170 170 username=user.username,
171 171 firstname=user.name,
172 172 lastname=user.lastname,
173 173 email=user.email,
174 174 active=user.active,
175 175 admin=user.admin,
176 176 ldap_dn=user.ldap_dn,
177 177 last_login=user.last_login,
178 178 )
179 179 )
180 180 except Exception:
181 181 log.error(traceback.format_exc())
182 182 raise JSONRPCError('failed to create user %s' % username)
183 183
184 184 @HasPermissionAllDecorator('hg.admin')
185 185 def update_user(self, apiuser, userid, username, password, email,
186 186 firstname, lastname, active, admin, ldap_dn):
187 187 """
188 188 Updates given user
189 189
190 190 :param apiuser:
191 191 :param username:
192 192 :param password:
193 193 :param email:
194 194 :param name:
195 195 :param lastname:
196 196 :param active:
197 197 :param admin:
198 198 :param ldap_dn:
199 199 """
200 200 usr = UserModel().get_user(userid)
201 201 if not usr:
202 202 raise JSONRPCError("user ID:%s does not exist" % userid)
203 203
204 204 try:
205 usr = UserModel().create_or_update(
205 user = UserModel().create_or_update(
206 206 username, password, email, firstname,
207 207 lastname, active, admin, ldap_dn
208 208 )
209 209 Session.commit()
210 210 return dict(
211 211 id=usr.user_id,
212 msg='updated user ID:%s %s' % (usr.user_id, usr.username)
212 msg='updated user ID:%s %s' % (user.user_id, user.username),
213 user=dict(
214 id=user.user_id,
215 username=user.username,
216 firstname=user.name,
217 lastname=user.lastname,
218 email=user.email,
219 active=user.active,
220 admin=user.admin,
221 ldap_dn=user.ldap_dn,
222 last_login=user.last_login,
223 )
213 224 )
214 225 except Exception:
215 226 log.error(traceback.format_exc())
216 227 raise JSONRPCError('failed to update user %s' % userid)
217 228
218 229 @HasPermissionAllDecorator('hg.admin')
219 230 def delete_user(self, apiuser, userid):
220 231 """"
221 232 Deletes an user
222 233
223 234 :param apiuser:
224 235 """
225 236 usr = UserModel().get_user(userid)
226 237 if not usr:
227 238 raise JSONRPCError("user ID:%s does not exist" % userid)
228 239
229 240 try:
230 241 UserModel().delete(userid)
231 242 Session.commit()
232 243 return dict(
233 244 id=usr.user_id,
234 245 msg='deleted user ID:%s %s' % (usr.user_id, usr.username)
235 246 )
236 247 except Exception:
237 248 log.error(traceback.format_exc())
238 249 raise JSONRPCError('failed to delete ID:%s %s' % (usr.user_id,
239 250 usr.username))
240 251
241 252 @HasPermissionAllDecorator('hg.admin')
242 253 def get_users_group(self, apiuser, group_name):
243 254 """"
244 255 Get users group by name
245 256
246 257 :param apiuser:
247 258 :param group_name:
248 259 """
249 260
250 261 users_group = UsersGroup.get_by_group_name(group_name)
251 262 if not users_group:
252 263 return None
253 264
254 265 members = []
255 266 for user in users_group.members:
256 267 user = user.user
257 268 members.append(dict(id=user.user_id,
258 269 username=user.username,
259 270 firstname=user.name,
260 271 lastname=user.lastname,
261 272 email=user.email,
262 273 active=user.active,
263 274 admin=user.admin,
264 275 ldap=user.ldap_dn))
265 276
266 277 return dict(id=users_group.users_group_id,
267 278 group_name=users_group.users_group_name,
268 279 active=users_group.users_group_active,
269 280 members=members)
270 281
271 282 @HasPermissionAllDecorator('hg.admin')
272 283 def get_users_groups(self, apiuser):
273 284 """"
274 285 Get all users groups
275 286
276 287 :param apiuser:
277 288 """
278 289
279 290 result = []
280 291 for users_group in UsersGroup.getAll():
281 292 members = []
282 293 for user in users_group.members:
283 294 user = user.user
284 295 members.append(dict(id=user.user_id,
285 296 username=user.username,
286 297 firstname=user.name,
287 298 lastname=user.lastname,
288 299 email=user.email,
289 300 active=user.active,
290 301 admin=user.admin,
291 302 ldap=user.ldap_dn))
292 303
293 304 result.append(dict(id=users_group.users_group_id,
294 305 group_name=users_group.users_group_name,
295 306 active=users_group.users_group_active,
296 307 members=members))
297 308 return result
298 309
299 310 @HasPermissionAllDecorator('hg.admin')
300 311 def create_users_group(self, apiuser, group_name, active=True):
301 312 """
302 313 Creates an new usergroup
303 314
304 315 :param group_name:
305 316 :param active:
306 317 """
307 318
308 319 if self.get_users_group(apiuser, group_name):
309 320 raise JSONRPCError("users group %s already exist" % group_name)
310 321
311 322 try:
312 323 ug = UsersGroupModel().create(name=group_name, active=active)
313 324 Session.commit()
314 325 return dict(id=ug.users_group_id,
315 326 msg='created new users group %s' % group_name)
316 327 except Exception:
317 328 log.error(traceback.format_exc())
318 329 raise JSONRPCError('failed to create group %s' % group_name)
319 330
320 331 @HasPermissionAllDecorator('hg.admin')
321 332 def add_user_to_users_group(self, apiuser, group_name, username):
322 333 """"
323 334 Add a user to a users group
324 335
325 336 :param apiuser:
326 337 :param group_name:
327 338 :param username:
328 339 """
329 340
330 341 try:
331 342 users_group = UsersGroup.get_by_group_name(group_name)
332 343 if not users_group:
333 344 raise JSONRPCError('unknown users group %s' % group_name)
334 345
335 346 user = User.get_by_username(username)
336 347 if user is None:
337 348 raise JSONRPCError('unknown user %s' % username)
338 349
339 350 ugm = UsersGroupModel().add_user_to_group(users_group, user)
340 351 success = True if ugm != True else False
341 352 msg = 'added member %s to users group %s' % (username, group_name)
342 353 msg = msg if success else 'User is already in that group'
343 354 Session.commit()
344 355
345 356 return dict(
346 357 id=ugm.users_group_member_id if ugm != True else None,
347 358 success=success,
348 359 msg=msg
349 360 )
350 361 except Exception:
351 362 log.error(traceback.format_exc())
352 363 raise JSONRPCError('failed to add users group member')
353 364
354 365 @HasPermissionAllDecorator('hg.admin')
355 366 def remove_user_from_users_group(self, apiuser, group_name, username):
356 367 """
357 368 Remove user from a group
358 369
359 370 :param apiuser
360 371 :param group_name
361 372 :param username
362 373 """
363 374
364 375 try:
365 376 users_group = UsersGroup.get_by_group_name(group_name)
366 377 if not users_group:
367 378 raise JSONRPCError('unknown users group %s' % group_name)
368 379
369 380 user = User.get_by_username(username)
370 381 if user is None:
371 382 raise JSONRPCError('unknown user %s' % username)
372 383
373 384 success = UsersGroupModel().remove_user_from_group(users_group, user)
374 385 msg = 'removed member %s from users group %s' % (username, group_name)
375 386 msg = msg if success else "User wasn't in group"
376 387 Session.commit()
377 388 return dict(success=success, msg=msg)
378 389 except Exception:
379 390 log.error(traceback.format_exc())
380 391 raise JSONRPCError('failed to remove user from group')
381 392
382 393 @HasPermissionAnyDecorator('hg.admin')
383 394 def get_repo(self, apiuser, repoid):
384 395 """"
385 396 Get repository by name
386 397
387 398 :param apiuser:
388 399 :param repo_name:
389 400 """
390 401
391 402 repo = RepoModel().get_repo(repoid)
392 403 if repo is None:
393 404 raise JSONRPCError('unknown repository "%s"' % (repo or repoid))
394 405
395 406 members = []
396 407 for user in repo.repo_to_perm:
397 408 perm = user.permission.permission_name
398 409 user = user.user
399 410 members.append(
400 411 dict(
401 412 type="user",
402 413 id=user.user_id,
403 414 username=user.username,
404 415 firstname=user.name,
405 416 lastname=user.lastname,
406 417 email=user.email,
407 418 active=user.active,
408 419 admin=user.admin,
409 420 ldap=user.ldap_dn,
410 421 permission=perm
411 422 )
412 423 )
413 424 for users_group in repo.users_group_to_perm:
414 425 perm = users_group.permission.permission_name
415 426 users_group = users_group.users_group
416 427 members.append(
417 428 dict(
418 429 type="users_group",
419 430 id=users_group.users_group_id,
420 431 name=users_group.users_group_name,
421 432 active=users_group.users_group_active,
422 433 permission=perm
423 434 )
424 435 )
425 436
426 437 return dict(
427 438 id=repo.repo_id,
428 439 repo_name=repo.repo_name,
429 440 type=repo.repo_type,
430 441 clone_uri=repo.clone_uri,
431 442 private=repo.private,
432 443 created_on=repo.created_on,
433 444 description=repo.description,
434 445 members=members
435 446 )
436 447
437 448 @HasPermissionAnyDecorator('hg.admin')
438 449 def get_repos(self, apiuser):
439 450 """"
440 451 Get all repositories
441 452
442 453 :param apiuser:
443 454 """
444 455
445 456 result = []
446 457 for repo in Repository.getAll():
447 458 result.append(
448 459 dict(
449 460 id=repo.repo_id,
450 461 repo_name=repo.repo_name,
451 462 type=repo.repo_type,
452 463 clone_uri=repo.clone_uri,
453 464 private=repo.private,
454 465 created_on=repo.created_on,
455 466 description=repo.description,
456 467 )
457 468 )
458 469 return result
459 470
460 471 @HasPermissionAnyDecorator('hg.admin')
461 472 def get_repo_nodes(self, apiuser, repo_name, revision, root_path,
462 473 ret_type='all'):
463 474 """
464 475 returns a list of nodes and it's children
465 476 for a given path at given revision. It's possible to specify ret_type
466 477 to show only files or dirs
467 478
468 479 :param apiuser:
469 480 :param repo_name: name of repository
470 481 :param revision: revision for which listing should be done
471 482 :param root_path: path from which start displaying
472 483 :param ret_type: return type 'all|files|dirs' nodes
473 484 """
474 485 try:
475 486 _d, _f = ScmModel().get_nodes(repo_name, revision, root_path,
476 487 flat=False)
477 488 _map = {
478 489 'all': _d + _f,
479 490 'files': _f,
480 491 'dirs': _d,
481 492 }
482 493 return _map[ret_type]
483 494 except KeyError:
484 495 raise JSONRPCError('ret_type must be one of %s' % _map.keys())
485 496 except Exception, e:
486 497 raise JSONRPCError(e)
487 498
488 499 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
489 500 def create_repo(self, apiuser, repo_name, owner_name, description='',
490 501 repo_type='hg', private=False, clone_uri=None):
491 502 """
492 503 Create repository, if clone_url is given it makes a remote clone
493 504
494 505 :param apiuser:
495 506 :param repo_name:
496 507 :param owner_name:
497 508 :param description:
498 509 :param repo_type:
499 510 :param private:
500 511 :param clone_uri:
501 512 """
502 513
503 514 try:
504 515 owner = User.get_by_username(owner_name)
505 516 if owner is None:
506 517 raise JSONRPCError('unknown user %s' % owner_name)
507 518
508 519 if Repository.get_by_repo_name(repo_name):
509 520 raise JSONRPCError("repo %s already exist" % repo_name)
510 521
511 522 groups = repo_name.split(Repository.url_sep())
512 523 real_name = groups[-1]
513 524 # create structure of groups
514 525 group = map_groups(repo_name)
515 526
516 527 repo = RepoModel().create(
517 528 dict(
518 529 repo_name=real_name,
519 530 repo_name_full=repo_name,
520 531 description=description,
521 532 private=private,
522 533 repo_type=repo_type,
523 534 repo_group=group.group_id if group else None,
524 535 clone_uri=clone_uri
525 536 )
526 537 )
527 538 Session.commit()
528 539
529 540 return dict(
530 541 id=repo.repo_id,
531 542 msg="Created new repository %s" % (repo.repo_name),
532 543 repo=dict(
533 544 id=repo.repo_id,
534 545 repo_name=repo.repo_name,
535 546 type=repo.repo_type,
536 547 clone_uri=repo.clone_uri,
537 548 private=repo.private,
538 549 created_on=repo.created_on,
539 550 description=repo.description,
540 551 )
541 552 )
542 553
543 554 except Exception:
544 555 log.error(traceback.format_exc())
545 556 raise JSONRPCError('failed to create repository %s' % repo_name)
546 557
547 558 @HasPermissionAnyDecorator('hg.admin')
548 559 def fork_repo(self, apiuser, repoid):
549 560 repo = RepoModel().get_repo(repoid)
550 561 if repo is None:
551 562 raise JSONRPCError('unknown repository "%s"' % (repo or repoid))
552 563
553 564 RepoModel().create_fork(form_data, cur_user)
554 565
555 566
556 567 @HasPermissionAnyDecorator('hg.admin')
557 568 def delete_repo(self, apiuser, repo_name):
558 569 """
559 570 Deletes a given repository
560 571
561 572 :param repo_name:
562 573 """
563 574 if not Repository.get_by_repo_name(repo_name):
564 575 raise JSONRPCError("repo %s does not exist" % repo_name)
565 576 try:
566 577 RepoModel().delete(repo_name)
567 578 Session.commit()
568 579 return dict(
569 580 msg='Deleted repository %s' % repo_name
570 581 )
571 582 except Exception:
572 583 log.error(traceback.format_exc())
573 584 raise JSONRPCError('failed to delete repository %s' % repo_name)
574 585
575 586 @HasPermissionAnyDecorator('hg.admin')
576 587 def grant_user_permission(self, apiuser, repo_name, username, perm):
577 588 """
578 589 Grant permission for user on given repository, or update existing one
579 590 if found
580 591
581 592 :param repo_name:
582 593 :param username:
583 594 :param perm:
584 595 """
585 596
586 597 try:
587 598 repo = Repository.get_by_repo_name(repo_name)
588 599 if repo is None:
589 600 raise JSONRPCError('unknown repository %s' % repo)
590 601
591 602 user = User.get_by_username(username)
592 603 if user is None:
593 604 raise JSONRPCError('unknown user %s' % username)
594 605
595 606 RepoModel().grant_user_permission(repo=repo, user=user, perm=perm)
596 607
597 608 Session.commit()
598 609 return dict(
599 610 msg='Granted perm: %s for user: %s in repo: %s' % (
600 611 perm, username, repo_name
601 612 )
602 613 )
603 614 except Exception:
604 615 log.error(traceback.format_exc())
605 616 raise JSONRPCError(
606 617 'failed to edit permission %(repo)s for %(user)s' % dict(
607 618 user=username, repo=repo_name
608 619 )
609 620 )
610 621
611 622 @HasPermissionAnyDecorator('hg.admin')
612 623 def revoke_user_permission(self, apiuser, repo_name, username):
613 624 """
614 625 Revoke permission for user on given repository
615 626
616 627 :param repo_name:
617 628 :param username:
618 629 """
619 630
620 631 try:
621 632 repo = Repository.get_by_repo_name(repo_name)
622 633 if repo is None:
623 634 raise JSONRPCError('unknown repository %s' % repo)
624 635
625 636 user = User.get_by_username(username)
626 637 if user is None:
627 638 raise JSONRPCError('unknown user %s' % username)
628 639
629 640 RepoModel().revoke_user_permission(repo=repo_name, user=username)
630 641
631 642 Session.commit()
632 643 return dict(
633 644 msg='Revoked perm for user: %s in repo: %s' % (
634 645 username, repo_name
635 646 )
636 647 )
637 648 except Exception:
638 649 log.error(traceback.format_exc())
639 650 raise JSONRPCError(
640 651 'failed to edit permission %(repo)s for %(user)s' % dict(
641 652 user=username, repo=repo_name
642 653 )
643 654 )
644 655
645 656 @HasPermissionAnyDecorator('hg.admin')
646 657 def grant_users_group_permission(self, apiuser, repo_name, group_name, perm):
647 658 """
648 659 Grant permission for users group on given repository, or update
649 660 existing one if found
650 661
651 662 :param repo_name:
652 663 :param group_name:
653 664 :param perm:
654 665 """
655 666
656 667 try:
657 668 repo = Repository.get_by_repo_name(repo_name)
658 669 if repo is None:
659 670 raise JSONRPCError('unknown repository %s' % repo)
660 671
661 672 user_group = UsersGroup.get_by_group_name(group_name)
662 673 if user_group is None:
663 674 raise JSONRPCError('unknown users group %s' % user_group)
664 675
665 676 RepoModel().grant_users_group_permission(repo=repo_name,
666 677 group_name=group_name,
667 678 perm=perm)
668 679
669 680 Session.commit()
670 681 return dict(
671 682 msg='Granted perm: %s for group: %s in repo: %s' % (
672 683 perm, group_name, repo_name
673 684 )
674 685 )
675 686 except Exception:
676 687 log.error(traceback.format_exc())
677 688 raise JSONRPCError(
678 689 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
679 690 usersgr=group_name, repo=repo_name
680 691 )
681 692 )
682 693
683 694 @HasPermissionAnyDecorator('hg.admin')
684 695 def revoke_users_group_permission(self, apiuser, repo_name, group_name):
685 696 """
686 697 Revoke permission for users group on given repository
687 698
688 699 :param repo_name:
689 700 :param group_name:
690 701 """
691 702
692 703 try:
693 704 repo = Repository.get_by_repo_name(repo_name)
694 705 if repo is None:
695 706 raise JSONRPCError('unknown repository %s' % repo)
696 707
697 708 user_group = UsersGroup.get_by_group_name(group_name)
698 709 if user_group is None:
699 710 raise JSONRPCError('unknown users group %s' % user_group)
700 711
701 712 RepoModel().revoke_users_group_permission(repo=repo_name,
702 713 group_name=group_name)
703 714
704 715 Session.commit()
705 716 return dict(
706 717 msg='Revoked perm for group: %s in repo: %s' % (
707 718 group_name, repo_name
708 719 )
709 720 )
710 721 except Exception:
711 722 log.error(traceback.format_exc())
712 723 raise JSONRPCError(
713 724 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
714 725 usersgr=group_name, repo=repo_name
715 726 )
716 727 )
General Comments 0
You need to be logged in to leave comments. Login now