Show More
@@ -39,7 +39,8 b' from rhodecode.model.db import true, Use' | |||||
39 | from rhodecode.lib import audit_logger, rc_cache |
|
39 | from rhodecode.lib import audit_logger, rc_cache | |
40 | from rhodecode.lib.exceptions import ( |
|
40 | from rhodecode.lib.exceptions import ( | |
41 | UserCreationError, UserOwnsReposException, UserOwnsRepoGroupsException, |
|
41 | UserCreationError, UserOwnsReposException, UserOwnsRepoGroupsException, | |
42 |
UserOwnsUserGroupsException, |
|
42 | UserOwnsUserGroupsException, UserOwnsPullRequestsException, | |
|
43 | UserOwnsArtifactsException, DefaultUserException) | |||
43 | from rhodecode.lib.ext_json import json |
|
44 | from rhodecode.lib.ext_json import json | |
44 | from rhodecode.lib.auth import ( |
|
45 | from rhodecode.lib.auth import ( | |
45 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) |
|
46 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) | |
@@ -377,11 +378,13 b' class UsersView(UserAppView):' | |||||
377 | _repos = c.user.repositories |
|
378 | _repos = c.user.repositories | |
378 | _repo_groups = c.user.repository_groups |
|
379 | _repo_groups = c.user.repository_groups | |
379 | _user_groups = c.user.user_groups |
|
380 | _user_groups = c.user.user_groups | |
|
381 | _pull_requests = c.user.user_pull_requests | |||
380 | _artifacts = c.user.artifacts |
|
382 | _artifacts = c.user.artifacts | |
381 |
|
383 | |||
382 | handle_repos = None |
|
384 | handle_repos = None | |
383 | handle_repo_groups = None |
|
385 | handle_repo_groups = None | |
384 | handle_user_groups = None |
|
386 | handle_user_groups = None | |
|
387 | handle_pull_requests = None | |||
385 | handle_artifacts = None |
|
388 | handle_artifacts = None | |
386 |
|
389 | |||
387 | # calls for flash of handle based on handle case detach or delete |
|
390 | # calls for flash of handle based on handle case detach or delete | |
@@ -412,6 +415,15 b' class UsersView(UserAppView):' | |||||
412 | h.flash(_('Deleted %s user groups') % len(_user_groups), |
|
415 | h.flash(_('Deleted %s user groups') % len(_user_groups), | |
413 | category='success') |
|
416 | category='success') | |
414 |
|
417 | |||
|
418 | def set_handle_flash_pull_requests(): | |||
|
419 | handle = handle_pull_requests | |||
|
420 | if handle == 'detach': | |||
|
421 | h.flash(_('Detached %s pull requests') % len(_pull_requests), | |||
|
422 | category='success') | |||
|
423 | elif handle == 'delete': | |||
|
424 | h.flash(_('Deleted %s pull requests') % len(_pull_requests), | |||
|
425 | category='success') | |||
|
426 | ||||
415 | def set_handle_flash_artifacts(): |
|
427 | def set_handle_flash_artifacts(): | |
416 | handle = handle_artifacts |
|
428 | handle = handle_artifacts | |
417 | if handle == 'detach': |
|
429 | if handle == 'detach': | |
@@ -421,6 +433,12 b' class UsersView(UserAppView):' | |||||
421 | h.flash(_('Deleted %s artifacts') % len(_artifacts), |
|
433 | h.flash(_('Deleted %s artifacts') % len(_artifacts), | |
422 | category='success') |
|
434 | category='success') | |
423 |
|
435 | |||
|
436 | handle_user = User.get_first_super_admin() | |||
|
437 | handle_user_id = safe_int(self.request.POST.get('detach_user_id')) | |||
|
438 | if handle_user_id: | |||
|
439 | # NOTE(marcink): we get new owner for objects... | |||
|
440 | handle_user = User.get_or_404(handle_user_id) | |||
|
441 | ||||
424 | if _repos and self.request.POST.get('user_repos'): |
|
442 | if _repos and self.request.POST.get('user_repos'): | |
425 | handle_repos = self.request.POST['user_repos'] |
|
443 | handle_repos = self.request.POST['user_repos'] | |
426 |
|
444 | |||
@@ -430,16 +448,25 b' class UsersView(UserAppView):' | |||||
430 | if _user_groups and self.request.POST.get('user_user_groups'): |
|
448 | if _user_groups and self.request.POST.get('user_user_groups'): | |
431 | handle_user_groups = self.request.POST['user_user_groups'] |
|
449 | handle_user_groups = self.request.POST['user_user_groups'] | |
432 |
|
450 | |||
|
451 | if _pull_requests and self.request.POST.get('user_pull_requests'): | |||
|
452 | handle_pull_requests = self.request.POST['user_pull_requests'] | |||
|
453 | ||||
433 | if _artifacts and self.request.POST.get('user_artifacts'): |
|
454 | if _artifacts and self.request.POST.get('user_artifacts'): | |
434 | handle_artifacts = self.request.POST['user_artifacts'] |
|
455 | handle_artifacts = self.request.POST['user_artifacts'] | |
435 |
|
456 | |||
436 | old_values = c.user.get_api_data() |
|
457 | old_values = c.user.get_api_data() | |
437 |
|
458 | |||
438 | try: |
|
459 | try: | |
439 | UserModel().delete(c.user, handle_repos=handle_repos, |
|
460 | ||
440 | handle_repo_groups=handle_repo_groups, |
|
461 | UserModel().delete( | |
441 | handle_user_groups=handle_user_groups, |
|
462 | c.user, | |
442 |
|
|
463 | handle_repos=handle_repos, | |
|
464 | handle_repo_groups=handle_repo_groups, | |||
|
465 | handle_user_groups=handle_user_groups, | |||
|
466 | handle_pull_requests=handle_pull_requests, | |||
|
467 | handle_artifacts=handle_artifacts, | |||
|
468 | handle_new_owner=handle_user | |||
|
469 | ) | |||
443 |
|
470 | |||
444 | audit_logger.store_web( |
|
471 | audit_logger.store_web( | |
445 | 'user.delete', action_data={'old_data': old_values}, |
|
472 | 'user.delete', action_data={'old_data': old_values}, | |
@@ -449,11 +476,13 b' class UsersView(UserAppView):' | |||||
449 | set_handle_flash_repos() |
|
476 | set_handle_flash_repos() | |
450 | set_handle_flash_repo_groups() |
|
477 | set_handle_flash_repo_groups() | |
451 | set_handle_flash_user_groups() |
|
478 | set_handle_flash_user_groups() | |
|
479 | set_handle_flash_pull_requests() | |||
452 | set_handle_flash_artifacts() |
|
480 | set_handle_flash_artifacts() | |
453 | username = h.escape(old_values['username']) |
|
481 | username = h.escape(old_values['username']) | |
454 | h.flash(_('Successfully deleted user `{}`').format(username), category='success') |
|
482 | h.flash(_('Successfully deleted user `{}`').format(username), category='success') | |
455 | except (UserOwnsReposException, UserOwnsRepoGroupsException, |
|
483 | except (UserOwnsReposException, UserOwnsRepoGroupsException, | |
456 |
UserOwnsUserGroupsException, |
|
484 | UserOwnsUserGroupsException, UserOwnsPullRequestsException, | |
|
485 | UserOwnsArtifactsException, DefaultUserException) as e: | |||
457 | h.flash(e, category='warning') |
|
486 | h.flash(e, category='warning') | |
458 | except Exception: |
|
487 | except Exception: | |
459 | log.exception("Exception during deletion of user") |
|
488 | log.exception("Exception during deletion of user") | |
@@ -502,6 +531,11 b' class UsersView(UserAppView):' | |||||
502 | user_id = self.db_user_id |
|
531 | user_id = self.db_user_id | |
503 | c.user = self.db_user |
|
532 | c.user = self.db_user | |
504 |
|
533 | |||
|
534 | c.detach_user = User.get_first_super_admin() | |||
|
535 | detach_user_id = safe_int(self.request.GET.get('detach_user_id')) | |||
|
536 | if detach_user_id: | |||
|
537 | c.detach_user = User.get_or_404(detach_user_id) | |||
|
538 | ||||
505 | c.active = 'advanced' |
|
539 | c.active = 'advanced' | |
506 | c.personal_repo_group = RepoGroup.get_user_personal_repo_group(user_id) |
|
540 | c.personal_repo_group = RepoGroup.get_user_personal_repo_group(user_id) | |
507 | c.personal_repo_group_name = RepoGroupModel()\ |
|
541 | c.personal_repo_group_name = RepoGroupModel()\ | |
@@ -511,7 +545,6 b' class UsersView(UserAppView):' | |||||
511 | (x.user for x in c.user.user_review_rules), |
|
545 | (x.user for x in c.user.user_review_rules), | |
512 | key=lambda u: u.username.lower()) |
|
546 | key=lambda u: u.username.lower()) | |
513 |
|
547 | |||
514 | c.first_admin = User.get_first_super_admin() |
|
|||
515 | defaults = c.user.get_dict() |
|
548 | defaults = c.user.get_dict() | |
516 |
|
549 | |||
517 | # Interim workaround if the user participated on any pull requests as a |
|
550 | # Interim workaround if the user participated on any pull requests as a |
@@ -58,6 +58,10 b' class UserOwnsUserGroupsException(Except' | |||||
58 | pass |
|
58 | pass | |
59 |
|
59 | |||
60 |
|
60 | |||
|
61 | class UserOwnsPullRequestsException(Exception): | |||
|
62 | pass | |||
|
63 | ||||
|
64 | ||||
61 | class UserOwnsArtifactsException(Exception): |
|
65 | class UserOwnsArtifactsException(Exception): | |
62 | pass |
|
66 | pass | |
63 |
|
67 |
@@ -617,6 +617,7 b' class User(Base, BaseModel):' | |||||
617 | user_gists = relationship('Gist', cascade='all') |
|
617 | user_gists = relationship('Gist', cascade='all') | |
618 | # user pull requests |
|
618 | # user pull requests | |
619 | user_pull_requests = relationship('PullRequest', cascade='all') |
|
619 | user_pull_requests = relationship('PullRequest', cascade='all') | |
|
620 | ||||
620 | # external identities |
|
621 | # external identities | |
621 | external_identities = relationship( |
|
622 | external_identities = relationship( | |
622 | 'ExternalIdentity', |
|
623 | 'ExternalIdentity', |
@@ -43,7 +43,9 b' from rhodecode.lib.compat import Ordered' | |||||
43 | from rhodecode.lib.hooks_daemon import prepare_callback_daemon |
|
43 | from rhodecode.lib.hooks_daemon import prepare_callback_daemon | |
44 | from rhodecode.lib.markup_renderer import ( |
|
44 | from rhodecode.lib.markup_renderer import ( | |
45 | DEFAULT_COMMENTS_RENDERER, RstTemplateRenderer) |
|
45 | DEFAULT_COMMENTS_RENDERER, RstTemplateRenderer) | |
46 | from rhodecode.lib.utils2 import safe_unicode, safe_str, md5_safe, AttributeDict, safe_int |
|
46 | from rhodecode.lib.utils2 import ( | |
|
47 | safe_unicode, safe_str, md5_safe, AttributeDict, safe_int, | |||
|
48 | get_current_rhodecode_user) | |||
47 | from rhodecode.lib.vcs.backends.base import ( |
|
49 | from rhodecode.lib.vcs.backends.base import ( | |
48 | Reference, MergeResponse, MergeFailureReason, UpdateFailureReason, |
|
50 | Reference, MergeResponse, MergeFailureReason, UpdateFailureReason, | |
49 | TargetRefMissing, SourceRefMissing) |
|
51 | TargetRefMissing, SourceRefMissing) | |
@@ -1427,7 +1429,10 b' class PullRequestModel(BaseModel):' | |||||
1427 | email_kwargs=email_kwargs, |
|
1429 | email_kwargs=email_kwargs, | |
1428 | ) |
|
1430 | ) | |
1429 |
|
1431 | |||
1430 | def delete(self, pull_request, user): |
|
1432 | def delete(self, pull_request, user=None): | |
|
1433 | if not user: | |||
|
1434 | user = getattr(get_current_rhodecode_user(), 'username', None) | |||
|
1435 | ||||
1431 | pull_request = self.__get_pull_request(pull_request) |
|
1436 | pull_request = self.__get_pull_request(pull_request) | |
1432 | old_data = pull_request.get_api_data(with_merge_state=False) |
|
1437 | old_data = pull_request.get_api_data(with_merge_state=False) | |
1433 | self._cleanup_merge_workspace(pull_request) |
|
1438 | self._cleanup_merge_workspace(pull_request) |
@@ -37,17 +37,17 b' from rhodecode.lib.utils2 import (' | |||||
37 | AttributeDict, str2bool) |
|
37 | AttributeDict, str2bool) | |
38 | from rhodecode.lib.exceptions import ( |
|
38 | from rhodecode.lib.exceptions import ( | |
39 | DefaultUserException, UserOwnsReposException, UserOwnsRepoGroupsException, |
|
39 | DefaultUserException, UserOwnsReposException, UserOwnsRepoGroupsException, | |
40 |
UserOwnsUserGroupsException, NotAllowedToCreateUserError, |
|
40 | UserOwnsUserGroupsException, NotAllowedToCreateUserError, | |
|
41 | UserOwnsPullRequestsException, UserOwnsArtifactsException) | |||
41 | from rhodecode.lib.caching_query import FromCache |
|
42 | from rhodecode.lib.caching_query import FromCache | |
42 | from rhodecode.model import BaseModel |
|
43 | from rhodecode.model import BaseModel | |
43 | from rhodecode.model.auth_token import AuthTokenModel |
|
|||
44 | from rhodecode.model.db import ( |
|
44 | from rhodecode.model.db import ( | |
45 | _hash_key, true, false, or_, joinedload, User, UserToPerm, |
|
45 | _hash_key, true, false, or_, joinedload, User, UserToPerm, | |
46 | UserEmailMap, UserIpMap, UserLog) |
|
46 | UserEmailMap, UserIpMap, UserLog) | |
47 | from rhodecode.model.meta import Session |
|
47 | from rhodecode.model.meta import Session | |
|
48 | from rhodecode.model.auth_token import AuthTokenModel | |||
48 | from rhodecode.model.repo_group import RepoGroupModel |
|
49 | from rhodecode.model.repo_group import RepoGroupModel | |
49 |
|
50 | |||
50 |
|
||||
51 | log = logging.getLogger(__name__) |
|
51 | log = logging.getLogger(__name__) | |
52 |
|
52 | |||
53 |
|
53 | |||
@@ -261,7 +261,7 b' class UserModel(BaseModel):' | |||||
261 | cur_user = getattr(get_current_rhodecode_user(), 'username', None) |
|
261 | cur_user = getattr(get_current_rhodecode_user(), 'username', None) | |
262 |
|
262 | |||
263 | from rhodecode.lib.auth import ( |
|
263 | from rhodecode.lib.auth import ( | |
264 |
get_crypt_password, check_password |
|
264 | get_crypt_password, check_password) | |
265 | from rhodecode.lib.hooks_base import ( |
|
265 | from rhodecode.lib.hooks_base import ( | |
266 | log_create_user, check_allowed_create_user) |
|
266 | log_create_user, check_allowed_create_user) | |
267 |
|
267 | |||
@@ -443,15 +443,16 b' class UserModel(BaseModel):' | |||||
443 | log.error(traceback.format_exc()) |
|
443 | log.error(traceback.format_exc()) | |
444 | raise |
|
444 | raise | |
445 |
|
445 | |||
446 |
def _handle_user_repos(self, username, repositories, handle_ |
|
446 | def _handle_user_repos(self, username, repositories, handle_user, | |
447 | _superadmin = self.cls.get_first_super_admin() |
|
447 | handle_mode=None): | |
|
448 | ||||
448 | left_overs = True |
|
449 | left_overs = True | |
449 |
|
450 | |||
450 | from rhodecode.model.repo import RepoModel |
|
451 | from rhodecode.model.repo import RepoModel | |
451 |
|
452 | |||
452 | if handle_mode == 'detach': |
|
453 | if handle_mode == 'detach': | |
453 | for obj in repositories: |
|
454 | for obj in repositories: | |
454 |
obj.user = |
|
455 | obj.user = handle_user | |
455 | # set description we know why we super admin now owns |
|
456 | # set description we know why we super admin now owns | |
456 | # additional repositories that were orphaned ! |
|
457 | # additional repositories that were orphaned ! | |
457 | obj.description += ' \n::detached repository from deleted user: %s' % (username,) |
|
458 | obj.description += ' \n::detached repository from deleted user: %s' % (username,) | |
@@ -465,16 +466,16 b' class UserModel(BaseModel):' | |||||
465 | # if nothing is done we have left overs left |
|
466 | # if nothing is done we have left overs left | |
466 | return left_overs |
|
467 | return left_overs | |
467 |
|
468 | |||
468 | def _handle_user_repo_groups(self, username, repository_groups, |
|
469 | def _handle_user_repo_groups(self, username, repository_groups, handle_user, | |
469 | handle_mode=None): |
|
470 | handle_mode=None): | |
470 | _superadmin = self.cls.get_first_super_admin() |
|
471 | ||
471 | left_overs = True |
|
472 | left_overs = True | |
472 |
|
473 | |||
473 | from rhodecode.model.repo_group import RepoGroupModel |
|
474 | from rhodecode.model.repo_group import RepoGroupModel | |
474 |
|
475 | |||
475 | if handle_mode == 'detach': |
|
476 | if handle_mode == 'detach': | |
476 | for r in repository_groups: |
|
477 | for r in repository_groups: | |
477 |
r.user = |
|
478 | r.user = handle_user | |
478 | # set description we know why we super admin now owns |
|
479 | # set description we know why we super admin now owns | |
479 | # additional repositories that were orphaned ! |
|
480 | # additional repositories that were orphaned ! | |
480 | r.group_description += ' \n::detached repository group from deleted user: %s' % (username,) |
|
481 | r.group_description += ' \n::detached repository group from deleted user: %s' % (username,) | |
@@ -489,8 +490,9 b' class UserModel(BaseModel):' | |||||
489 | # if nothing is done we have left overs left |
|
490 | # if nothing is done we have left overs left | |
490 | return left_overs |
|
491 | return left_overs | |
491 |
|
492 | |||
492 |
def _handle_user_user_groups(self, username, user_groups, handle_ |
|
493 | def _handle_user_user_groups(self, username, user_groups, handle_user, | |
493 | _superadmin = self.cls.get_first_super_admin() |
|
494 | handle_mode=None): | |
|
495 | ||||
494 | left_overs = True |
|
496 | left_overs = True | |
495 |
|
497 | |||
496 | from rhodecode.model.user_group import UserGroupModel |
|
498 | from rhodecode.model.user_group import UserGroupModel | |
@@ -499,8 +501,8 b' class UserModel(BaseModel):' | |||||
499 | for r in user_groups: |
|
501 | for r in user_groups: | |
500 | for user_user_group_to_perm in r.user_user_group_to_perm: |
|
502 | for user_user_group_to_perm in r.user_user_group_to_perm: | |
501 | if user_user_group_to_perm.user.username == username: |
|
503 | if user_user_group_to_perm.user.username == username: | |
502 |
user_user_group_to_perm.user = |
|
504 | user_user_group_to_perm.user = handle_user | |
503 |
r.user = |
|
505 | r.user = handle_user | |
504 | # set description we know why we super admin now owns |
|
506 | # set description we know why we super admin now owns | |
505 | # additional repositories that were orphaned ! |
|
507 | # additional repositories that were orphaned ! | |
506 | r.user_group_description += ' \n::detached user group from deleted user: %s' % (username,) |
|
508 | r.user_group_description += ' \n::detached user group from deleted user: %s' % (username,) | |
@@ -514,13 +516,37 b' class UserModel(BaseModel):' | |||||
514 | # if nothing is done we have left overs left |
|
516 | # if nothing is done we have left overs left | |
515 | return left_overs |
|
517 | return left_overs | |
516 |
|
518 | |||
517 |
def _handle_user_ |
|
519 | def _handle_user_pull_requests(self, username, pull_requests, handle_user, | |
518 | _superadmin = self.cls.get_first_super_admin() |
|
520 | handle_mode=None): | |
|
521 | left_overs = True | |||
|
522 | ||||
|
523 | from rhodecode.model.pull_request import PullRequestModel | |||
|
524 | ||||
|
525 | if handle_mode == 'detach': | |||
|
526 | for pr in pull_requests: | |||
|
527 | pr.user_id = handle_user.user_id | |||
|
528 | # set description we know why we super admin now owns | |||
|
529 | # additional repositories that were orphaned ! | |||
|
530 | pr.description += ' \n::detached pull requests from deleted user: %s' % (username,) | |||
|
531 | self.sa.add(pr) | |||
|
532 | left_overs = False | |||
|
533 | elif handle_mode == 'delete': | |||
|
534 | for pr in pull_requests: | |||
|
535 | PullRequestModel().delete(pr) | |||
|
536 | ||||
|
537 | left_overs = False | |||
|
538 | ||||
|
539 | # if nothing is done we have left overs left | |||
|
540 | return left_overs | |||
|
541 | ||||
|
542 | def _handle_user_artifacts(self, username, artifacts, handle_user, | |||
|
543 | handle_mode=None): | |||
|
544 | ||||
519 | left_overs = True |
|
545 | left_overs = True | |
520 |
|
546 | |||
521 | if handle_mode == 'detach': |
|
547 | if handle_mode == 'detach': | |
522 | for a in artifacts: |
|
548 | for a in artifacts: | |
523 |
a.upload_user = |
|
549 | a.upload_user = handle_user | |
524 | # set description we know why we super admin now owns |
|
550 | # set description we know why we super admin now owns | |
525 | # additional artifacts that were orphaned ! |
|
551 | # additional artifacts that were orphaned ! | |
526 | a.file_description += ' \n::detached artifact from deleted user: %s' % (username,) |
|
552 | a.file_description += ' \n::detached artifact from deleted user: %s' % (username,) | |
@@ -528,7 +554,8 b' class UserModel(BaseModel):' | |||||
528 | left_overs = False |
|
554 | left_overs = False | |
529 | elif handle_mode == 'delete': |
|
555 | elif handle_mode == 'delete': | |
530 | from rhodecode.apps.file_store import utils as store_utils |
|
556 | from rhodecode.apps.file_store import utils as store_utils | |
531 | storage = store_utils.get_file_storage(self.request.registry.settings) |
|
557 | request = get_current_request() | |
|
558 | storage = store_utils.get_file_storage(request.registry.settings) | |||
532 | for a in artifacts: |
|
559 | for a in artifacts: | |
533 | file_uid = a.file_uid |
|
560 | file_uid = a.file_uid | |
534 | storage.delete(file_uid) |
|
561 | storage.delete(file_uid) | |
@@ -540,11 +567,13 b' class UserModel(BaseModel):' | |||||
540 | return left_overs |
|
567 | return left_overs | |
541 |
|
568 | |||
542 | def delete(self, user, cur_user=None, handle_repos=None, |
|
569 | def delete(self, user, cur_user=None, handle_repos=None, | |
543 |
handle_repo_groups=None, handle_user_groups=None, |
|
570 | handle_repo_groups=None, handle_user_groups=None, | |
|
571 | handle_pull_requests=None, handle_artifacts=None, handle_new_owner=None): | |||
544 | from rhodecode.lib.hooks_base import log_delete_user |
|
572 | from rhodecode.lib.hooks_base import log_delete_user | |
545 |
|
573 | |||
546 | if not cur_user: |
|
574 | if not cur_user: | |
547 | cur_user = getattr(get_current_rhodecode_user(), 'username', None) |
|
575 | cur_user = getattr(get_current_rhodecode_user(), 'username', None) | |
|
576 | ||||
548 | user = self._get_user(user) |
|
577 | user = self._get_user(user) | |
549 |
|
578 | |||
550 | try: |
|
579 | try: | |
@@ -552,9 +581,11 b' class UserModel(BaseModel):' | |||||
552 | raise DefaultUserException( |
|
581 | raise DefaultUserException( | |
553 | u"You can't remove this user since it's" |
|
582 | u"You can't remove this user since it's" | |
554 | u" crucial for entire application") |
|
583 | u" crucial for entire application") | |
|
584 | handle_user = handle_new_owner or self.cls.get_first_super_admin() | |||
|
585 | log.debug('New detached objects owner %s', handle_user) | |||
555 |
|
586 | |||
556 | left_overs = self._handle_user_repos( |
|
587 | left_overs = self._handle_user_repos( | |
557 | user.username, user.repositories, handle_repos) |
|
588 | user.username, user.repositories, handle_user, handle_repos) | |
558 | if left_overs and user.repositories: |
|
589 | if left_overs and user.repositories: | |
559 | repos = [x.repo_name for x in user.repositories] |
|
590 | repos = [x.repo_name for x in user.repositories] | |
560 | raise UserOwnsReposException( |
|
591 | raise UserOwnsReposException( | |
@@ -564,7 +595,7 b' class UserModel(BaseModel):' | |||||
564 | 'list_repos': ', '.join(repos)}) |
|
595 | 'list_repos': ', '.join(repos)}) | |
565 |
|
596 | |||
566 | left_overs = self._handle_user_repo_groups( |
|
597 | left_overs = self._handle_user_repo_groups( | |
567 | user.username, user.repository_groups, handle_repo_groups) |
|
598 | user.username, user.repository_groups, handle_user, handle_repo_groups) | |
568 | if left_overs and user.repository_groups: |
|
599 | if left_overs and user.repository_groups: | |
569 | repo_groups = [x.group_name for x in user.repository_groups] |
|
600 | repo_groups = [x.group_name for x in user.repository_groups] | |
570 | raise UserOwnsRepoGroupsException( |
|
601 | raise UserOwnsRepoGroupsException( | |
@@ -574,7 +605,7 b' class UserModel(BaseModel):' | |||||
574 | 'list_repo_groups': ', '.join(repo_groups)}) |
|
605 | 'list_repo_groups': ', '.join(repo_groups)}) | |
575 |
|
606 | |||
576 | left_overs = self._handle_user_user_groups( |
|
607 | left_overs = self._handle_user_user_groups( | |
577 | user.username, user.user_groups, handle_user_groups) |
|
608 | user.username, user.user_groups, handle_user, handle_user_groups) | |
578 | if left_overs and user.user_groups: |
|
609 | if left_overs and user.user_groups: | |
579 | user_groups = [x.users_group_name for x in user.user_groups] |
|
610 | user_groups = [x.users_group_name for x in user.user_groups] | |
580 | raise UserOwnsUserGroupsException( |
|
611 | raise UserOwnsUserGroupsException( | |
@@ -582,8 +613,17 b' class UserModel(BaseModel):' | |||||
582 | u'removed. Switch owners or remove those user groups:%s' |
|
613 | u'removed. Switch owners or remove those user groups:%s' | |
583 | % (user.username, len(user_groups), ', '.join(user_groups))) |
|
614 | % (user.username, len(user_groups), ', '.join(user_groups))) | |
584 |
|
615 | |||
|
616 | left_overs = self._handle_user_pull_requests( | |||
|
617 | user.username, user.user_pull_requests, handle_user, handle_pull_requests) | |||
|
618 | if left_overs and user.user_pull_requests: | |||
|
619 | pull_requests = ['!{}'.format(x.pull_request_id) for x in user.user_pull_requests] | |||
|
620 | raise UserOwnsPullRequestsException( | |||
|
621 | u'user "%s" still owns %s pull requests and cannot be ' | |||
|
622 | u'removed. Switch owners or remove those pull requests:%s' | |||
|
623 | % (user.username, len(pull_requests), ', '.join(pull_requests))) | |||
|
624 | ||||
585 | left_overs = self._handle_user_artifacts( |
|
625 | left_overs = self._handle_user_artifacts( | |
586 | user.username, user.artifacts, handle_artifacts) |
|
626 | user.username, user.artifacts, handle_user, handle_artifacts) | |
587 | if left_overs and user.artifacts: |
|
627 | if left_overs and user.artifacts: | |
588 | artifacts = [x.file_uid for x in user.artifacts] |
|
628 | artifacts = [x.file_uid for x in user.artifacts] | |
589 | raise UserOwnsArtifactsException( |
|
629 | raise UserOwnsArtifactsException( | |
@@ -878,7 +918,7 b' class UserModel(BaseModel):' | |||||
878 | end_ip = ipaddress.ip_address(safe_unicode(end_ip.strip())) |
|
918 | end_ip = ipaddress.ip_address(safe_unicode(end_ip.strip())) | |
879 | parsed_ip_range = [] |
|
919 | parsed_ip_range = [] | |
880 |
|
920 | |||
881 |
for index in |
|
921 | for index in range(int(start_ip), int(end_ip) + 1): | |
882 | new_ip = ipaddress.ip_address(index) |
|
922 | new_ip = ipaddress.ip_address(index) | |
883 | parsed_ip_range.append(str(new_ip)) |
|
923 | parsed_ip_range.append(str(new_ip)) | |
884 | ip_list.extend(parsed_ip_range) |
|
924 | ip_list.extend(parsed_ip_range) |
@@ -149,6 +149,18 b'' | |||||
149 |
|
149 | |||
150 | <tr> |
|
150 | <tr> | |
151 | <td> |
|
151 | <td> | |
|
152 | ${_ungettext('This user owns %s pull request.', 'This user owns %s pull requests.', len(c.user.user_pull_requests)) % len(c.user.user_pull_requests)} | |||
|
153 | </td> | |||
|
154 | <td> | |||
|
155 | <input type="radio" id="user_pull_requests_1" name="user_pull_requests" value="detach" checked="checked" ${'disabled=1' if len(c.user.user_pull_requests) == 0 else ''}/> <label for="user_pull_requests_1">${_('Detach pull requests')}</label> | |||
|
156 | </td> | |||
|
157 | <td> | |||
|
158 | <input type="radio" id="user_pull_requests_2" name="user_pull_requests" value="delete" ${'disabled=1' if len(c.user.user_pull_requests) == 0 else ''}/> <label for="user_pull_requests_2">${_('Delete pull requests')}</label> | |||
|
159 | </td> | |||
|
160 | </tr> | |||
|
161 | ||||
|
162 | <tr> | |||
|
163 | <td> | |||
152 | ${_ungettext('This user owns %s artifact.', 'This user owns %s artifacts.', len(c.user.artifacts)) % len(c.user.artifacts)} |
|
164 | ${_ungettext('This user owns %s artifact.', 'This user owns %s artifacts.', len(c.user.artifacts)) % len(c.user.artifacts)} | |
153 | </td> |
|
165 | </td> | |
154 | <td> |
|
166 | <td> | |
@@ -166,7 +178,8 b'' | |||||
166 | % endif |
|
178 | % endif | |
167 |
|
179 | |||
168 | <span style="padding: 0 5px 0 0">${_('New owner for detached objects')}:</span> |
|
180 | <span style="padding: 0 5px 0 0">${_('New owner for detached objects')}:</span> | |
169 |
<div class="pull-right">${base.gravatar_with_user(c. |
|
181 | <div class="pull-right">${base.gravatar_with_user(c.detach_user.email, 16, tooltip=True)}</div> | |
|
182 | <input type="hidden" name="detach_user_id" value="${c.detach_user.user_id}"> | |||
170 | </div> |
|
183 | </div> | |
171 | <div style="clear: both"> |
|
184 | <div style="clear: both"> | |
172 |
|
185 | |||
@@ -186,11 +199,11 b'' | |||||
186 | <div style="margin: 0 0 20px 0" class="fake-space"></div> |
|
199 | <div style="margin: 0 0 20px 0" class="fake-space"></div> | |
187 |
|
200 | |||
188 | <div class="field"> |
|
201 | <div class="field"> | |
189 |
< |
|
202 | <input class="btn btn-small btn-danger" id="remove_user" name="remove_user" | |
190 |
|
|
203 | onclick="submitConfirm(event, this, _gettext('Confirm to delete this user'), _gettext('Confirm Delete'), '${c.user.username}')" | |
191 |
|
|
204 | ${("disabled=1" if not c.can_delete_user else "")} | |
192 | ${_('Delete this user')} |
|
205 | type="submit" value="${_('Delete this user')}" | |
193 |
|
|
206 | > | |
194 | </div> |
|
207 | </div> | |
195 |
|
208 | |||
196 | ${h.end_form()} |
|
209 | ${h.end_form()} |
General Comments 0
You need to be logged in to leave comments.
Login now