diff --git a/scm-plugins/scm-legacy-plugin/src/main/java/sonia/scm/legacy/RepositoryLegacyProtocolRedirectFilter.java b/scm-plugins/scm-legacy-plugin/src/main/java/sonia/scm/legacy/RepositoryLegacyProtocolRedirectFilter.java index 43808a7fb8..b95d374245 100644 --- a/scm-plugins/scm-legacy-plugin/src/main/java/sonia/scm/legacy/RepositoryLegacyProtocolRedirectFilter.java +++ b/scm-plugins/scm-legacy-plugin/src/main/java/sonia/scm/legacy/RepositoryLegacyProtocolRedirectFilter.java @@ -2,6 +2,7 @@ package sonia.scm.legacy; import sonia.scm.migration.MigrationDAO; import sonia.scm.migration.MigrationInfo; +import sonia.scm.repository.RepositoryManager; import sonia.scm.web.filter.HttpFilter; import javax.inject.Inject; @@ -21,16 +22,17 @@ import static java.util.Arrays.asList; import static java.util.Optional.empty; import static java.util.Optional.of; import static org.apache.commons.lang.StringUtils.isEmpty; -import static org.apache.commons.lang.StringUtils.isNotEmpty; @Singleton public class RepositoryLegacyProtocolRedirectFilter extends HttpFilter { private final ProtocolBasedLegacyRepositoryInfo info; + private final RepositoryManager repositoryManager; @Inject - public RepositoryLegacyProtocolRedirectFilter(MigrationDAO migrationDAO) { + public RepositoryLegacyProtocolRedirectFilter(MigrationDAO migrationDAO, RepositoryManager repositoryManager) { this.info = load(migrationDAO); + this.repositoryManager = repositoryManager; } private static ProtocolBasedLegacyRepositoryInfo load(MigrationDAO migrationDAO) { @@ -53,7 +55,7 @@ public class RepositoryLegacyProtocolRedirectFilter extends HttpFilter { this.chain = chain; } - public void doFilter() throws IOException, ServletException { + void doFilter() throws IOException, ServletException { String servletPath = getServletPathWithoutLeadingSlash(); String[] pathElements = servletPath.split("/"); if (pathElements.length > 0) { @@ -72,13 +74,17 @@ public class RepositoryLegacyProtocolRedirectFilter extends HttpFilter { } } - private void doRedirect(String servletPath, MigrationInfo migrationInfo) throws IOException { - String furtherPath = servletPath.substring(migrationInfo.getProtocol().length() + 1 + migrationInfo.getOriginalRepositoryName().length()); - String queryString = request.getQueryString(); - if (isEmpty(queryString)) { - redirectWithoutQueryParameters(migrationInfo, furtherPath); + private void doRedirect(String servletPath, MigrationInfo migrationInfo) throws IOException, ServletException { + if (repositoryManager.get(migrationInfo.getId()) == null) { + noRedirect(); } else { - redirectWithQueryParameters(migrationInfo, furtherPath, queryString); + String furtherPath = servletPath.substring(migrationInfo.getProtocol().length() + 1 + migrationInfo.getOriginalRepositoryName().length()); + String queryString = request.getQueryString(); + if (isEmpty(queryString)) { + redirectWithoutQueryParameters(migrationInfo, furtherPath); + } else { + redirectWithQueryParameters(migrationInfo, furtherPath, queryString); + } } } @@ -108,7 +114,7 @@ public class RepositoryLegacyProtocolRedirectFilter extends HttpFilter { private final Map infosForProtocol = new HashMap<>(); - public ProtocolBasedLegacyRepositoryInfo(Collection all) { + ProtocolBasedLegacyRepositoryInfo(Collection all) { all.forEach(this::add); } @@ -126,7 +132,7 @@ public class RepositoryLegacyProtocolRedirectFilter extends HttpFilter { return infosForProtocol.get(protocol).findRepository(removeFirstElement(pathElements)); } - public boolean isProtocol(String protocol) { + boolean isProtocol(String protocol) { return infosForProtocol.containsKey(protocol); } } @@ -136,7 +142,7 @@ public class RepositoryLegacyProtocolRedirectFilter extends HttpFilter { private final Map repositories = new HashMap<>(); private final Map next = new HashMap<>(); - public Optional findRepository(List pathElements) { + Optional findRepository(List pathElements) { String firstPathElement = pathElements.get(0); if (repositories.containsKey(firstPathElement)) { return of(repositories.get(firstPathElement)); diff --git a/scm-plugins/scm-legacy-plugin/src/test/java/sonia/scm/legacy/RepositoryLegacyProtocolRedirectFilterTest.java b/scm-plugins/scm-legacy-plugin/src/test/java/sonia/scm/legacy/RepositoryLegacyProtocolRedirectFilterTest.java index 2dba66f54a..c54193f455 100644 --- a/scm-plugins/scm-legacy-plugin/src/test/java/sonia/scm/legacy/RepositoryLegacyProtocolRedirectFilterTest.java +++ b/scm-plugins/scm-legacy-plugin/src/test/java/sonia/scm/legacy/RepositoryLegacyProtocolRedirectFilterTest.java @@ -7,6 +7,8 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import sonia.scm.migration.MigrationDAO; import sonia.scm.migration.MigrationInfo; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryManager; import javax.servlet.FilterChain; import javax.servlet.ServletException; @@ -15,6 +17,7 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; import static java.util.Collections.singletonList; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -26,6 +29,8 @@ class RepositoryLegacyProtocolRedirectFilterTest { @Mock MigrationDAO migrationDAO; @Mock + RepositoryManager repositoryManager; + @Mock HttpServletRequest request; @Mock HttpServletResponse response; @@ -33,7 +38,7 @@ class RepositoryLegacyProtocolRedirectFilterTest { FilterChain filterChain; @BeforeEach - void initContextPath() { + void initRequest() { lenient().when(request.getContextPath()).thenReturn("/scm"); lenient().when(request.getQueryString()).thenReturn(""); } @@ -42,7 +47,7 @@ class RepositoryLegacyProtocolRedirectFilterTest { void shouldNotRedirectForEmptyMigrationList() throws IOException, ServletException { when(request.getServletPath()).thenReturn("/git/old/name"); - new RepositoryLegacyProtocolRedirectFilter(migrationDAO).doFilter(request, response, filterChain); + new RepositoryLegacyProtocolRedirectFilter(migrationDAO, repositoryManager).doFilter(request, response, filterChain); verify(filterChain).doFilter(request, response); } @@ -50,9 +55,10 @@ class RepositoryLegacyProtocolRedirectFilterTest { @Test void shouldRedirectForExistingRepository() throws IOException, ServletException { when(migrationDAO.getAll()).thenReturn(singletonList(new MigrationInfo("id", "git", "old/name", "namespace", "name"))); + when(repositoryManager.get("id")).thenReturn(new Repository()); when(request.getServletPath()).thenReturn("/git/old/name"); - new RepositoryLegacyProtocolRedirectFilter(migrationDAO).doFilter(request, response, filterChain); + new RepositoryLegacyProtocolRedirectFilter(migrationDAO, repositoryManager).doFilter(request, response, filterChain); verify(response).sendRedirect("/scm/repo/namespace/name"); verify(filterChain, never()).doFilter(request, response); @@ -61,9 +67,10 @@ class RepositoryLegacyProtocolRedirectFilterTest { @Test void shouldRedirectForExistingRepositoryWithFurtherPathElements() throws IOException, ServletException { when(migrationDAO.getAll()).thenReturn(singletonList(new MigrationInfo("id", "git", "old/name", "namespace", "name"))); + when(repositoryManager.get("id")).thenReturn(new Repository()); when(request.getServletPath()).thenReturn("/git/old/name/info/refs"); - new RepositoryLegacyProtocolRedirectFilter(migrationDAO).doFilter(request, response, filterChain); + new RepositoryLegacyProtocolRedirectFilter(migrationDAO, repositoryManager).doFilter(request, response, filterChain); verify(response).sendRedirect("/scm/repo/namespace/name/info/refs"); verify(filterChain, never()).doFilter(request, response); @@ -72,12 +79,25 @@ class RepositoryLegacyProtocolRedirectFilterTest { @Test void shouldRedirectWithQueryParameters() throws IOException, ServletException { when(migrationDAO.getAll()).thenReturn(singletonList(new MigrationInfo("id", "git", "old/name", "namespace", "name"))); + when(repositoryManager.get("id")).thenReturn(new Repository()); when(request.getServletPath()).thenReturn("/git/old/name/info/refs"); when(request.getQueryString()).thenReturn("parameter=value"); - new RepositoryLegacyProtocolRedirectFilter(migrationDAO).doFilter(request, response, filterChain); + new RepositoryLegacyProtocolRedirectFilter(migrationDAO, repositoryManager).doFilter(request, response, filterChain); verify(response).sendRedirect("/scm/repo/namespace/name/info/refs?parameter=value"); verify(filterChain, never()).doFilter(request, response); } + + @Test + void shouldNotRedirectWhenRepositoryHasBeenDeleted() throws IOException, ServletException { + when(migrationDAO.getAll()).thenReturn(singletonList(new MigrationInfo("id", "git", "old/name", "namespace", "name"))); + when(repositoryManager.get("id")).thenReturn(null); + when(request.getServletPath()).thenReturn("/git/old/name"); + + new RepositoryLegacyProtocolRedirectFilter(migrationDAO, repositoryManager).doFilter(request, response, filterChain); + + verify(response, never()).sendRedirect(any()); + verify(filterChain).doFilter(request, response); + } }