This commit is contained in:
Thorsten Ludewig
2011-02-02 09:41:03 +01:00
73 changed files with 1793 additions and 545 deletions

View File

@@ -6,13 +6,13 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.maven</groupId>
<artifactId>scm-maven-plugins</artifactId>
<packaging>pom</packaging>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-maven-plugins</name>
<modules>
@@ -24,7 +24,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-maven-plugins</artifactId>
<groupId>sonia.scm.maven</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.maven</groupId>
<artifactId>scm-plugin-archetype</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-plugin-archetype</name>
</project>

View File

@@ -7,7 +7,7 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>${groupId}</groupId>
@@ -31,7 +31,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<scope>test</scope>
</dependency>

View File

@@ -6,13 +6,13 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-plugins</artifactId>
<packaging>pom</packaging>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-plugins</name>
<modules>
@@ -31,7 +31,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-activedirectory-auth-plugin</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-activedirectory-auth-plugin</name>
<url>https://bitbucket.org/sdorra/scm-manager</url>
<description>
@@ -32,7 +32,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
<dependency>

View File

@@ -6,13 +6,13 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-auth-ldap-plugin</artifactId>
<packaging>jar</packaging>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>${project.artifactId}</name>
<description>plugin description</description>
@@ -30,7 +30,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<scope>test</scope>
</dependency>

View File

@@ -49,6 +49,7 @@ import sonia.scm.user.User;
import sonia.scm.util.AssertUtil;
import sonia.scm.web.security.AuthenticationHandler;
import sonia.scm.web.security.AuthenticationResult;
import sonia.scm.web.security.AuthenticationState;
//~--- JDK imports ------------------------------------------------------------
@@ -57,8 +58,10 @@ import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
@@ -136,7 +139,8 @@ public class LDAPAuthenticationHandler implements AuthenticationHandler
searchControls.setCountLimit(1);
searchControls.setReturningAttributes(new String[] {
config.getAttributeNameId(),
config.getAttributeNameFullname(), config.getAttributeNameMail() });
config.getAttributeNameFullname(), config.getAttributeNameMail(),
config.getAttributeNameGroup() });
String filter = MessageFormat.format(config.getSearchFilter(), username);
String baseDn = config.getUnitPeople() + "," + config.getBaseDn();
@@ -177,7 +181,7 @@ public class LDAPAuthenticationHandler implements AuthenticationHandler
user.setType(TYPE);
//
ArrayList<String> groups = new ArrayList<String>();
HashSet<String> groups = new HashSet<String>();
searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
@@ -190,7 +194,6 @@ public class LDAPAuthenticationHandler implements AuthenticationHandler
+ userDn + "))", searchControls);
//
while (searchResult2.hasMore())
{
SearchResult sr2 = searchResult2.next();
@@ -209,9 +212,9 @@ public class LDAPAuthenticationHandler implements AuthenticationHandler
}
//
result = new AuthenticationResult(user, groups);
getGroups(userAttributes, groups);
user.setAdmin(isAdmin(user.getName(), groups));
//
result = new AuthenticationResult(user, groups);
}
catch (NamingException ex)
@@ -370,6 +373,39 @@ public class LDAPAuthenticationHandler implements AuthenticationHandler
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param userAttributes
* @param groups
*
* @throws NamingException
*/
private void getGroups(Attributes userAttributes, HashSet<String> groups)
throws NamingException
{
Attribute groupsAttribute =
userAttributes.get(config.getAttributeNameGroup());
if (groupsAttribute != null)
{
NamingEnumeration<?> userGroups =
(NamingEnumeration<?>) groupsAttribute.getAll();
while (userGroups.hasMore())
{
groups.add((String) userGroups.next());
}
userGroups.close();
}
else
{
logger.info("user has no groups assigned");
}
}
/**
* Method description
*
@@ -379,7 +415,7 @@ public class LDAPAuthenticationHandler implements AuthenticationHandler
*
* @return
*/
private boolean isAdmin(String userName, List<String> groups)
private boolean isAdmin(String userName, Set<String> groups)
{
boolean admin = false;

View File

@@ -118,6 +118,10 @@ public class LDAPConfig
return attributeNameMail;
}
public String getAttributeNameGroup() {
return attributeNameGroup;
}
/**
* Method description
*
@@ -306,6 +310,9 @@ public class LDAPConfig
/** Field description */
@XmlElement(name = "attribute-name-mail")
private String attributeNameMail = "mail";
@XmlElement(name = "attribute-name-group")
private String attributeNameGroup = "group";
/** Field description */
@XmlElement(name = "base-dn")

View File

