Merge pull request !2935 from rhodecode-enterprise-ce fefature/RCCE-371_If-repo-is-damaged-redirect-to-deletion-page
feature: redirect to repo remove if repo is damaged
This commit is contained in:
commit
7bc3381ddb
4 changed files with 57 additions and 8 deletions
|
|
@ -333,7 +333,9 @@ class RepoAppView(BaseAppView):
|
|||
|
||||
c.path_filter = self.path_filter # used by atom_feed_entry.mako
|
||||
|
||||
if self.rhodecode_vcs_repo is None:
|
||||
is_broken = self.request.params.get("broken") # needed to prevent infinit loop
|
||||
|
||||
if self.rhodecode_vcs_repo is None and is_broken is None:
|
||||
# unable to fetch this repo as vcs instance, report back to user
|
||||
log.debug("Repository was not found on filesystem, check if it exists or is not damaged")
|
||||
h.flash(
|
||||
|
|
@ -353,8 +355,15 @@ class RepoAppView(BaseAppView):
|
|||
|
||||
raise HTTPFound(h.route_path("repo_summary", repo_name=self.db_repo_name))
|
||||
|
||||
else: # redirect if we don't show missing requirements
|
||||
raise HTTPFound(h.route_path("home"))
|
||||
else: # give user possibility to remove broken repo
|
||||
raise HTTPFound(
|
||||
h.route_path(
|
||||
"edit_repo_advanced",
|
||||
repo_name=self.db_repo_name,
|
||||
_anchor="advanced-delete",
|
||||
_query={"broken": True},
|
||||
)
|
||||
)
|
||||
|
||||
c.has_origin_repo_read_perm = False
|
||||
if self.db_repo.fork:
|
||||
|
|
|
|||
|
|
@ -115,6 +115,29 @@ class TestAdminRepoSettingsAdvanced(object):
|
|||
assert RepoModel().get_by_repo_name(repo_name) is None
|
||||
assert not repo_on_filesystem(repo_name_str)
|
||||
|
||||
@pytest.mark.parametrize("suffix", ["", "ąęł", "123"], ids=no_newline_id_generator)
|
||||
def test_delete_broken_repo(self, autologin_user, backend, suffix, csrf_token):
|
||||
repo = backend.create_repo(name_suffix=suffix, private_repo=True)
|
||||
repo.private = True
|
||||
Session().commit()
|
||||
|
||||
repo_name = repo.repo_name
|
||||
repo_name_str = safe_str(repo.repo_name)
|
||||
|
||||
# delete from file system
|
||||
RepoModel()._delete_filesystem_repo(repo)
|
||||
assert not repo_on_filesystem(repo_name_str)
|
||||
|
||||
response = self.app.post(
|
||||
route_path("edit_repo_advanced_delete", repo_name=repo_name_str), params={"csrf_token": csrf_token}
|
||||
)
|
||||
assert_session_flash(response, "Deleted repository `{}`".format(repo_name))
|
||||
response.follow()
|
||||
|
||||
# check if repo was deleted from db
|
||||
assert RepoModel().get_by_repo_name(repo_name) is None
|
||||
assert not repo_on_filesystem(repo_name_str)
|
||||
|
||||
@patch.object(RepoSettingsAdvancedView, "_maybe_needs_password_change")
|
||||
@patch.object(RepoSettingsAdvancedView, "_maybe_needs_2fa_configuration")
|
||||
@patch.object(RepoSettingsAdvancedView, "_maybe_needs_2fa_check")
|
||||
|
|
@ -128,6 +151,7 @@ class TestAdminRepoSettingsAdvanced(object):
|
|||
|
||||
db_repo.scm_instance.return_value = scm_instance
|
||||
request.db_repo = db_repo
|
||||
request.params = {}
|
||||
|
||||
obj = RepoSettingsAdvancedView(MagicMock(), request)
|
||||
# bypass decorators
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
import re
|
||||
import urllib
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
|
|
@ -232,6 +233,9 @@ class TestRepoLocation(object):
|
|||
f"The repository `{repo_name}` cannot be loaded in filesystem. Please check if it exist, or is not damaged."
|
||||
)
|
||||
assert_session_flash(response, msg)
|
||||
path = route_path("edit_repo_advanced", repo_name=safe_str(repo_name))
|
||||
path = urllib.parse.quote(path) + "?broken=True#advanced-delete"
|
||||
assert response.location.endswith(path)
|
||||
|
||||
@pytest.mark.parametrize("suffix", ["", "ąęł"], ids=["", "non-ascii"])
|
||||
def test_missing_filesystem_repo_on_repo_check(self, autologin_user, backend, suffix, csrf_token):
|
||||
|
|
|
|||
|
|
@ -57,6 +57,17 @@ class RepoSettingsAdvancedView(RepoAppView):
|
|||
c = self.load_default_context()
|
||||
c.active = "advanced"
|
||||
|
||||
is_broken = self.request.params.get("broken")
|
||||
if is_broken:
|
||||
# Special case: the repository is missing on the filesystem, so its state is unknown.
|
||||
# Only allow deletion in this mode.
|
||||
c.fork_links = []
|
||||
c.pr_link = None
|
||||
c.in_public_journal = None
|
||||
c.ver_info_dict = {}
|
||||
c.hooks_outdated = False
|
||||
return self._get_template_context(c)
|
||||
|
||||
c.fork_links = self._resolve_repo_forks_links()
|
||||
c.pr_link = h.route_path("pullrequest_show_all", repo_name=self.db_repo_name)
|
||||
|
||||
|
|
@ -139,8 +150,6 @@ class RepoSettingsAdvancedView(RepoAppView):
|
|||
|
||||
repo_advanced_url = h.route_path("edit_repo_advanced", repo_name=self.db_repo_name, _anchor="advanced-delete")
|
||||
try:
|
||||
old_data = self.db_repo.get_api_data()
|
||||
|
||||
delete_cache = True
|
||||
self._invalidate_remote_cache(delete=delete_cache)
|
||||
|
||||
|
|
@ -159,6 +168,7 @@ class RepoSettingsAdvancedView(RepoAppView):
|
|||
h.flash(_("Deleted %s forks") % fork_cnt, category="success")
|
||||
|
||||
repo = audit_logger.RepoWrap(repo_id=None, repo_name=self.db_repo.repo_name)
|
||||
old_data = self.db_repo.get_api_data()
|
||||
audit_logger.store_web(
|
||||
"repo.delete", action_data={"old_data": old_data}, user=self._rhodecode_user, repo=repo
|
||||
)
|
||||
|
|
@ -203,8 +213,8 @@ class RepoSettingsAdvancedView(RepoAppView):
|
|||
|
||||
# redirect to advanced for forks handle action ?
|
||||
raise HTTPFound(repo_advanced_url)
|
||||
except Exception:
|
||||
log.exception("Exception during deletion of repository")
|
||||
except Exception as e:
|
||||
log.exception(f"Exception during deletion of repository: {str(e)}")
|
||||
h.flash(_("An error occurred during deletion of `%s`") % self.db_repo_name, category="error")
|
||||
# redirect to advanced for more deletion options
|
||||
raise HTTPFound(h.route_path("edit_repo_advanced", repo_name=self.db_repo_name, _anchor="advanced-delete"))
|
||||
|
|
@ -214,7 +224,9 @@ class RepoSettingsAdvancedView(RepoAppView):
|
|||
def _invalidate_remote_cache(self, delete: bool):
|
||||
log.debug(f"Invalidating remote cache, for repository: {self.db_repo_name}")
|
||||
scm_repo = self.db_repo.scm_instance(cache=False)
|
||||
scm_repo.vcsserver_invalidate_cache(delete=delete)
|
||||
if scm_repo is not None:
|
||||
# if it's None - probably repo is broken and physically absent on the disk
|
||||
scm_repo.vcsserver_invalidate_cache(delete=delete)
|
||||
|
||||
@LoginRequired()
|
||||
@HasRepoPermissionAnyDecorator("repository.admin")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue