mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-14 09:25:43 +01:00
prepare ui and repository manager for directory structure
This commit is contained in:
@@ -219,8 +219,18 @@ public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepository
|
|||||||
|
|
||||||
if (isConfigured())
|
if (isConfigured())
|
||||||
{
|
{
|
||||||
directory = new File(config.getRepositoryDirectory(),
|
File repositoryDirectory = config.getRepositoryDirectory();
|
||||||
repository.getName());
|
|
||||||
|
directory = new File(repositoryDirectory, repository.getName());
|
||||||
|
|
||||||
|
if (!IOUtil.isChild(repositoryDirectory, directory))
|
||||||
|
{
|
||||||
|
StringBuilder msg = new StringBuilder(directory.getPath());
|
||||||
|
|
||||||
|
msg.append("is not a child of ").append(repositoryDirectory.getPath());
|
||||||
|
|
||||||
|
throw new ConfigurationException(msg.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -434,7 +434,7 @@ public class Repository extends BasicPropertiesAware implements ModelObject
|
|||||||
/**
|
/**
|
||||||
* Returns true if the {@link Repository} is valid.
|
* Returns true if the {@link Repository} is valid.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>The name is not empty and contains only A-z, 0-9, _, -</li>
|
* <li>The name is not empty and contains only A-z, 0-9, _, -, /</li>
|
||||||
* <li>The type is not empty</li>
|
* <li>The type is not empty</li>
|
||||||
* <li>The contact is empty or contains a valid email address</li>
|
* <li>The contact is empty or contains a valid email address</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
@@ -445,7 +445,7 @@ public class Repository extends BasicPropertiesAware implements ModelObject
|
|||||||
@Override
|
@Override
|
||||||
public boolean isValid()
|
public boolean isValid()
|
||||||
{
|
{
|
||||||
return ValidationUtil.isNameValid(name) && Util.isNotEmpty(type)
|
return ValidationUtil.isRepositoryNameValid(name) && Util.isNotEmpty(type)
|
||||||
&& ((Util.isEmpty(contact))
|
&& ((Util.isEmpty(contact))
|
||||||
|| ValidationUtil.isMailAddressValid(contact));
|
|| ValidationUtil.isMailAddressValid(contact));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ import sonia.scm.TypeManager;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The central class for managing {@link Repository} objects.
|
* The central class for managing {@link Repository} objects.
|
||||||
* This class is a singleton and is available via injection.
|
* This class is a singleton and is available via injection.
|
||||||
@@ -80,6 +82,41 @@ public interface RepositoryManager
|
|||||||
*/
|
*/
|
||||||
public Collection<Type> getConfiguredTypes();
|
public Collection<Type> getConfiguredTypes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link Repository} associated to the request uri.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param request the current http request
|
||||||
|
*
|
||||||
|
* @return associated to the request uri
|
||||||
|
* @since 1.9
|
||||||
|
*/
|
||||||
|
public Repository getFromRequest(HttpServletRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link Repository} associated to the given type and path.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param type type of the repository (hg, git ...)
|
||||||
|
* @param uri
|
||||||
|
*
|
||||||
|
* @return the {@link Repository} associated to the given type and path
|
||||||
|
* @since 1.9
|
||||||
|
*/
|
||||||
|
public Repository getFromTypeAndUri(String type, String uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link Repository} associated to the request uri.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param uri request uri without context path
|
||||||
|
*
|
||||||
|
* @return associated to the request uri
|
||||||
|
* @since 1.9
|
||||||
|
*/
|
||||||
|
public Repository getFromUri(String uri);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@link RepositoryHandler} by the given type (hg, git, svn ...).
|
* Returns a {@link RepositoryHandler} by the given type (hg, git, svn ...).
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -664,6 +664,29 @@ public class IOUtil
|
|||||||
return getScript(baseFile, baseFile.getAbsolutePath());
|
return getScript(baseFile, baseFile.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param parent
|
||||||
|
* @param child
|
||||||
|
* @since 1.9
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static boolean isChild(File parent, File child)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return child.getCanonicalPath().startsWith(parent.getCanonicalPath());
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ public class ValidationUtil
|
|||||||
/** Field description */
|
/** Field description */
|
||||||
private static final String REGEX_NAME = "^[A-z0-9\\.\\-_]+$";
|
private static final String REGEX_NAME = "^[A-z0-9\\.\\-_]+$";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private static final String REGEX_REPOSITORYNAME = "^[A-z0-9\\.\\-_/]+$";
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
private static final String REGEX_USERNAME = "^[A-z0-9\\.\\-_@]+$";
|
private static final String REGEX_USERNAME = "^[A-z0-9\\.\\-_@]+$";
|
||||||
|
|
||||||
@@ -125,6 +128,20 @@ public class ValidationUtil
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @since 1.9
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean isRepositoryNameValid(String name)
|
||||||
|
{
|
||||||
|
return Util.isNotEmpty(name) && name.matches(REGEX_REPOSITORYNAME);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ import sonia.scm.store.Store;
|
|||||||
import sonia.scm.store.StoreFactory;
|
import sonia.scm.store.StoreFactory;
|
||||||
import sonia.scm.util.AssertUtil;
|
import sonia.scm.util.AssertUtil;
|
||||||
import sonia.scm.util.CollectionAppender;
|
import sonia.scm.util.CollectionAppender;
|
||||||
|
import sonia.scm.util.HttpUtil;
|
||||||
import sonia.scm.util.IOUtil;
|
import sonia.scm.util.IOUtil;
|
||||||
import sonia.scm.util.SecurityUtil;
|
import sonia.scm.util.SecurityUtil;
|
||||||
import sonia.scm.util.Util;
|
import sonia.scm.util.Util;
|
||||||
@@ -87,6 +88,8 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
@@ -625,6 +628,89 @@ public class XmlRepositoryManager extends AbstractRepositoryManager
|
|||||||
return viewer;
|
return viewer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Repository getFromRequest(HttpServletRequest request)
|
||||||
|
{
|
||||||
|
AssertUtil.assertIsNotNull(request);
|
||||||
|
|
||||||
|
return getFromUri(HttpUtil.getStrippedURI(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
* @param uri
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Repository getFromTypeAndUri(String type, String uri)
|
||||||
|
{
|
||||||
|
AssertUtil.assertIsNotEmpty(type);
|
||||||
|
AssertUtil.assertIsNotEmpty(uri);
|
||||||
|
|
||||||
|
Repository repository = null;
|
||||||
|
|
||||||
|
if (handlerMap.containsKey(type))
|
||||||
|
{
|
||||||
|
Collection<Repository> repositories = repositoryDB.values();
|
||||||
|
|
||||||
|
for (Repository r : repositories)
|
||||||
|
{
|
||||||
|
if (type.equals(r.getType()) && isNameMatching(r, uri))
|
||||||
|
{
|
||||||
|
if (isReader(r))
|
||||||
|
{
|
||||||
|
repository = r.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param uri
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Repository getFromUri(String uri)
|
||||||
|
{
|
||||||
|
AssertUtil.assertIsNotEmpty(uri);
|
||||||
|
|
||||||
|
if (uri.startsWith(HttpUtil.SEPARATOR_PATH))
|
||||||
|
{
|
||||||
|
uri = uri.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int typeSeperator = uri.indexOf(HttpUtil.SEPARATOR_PATH);
|
||||||
|
|
||||||
|
AssertUtil.assertPositive(typeSeperator);
|
||||||
|
|
||||||
|
String type = uri.substring(0, typeSeperator);
|
||||||
|
|
||||||
|
uri = uri.substring(typeSeperator + 1);
|
||||||
|
|
||||||
|
return getFromTypeAndUri(type, uri);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
@@ -814,6 +900,30 @@ public class XmlRepositoryManager extends AbstractRepositoryManager
|
|||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param repository
|
||||||
|
* @param path
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean isNameMatching(Repository repository, String path)
|
||||||
|
{
|
||||||
|
boolean result = false;
|
||||||
|
String name = repository.getName();
|
||||||
|
|
||||||
|
if (path.startsWith(name))
|
||||||
|
{
|
||||||
|
String sub = path.substring(name.length());
|
||||||
|
|
||||||
|
result = Util.isEmpty(sub) || sub.startsWith(HttpUtil.SEPARATOR_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -51,6 +51,13 @@ Ext.apply(Ext.form.VTypes, {
|
|||||||
|
|
||||||
nameText: 'The name is invalid.',
|
nameText: 'The name is invalid.',
|
||||||
|
|
||||||
|
// repository name validator
|
||||||
|
repositoryName: function(val){
|
||||||
|
return /^[A-z0-9\.\-_\/]+$/.test(val);
|
||||||
|
},
|
||||||
|
|
||||||
|
repositoryNameText: 'The name of the repository is invalid.',
|
||||||
|
|
||||||
// username validator
|
// username validator
|
||||||
|
|
||||||
username: function(val){
|
username: function(val){
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ Sonia.repository.SettingsFormPanel = Ext.extend(Sonia.repository.FormPanel, {
|
|||||||
readOnly: update,
|
readOnly: update,
|
||||||
allowBlank: false,
|
allowBlank: false,
|
||||||
helpText: this.nameHelpText,
|
helpText: this.nameHelpText,
|
||||||
vtype: 'name'
|
vtype: 'repositoryName'
|
||||||
},{
|
},{
|
||||||
fieldLabel: this.typeText,
|
fieldLabel: this.typeText,
|
||||||
name: 'type',
|
name: 'type',
|
||||||
|
|||||||
@@ -37,16 +37,22 @@ package sonia.scm.repository;
|
|||||||
|
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
import sonia.scm.Manager;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import sonia.scm.Type;
|
||||||
import sonia.scm.repository.xml.XmlRepositoryManager;
|
import sonia.scm.repository.xml.XmlRepositoryManager;
|
||||||
import sonia.scm.store.JAXBStoreFactory;
|
import sonia.scm.store.JAXBStoreFactory;
|
||||||
import sonia.scm.store.StoreFactory;
|
import sonia.scm.store.StoreFactory;
|
||||||
import sonia.scm.util.MockUtil;
|
import sonia.scm.util.MockUtil;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -57,6 +63,36 @@ import java.util.Set;
|
|||||||
public class XmlRepositoryManagerTest extends RepositoryManagerTestBase
|
public class XmlRepositoryManagerTest extends RepositoryManagerTestBase
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void getRepositoryFromRequestUriTest()
|
||||||
|
throws RepositoryException, IOException
|
||||||
|
{
|
||||||
|
RepositoryManager m = createManager();
|
||||||
|
|
||||||
|
m.init(contextProvider);
|
||||||
|
createRepository(m, new Repository("1", "hg", "scm"));
|
||||||
|
createRepository(m, new Repository("2", "hg", "scm-test"));
|
||||||
|
createRepository(m, new Repository("3", "git", "project1/test-1"));
|
||||||
|
createRepository(m, new Repository("4", "git", "project1/test-2"));
|
||||||
|
assertEquals("scm", m.getFromUri("hg/scm").getName());
|
||||||
|
assertEquals("scm-test", m.getFromUri("hg/scm-test").getName());
|
||||||
|
assertEquals("scm-test", m.getFromUri("/hg/scm-test").getName());
|
||||||
|
assertEquals("project1/test-1",
|
||||||
|
m.getFromUri("/git/project1/test-1").getName());
|
||||||
|
assertEquals("project1/test-1",
|
||||||
|
m.getFromUri("/git/project1/test-1/ka/some/path").getName());
|
||||||
|
assertNull(m.getFromUri("/git/project1/test-3/ka/some/path"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
@@ -64,13 +100,29 @@ public class XmlRepositoryManagerTest extends RepositoryManagerTestBase
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Manager<Repository, RepositoryException> createManager()
|
protected XmlRepositoryManager createManager()
|
||||||
{
|
{
|
||||||
Set<RepositoryHandler> handlerSet = new HashSet<RepositoryHandler>();
|
Set<RepositoryHandler> handlerSet = new HashSet<RepositoryHandler>();
|
||||||
StoreFactory factory = new JAXBStoreFactory();
|
StoreFactory factory = new JAXBStoreFactory();
|
||||||
|
|
||||||
factory.init(contextProvider);
|
factory.init(contextProvider);
|
||||||
handlerSet.add(new DummyRepositoryHandler(factory));
|
handlerSet.add(new DummyRepositoryHandler(factory));
|
||||||
|
handlerSet.add(new DummyRepositoryHandler(factory)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Type getType()
|
||||||
|
{
|
||||||
|
return new Type("hg", "Mercurial");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
handlerSet.add(new DummyRepositoryHandler(factory)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Type getType()
|
||||||
|
{
|
||||||
|
return new Type("git", "Git");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Provider<Set<RepositoryListener>> listenerProvider = mock(Provider.class);
|
Provider<Set<RepositoryListener>> listenerProvider = mock(Provider.class);
|
||||||
|
|
||||||
@@ -85,4 +137,20 @@ public class XmlRepositoryManagerTest extends RepositoryManagerTestBase
|
|||||||
factory, handlerSet, listenerProvider,
|
factory, handlerSet, listenerProvider,
|
||||||
hookProvider);
|
hookProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* @param repository
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* @throws RepositoryException
|
||||||
|
*/
|
||||||
|
private void createRepository(RepositoryManager m, Repository repository)
|
||||||
|
throws RepositoryException, IOException
|
||||||
|
{
|
||||||
|
m.create(repository);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user