@@ -69,6 +69,12 @@ registerGeneralConfigPanel({
name : 'attribute-name-mail',
allowBlank : true
}
,{
xtype : 'textfield',
fieldLabel : 'Group Attribute Name',
name : 'attribute-name-group',
allowBlank : true
}
,{
xtype : 'textfield',
fieldLabel : 'Base DN',

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-bzr-plugin</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-bzr-plugin</name>
<url>https://bitbucket.org/sdorra/scm-manager</url>
<description>Plugin for the version control system Bazaar</description>

View File

@@ -36,15 +36,16 @@ package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.Type;
import sonia.scm.io.ExtendedCommand;
import sonia.scm.io.FileSystem;
import sonia.scm.plugin.ext.Extension;
import sonia.scm.store.StoreFactory;
import sonia.scm.util.SecurityUtil;
import sonia.scm.web.security.WebSecurityContext;
//~--- JDK imports ------------------------------------------------------------
@@ -60,6 +61,9 @@ public class BzrRepositoryHandler
extends AbstractSimpleRepositoryHandler<BzrConfig>
{
/** Field description */
public static final String PUBLIC_RESOURCEPATH_BASE = "/public/bzr/";
/** Field description */
public static final String TYPE_DISPLAYNAME = "Bazaar";
@@ -69,10 +73,6 @@ public class BzrRepositoryHandler
/** Field description */
public static final Type TYPE = new Type(TYPE_NAME, TYPE_DISPLAYNAME);
/** the logger for BzrRepositoryHandler */
private static final Logger logger =
LoggerFactory.getLogger(BzrRepositoryHandler.class);
//~--- constructors ---------------------------------------------------------
/**
@@ -80,11 +80,43 @@ public class BzrRepositoryHandler
*
*
* @param storeFactory
* @param fileSystem
* @param securityContextProvider
*/
@Inject
public BzrRepositoryHandler(StoreFactory storeFactory)
public BzrRepositoryHandler(
StoreFactory storeFactory, FileSystem fileSystem,
Provider<WebSecurityContext> securityContextProvider)
{
super(storeFactory);
super(storeFactory, fileSystem);
this.securityContextProvider = securityContextProvider;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param repository
*
* @return
*/
@Override
public String createResourcePath(Repository repository)
{
String resourcePath = null;
if (SecurityUtil.isAnonymous(securityContextProvider))
{
resourcePath = PUBLIC_RESOURCEPATH_BASE.concat(repository.getName());
}
else
{
resourcePath = super.createResourcePath(repository);
}
return resourcePath;
}
//~--- get methods ----------------------------------------------------------
@@ -145,4 +177,9 @@ public class BzrRepositoryHandler
{
return BzrConfig.class;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private Provider<WebSecurityContext> securityContextProvider;
}

View File

@@ -0,0 +1,131 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject;
import com.google.inject.Singleton;
import sonia.scm.repository.BzrRepositoryHandler;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryManager;
import sonia.scm.util.HttpUtil;
import sonia.scm.web.filter.HttpFilter;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Sebastian Sdorra
*/
@Singleton
public class BzrPublicFilter extends HttpFilter
{
/** Field description */
private static final Pattern REGEX_REPOSITORYNAME =
Pattern.compile("/public/bzr/([^/]+)");
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*
* @param repositoryManager
*/
@Inject
public BzrPublicFilter(RepositoryManager repositoryManager)
{
this.repositoryManager = repositoryManager;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param request
* @param response
* @param chain
*
* @throws IOException
* @throws ServletException
*/
@Override
protected void doFilter(HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws IOException, ServletException
{
String requestURI = HttpUtil.getStrippedURI(request);
Matcher m = REGEX_REPOSITORYNAME.matcher(requestURI);
if (m.find())
{
String name = m.group(1);
Repository repository =
repositoryManager.get(BzrRepositoryHandler.TYPE_NAME, name);
if ((repository != null) && repository.isPublicReadable())
{
chain.doFilter(request, response);
}
else
{
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
}
}
else
{
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
}
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private RepositoryManager repositoryManager;
}

View File

@@ -51,6 +51,9 @@ public class BzrServletModule extends ServletModule
/** Field description */
public static final String MAPPING_BZR = "/bzr/*";
/** Field description */
public static final String MAPPING_PUBLICBZR = "/public/bzr/*";
//~--- methods --------------------------------------------------------------
/**
@@ -60,8 +63,10 @@ public class BzrServletModule extends ServletModule
@Override
protected void configureServlets()
{
filter(MAPPING_BZR).through(BasicAuthenticationFilter.class);
filter(MAPPING_BZR,
MAPPING_PUBLICBZR).through(BasicAuthenticationFilter.class);
filter(MAPPING_BZR).through(BzrPermissionFilter.class);
serve(MAPPING_BZR).with(BzrCGIServlet.class);
filter(MAPPING_PUBLICBZR).through(BzrPublicFilter.class);
serve(MAPPING_BZR, MAPPING_PUBLICBZR).with(BzrCGIServlet.class);
}
}

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-git-plugin</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-git-plugin</name>
<url>https://bitbucket.org/sdorra/scm-manager</url>
<description>Plugin for the version control system Git</description>
@@ -50,7 +50,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<scope>test</scope>
</dependency>

View File

@@ -41,6 +41,7 @@ import com.google.inject.Singleton;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import sonia.scm.Type;
import sonia.scm.io.FileSystem;
import sonia.scm.plugin.ext.Extension;
import sonia.scm.store.StoreFactory;
@@ -75,11 +76,12 @@ public class GitRepositoryHandler
*
*
* @param storeFactory
* @param fileSystem
*/
@Inject
public GitRepositoryHandler(StoreFactory storeFactory)
public GitRepositoryHandler(StoreFactory storeFactory, FileSystem fileSystem)
{
super(storeFactory);
super(storeFactory, fileSystem);
}
//~--- get methods ----------------------------------------------------------

View File

@@ -35,6 +35,7 @@ package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.io.DefaultFileSystem;
import sonia.scm.store.StoreFactory;
import static org.junit.Assert.*;
@@ -88,7 +89,8 @@ public class GitRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
protected RepositoryHandler createRepositoryHandler(StoreFactory factory,
File directory)
{
GitRepositoryHandler repositoryHandler = new GitRepositoryHandler(factory);
GitRepositoryHandler repositoryHandler = new GitRepositoryHandler(factory,
new DefaultFileSystem());
repositoryHandler.init(contextProvider);

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-graph-plugin</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-graph-plugin</name>
<description>Creates an Google Guice injection graph</description>
<url>https://bitbucket.org/sdorra/scm-manager</url>

View File

@@ -7,12 +7,12 @@
<parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-plugins</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-hg-plugin</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-hg-plugin</name>
<url>https://bitbucket.org/sdorra/scm-manager</url>
<description>Plugin for the version control system Mercurial</description>
@@ -37,7 +37,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<scope>test</scope>
</dependency>

View File

@@ -57,6 +57,7 @@ import sonia.scm.web.HgWebConfigWriter;
import java.io.File;
import java.io.IOException;
import sonia.scm.io.FileSystem;
/**
*
@@ -90,9 +91,9 @@ public class HgRepositoryHandler
* @param storeFactory
*/
@Inject
public HgRepositoryHandler(StoreFactory storeFactory)
public HgRepositoryHandler(StoreFactory storeFactory, FileSystem fileSystem)
{
super(storeFactory);
super(storeFactory, fileSystem);
}
//~--- methods --------------------------------------------------------------

View File

@@ -35,6 +35,7 @@ package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.io.DefaultFileSystem;
import sonia.scm.store.StoreFactory;
import sonia.scm.util.Util;
@@ -86,7 +87,8 @@ public class HgRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
protected RepositoryHandler createRepositoryHandler(StoreFactory factory,
File directory)
{
HgRepositoryHandler handler = new HgRepositoryHandler(factory);
HgRepositoryHandler handler = new HgRepositoryHandler(factory,
new DefaultFileSystem());
handler.init(contextProvider);
handler.getConfig().setRepositoryDirectory(directory);

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-pam-plugin</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-pam-plugin</name>
<url>https://bitbucket.org/sdorra/scm-manager</url>
<description>Using pam as an authentication handler.</description>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-svn-plugin</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-svn-plugin</name>
<url>https://bitbucket.org/sdorra/scm-manager</url>
<description>Plugin for the version control system Subversion</description>
@@ -47,7 +47,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<scope>test</scope>
</dependency>

View File

@@ -42,35 +42,4 @@ import javax.xml.bind.annotation.XmlRootElement;
* @author Sebastian Sdorra
*/
@XmlRootElement(name = "config")
public class SvnConfig extends SimpleRepositoryConfig
{
/**
* Method description
*
*
* @return
*/
public String getSvnAccessFile()
{
return svnAccessFile;
}
//~--- set methods ----------------------------------------------------------
/**
* Method description
*
*
* @param svnAccessFile
*/
public void setSvnAccessFile(String svnAccessFile)
{
this.svnAccessFile = svnAccessFile;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private String svnAccessFile;
}
public class SvnConfig extends SimpleRepositoryConfig {}

View File

@@ -42,6 +42,7 @@ import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import sonia.scm.Type;
import sonia.scm.io.FileSystem;
import sonia.scm.plugin.ext.Extension;
import sonia.scm.store.StoreFactory;
@@ -76,11 +77,12 @@ public class SvnRepositoryHandler
*
*
* @param storeFactory
* @param fileSystem
*/
@Inject
public SvnRepositoryHandler(StoreFactory storeFactory)
public SvnRepositoryHandler(StoreFactory storeFactory, FileSystem fileSystem)
{
super(storeFactory);
super(storeFactory, fileSystem);
}
//~--- get methods ----------------------------------------------------------

View File

@@ -35,6 +35,7 @@ package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.io.DefaultFileSystem;
import sonia.scm.store.StoreFactory;
import static org.junit.Assert.*;
@@ -83,7 +84,8 @@ public class SvnRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
protected RepositoryHandler createRepositoryHandler(StoreFactory factory,
File directory)
{
SvnRepositoryHandler handler = new SvnRepositoryHandler(factory);
SvnRepositoryHandler handler = new SvnRepositoryHandler(factory,
new DefaultFileSystem());
handler.init(contextProvider);

20
pom.xml
View File

@@ -6,11 +6,23 @@
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<packaging>pom</packaging>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<description>
The easiest way to share your Git, Mercurial
and Subversion repositories over http.
</description>
<name>scm</name>
<url>http://bitbucket.org/sdorra/scm-manager</url>
<licenses>
<license>
<name>BSD</name>
<url>http://www.opensource.org/licenses/bsd-license.php</url>
</license>
</licenses>
<developers>
<developer>
<id>sdorra</id>
@@ -66,12 +78,6 @@
<dependencies>
<dependency>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

View File

@@ -6,13 +6,13 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.samples</groupId>
<artifactId>scm-samples</artifactId>
<packaging>pom</packaging>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-samples</name>
<modules>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-samples</artifactId>
<groupId>sonia.scm.samples</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.sample</groupId>
<artifactId>scm-sample-auth</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-sample-auth</name>
<description>Sample Authentication Plugin</description>
<url>https://bitbucket.org/sdorra/scm-manager</url>
@@ -29,7 +29,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-samples</artifactId>
<groupId>sonia.scm.samples</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.sample</groupId>
<artifactId>scm-sample-hello</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-sample-hello</name>
<description>A simple hello world plugin</description>
<url>https://bitbucket.org/sdorra/scm-manager</url>
@@ -29,7 +29,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm</artifactId>
<groupId>sonia.scm</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-core</name>
<dependencies>
@@ -24,6 +24,12 @@
<scope>provided</scope>
</dependency>
<dependency>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>

View File

@@ -0,0 +1,98 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.io;
//~--- non-JDK imports --------------------------------------------------------
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.util.IOUtil;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.IOException;
/**
*
* @author Sebastian Sdorra
*/
public class DefaultFileSystem implements FileSystem
{
/** the logger for DefaultFileSystem */
private static final Logger logger =
LoggerFactory.getLogger(DefaultFileSystem.class);
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param directory
*
* @throws IOException
*/
@Override
public void create(File directory) throws IOException
{
if (logger.isInfoEnabled())
{
logger.info("create directory {}", directory.getPath());
}
IOUtil.mkdirs(directory);
}
/**
* Method description
*
*
* @param directory
*
* @throws IOException
*/
@Override
public void destroy(File directory) throws IOException
{
if (logger.isInfoEnabled())
{
logger.info("destroy directory {}", directory.getPath());
}
IOUtil.delete(directory);
}
}

View File

@@ -0,0 +1,74 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.io;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.plugin.ExtensionPoint;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.IOException;
/**
*
* @author Sebastian Sdorra
*/
@ExtensionPoint
public interface FileSystem
{
/**
* Method description
*
*
*
* @param directory
*
* @throws IOException
*/
public void create(File directory) throws IOException;
/**
* Method description
*
*
*
* @param directory
*
* @throws IOException
*/
public void destroy(File directory) throws IOException;
}

View File

@@ -39,5 +39,5 @@ package sonia.scm.plugin;
*/
public enum PluginState
{
CORE, AVAILABLE, INSTALLED, UPDATE_AVAILABLE;
CORE, AVAILABLE, INSTALLED, NEWER_VERSION_INSTALLED, UPDATE_AVAILABLE;
}

View File

@@ -0,0 +1,585 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.plugin;
//~--- non-JDK imports --------------------------------------------------------
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.util.AssertUtil;
/**
*
* @author Sebastian Sdorra
*/
public class PluginVersion implements Comparable<PluginVersion>
{
/** the logger for PluginVersion */
private static final Logger logger =
LoggerFactory.getLogger(PluginVersion.class);
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*
* @param versionString
*/
public PluginVersion(String versionString)
{
this.unparsedVersion = versionString;
int index = versionString.indexOf("-");
String versionPart = null;
String qualifierPart = null;
if (index > 0)
{
versionPart = versionString.substring(0, index);
qualifierPart = versionString.substring(index);
}
else
{
versionPart = versionString;
}
parseVersionPart(versionPart);
type = PluginVersionType.RELEASE;
if (qualifierPart != null)
{
parseQualifierPart(qualifierPart);
}
parsedVersion = createParsedVersion();
}
//~--- methods --------------------------------------------------------------
/**
* Enum description
*
*
* @param versionString
*
* @return
*/
/**
* Method description
*
*
* @param versionString
*
* @return
*/
public static PluginVersion createVersion(String versionString)
{
PluginVersion version = null;
try
{
version = new PluginVersion(versionString);
}
catch (NumberFormatException ex)
{
if (logger.isWarnEnabled())
{
logger.warn("could not parse version ".concat(versionString), ex);
}
}
return version;
}
/**
* Method description
*
*
* @param o
*
* @return
*/
@Override
public int compareTo(PluginVersion o)
{
AssertUtil.assertIsNotNull(o);
int result = o.major - major;
if (result == 0)
{
result = o.minor - minor;
if (result == 0)
{
result = o.maintenance - maintenance;
if (result == 0)
{
result = o.type.getValue() - type.getValue();
if (result == 0)
{
result = o.typeVersion - typeVersion;
if (result == 0)
{
if (o.snapshot &&!snapshot)
{
result = 0;
}
else if (!o.snapshot && snapshot)
{
result = 1;
}
}
}
}
}
}
return result;
}
/**
* Method description
*
*
* @param obj
*
* @return
*/
@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final PluginVersion other = (PluginVersion) obj;
if (this.maintenance != other.maintenance)
{
return false;
}
if (this.major != other.major)
{
return false;
}
if (this.minor != other.minor)
{
return false;
}
if ((this.parsedVersion == null)
? (other.parsedVersion != null)
: !this.parsedVersion.equals(other.parsedVersion))
{
return false;
}
if (this.snapshot != other.snapshot)
{
return false;
}
if (this.type != other.type)
{
return false;
}
if (this.typeVersion != other.typeVersion)
{
return false;
}
return true;
}
/**
* Method description
*
*
* @return
*/
@Override
public int hashCode()
{
int hash = 5;
hash = 61 * hash + this.maintenance;
hash = 61 * hash + this.major;
hash = 61 * hash + this.minor;
hash = 61 * hash + ((this.parsedVersion != null)
? this.parsedVersion.hashCode()
: 0);
hash = 61 * hash + (this.snapshot
? 1
: 0);
hash = 61 * hash + ((this.type != null)
? this.type.hashCode()
: 0);
hash = 61 * hash + this.typeVersion;
return hash;
}
/**
* Method description
*
*
* @return
*/
@Override
public String toString()
{
return parsedVersion;
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public int getMaintenance()
{
return maintenance;
}
/**
* Method description
*
*
* @return
*/
public int getMajor()
{
return major;
}
/**
* Method description
*
*
* @return
*/
public int getMinor()
{
return minor;
}
/**
* Method description
*
*
* @return
*/
public String getParsedVersion()
{
return parsedVersion;
}
/**
* Method description
*
*
* @return
*/
public PluginVersionType getType()
{
return type;
}
/**
* Method description
*
*
* @return
*/
public int getTypeVersion()
{
return typeVersion;
}
/**
* Method description
*
*
* @return
*/
public String getUnparsedVersion()
{
return unparsedVersion;
}
/**
* Method description
*
*
* @param o
*
* @return
*/
public boolean isNewer(PluginVersion o)
{
return compareTo(o) < 0;
}
/**
* Method description
*
*
* @param versionString
*
* @return
*/
public boolean isNewer(String versionString)
{
PluginVersion o = PluginVersion.createVersion(versionString);
return (o != null) && isNewer(o);
}
/**
* Method description
*
*
* @param o
*
* @return
*/
public boolean isOlder(PluginVersion o)
{
return compareTo(o) > 0;
}
/**
* Method description
*
*
* @param versionString
*
* @return
*/
public boolean isOlder(String versionString)
{
PluginVersion o = PluginVersion.createVersion(versionString);
return (o != null) && isOlder(o);
}
/**
* Method description
*
*
* @return
*/
public boolean isSnapshot()
{
return snapshot;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*/
private String createParsedVersion()
{
StringBuilder v = new StringBuilder();
v.append(major).append(".").append(minor).append(".").append(maintenance);
String typeId = type.getId();
if (typeId != null)
{
v.append("-").append(typeId).append(typeVersion);
}
if (snapshot)
{
v.append("-").append("SNAPSHOT");
}
return v.toString();
}
/**
* Method description
*
*
* @param qualifierPart
*/
private void parseQualifierPart(String qualifierPart)
{
String qualifier = qualifierPart.trim().toLowerCase();
if (qualifier.contains("snapshot"))
{
snapshot = true;
qualifier = qualifier.replace("snapshot", "");
}
if (qualifier.length() > 0)
{
for (PluginVersionType versionType : PluginVersionType.values())
{
for (String name : versionType.getNames())
{
name = name.toLowerCase();
int index = qualifier.indexOf(name);
if (index > 0)
{
type = versionType;
qualifier = qualifier.substring(index + name.length());
parseTypeVersion(qualifier);
break;
}
}
}
}
}
/**
* Method description
*
*
* @param qualifier
*/
private void parseTypeVersion(String qualifier)
{
String version = null;
StringBuilder vb = new StringBuilder();
for (char c : qualifier.toCharArray())
{
if (version != null)
{
break;
}
else if (Character.isDigit(c))
{
vb.append(c);
}
else if (vb.length() > 0)
{
version = vb.toString();
}
}
if (vb.length() > 0)
{
version = vb.toString();
}
if (version != null)
{
typeVersion = Integer.parseInt(version);
}
}
/**
* Method description
*
*
* @param versionPart
*/
private void parseVersionPart(String versionPart)
{
String[] parts = versionPart.split("\\.");
if (parts.length > 0)
{
major = Integer.parseInt(parts[0]);
if (parts.length > 1)
{
minor = Integer.parseInt(parts[1]);
if (parts.length > 2)
{
maintenance = Integer.parseInt(parts[2]);
}
}
}
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private int maintenance = 0;
/** Field description */
private int major = 0;
/** Field description */
private int minor = 0;
/** Field description */
private String parsedVersion;
/** Field description */
private boolean snapshot;
/** Field description */
private PluginVersionType type;
/** Field description */
private int typeVersion = 1;
/** Field description */
private String unparsedVersion;
}

View File

@@ -29,24 +29,53 @@
*
*/
package sonia.scm.server;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.cli.Argument;
package sonia.scm.plugin;
//~--- JDK imports ------------------------------------------------------------
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
*
* @author Sebastian Sdorra
*/
public class ServerConfig
public enum PluginVersionType
{
EARLY_ACESS("ea", 0, "early", "earlyaccess"), MILESTONE("M", 1, "milestone"),
ALPHA("alpha", 2), BETA("beta", 3),
RELEASE_CANDIDAT("RC", 4, "releasecandidate"), RELEASE(10);
/**
* Constructs ...
*
*
* @param value
*/
public ServerConfig() {}
private PluginVersionType(int value)
{
this(null, value);
}
/**
* Constructs ...
*
*
*
* @param id
* @param value
* @param aliases
*/
private PluginVersionType(String id, int value, String... aliases)
{
this.id = id;
this.value = value;
this.aliases = aliases;
}
//~--- get methods ----------------------------------------------------------
@@ -56,9 +85,9 @@ public class ServerConfig
*
* @return
*/
public String getContextPath()
public String[] getAliases()
{
return contextPath;
return aliases;
}
/**
@@ -67,9 +96,9 @@ public class ServerConfig
*
* @return
*/
public Integer getPort()
public String getId()
{
return port;
return id;
}
/**
@@ -78,9 +107,21 @@ public class ServerConfig
*
* @return
*/
public String getResourcePath()
public Collection<String> getNames()
{
return resourcePath;
List<String> names = new ArrayList<String>();
if (id != null)
{
names.add(id);
}
if (aliases != null)
{
names.addAll(Arrays.asList(aliases));
}
return names;
}
/**
@@ -89,88 +130,19 @@ public class ServerConfig
*
* @return
*/
public Boolean getShowHelp()
public int getValue()
{
return showHelp;
}
//~--- set methods ----------------------------------------------------------
/**
* Method description
*
*
* @param contextPath
*/
public void setContextPath(String contextPath)
{
this.contextPath = contextPath;
}
/**
* Method description
*
*
* @param port
*/
public void setPort(Integer port)
{
this.port = port;
}
/**
* Method description
*
*
* @param resourcePath
*/
public void setResourcePath(String resourcePath)
{
this.resourcePath = resourcePath;
}
/**
* Method description
*
*
* @param showHelp
*/
public void setShowHelp(Boolean showHelp)
{
this.showHelp = showHelp;
return value;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
@Argument(
value = "c",
longName = "context-path",
description = "The Context-Path of the Jab-WebApp"
)
private String contextPath = "/";
public String[] aliases;
/** Field description */
@Argument(
value = "p",
longName = "port",
description = "The port for the listener"
)
private Integer port = Integer.valueOf(8080);
private String id;
/** Field description */
@Argument(
value = "r",
longName = "resource-path",
description = "Path to the server resource directory"
)
private String resourcePath;
/** Field description */
@Argument(
value = "h",
longName = "help",
description = "Shows this help"
)
private Boolean showHelp = Boolean.FALSE;
private int value;
}

View File

@@ -39,9 +39,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.ConfigurationException;
import sonia.scm.SCMContextProvider;
import sonia.scm.io.CommandResult;
import sonia.scm.io.ExtendedCommand;
import sonia.scm.io.FileSystem;
import sonia.scm.store.StoreFactory;
import sonia.scm.util.IOUtil;
@@ -75,10 +75,13 @@ public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepository
*
*
* @param storeFactory
* @param fileSystem
*/
public AbstractSimpleRepositoryHandler(StoreFactory storeFactory)
public AbstractSimpleRepositoryHandler(StoreFactory storeFactory,
FileSystem fileSystem)
{
super(storeFactory);
this.fileSystem = fileSystem;
}
//~--- methods --------------------------------------------------------------
@@ -103,6 +106,7 @@ public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepository
throw new RepositoryAllreadyExistExeption();
}
fileSystem.create(directory);
create(repository, directory);
postCreate(repository, directory);
}
@@ -142,7 +146,7 @@ public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepository
if (directory.exists())
{
IOUtil.delete(directory);
fileSystem.destroy(directory);
}
else if (logger.isWarnEnabled())
{
@@ -150,18 +154,6 @@ public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepository
}
}
/**
* Method description
*
*
* @param context
*/
@Override
public void init(SCMContextProvider context)
{
super.init(context);
}
/**
* Method description
*
@@ -305,4 +297,9 @@ public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepository
*/
protected void postCreate(Repository repository, File directory)
throws IOException, RepositoryException {}
//~--- fields ---------------------------------------------------------------
/** Field description */
private FileSystem fileSystem;
}

View File

@@ -163,15 +163,13 @@ public class PermissionUtil
{
String name = p.getName();
if ((name != null) && (p.getType().getValue() >= pt.getValue()))
if (((name != null) && (p.getType().getValue() >= pt.getValue()))
&& (name.equals(username)
|| (p.isGroupPermission() && groups.contains(p.getName()))))
{
if (name.equals(username)
|| (p.isGroupPermission() && groups.contains(p.getName())))
{
result = true;
result = true;
break;
}
break;
}
}

View File

@@ -39,15 +39,23 @@ import sonia.scm.util.Util;
//~--- JDK imports ------------------------------------------------------------
import java.io.Serializable;
import java.util.Comparator;
/**
*
* @author Sebastian Sdorra
*/
public class ResourceHandlerComparator implements Comparator<ResourceHandler>
public class ResourceHandlerComparator
implements Comparator<ResourceHandler>, Serializable
{
/** Field description */
private static final long serialVersionUID = -1760229246326556762L;
//~--- methods --------------------------------------------------------------
/**
* Method description
*

View File

@@ -66,10 +66,10 @@ public class IOUtil
{
/** Field description */
public static final String DEFAULT_CHECKPARAMETER = "--version";
private static final String DEFAULT_CHECKPARAMETER = "--version";
/** Field description */
public static final String[] DEFAULT_PATH = new String[]
private static final String[] DEFAULT_PATH = new String[]
{
// default path
@@ -336,7 +336,13 @@ public class IOUtil
cmdPath = cmd;
}
}
catch (IOException ex) {}
catch (IOException ex)
{
if (logger.isTraceEnabled())
{
logger.trace("could not execute command", ex);
}
}
if (cmdPath == null)
{

View File

@@ -37,6 +37,7 @@ package sonia.scm.util;
import com.google.inject.Provider;
import sonia.scm.SCMContext;
import sonia.scm.security.ScmSecurityException;
import sonia.scm.security.SecurityContext;
import sonia.scm.user.User;
@@ -111,4 +112,31 @@ public class SecurityUtil
return user;
}
/**
* Method description
*
*
* @param contextProvider
*
* @return
*/
public static boolean isAnonymous(
Provider<? extends SecurityContext> contextProvider)
{
return isAnonymous(contextProvider.get());
}
/**
* Method description
*
*
* @param context
*
* @return
*/
public static boolean isAnonymous(SecurityContext context)
{
return SCMContext.USER_ANONYMOUS.equals(context.getUser().getName());
}
}

View File

@@ -47,9 +47,7 @@ import sonia.scm.util.Util;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Enumeration;

View File

@@ -0,0 +1,169 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.plugin;
//~--- non-JDK imports --------------------------------------------------------
import org.junit.Test;
import static org.junit.Assert.*;
//~--- JDK imports ------------------------------------------------------------
import java.util.Arrays;
/**
*
* @author Sebastian Sdorra
*/
public class PluginVersionTest
{
/**
* Method description
*
*/
@Test
public void parseSimpleVersion()
{
PluginVersion v = new PluginVersion("1.0");
assertTrue(v.getMajor() == 1);
assertTrue(v.getMinor() == 0);
assertTrue(v.getMaintenance() == 0);
assertFalse(v.isSnapshot());
assertTrue(v.getType() == PluginVersionType.RELEASE);
assertEquals(v.getParsedVersion(), "1.0.0");
// test with snapshot
v = new PluginVersion("1.1-SNAPSHOT");
assertTrue(v.getMajor() == 1);
assertTrue(v.getMinor() == 1);
assertTrue(v.getMaintenance() == 0);
assertTrue(v.isSnapshot());
assertTrue(v.getType() == PluginVersionType.RELEASE);
assertEquals(v.getParsedVersion(), "1.1.0-SNAPSHOT");
// test with maintenance
v = new PluginVersion("2.3.14");
assertTrue(v.getMajor() == 2);
assertTrue(v.getMinor() == 3);
assertTrue(v.getMaintenance() == 14);
assertFalse(v.isSnapshot());
assertTrue(v.getType() == PluginVersionType.RELEASE);
assertEquals(v.getParsedVersion(), "2.3.14");
}
/**
* Method description
*
*/
@Test
public void parseTypeVersions()
{
PluginVersion v = new PluginVersion("1.0-alpha");
assertTrue(v.getMajor() == 1);
assertTrue(v.getMinor() == 0);
assertTrue(v.getMaintenance() == 0);
assertFalse(v.isSnapshot());
assertTrue(v.getType() == PluginVersionType.ALPHA);
assertTrue(v.getTypeVersion() == 1);
assertEquals(v.getParsedVersion(), "1.0.0-alpha1");
// Test release candidate
v = new PluginVersion("2.1.2-RC3");
assertTrue(v.getMajor() == 2);
assertTrue(v.getMinor() == 1);
assertTrue(v.getMaintenance() == 2);
assertFalse(v.isSnapshot());
assertTrue(v.getType() == PluginVersionType.RELEASE_CANDIDAT);
assertTrue(v.getTypeVersion() == 3);
assertEquals(v.getParsedVersion(), "2.1.2-RC3");
}
/**
* Method description
*
*/
@Test
public void testCompareTo()
{
PluginVersion[] versions = new PluginVersion[9];
versions[0] = PluginVersion.createVersion("2.3.1-SNAPSHOT");
versions[1] = PluginVersion.createVersion("2.3.1-beta1");
versions[2] = PluginVersion.createVersion("2.3.1-beta2");
versions[3] = PluginVersion.createVersion("2.3.1-M1");
versions[4] = PluginVersion.createVersion("2.3.1-alpha2");
versions[5] = PluginVersion.createVersion("2.3.1-RC1");
versions[6] = PluginVersion.createVersion("2.3.1");
versions[7] = PluginVersion.createVersion("2.3");
versions[8] = PluginVersion.createVersion("2.4.6");
Arrays.sort(versions);
assertEquals(versions[0].getParsedVersion(), "2.4.6");
assertEquals(versions[1].getParsedVersion(), "2.3.1");
assertEquals(versions[2].getParsedVersion(), "2.3.1-SNAPSHOT");
assertEquals(versions[3].getParsedVersion(), "2.3.1-RC1");
assertEquals(versions[4].getParsedVersion(), "2.3.1-beta2");
assertEquals(versions[5].getParsedVersion(), "2.3.1-beta1");
assertEquals(versions[6].getParsedVersion(), "2.3.1-alpha2");
assertEquals(versions[7].getParsedVersion(), "2.3.1-M1");
assertEquals(versions[8].getParsedVersion(), "2.3.0");
}
/**
* Method description
*
*/
@Test
public void testIsNewer()
{
assertFalse(PluginVersion.createVersion("1.0").isNewer("1.0.1"));
assertTrue(PluginVersion.createVersion("1.1").isNewer("1.1-alpha1"));
assertTrue(PluginVersion.createVersion("1.1").isNewer("1.1-RC5"));
}
/**
* Method description
*
*/
@Test
public void testIsOlder()
{
assertFalse(PluginVersion.createVersion("1.0.1").isOlder("1.0"));
assertTrue(PluginVersion.createVersion("1.1-alpha1").isOlder("1.1"));
assertTrue(PluginVersion.createVersion("1.1-RC5").isOlder("1.1"));
}
}

View File

@@ -7,22 +7,12 @@
<parent>
<artifactId>scm</artifactId>
<groupId>sonia.scm</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-server-api</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-server-api</name>
<dependencies>
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@@ -29,6 +29,8 @@
*
*/
package sonia.scm.server;
//~--- JDK imports ------------------------------------------------------------
@@ -63,14 +65,12 @@ public interface Server
* Method description
*
*
* @param config
* @param webapp
*
* @throws IOException
* @throws ServerException
*/
public void start(ServerConfig config, File webapp)
throws ServerException, IOException;
public void start(File webapp) throws ServerException, IOException;
/**
* Method description

View File

@@ -33,23 +33,15 @@
package sonia.scm.server;
//~--- non-JDK imports --------------------------------------------------------
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.cli.CliException;
import sonia.scm.cli.CliParser;
import sonia.scm.cli.DefaultCliHelpBuilder;
import sonia.scm.util.IOUtil;
import sonia.scm.util.ServiceUtil;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.NoSuchElementException;
import java.util.ServiceLoader;
import javax.xml.bind.JAXB;
/**
@@ -74,48 +66,6 @@ public class ServerApplication
/** Field description */
public static final String SERVERCONFIG = "/config.xml";
/** Field description */
private static final Logger logger =
LoggerFactory.getLogger(ServerApplication.class.getName());
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
private static ServerConfig getServerConfig()
{
ServerConfig config = null;
InputStream input =
ServerApplication.class.getResourceAsStream(SERVERCONFIG);
if (input != null)
{
try
{
config = JAXB.unmarshal(input, ServerConfig.class);
}
catch (Exception ex)
{
logger.error(ex.getMessage(), ex);
}
finally
{
IOUtil.close(input);
}
}
if (config == null)
{
config = new ServerConfig();
}
return config;
}
//~--- methods --------------------------------------------------------------
/**
@@ -124,12 +74,10 @@ public class ServerApplication
*
* @param args
*
* @throws CliException
* @throws IOException
* @throws ServerException
*/
public static void main(String[] args)
throws CliException, ServerException, IOException
public static void main(String[] args) throws ServerException, IOException
{
InputStream input = ServerApplication.class.getResourceAsStream(APPINFO);
@@ -141,76 +89,68 @@ public class ServerApplication
ApplicationInformation appInfo = JAXB.unmarshal(input,
ApplicationInformation.class);
ServerConfig config = getServerConfig();
CliParser parser = new CliParser();
final Server server = getServer();
parser.parse(config, args);
if (config.getShowHelp())
if (server == null)
{
printHelp(appInfo, parser, config);
System.err.println("could not find an server implementation");
System.exit(RETURNCODE_MISSING_SERVER_IMPLEMENTATION);
}
else
File webapp = new File("webapp", appInfo.getAppName());
server.start(webapp);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable()
{
final Server server = ServiceUtil.getService(Server.class);
if (server == null)
@Override
public void run()
{
System.err.println("could not find an server implementation");
System.exit(RETURNCODE_MISSING_SERVER_IMPLEMENTATION);
}
File webapp = new File("webapp", appInfo.getAppName());
server.start(config, webapp);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable()
{
@Override
public void run()
if (server.isRunning())
{
if (server.isRunning())
try
{
try
{
server.stop();
}
catch (ServerException ex)
{
logger.error(ex.getMessage(), ex);
}
catch (IOException ex)
{
logger.error(ex.getMessage(), ex);
}
server.stop();
}
catch (ServerException ex)
{
ex.printStackTrace(System.err);
}
catch (IOException ex)
{
ex.printStackTrace(System.err);
}
}
}));
}
}
}));
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
*
* @param appInfo
* @param parser
* @param config
* @return
*/
private static void printHelp(ApplicationInformation appInfo,
CliParser parser, ServerConfig config)
private static Server getServer()
{
String s = System.getProperty("line.separator");
StringBuilder prefix = new StringBuilder(appInfo.getName());
Server server = null;
prefix.append(" ").append(appInfo.getVersion());
prefix.append(s).append("usage: ");
prefix.append(s);
try
{
ServiceLoader<Server> loader = ServiceLoader.load(Server.class);
DefaultCliHelpBuilder helpBuilder =
new DefaultCliHelpBuilder(prefix.toString(), null);
if (loader != null)
{
server = loader.iterator().next();
}
}
catch (NoSuchElementException ex)
{
System.err.println(parser.createHelp(helpBuilder, config));
System.exit(RETURNCODE_CLI_ERROR);
// no server available
}
return server;
}
}

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm</artifactId>
<groupId>sonia.scm</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-server-jetty</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-server-jetty</name>
<dependencies>
@@ -20,7 +20,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-server-api</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
<dependency>
@@ -38,7 +38,7 @@
</dependencies>
<properties>
<jetty.version>7.1.6.v20100715</jetty.version>
<jetty.version>7.2.2.v20101205</jetty.version>
</properties>
</project>

View File

@@ -29,17 +29,17 @@
*
*/
package sonia.scm.server.jetty;
//~--- non-JDK imports --------------------------------------------------------
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.xml.XmlConfiguration;
import sonia.scm.server.Server;
import sonia.scm.server.ServerAllreadyRunningException;
import sonia.scm.server.ServerConfig;
import sonia.scm.server.ServerException;
import sonia.scm.server.ServerListener;
@@ -48,6 +48,8 @@ import sonia.scm.server.ServerListener;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
@@ -58,6 +60,11 @@ import java.util.Set;
public class JettyServer implements Server
{
/** Field description */
public static final String CONFIGURATION = "/server-config.xml";
//~--- methods --------------------------------------------------------------
/**
* Method description
*
@@ -86,44 +93,46 @@ public class JettyServer implements Server
* Method description
*
*
* @param config
* @param webapp
*
* @throws IOException
* @throws ServerException
*/
@Override
public void start(ServerConfig config, File webapp)
throws ServerException, IOException
public void start(File webapp) throws ServerException, IOException
{
if (isRunning())
{
throw new ServerAllreadyRunningException();
}
server = new org.eclipse.jetty.server.Server();
URL configURL = JettyServer.class.getResource(CONFIGURATION);
Connector connector = new SelectChannelConnector();
for (ServerListener listener : listeners)
if (configURL == null)
{
connector.addLifeCycleListener(new JettyServerListenerAdapter(listener));
throw new ServerException("could not find server-config.xml");
}
connector.setPort(config.getPort());
server.addConnector(connector);
WebAppContext wac = new WebAppContext();
wac.setContextPath(config.getContextPath());
wac.setWar(webapp.getAbsolutePath());
wac.setExtractWAR(true);
server.setHandler(wac);
// server.setStopAtShutdown(true);
try
{
server = new org.eclipse.jetty.server.Server();
XmlConfiguration config = new XmlConfiguration(configURL);
config.configure(server);
for (ServerListener listener : listeners)
{
server.addLifeCycleListener(new JettyServerListenerAdapter(listener));
}
WebAppContext wac = new WebAppContext();
wac.setWar(webapp.getAbsolutePath());
wac.setExtractWAR(true);
server.setHandler(wac);
// server.setStopAtShutdown(true);
server.start();
server.join();
}

View File

@@ -7,33 +7,27 @@
<parent>
<artifactId>scm</artifactId>
<groupId>sonia.scm</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-server</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-server</name>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-server-api</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-server-jetty</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
</dependencies>
@@ -76,6 +70,15 @@
<generatorConfigurations>
<generatorConfiguration>
<generator>jsw</generator>
<includes>
<include>linux-x86-32</include>
<include>linux-x86-64</include>
<include>macosx-x86-universal-32</include>
<include>solaris-sparc-32</include>
<include>solaris-sparc-64</include>
<include>solaris-x86-32</include>
<include>windows-x86-32</include>
</includes>
<configuration>
<property>
<name>configuration.directory.in.classpath.first</name>

View File

@@ -92,6 +92,11 @@
<filtered>true</filtered>
<outputDirectory>conf</outputDirectory>
</file>
<file>
<source>src/main/conf/server-config.xml</source>
<filtered>true</filtered>
<outputDirectory>conf</outputDirectory>
</file>
</files>
</assembly>

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Document : server-config.xml
Created on : January 20, 2011, 6:05 PM
Author : sdorra
Description:
Purpose of the document follows.
-->
<Configure class="org.eclipse.jetty.server.Server">
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<Set name="host">
<SystemProperty name="jetty.host" />
</Set>
<Set name="port">
<SystemProperty name="jetty.port" default="8080"/>
</Set>
<!-- for mod_proxy -->
<!--
<Set name="forwarded">true</Set>
-->
</New>
</Arg>
</Call>
<!-- mod_proxy_ajp or mod_jk -->
<!--
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.ajp.Ajp13SocketConnector">
<Set name="port">8009</Set>
</New>
</Arg>
</Call>
-->
<!-- SSL-Connector -->
<!--
<Call name="addConnector">
<Arg>
<New class="org.mortbay.jetty.security.SslSocketConnector">
<Set name="Port">8181</Set>
<Set name="maxIdleTime">30000</Set>
<Set name="keystore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
<Set name="password">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
<Set name="keyPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
<Set name="truststore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
<Set name="trustPassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
</New>
</Arg>
</Call>
-->
</Configure>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm</artifactId>
<groupId>sonia.scm</groupId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-test</name>
<dependencies>
@@ -26,7 +26,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
<dependency>

View File

@@ -33,28 +33,6 @@
package sonia.scm;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Provider;
import org.junit.After;
import org.junit.Before;
import sonia.scm.security.SecurityContext;
import sonia.scm.user.User;
import sonia.scm.util.IOUtil;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.IOException;
import java.util.UUID;
/**
*
* @author Sebastian Sdorra

View File

@@ -36,6 +36,7 @@ package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.Type;
import sonia.scm.io.DefaultFileSystem;
import sonia.scm.store.StoreFactory;
//~--- JDK imports ------------------------------------------------------------
@@ -70,7 +71,7 @@ public class DummyRepositoryHandler
*/
public DummyRepositoryHandler(StoreFactory storeFactory)
{
super(storeFactory);
super(storeFactory, new DefaultFileSystem());
}
//~--- get methods ----------------------------------------------------------

View File

@@ -7,13 +7,13 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-webapp</artifactId>
<packaging>war</packaging>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>scm-webapp</name>
<dependencies>
@@ -28,25 +28,25 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-hg-plugin</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-svn-plugin</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-git-plugin</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
<dependency>
@@ -86,7 +86,7 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>0.9.27</version>
<version>0.9.28</version>
</dependency>
<dependency>
@@ -164,7 +164,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<scope>test</scope>
<exclusions>
<exclusion>
@@ -288,43 +288,43 @@
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-graph-plugin</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.sample</groupId>
<artifactId>scm-sample-auth</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.sample</groupId>
<artifactId>scm-sample-hello</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-activedirectory-auth-plugin</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-pam-plugin</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-bzr-plugin</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-auth-ldap-plugin</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@@ -43,6 +43,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.group.GroupListener;
import sonia.scm.io.FileSystem;
import sonia.scm.plugin.ext.Extension;
import sonia.scm.plugin.ext.ExtensionProcessor;
import sonia.scm.repository.RepositoryHandler;
@@ -188,6 +189,15 @@ public class BindingExtensionProcessor implements ExtensionProcessor
resourceHandler.addBinding().to(extensionClass);
}
else if (FileSystem.class.isAssignableFrom(extensionClass))
{
if (logger.isInfoEnabled())
{
logger.info("bind FileSystem {}", extensionClass.getName());
}
fileSystemClass = extensionClass;
}
else
{
if (logger.isInfoEnabled())
@@ -198,7 +208,11 @@ public class BindingExtensionProcessor implements ExtensionProcessor
binder.bind(extensionClass);
}
}
catch (Exception ex)
catch (IllegalAccessException ex)
{
logger.error(ex.getMessage(), ex);
}
catch (InstantiationException ex)
{
logger.error(ex.getMessage(), ex);
}
@@ -243,6 +257,17 @@ public class BindingExtensionProcessor implements ExtensionProcessor
return authenticationListeners;
}
/**
* Method description
*
*
* @return
*/
public Class<? extends FileSystem> getFileSystemClass()
{
return fileSystemClass;
}
/**
* Method description
*
@@ -337,6 +362,9 @@ public class BindingExtensionProcessor implements ExtensionProcessor
/** Field description */
private Set<Class<?>> extensions;
/** Field description */
private Class<? extends FileSystem> fileSystemClass;
/** Field description */
private Set<Module> moduleSet;

View File

@@ -49,6 +49,8 @@ import sonia.scm.filter.SSLFilter;
import sonia.scm.filter.SecurityFilter;
import sonia.scm.group.GroupManager;
import sonia.scm.group.xml.XmlGroupManager;
import sonia.scm.io.DefaultFileSystem;
import sonia.scm.io.FileSystem;
import sonia.scm.plugin.DefaultPluginManager;
import sonia.scm.plugin.Plugin;
import sonia.scm.plugin.PluginLoader;
@@ -175,6 +177,16 @@ public class ScmServletModule extends ServletModule
bind(EncryptionHandler.class).to(MessageDigestEncryptionHandler.class);
bindExtProcessor.bindExtensions(binder());
Class<? extends FileSystem> fileSystem =
bindExtProcessor.getFileSystemClass();
if (fileSystem == null)
{
fileSystem = DefaultFileSystem.class;
}
bind(FileSystem.class).to(fileSystem);
// bind security stuff
bind(AuthenticationManager.class).to(ChainAuthenticatonManager.class);
bind(SecurityContext.class).to(BasicSecurityContext.class);

View File

@@ -43,7 +43,6 @@ import org.slf4j.LoggerFactory;
import sonia.scm.SCMContext;
import sonia.scm.ScmState;
import sonia.scm.Type;
import sonia.scm.repository.RepositoryManager;
import sonia.scm.user.User;
import sonia.scm.web.security.WebSecurityContext;

View File

@@ -39,6 +39,7 @@ import com.google.inject.Inject;
import com.google.inject.Singleton;
import sonia.scm.plugin.DefaultPluginManager;
import sonia.scm.plugin.OverviewPluginFilter;
import sonia.scm.plugin.PluginInformation;
//~--- JDK imports ------------------------------------------------------------
@@ -137,9 +138,9 @@ public class PluginResource
*/
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public PluginInformation[] getAll()
public Collection<PluginInformation> getAll()
{
return getArray(pluginManager.getAll());
return pluginManager.getAll();
}
/**
@@ -151,9 +152,9 @@ public class PluginResource
@GET
@Path("available")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public PluginInformation[] getAvailable()
public Collection<PluginInformation> getAvailable()
{
return getArray(pluginManager.getAvailable());
return pluginManager.getAvailable();
}
/**
@@ -165,9 +166,9 @@ public class PluginResource
@GET
@Path("updates")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public PluginInformation[] getAvailableUpdates()
public Collection<PluginInformation> getAvailableUpdates()
{
return getArray(pluginManager.getAvailableUpdates());
return pluginManager.getAvailableUpdates();
}
/**
@@ -179,34 +180,23 @@ public class PluginResource
@GET
@Path("installed")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public PluginInformation[] getInstalled()
public Collection<PluginInformation> getInstalled()
{
return getArray(pluginManager.getInstalled());
return pluginManager.getInstalled();
}
/**
* Method description
*
*
* @param pluginCollection
*
* @return
*/
private PluginInformation[] getArray(
Collection<PluginInformation> pluginCollection)
@GET
@Path("overview")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Collection<PluginInformation> getOverview()
{
PluginInformation[] plugins = null;
if (pluginCollection != null)
{
plugins = pluginCollection.toArray(new PluginInformation[0]);
}
else
{
plugins = new PluginInformation[0];
}
return plugins;
return pluginManager.get(OverviewPluginFilter.INSTANCE);
}
//~--- fields ---------------------------------------------------------------

View File

@@ -36,24 +36,29 @@ package sonia.scm.api.rest.resources;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import sonia.scm.config.ScmConfiguration;
import sonia.scm.repository.Permission;
import sonia.scm.repository.PermissionType;
import sonia.scm.repository.PermissionUtil;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryException;
import sonia.scm.repository.RepositoryHandler;
import sonia.scm.repository.RepositoryManager;
import sonia.scm.web.security.WebSecurityContext;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
/**
*
@@ -75,13 +80,19 @@ public class RepositoryResource extends AbstractResource<Repository>
*
* @param configuration
* @param repositoryManager
* @param securityContextProvider
* @param requestProvider
*/
@Inject
public RepositoryResource(ScmConfiguration configuration,
RepositoryManager repositoryManager)
public RepositoryResource(
ScmConfiguration configuration, RepositoryManager repositoryManager,
Provider<WebSecurityContext> securityContextProvider,
Provider<HttpServletRequest> requestProvider)
{
this.configuration = configuration;
this.repositoryManager = repositoryManager;
this.securityContextProvider = securityContextProvider;
this.requestProvider = requestProvider;
}
//~--- methods --------------------------------------------------------------
@@ -151,6 +162,7 @@ public class RepositoryResource extends AbstractResource<Repository>
for (Repository repository : repositories)
{
appendUrl(repository);
prepareRepository(repository);
}
return repositories;
@@ -185,6 +197,7 @@ public class RepositoryResource extends AbstractResource<Repository>
Repository repository = repositoryManager.get(id);
appendUrl(repository);
prepareRepository(repository);
return repository;
}
@@ -216,6 +229,7 @@ public class RepositoryResource extends AbstractResource<Repository>
if (handler != null)
{
HttpServletRequest request = requestProvider.get();
StringBuilder url = new StringBuilder(request.getScheme());
url.append("://").append(configuration.getServername());
@@ -234,6 +248,43 @@ public class RepositoryResource extends AbstractResource<Repository>
}
}
/**
* Method description
*
*
* @param repository
*/
private void prepareRepository(Repository repository)
{
if (isOwner(repository))
{
if (repository.getPermissions() == null)
{
repository.setPermissions(new ArrayList<Permission>());
}
}
else
{
repository.setPermissions(null);
}
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param repository
*
* @return
*/
private boolean isOwner(Repository repository)
{
return PermissionUtil.hasPermission(repository, securityContextProvider,
PermissionType.OWNER);
}
//~--- fields ---------------------------------------------------------------
/** Field description */
@@ -242,7 +293,9 @@ public class RepositoryResource extends AbstractResource<Repository>
/** Field description */
private RepositoryManager repositoryManager;
/** TODO path request direct to method */
@Context
private HttpServletRequest request;
/** Field description */
private Provider<HttpServletRequest> requestProvider;
/** Field description */
private Provider<WebSecurityContext> securityContextProvider;
}

