Mercurial > kallithea
comparison rhodecode/controllers/api/api.py @ 3700:3563bb7b4b82
merge with rc1
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Sun, 07 Apr 2013 18:37:22 +0200 |
parents | cd50d1b5f35b b44979649915 |
children | e3857cbb6d10 |
comparison
equal
deleted
inserted
replaced
3525:0cef54d34605 | 3700:3563bb7b4b82 |
---|---|
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 from pylons.controllers.util import abort | |
31 | 30 |
32 from rhodecode.controllers.api import JSONRPCController, JSONRPCError | 31 from rhodecode.controllers.api import JSONRPCController, JSONRPCError |
33 from rhodecode.lib.auth import PasswordGenerator, AuthUser, \ | 32 from rhodecode.lib.auth import PasswordGenerator, AuthUser, \ |
34 HasPermissionAllDecorator, HasPermissionAnyDecorator, \ | 33 HasPermissionAllDecorator, HasPermissionAnyDecorator, \ |
35 HasPermissionAnyApi, HasRepoPermissionAnyApi | 34 HasPermissionAnyApi, HasRepoPermissionAnyApi |
36 from rhodecode.lib.utils import map_groups, repo2db_mapper | 35 from rhodecode.lib.utils import map_groups, repo2db_mapper |
36 from rhodecode.lib.utils2 import str2bool, time_to_datetime, safe_int | |
37 from rhodecode.lib import helpers as h | |
37 from rhodecode.model.meta import Session | 38 from rhodecode.model.meta import Session |
38 from rhodecode.model.scm import ScmModel | 39 from rhodecode.model.scm import ScmModel |
39 from rhodecode.model.repo import RepoModel | 40 from rhodecode.model.repo import RepoModel |
40 from rhodecode.model.user import UserModel | 41 from rhodecode.model.user import UserModel |
41 from rhodecode.model.users_group import UsersGroupModel | 42 from rhodecode.model.users_group import UserGroupModel |
42 from rhodecode.model.permission import PermissionModel | 43 from rhodecode.model.permission import PermissionModel |
43 from rhodecode.model.db import Repository, RhodeCodeSetting, UserIpMap | 44 from rhodecode.model.db import Repository, RhodeCodeSetting, UserIpMap |
45 from rhodecode.lib.compat import json | |
44 | 46 |
45 log = logging.getLogger(__name__) | 47 log = logging.getLogger(__name__) |
46 | 48 |
47 | 49 |
48 class OptionalAttr(object): | 50 class OptionalAttr(object): |
119 return repo | 121 return repo |
120 | 122 |
121 | 123 |
122 def get_users_group_or_error(usersgroupid): | 124 def get_users_group_or_error(usersgroupid): |
123 """ | 125 """ |
124 Get users group by id or name or return JsonRPCError if not found | 126 Get user group by id or name or return JsonRPCError if not found |
125 | 127 |
126 :param userid: | 128 :param userid: |
127 """ | 129 """ |
128 users_group = UsersGroupModel().get_group(usersgroupid) | 130 users_group = UserGroupModel().get_group(usersgroupid) |
129 if users_group is None: | 131 if users_group is None: |
130 raise JSONRPCError('users group `%s` does not exist' % usersgroupid) | 132 raise JSONRPCError('user group `%s` does not exist' % usersgroupid) |
131 return users_group | 133 return users_group |
132 | 134 |
133 | 135 |
134 def get_perm_or_error(permid): | 136 def get_perm_or_error(permid): |
135 """ | 137 """ |
200 log.error(traceback.format_exc()) | 202 log.error(traceback.format_exc()) |
201 raise JSONRPCError( | 203 raise JSONRPCError( |
202 'Error occurred during rescan repositories action' | 204 'Error occurred during rescan repositories action' |
203 ) | 205 ) |
204 | 206 |
205 def lock(self, apiuser, repoid, locked, userid=Optional(OAttr('apiuser'))): | 207 def invalidate_cache(self, apiuser, repoid): |
208 """ | |
209 Dispatch cache invalidation action on given repo | |
210 | |
211 :param apiuser: | |
212 :param repoid: | |
213 """ | |
214 repo = get_repo_or_error(repoid) | |
215 if HasPermissionAnyApi('hg.admin')(user=apiuser) is False: | |
216 # check if we have admin permission for this repo ! | |
217 if HasRepoPermissionAnyApi('repository.admin', | |
218 'repository.write')(user=apiuser, | |
219 repo_name=repo.repo_name) is False: | |
220 raise JSONRPCError('repository `%s` does not exist' % (repoid)) | |
221 | |
222 try: | |
223 invalidated_keys = ScmModel().mark_for_invalidation(repo.repo_name) | |
224 Session().commit() | |
225 return ('Cache for repository `%s` was invalidated: ' | |
226 'invalidated cache keys: %s' % (repoid, invalidated_keys)) | |
227 except Exception: | |
228 log.error(traceback.format_exc()) | |
229 raise JSONRPCError( | |
230 'Error occurred during cache invalidation action' | |
231 ) | |
232 | |
233 def lock(self, apiuser, repoid, locked=Optional(None), | |
234 userid=Optional(OAttr('apiuser'))): | |
206 """ | 235 """ |
207 Set locking state on particular repository by given user, if | 236 Set locking state on particular repository by given user, if |
208 this command is runned by non-admin account userid is set to user | 237 this command is runned by non-admin account userid is set to user |
209 who is calling this method | 238 who is calling this method |
210 | 239 |
228 else: | 257 else: |
229 raise JSONRPCError('repository `%s` does not exist' % (repoid)) | 258 raise JSONRPCError('repository `%s` does not exist' % (repoid)) |
230 | 259 |
231 if isinstance(userid, Optional): | 260 if isinstance(userid, Optional): |
232 userid = apiuser.user_id | 261 userid = apiuser.user_id |
262 | |
233 user = get_user_or_error(userid) | 263 user = get_user_or_error(userid) |
234 locked = bool(locked) | 264 |
235 try: | 265 if isinstance(locked, Optional): |
236 if locked: | 266 lockobj = Repository.getlock(repo) |
237 Repository.lock(repo, user.user_id) | 267 |
268 if lockobj[0] is None: | |
269 return ('Repo `%s` not locked. Locked=`False`.' | |
270 % (repo.repo_name)) | |
238 else: | 271 else: |
239 Repository.unlock(repo) | 272 userid, time_ = lockobj |
240 | 273 user = get_user_or_error(userid) |
241 return ('User `%s` set lock state for repo `%s` to `%s`' | 274 |
242 % (user.username, repo.repo_name, locked)) | 275 return ('Repo `%s` locked by `%s`. Locked=`True`. ' |
243 except Exception: | 276 'Locked since: `%s`' |
244 log.error(traceback.format_exc()) | 277 % (repo.repo_name, user.username, |
245 raise JSONRPCError( | 278 json.dumps(time_to_datetime(time_)))) |
246 'Error occurred locking repository `%s`' % repo.repo_name | 279 |
247 ) | 280 else: |
281 locked = str2bool(locked) | |
282 try: | |
283 if locked: | |
284 Repository.lock(repo, user.user_id) | |
285 else: | |
286 Repository.unlock(repo) | |
287 | |
288 return ('User `%s` set lock state for repo `%s` to `%s`' | |
289 % (user.username, repo.repo_name, locked)) | |
290 except Exception: | |
291 log.error(traceback.format_exc()) | |
292 raise JSONRPCError( | |
293 'Error occurred locking repository `%s`' % repo.repo_name | |
294 ) | |
295 | |
296 def get_locks(self, apiuser, userid=Optional(OAttr('apiuser'))): | |
297 """ | |
298 Get all locks for given userid, if | |
299 this command is runned by non-admin account userid is set to user | |
300 who is calling this method, thus returning locks for himself | |
301 | |
302 :param apiuser: | |
303 :param userid: | |
304 """ | |
305 if HasPermissionAnyApi('hg.admin')(user=apiuser): | |
306 pass | |
307 else: | |
308 #make sure normal user does not pass someone else userid, | |
309 #he is not allowed to do that | |
310 if not isinstance(userid, Optional) and userid != apiuser.user_id: | |
311 raise JSONRPCError( | |
312 'userid is not the same as your user' | |
313 ) | |
314 ret = [] | |
315 if isinstance(userid, Optional): | |
316 user = None | |
317 else: | |
318 user = get_user_or_error(userid) | |
319 | |
320 #show all locks | |
321 for r in Repository.getAll(): | |
322 userid, time_ = r.locked | |
323 if time_: | |
324 _api_data = r.get_api_data() | |
325 # if we use userfilter just show the locks for this user | |
326 if user: | |
327 if safe_int(userid) == user.user_id: | |
328 ret.append(_api_data) | |
329 else: | |
330 ret.append(_api_data) | |
331 | |
332 return ret | |
248 | 333 |
249 @HasPermissionAllDecorator('hg.admin') | 334 @HasPermissionAllDecorator('hg.admin') |
250 def show_ip(self, apiuser, userid): | 335 def show_ip(self, apiuser, userid): |
251 """ | 336 """ |
252 Shows IP address as seen from RhodeCode server, together with all | 337 Shows IP address as seen from RhodeCode server, together with all |
421 user.username)) | 506 user.username)) |
422 | 507 |
423 @HasPermissionAllDecorator('hg.admin') | 508 @HasPermissionAllDecorator('hg.admin') |
424 def get_users_group(self, apiuser, usersgroupid): | 509 def get_users_group(self, apiuser, usersgroupid): |
425 """" | 510 """" |
426 Get users group by name or id | 511 Get user group by name or id |
427 | 512 |
428 :param apiuser: | 513 :param apiuser: |
429 :param usersgroupid: | 514 :param usersgroupid: |
430 """ | 515 """ |
431 users_group = get_users_group_or_error(usersgroupid) | 516 users_group = get_users_group_or_error(usersgroupid) |
440 return data | 525 return data |
441 | 526 |
442 @HasPermissionAllDecorator('hg.admin') | 527 @HasPermissionAllDecorator('hg.admin') |
443 def get_users_groups(self, apiuser): | 528 def get_users_groups(self, apiuser): |
444 """" | 529 """" |
445 Get all users groups | 530 Get all user groups |
446 | 531 |
447 :param apiuser: | 532 :param apiuser: |
448 """ | 533 """ |
449 | 534 |
450 result = [] | 535 result = [] |
451 for users_group in UsersGroupModel().get_all(): | 536 for users_group in UserGroupModel().get_all(): |
452 result.append(users_group.get_api_data()) | 537 result.append(users_group.get_api_data()) |
453 return result | 538 return result |
454 | 539 |
455 @HasPermissionAllDecorator('hg.admin') | 540 @HasPermissionAllDecorator('hg.admin') |
456 def create_users_group(self, apiuser, group_name, active=Optional(True)): | 541 def create_users_group(self, apiuser, group_name, active=Optional(True)): |
460 :param apiuser: | 545 :param apiuser: |
461 :param group_name: | 546 :param group_name: |
462 :param active: | 547 :param active: |
463 """ | 548 """ |
464 | 549 |
465 if UsersGroupModel().get_by_name(group_name): | 550 if UserGroupModel().get_by_name(group_name): |
466 raise JSONRPCError("users group `%s` already exist" % group_name) | 551 raise JSONRPCError("user group `%s` already exist" % group_name) |
467 | 552 |
468 try: | 553 try: |
469 active = Optional.extract(active) | 554 active = Optional.extract(active) |
470 ug = UsersGroupModel().create(name=group_name, active=active) | 555 ug = UserGroupModel().create(name=group_name, active=active) |
471 Session().commit() | 556 Session().commit() |
472 return dict( | 557 return dict( |
473 msg='created new users group `%s`' % group_name, | 558 msg='created new user group `%s`' % group_name, |
474 users_group=ug.get_api_data() | 559 users_group=ug.get_api_data() |
475 ) | 560 ) |
476 except Exception: | 561 except Exception: |
477 log.error(traceback.format_exc()) | 562 log.error(traceback.format_exc()) |
478 raise JSONRPCError('failed to create group `%s`' % group_name) | 563 raise JSONRPCError('failed to create group `%s`' % group_name) |
479 | 564 |
480 @HasPermissionAllDecorator('hg.admin') | 565 @HasPermissionAllDecorator('hg.admin') |
481 def add_user_to_users_group(self, apiuser, usersgroupid, userid): | 566 def add_user_to_users_group(self, apiuser, usersgroupid, userid): |
482 """" | 567 """" |
483 Add a user to a users group | 568 Add a user to a user group |
484 | 569 |
485 :param apiuser: | 570 :param apiuser: |
486 :param usersgroupid: | 571 :param usersgroupid: |
487 :param userid: | 572 :param userid: |
488 """ | 573 """ |
489 user = get_user_or_error(userid) | 574 user = get_user_or_error(userid) |
490 users_group = get_users_group_or_error(usersgroupid) | 575 users_group = get_users_group_or_error(usersgroupid) |
491 | 576 |
492 try: | 577 try: |
493 ugm = UsersGroupModel().add_user_to_group(users_group, user) | 578 ugm = UserGroupModel().add_user_to_group(users_group, user) |
494 success = True if ugm != True else False | 579 success = True if ugm != True else False |
495 msg = 'added member `%s` to users group `%s`' % ( | 580 msg = 'added member `%s` to user group `%s`' % ( |
496 user.username, users_group.users_group_name | 581 user.username, users_group.users_group_name |
497 ) | 582 ) |
498 msg = msg if success else 'User is already in that group' | 583 msg = msg if success else 'User is already in that group' |
499 Session().commit() | 584 Session().commit() |
500 | 585 |
503 msg=msg | 588 msg=msg |
504 ) | 589 ) |
505 except Exception: | 590 except Exception: |
506 log.error(traceback.format_exc()) | 591 log.error(traceback.format_exc()) |
507 raise JSONRPCError( | 592 raise JSONRPCError( |
508 'failed to add member to users group `%s`' % ( | 593 'failed to add member to user group `%s`' % ( |
509 users_group.users_group_name | 594 users_group.users_group_name |
510 ) | 595 ) |
511 ) | 596 ) |
512 | 597 |
513 @HasPermissionAllDecorator('hg.admin') | 598 @HasPermissionAllDecorator('hg.admin') |
521 """ | 606 """ |
522 user = get_user_or_error(userid) | 607 user = get_user_or_error(userid) |
523 users_group = get_users_group_or_error(usersgroupid) | 608 users_group = get_users_group_or_error(usersgroupid) |
524 | 609 |
525 try: | 610 try: |
526 success = UsersGroupModel().remove_user_from_group(users_group, | 611 success = UserGroupModel().remove_user_from_group(users_group, |
527 user) | 612 user) |
528 msg = 'removed member `%s` from users group `%s`' % ( | 613 msg = 'removed member `%s` from user group `%s`' % ( |
529 user.username, users_group.users_group_name | 614 user.username, users_group.users_group_name |
530 ) | 615 ) |
531 msg = msg if success else "User wasn't in group" | 616 msg = msg if success else "User wasn't in group" |
532 Session().commit() | 617 Session().commit() |
533 return dict(success=success, msg=msg) | 618 return dict(success=success, msg=msg) |
534 except Exception: | 619 except Exception: |
535 log.error(traceback.format_exc()) | 620 log.error(traceback.format_exc()) |
536 raise JSONRPCError( | 621 raise JSONRPCError( |
537 'failed to remove member from users group `%s`' % ( | 622 'failed to remove member from user group `%s`' % ( |
538 users_group.users_group_name | 623 users_group.users_group_name |
539 ) | 624 ) |
540 ) | 625 ) |
541 | 626 |
542 def get_repo(self, apiuser, repoid): | 627 def get_repo(self, apiuser, repoid): |
553 if HasRepoPermissionAnyApi('repository.admin')(user=apiuser, | 638 if HasRepoPermissionAnyApi('repository.admin')(user=apiuser, |
554 repo_name=repo.repo_name) is False: | 639 repo_name=repo.repo_name) is False: |
555 raise JSONRPCError('repository `%s` does not exist' % (repoid)) | 640 raise JSONRPCError('repository `%s` does not exist' % (repoid)) |
556 | 641 |
557 members = [] | 642 members = [] |
643 followers = [] | |
558 for user in repo.repo_to_perm: | 644 for user in repo.repo_to_perm: |
559 perm = user.permission.permission_name | 645 perm = user.permission.permission_name |
560 user = user.user | 646 user = user.user |
561 user_data = user.get_api_data() | 647 user_data = user.get_api_data() |
562 user_data['type'] = "user" | 648 user_data['type'] = "user" |
569 users_group_data = users_group.get_api_data() | 655 users_group_data = users_group.get_api_data() |
570 users_group_data['type'] = "users_group" | 656 users_group_data['type'] = "users_group" |
571 users_group_data['permission'] = perm | 657 users_group_data['permission'] = perm |
572 members.append(users_group_data) | 658 members.append(users_group_data) |
573 | 659 |
660 for user in repo.followers: | |
661 followers.append(user.user.get_api_data()) | |
662 | |
574 data = repo.get_api_data() | 663 data = repo.get_api_data() |
575 data['members'] = members | 664 data['members'] = members |
665 data['followers'] = followers | |
576 return data | 666 return data |
577 | 667 |
578 def get_repos(self, apiuser): | 668 def get_repos(self, apiuser): |
579 """" | 669 """" |
580 Get all repositories | 670 Get all repositories |
761 raise JSONRPCError( | 851 raise JSONRPCError( |
762 'failed to fork repository `%s` as `%s`' % (repo_name, | 852 'failed to fork repository `%s` as `%s`' % (repo_name, |
763 fork_name) | 853 fork_name) |
764 ) | 854 ) |
765 | 855 |
766 def delete_repo(self, apiuser, repoid): | 856 def delete_repo(self, apiuser, repoid, forks=Optional(None)): |
767 """ | 857 """ |
768 Deletes a given repository | 858 Deletes a given repository |
769 | 859 |
770 :param apiuser: | 860 :param apiuser: |
771 :param repoid: | 861 :param repoid: |
862 :param forks: detach or delete, what do do with attached forks for repo | |
772 """ | 863 """ |
773 repo = get_repo_or_error(repoid) | 864 repo = get_repo_or_error(repoid) |
774 | 865 |
775 if HasPermissionAnyApi('hg.admin')(user=apiuser) is False: | 866 if HasPermissionAnyApi('hg.admin')(user=apiuser) is False: |
776 # check if we have admin permission for this repo ! | 867 # check if we have admin permission for this repo ! |
777 if HasRepoPermissionAnyApi('repository.admin')(user=apiuser, | 868 if HasRepoPermissionAnyApi('repository.admin')(user=apiuser, |
778 repo_name=repo.repo_name) is False: | 869 repo_name=repo.repo_name) is False: |
779 raise JSONRPCError('repository `%s` does not exist' % (repoid)) | 870 raise JSONRPCError('repository `%s` does not exist' % (repoid)) |
780 | 871 |
781 try: | 872 try: |
782 RepoModel().delete(repo) | 873 handle_forks = Optional.extract(forks) |
783 Session().commit() | 874 _forks_msg = '' |
784 return dict( | 875 _forks = [f for f in repo.forks] |
785 msg='Deleted repository `%s`' % repo.repo_name, | 876 if handle_forks == 'detach': |
877 _forks_msg = ' ' + _('Detached %s forks') % len(_forks) | |
878 elif handle_forks == 'delete': | |
879 _forks_msg = ' ' + _('Deleted %s forks') % len(_forks) | |
880 elif _forks: | |
881 raise JSONRPCError( | |
882 'Cannot delete `%s` it still contains attached forks' | |
883 % repo.repo_name | |
884 ) | |
885 | |
886 RepoModel().delete(repo, forks=forks) | |
887 Session().commit() | |
888 return dict( | |
889 msg='Deleted repository `%s`%s' % (repo.repo_name, _forks_msg), | |
786 success=True | 890 success=True |
787 ) | 891 ) |
788 except Exception: | 892 except Exception: |
789 log.error(traceback.format_exc()) | 893 log.error(traceback.format_exc()) |
790 raise JSONRPCError( | 894 raise JSONRPCError( |
857 | 961 |
858 @HasPermissionAllDecorator('hg.admin') | 962 @HasPermissionAllDecorator('hg.admin') |
859 def grant_users_group_permission(self, apiuser, repoid, usersgroupid, | 963 def grant_users_group_permission(self, apiuser, repoid, usersgroupid, |
860 perm): | 964 perm): |
861 """ | 965 """ |
862 Grant permission for users group on given repository, or update | 966 Grant permission for user group on given repository, or update |
863 existing one if found | 967 existing one if found |
864 | 968 |
865 :param apiuser: | 969 :param apiuser: |
866 :param repoid: | 970 :param repoid: |
867 :param usersgroupid: | 971 :param usersgroupid: |
876 group_name=users_group, | 980 group_name=users_group, |
877 perm=perm) | 981 perm=perm) |
878 | 982 |
879 Session().commit() | 983 Session().commit() |
880 return dict( | 984 return dict( |
881 msg='Granted perm: `%s` for users group: `%s` in ' | 985 msg='Granted perm: `%s` for user group: `%s` in ' |
882 'repo: `%s`' % ( | 986 'repo: `%s`' % ( |
883 perm.permission_name, users_group.users_group_name, | 987 perm.permission_name, users_group.users_group_name, |
884 repo.repo_name | 988 repo.repo_name |
885 ), | 989 ), |
886 success=True | 990 success=True |
887 ) | 991 ) |
888 except Exception: | 992 except Exception: |
889 log.error(traceback.format_exc()) | 993 log.error(traceback.format_exc()) |
890 raise JSONRPCError( | 994 raise JSONRPCError( |
891 'failed to edit permission for users group: `%s` in ' | 995 'failed to edit permission for user group: `%s` in ' |
892 'repo: `%s`' % ( | 996 'repo: `%s`' % ( |
893 usersgroupid, repo.repo_name | 997 usersgroupid, repo.repo_name |
894 ) | 998 ) |
895 ) | 999 ) |
896 | 1000 |
897 @HasPermissionAllDecorator('hg.admin') | 1001 @HasPermissionAllDecorator('hg.admin') |
898 def revoke_users_group_permission(self, apiuser, repoid, usersgroupid): | 1002 def revoke_users_group_permission(self, apiuser, repoid, usersgroupid): |
899 """ | 1003 """ |
900 Revoke permission for users group on given repository | 1004 Revoke permission for user group on given repository |
901 | 1005 |
902 :param apiuser: | 1006 :param apiuser: |
903 :param repoid: | 1007 :param repoid: |
904 :param usersgroupid: | 1008 :param usersgroupid: |
905 """ | 1009 """ |
910 RepoModel().revoke_users_group_permission(repo=repo, | 1014 RepoModel().revoke_users_group_permission(repo=repo, |
911 group_name=users_group) | 1015 group_name=users_group) |
912 | 1016 |
913 Session().commit() | 1017 Session().commit() |
914 return dict( | 1018 return dict( |
915 msg='Revoked perm for users group: `%s` in repo: `%s`' % ( | 1019 msg='Revoked perm for user group: `%s` in repo: `%s`' % ( |
916 users_group.users_group_name, repo.repo_name | 1020 users_group.users_group_name, repo.repo_name |
917 ), | 1021 ), |
918 success=True | 1022 success=True |
919 ) | 1023 ) |
920 except Exception: | 1024 except Exception: |
921 log.error(traceback.format_exc()) | 1025 log.error(traceback.format_exc()) |
922 raise JSONRPCError( | 1026 raise JSONRPCError( |
923 'failed to edit permission for users group: `%s` in ' | 1027 'failed to edit permission for user group: `%s` in ' |
924 'repo: `%s`' % ( | 1028 'repo: `%s`' % ( |
925 users_group.users_group_name, repo.repo_name | 1029 users_group.users_group_name, repo.repo_name |
926 ) | 1030 ) |
927 ) | 1031 ) |