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
This commit is contained in:
RhodeCode Admin 2024-10-14 11:07:44 +02:00
parent d395289357
commit a7e6b8d86c
3 changed files with 89 additions and 18 deletions

View file

@ -100,22 +100,16 @@ class RepoSettingsPermissionsView(RepoAppView):
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")

View file

@ -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 '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 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 kwargs.get('repo_landing_rev'):
landing_rev_val = kwargs['repo_landing_rev']
RepoModel().set_landing_rev(cur_repo, landing_rev_val)

View file

@ -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