View File

@@ -91,7 +91,10 @@ public class GZipResponseWrapper extends HttpServletResponseWrapper
@Override
public void flushBuffer() throws IOException
{
stream.flush();
if (stream != null)
{
stream.flush();
}
}
//~--- get methods ----------------------------------------------------------

View File

@@ -60,7 +60,6 @@ import java.io.IOException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Set;
/**
*

View File

@@ -167,8 +167,6 @@ public class AetherPluginHandler
List<Dependency> dependencies = getInstalledDependencies(null);
collectDependencies(dependency, dependencies);
}
/**
@@ -364,13 +362,10 @@ public class AetherPluginHandler
{
String id = plugin.getId();
if ((skipId == null) ||!id.equals(skipId))
if (Util.isNotEmpty(id) && ((skipId == null) ||!id.equals(skipId)))
{
if (Util.isNotEmpty(id))
{
dependencies.add(new Dependency(new DefaultArtifact(id),
PLUGIN_SCOPE));
}
dependencies.add(new Dependency(new DefaultArtifact(id),
PLUGIN_SCOPE));
}
}
}

View File

@@ -418,10 +418,14 @@ public class DefaultPluginManager implements PluginManager
{
state = PluginState.INSTALLED;
}
else
else if (isNewer(available, installed))
{
state = PluginState.UPDATE_AVAILABLE;
}
else
{
state = PluginState.NEWER_VERSION_INSTALLED;
}
break;
}
@@ -513,6 +517,29 @@ public class DefaultPluginManager implements PluginManager
return center;
}
/**
* Method description
*
*
* @param available
* @param installed
*
* @return
*/
private boolean isNewer(PluginInformation available,
PluginInformation installed)
{
boolean result = false;
PluginVersion version = PluginVersion.createVersion(installed.getVersion());
if (version != null)
{
result = version.isNewer(available.getVersion());
}
return result;
}
/**
* Method description
*

View File

@@ -0,0 +1,62 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.plugin;
/**
*
* @author Sebastian Sdorra
*/
public class OverviewPluginFilter implements PluginFilter
{
/** Field description */
public static final OverviewPluginFilter INSTANCE =
new OverviewPluginFilter();
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param plugin
*
* @return
*/
@Override
public boolean accept(PluginInformation plugin)
{
return plugin.getState() != PluginState.NEWER_VERSION_INSTALLED;
}
}

