Do not redirect for deleted repositories

This commit is contained in:
René Pfeuffer
2019-07-02 11:28:27 +02:00
parent c9861f6a04
commit 3e653713c1
2 changed files with 43 additions and 17 deletions

View File

@@ -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<String, LegacyRepositoryInfoCollection> infosForProtocol = new HashMap<>();
public ProtocolBasedLegacyRepositoryInfo(Collection<MigrationInfo> all) {
ProtocolBasedLegacyRepositoryInfo(Collection<MigrationInfo> 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<String, MigrationInfo> repositories = new HashMap<>();
private final Map<String, LegacyRepositoryInfoCollection> next = new HashMap<>();
public Optional<MigrationInfo> findRepository(List<String> pathElements) {
Optional<MigrationInfo> findRepository(List<String> pathElements) {
String firstPathElement = pathElements.get(0);
if (repositories.containsKey(firstPathElement)) {
return of(repositories.get(firstPathElement));

View File

@@ -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);
}
}