# HG changeset patch # User RhodeCode Admin # Date 2024-10-14 09:07:44 # Node ID 5b9b5ed22e497e27d9737b789dc4c5de944b0349 # Parent cb083474b1746e6185e2494a842dc0e5820d8e0c fix(permissions): added a common way to update private flag via repo model - this allows to have a one and only one way to control the flag with the business logic shared - added test for that - changed view to use this method instead of DB update and custom permissions flush - fixed a case when update of repo settings didn't flush permissions actually while it should when private flag changed diff --git a/rhodecode/apps/repository/views/repo_permissions.py b/rhodecode/apps/repository/views/repo_permissions.py --- a/rhodecode/apps/repository/views/repo_permissions.py +++ b/rhodecode/apps/repository/views/repo_permissions.py @@ -100,22 +100,16 @@ class RepoSettingsPermissionsView(RepoAp self.load_default_context() private_flag = str2bool(self.request.POST.get('private')) - + changes = { + 'repo_private': private_flag + } try: repo = RepoModel().get(self.db_repo.repo_id) - repo.private = private_flag - Session().add(repo) - RepoModel().grant_user_permission( - repo=self.db_repo, user=User.DEFAULT_USER, perm='repository.none' - ) - + RepoModel().update(repo, **changes) Session().commit() h.flash(_('Repository `{}` private mode set successfully').format(self.db_repo_name), category='success') - # NOTE(dan): we change repo private mode we need to notify all USERS - affected_user_ids = User.get_all_user_ids() - PermissionModel().trigger_permission_flush(affected_user_ids) except Exception: log.exception("Exception during update of repository") diff --git a/rhodecode/model/repo.py b/rhodecode/model/repo.py --- a/rhodecode/model/repo.py +++ b/rhodecode/model/repo.py @@ -452,15 +452,24 @@ class RepoModel(BaseModel): setattr(cur_repo, k, val) - new_name = cur_repo.get_new_name(kwargs['repo_name']) - cur_repo.repo_name = new_name + new_name = source_repo_name + if 'repo_name' in kwargs: + new_name = cur_repo.get_new_name(kwargs['repo_name']) + cur_repo.repo_name = new_name - # if private flag is set, reset default permission to NONE - if kwargs.get('repo_private'): - EMPTY_PERM = 'repository.none' - RepoModel().grant_user_permission( - repo=cur_repo, user=User.DEFAULT_USER, perm=EMPTY_PERM - ) + if 'repo_private' in kwargs: + # if private flag is set to True, reset default permission to NONE + set_private_to = kwargs.get('repo_private') + if set_private_to: + EMPTY_PERM = 'repository.none' + RepoModel().grant_user_permission( + repo=cur_repo, user=User.DEFAULT_USER, perm=EMPTY_PERM + ) + if set_private_to != cur_repo.private: + # NOTE(dan): we change repo private mode we need to notify all USERS + # this is just by having this value set to a different value then it was before + affected_user_ids = User.get_all_user_ids() + if kwargs.get('repo_landing_rev'): landing_rev_val = kwargs['repo_landing_rev'] RepoModel().set_landing_rev(cur_repo, landing_rev_val) diff --git a/rhodecode/tests/models/test_permissions.py b/rhodecode/tests/models/test_permissions.py --- a/rhodecode/tests/models/test_permissions.py +++ b/rhodecode/tests/models/test_permissions.py @@ -166,6 +166,74 @@ class TestPermissions(object): test_user_group.user = org_owner + def test_propagated_permissions_from_repo_group_to_private_repo(self, repo_name): + # make group + self.g1 = fixture.create_repo_group('TOP_LEVEL', skip_if_exists=True) + # both perms should be read ! + assert group_perms(self.anon) == { + 'TOP_LEVEL': 'group.read' + } + + # Create repo inside the TOP_LEVEL + repo_name_in_group = RepoGroup.url_sep().join([self.g1.group_name, 'test_perm_on_private_repo']) + self.test_repo = fixture.create_repo(name=repo_name_in_group, + repo_type='hg', + repo_group=self.g1, + cur_user=self.u1,) + assert repo_perms(self.anon) == { + repo_name_in_group: 'repository.read', + 'vcs_test_git': 'repository.read', + 'vcs_test_hg': 'repository.read', + 'vcs_test_svn': 'repository.read', + } + # Now change default user permissions + new_perm = 'repository.write' + perm_updates = [ + [self.anon.user_id, new_perm, 'user'] + ] + RepoGroupModel().update_permissions( + repo_group=self.g1, perm_updates=perm_updates, recursive='all') + + Session().commit() + assert repo_perms(self.anon) == { + repo_name_in_group: new_perm, + 'vcs_test_git': 'repository.read', + 'vcs_test_hg': 'repository.read', + 'vcs_test_svn': 'repository.read', + } + + # NOW MARK repo as private + changes = { + 'repo_private': True + } + repo = RepoModel().get_by_repo_name(repo_name_in_group) + RepoModel().update(repo, **changes) + Session().commit() + + # Private repo sets 'none' permission for default user + assert repo_perms(self.anon) == { + repo_name_in_group: 'repository.none', + 'vcs_test_git': 'repository.read', + 'vcs_test_hg': 'repository.read', + 'vcs_test_svn': 'repository.read', + } + + # apply same logic of "updated" recursive, but now the anon permissions should be not be impacted + new_perm = 'repository.write' + perm_updates = [ + [self.anon.user_id, new_perm, 'user'] + ] + RepoGroupModel().update_permissions( + repo_group=self.g1, perm_updates=perm_updates, recursive='all') + + Session().commit() + assert repo_perms(self.anon) == { + repo_name_in_group: 'repository.none', + 'vcs_test_git': 'repository.read', + 'vcs_test_hg': 'repository.read', + 'vcs_test_svn': 'repository.read', + } + def test_propagated_permission_from_users_group_by_explicit_perms_exist( self, repo_name): # make group