View File

@@ -44,7 +44,6 @@ import org.slf4j.LoggerFactory;
import sonia.scm.ConfigurationException;
import sonia.scm.HandlerEvent;
import sonia.scm.SCMContext;
import sonia.scm.SCMContextProvider;
import sonia.scm.Type;
import sonia.scm.repository.AbstractRepositoryManager;
@@ -98,12 +97,15 @@ public class XmlRepositoryManager extends AbstractRepositoryManager
*
*
*
*
* @param contextProvider
* @param securityContextProvider
* @param storeFactory
* @param handlerSet
*/
@Inject
public XmlRepositoryManager(
SCMContextProvider contextProvider,
Provider<WebSecurityContext> securityContextProvider,
StoreFactory storeFactory, Set<RepositoryHandler> handlerSet)
{
@@ -114,7 +116,7 @@ public class XmlRepositoryManager extends AbstractRepositoryManager
for (RepositoryHandler handler : handlerSet)
{
addHandler(handler);
addHandler(contextProvider, handler);
}
}
@@ -382,7 +384,9 @@ public class XmlRepositoryManager extends AbstractRepositoryManager
{
if (handlerMap.containsKey(repository.getType()) && isReader(repository))
{
repositories.add(repository.clone());
Repository r = repository.clone();
repositories.add(r);
}
}
@@ -421,9 +425,12 @@ public class XmlRepositoryManager extends AbstractRepositoryManager
* Method description
*
*
*
* @param contextProvider
* @param handler
*/
private void addHandler(RepositoryHandler handler)
private void addHandler(SCMContextProvider contextProvider,
RepositoryHandler handler)
{
AssertUtil.assertIsNotNull(handler);
@@ -444,7 +451,7 @@ public class XmlRepositoryManager extends AbstractRepositoryManager
}
handlerMap.put(type.getName(), handler);
handler.init(SCMContext.getContext());
handler.init(contextProvider);
types.add(type);
}

