Use "real paths" instead of absolute paths

See issue #82 for details:
https://bitbucket.org/sdorra/scm-manager/issues/82/symbolic-link-in-hg-repository-path
This commit is contained in:
René Pfeuffer
2018-11-23 11:59:12 +01:00
parent 5cff79fc97
commit c0000df508
3 changed files with 39 additions and 13 deletions

View File

@@ -45,8 +45,8 @@ import sonia.scm.store.ConfigurationStoreFactory;
import sonia.scm.xml.AbstractXmlDAO; import sonia.scm.xml.AbstractXmlDAO;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection; import java.util.Collection;
import java.util.Optional; import java.util.Optional;
@@ -158,11 +158,22 @@ public class XmlRepositoryDAO
@Override @Override
public String getIdForDirectory(File path) { public String getIdForDirectory(File path) {
return db.getPaths().stream() for (RepositoryPath p : db.getPaths()) {
.filter(p -> path.toPath().startsWith(context.getBaseDirectory().toPath().resolve(p.getPath()).toAbsolutePath())) if (toRealPath(path.toPath()).startsWith(toRealPath(context.getBaseDirectory().toPath().resolve(p.getPath())))) {
.map(RepositoryPath::getId) return p.getId();
.findAny() }
.orElseThrow(() -> new RuntimeException("could not find repository for directory: " + path)); }
throw new RuntimeException("could not find repository for directory: " + path);
}
private Path toRealPath(Path path) {
try {
// resolve links and other indirections
// (see issue #82, https://bitbucket.org/sdorra/scm-manager/issues/82/symbolic-link-in-hg-repository-path)
return path.toRealPath();
} catch (IOException e) {
throw new RuntimeException("could not get Path$toRealPath for path: " + path);
}
} }
private Optional<RepositoryPath> findExistingRepositoryPath(Repository repository) { private Optional<RepositoryPath> findExistingRepositoryPath(Repository repository) {

View File

@@ -15,6 +15,7 @@ import sonia.scm.store.ConfigurationStoreFactory;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import static java.util.Collections.emptyList; import static java.util.Collections.emptyList;
@@ -118,6 +119,7 @@ public class XmlRepositoryDAOTest {
@Test @Test
public void shouldFindRepositoryForRelativePath() { public void shouldFindRepositoryForRelativePath() {
new File(context.getBaseDirectory(), "relative/path/data").mkdirs();
Repository existingRepository = new Repository("id", "old", null, null); Repository existingRepository = new Repository("id", "old", null, null);
RepositoryPath repositoryPath = new RepositoryPath("relative/path", "id", existingRepository); RepositoryPath repositoryPath = new RepositoryPath("relative/path", "id", existingRepository);
when(db.getPaths()).thenReturn(asList(repositoryPath)); when(db.getPaths()).thenReturn(asList(repositoryPath));
@@ -130,14 +132,31 @@ public class XmlRepositoryDAOTest {
} }
@Test @Test
public void shouldFindRepositoryForAbsolutePath() { public void shouldFindRepositoryForAbsolutePath() throws IOException {
Repository existingRepository = new Repository("id", "old", null, null); Repository existingRepository = new Repository("id", "old", null, null);
RepositoryPath repositoryPath = new RepositoryPath("/tmp/somewhere/else", "id", existingRepository); File folder = temporaryFolder.newFolder("somewhere", "data");
RepositoryPath repositoryPath = new RepositoryPath(folder.getParent(), "id", existingRepository);
when(db.getPaths()).thenReturn(asList(repositoryPath)); when(db.getPaths()).thenReturn(asList(repositoryPath));
XmlRepositoryDAO dao = new XmlRepositoryDAO(storeFactory, new InitialRepositoryLocationResolver(context), context); XmlRepositoryDAO dao = new XmlRepositoryDAO(storeFactory, new InitialRepositoryLocationResolver(context), context);
String id = dao.getIdForDirectory(new File("/tmp/somewhere/else/data")); String id = dao.getIdForDirectory(folder);
assertThat(id).isEqualTo("id");
}
@Test
public void shouldFindRepositoryForLinks() throws IOException {
Repository existingRepository = new Repository("id", "old", null, null);
File folder = temporaryFolder.newFolder("somewhere", "else", "data");
File link = new File(folder.getParentFile().getParentFile(), "link");
Files.createSymbolicLink(link.toPath(), folder.getParentFile().toPath());
RepositoryPath repositoryPath = new RepositoryPath(new File(link, "data").getPath(), "id", existingRepository);
when(db.getPaths()).thenReturn(asList(repositoryPath));
XmlRepositoryDAO dao = new XmlRepositoryDAO(storeFactory, new InitialRepositoryLocationResolver(context), context);
String id = dao.getIdForDirectory(folder);
assertThat(id).isEqualTo("id"); assertThat(id).isEqualTo("id");
} }

View File

@@ -455,10 +455,6 @@ public class HgHookCallbackServlet extends HttpServlet
String path = request.getParameter(PARAM_REPOSITORYPATH); String path = request.getParameter(PARAM_REPOSITORYPATH);
if (Util.isNotEmpty(path)) { if (Util.isNotEmpty(path)) {
/*
* use canonical path to fix symbolic links
* https://bitbucket.org/sdorra/scm-manager/issue/82/symbolic-link-in-hg-repository-path
*/
id = repositoryDAO.getIdForDirectory(new File(path)); id = repositoryDAO.getIdForDirectory(new File(path));
} }
else if (logger.isWarnEnabled()) else if (logger.isWarnEnabled())