View File

@@ -198,7 +198,7 @@ Sonia.plugin.Grid = Ext.extend(Sonia.rest.Grid, {
initComponent: function(){
Sonia.plugin.StoreInstance = new Sonia.plugin.Store({
url: restUrl + 'plugins.json'
url: restUrl + 'plugins/overview.json'
});

View File

@@ -46,65 +46,8 @@ Ext.ns('Sonia.repository');
// functions
Sonia.repository.getPermissionValue = function(type){
var value = 0;
switch (type){
case "READ":
value = 0;
break;
case "WRITE":
value = 10;
break;
case "OWNER":
value = 100;
break;
}
return value;
}
Sonia.repository.isMember = function(group){
var result = false;
if ( Ext.isDefined(state.groups) ){
for ( var i=0; i<state.groups.length; i++ ){
if ( state.groups[i] == group ){
result = true;
break;
}
}
}
return result;
}
Sonia.repository.hasPermission = function(repository, type){
var result = false;
if ( admin ){
result = true;
} else {
var permissions = repository.permissions;
if ( Ext.isDefined(permissions) ){
var value = Sonia.repository.getPermissionValue( type );
for (var i=0;i<permissions.length; i++ ){
var p = permissions[i];
var pv = Sonia.repository.getPermissionValue( p.type );
if ( pv >= value ){
if ( p.groupPermission ){
if ( Sonia.repository.isMember( p.name ) ){
result = true;
break;
}
} else if ( p.name == state.user.name ) {
result = true;
break;
}
}
}
}
}
return result;
}
Sonia.repository.isOwner = function(repository){
return Sonia.repository.hasPermission(repository, 'OWNER');
return repository.permissions != null;
}
Sonia.repository.setEditPanel = function(panel){

View File

@@ -118,7 +118,7 @@ Ext.onReady(function(){
items: [{
label: 'Repositories',
fn: function(){
addTabPanel('repositories', 'repositoryPanel', 'Repositories');
mainTabPanel.setActiveTab('repositories');
}
}]
});
@@ -209,20 +209,18 @@ Ext.onReady(function(){
panel.doLayout();
}
function createWelcomePanel(){
function createRepositoryPanel(){
if ( debug ){
console.debug('create welcome tab');
console.debug('create repository panel');
}
mainTabPanel.add({
id: 'welcomeTab',
xtype: 'panel',
title: 'Welcome',
hideMode: 'offsets',
bodyCssClass: 'x-panel-mc',
enableTabScroll: true,
id: 'repositories',
xtype: 'repositoryPanel',
title: 'Repositories',
closeable: false,
autoScroll: true
});
mainTabPanel.setActiveTab('welcomeTab');
mainTabPanel.setActiveTab('repositories');
}
// register login callbacks
@@ -230,6 +228,6 @@ Ext.onReady(function(){
// create menu
loginCallbacks.splice(0, 0, createMainMenu );
// add welcome tab
loginCallbacks.push( createWelcomePanel );
loginCallbacks.push( createRepositoryPanel );
});

View File

@@ -36,10 +36,10 @@ package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.Manager;
import sonia.scm.util.MockUtil;
import sonia.scm.repository.xml.XmlRepositoryManager;
import sonia.scm.store.JAXBStoreFactory;
import sonia.scm.store.StoreFactory;
import sonia.scm.util.MockUtil;
//~--- JDK imports ------------------------------------------------------------
@@ -68,7 +68,8 @@ public class XmlRepositoryManagerTest extends RepositoryManagerTestBase
factory.init(contextProvider);
handlerSet.add(new DummyRepositoryHandler(factory));
return new XmlRepositoryManager(MockUtil.getAdminSecurityContextProvider(),
return new XmlRepositoryManager(contextProvider,
MockUtil.getAdminSecurityContextProvider(),
factory, handlerSet);
}
}

4
third-party/pom.xml vendored
View File

@@ -6,13 +6,13 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.third-party</groupId>
<artifactId>sonia.scm.third-party</artifactId>
<packaging>pom</packaging>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>third-party</name>
<modules>

View File

@@ -6,13 +6,13 @@
<parent>
<groupId>sonia.scm.third-party</groupId>
<artifactId>sonia.scm.third-party</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.third-party</groupId>
<artifactId>shared-libs</artifactId>
<packaging>pom</packaging>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
<name>shared-libs</name>
<build>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>sonia.scm.third-party</groupId>
<artifactId>sonia.scm.third-party</artifactId>
<version>1.0-M7-SNAPSHOT</version>
<version>1.0-RC1-SNAPSHOT</version>
</parent>
<groupId>org.tmatesoft.svnkit</groupId>