mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-12-22 00:09:47 +01:00
merge with branch 1.x
This commit is contained in:
16
pom.xml
16
pom.xml
@@ -169,6 +169,14 @@
|
||||
<version>1.0</version>
|
||||
</signature>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
@@ -438,7 +446,7 @@
|
||||
<logback.version>1.1.1</logback.version>
|
||||
<servlet.version>2.5</servlet.version>
|
||||
<guice.version>3.0</guice.version>
|
||||
<jersey.version>1.18</jersey.version>
|
||||
<jersey.version>1.18.1</jersey.version>
|
||||
<freemarker.version>2.3.20</freemarker.version>
|
||||
<jetty.version>7.6.14.v20131031</jetty.version>
|
||||
|
||||
@@ -446,11 +454,11 @@
|
||||
<legman.version>1.2.0</legman.version>
|
||||
|
||||
<!-- security libraries -->
|
||||
<shiro.version>1.2.2</shiro.version>
|
||||
<shiro.version>1.2.3</shiro.version>
|
||||
|
||||
<!-- repostitory libraries -->
|
||||
<jgit.version>3.2.0.201312181205-r</jgit.version>
|
||||
<svnkit.version>1.8.3-scm1</svnkit.version>
|
||||
<jgit.version>3.3.0.201403021825-r</jgit.version>
|
||||
<svnkit.version>1.8.4-scm2</svnkit.version>
|
||||
|
||||
<!-- util libraries -->
|
||||
<guava.version>16.0</guava.version>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
<dependency>
|
||||
<groupId>args4j</groupId>
|
||||
<artifactId>args4j</artifactId>
|
||||
<version>2.0.25</version>
|
||||
<version>2.0.26</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -98,7 +98,22 @@ public class GetRepositorySubCommand extends TemplateSubCommand
|
||||
protected void run()
|
||||
{
|
||||
ScmClientSession session = createSession();
|
||||
Repository repository = session.getRepositoryHandler().get(id);
|
||||
|
||||
Repository repository;
|
||||
|
||||
int index = id.indexOf("/");
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
String type = id.substring(0, index);
|
||||
String name = id.substring(index + 1);
|
||||
|
||||
repository = session.getRepositoryHandler().get(type, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
repository = session.getRepositoryHandler().get(id);
|
||||
}
|
||||
|
||||
if (repository != null)
|
||||
{
|
||||
@@ -117,7 +132,7 @@ public class GetRepositorySubCommand extends TemplateSubCommand
|
||||
|
||||
/** Field description */
|
||||
@Argument(
|
||||
usage = "optionRepositoryId",
|
||||
usage = "optionRepositoryIdOrTypeAndName",
|
||||
metaVar = "repositoryid",
|
||||
required = true
|
||||
)
|
||||
|
||||
@@ -44,6 +44,7 @@ optionLoggingLevel = Logging level (DEBUG, INFO, WARN, ERROR)
|
||||
optionTemplate = Template
|
||||
optionTemplateFile = Template file
|
||||
optionRepositoryId = Repository Id
|
||||
optionRepositoryIdOrTypeAndName = Repository Id or type/name
|
||||
optionRepositoryName = Repository name
|
||||
optionRepositoryType = Repository name
|
||||
optionRepositoryContact = Repository contact
|
||||
@@ -56,7 +57,7 @@ optionPermissionName = Group or user name
|
||||
optionPermissionType = Permission type (READ,WRITE or OWNER)
|
||||
|
||||
optionUserName = Username
|
||||
optionUserDisplayName = "Diesplay name
|
||||
optionUserDisplayName = Display name
|
||||
optionUserMail = E-Mail address
|
||||
optionUserPassword = Password
|
||||
optionUserType = Type
|
||||
|
||||
103
scm-core/src/main/java/sonia/scm/ClientMessages.java
Normal file
103
scm-core/src/main/java/sonia/scm/ClientMessages.java
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import sonia.scm.i18n.I18nMessages;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* I18n messages which are send back to client.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.37
|
||||
*/
|
||||
public final class ClientMessages
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs a new instance of ClientMessages. This constructor should not be
|
||||
* used. Use the {@link #get(javax.servlet.http.HttpServletRequest)} method
|
||||
* instead.
|
||||
*/
|
||||
public ClientMessages() {}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the localized string for a failed authentication.
|
||||
*
|
||||
*
|
||||
* @return localized string
|
||||
*/
|
||||
public String failedAuthentication()
|
||||
{
|
||||
return failedAuthentication;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the localized string for "not enough privileges.
|
||||
*
|
||||
*
|
||||
* @return localized string
|
||||
*/
|
||||
public String notEnoughPrivileges()
|
||||
{
|
||||
return notEnoughPrivileges;
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns an instance {@link ClientMessages}.
|
||||
*
|
||||
* @param request servlet request
|
||||
*
|
||||
* @return instance of client messages
|
||||
*/
|
||||
public static ClientMessages get(HttpServletRequest request)
|
||||
{
|
||||
return I18nMessages.get(ClientMessages.class, request);
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** failed authentication */
|
||||
private String failedAuthentication;
|
||||
|
||||
/** not enough privileges */
|
||||
private String notEnoughPrivileges;
|
||||
}
|
||||
@@ -295,6 +295,7 @@ public class ScmConfiguration
|
||||
*
|
||||
*
|
||||
* @return realm description
|
||||
* @since 1.36
|
||||
*/
|
||||
public String getRealmDescription()
|
||||
{
|
||||
@@ -577,6 +578,7 @@ public class ScmConfiguration
|
||||
*
|
||||
*
|
||||
* @param realmDescription
|
||||
* @since 1.36
|
||||
*/
|
||||
public void setRealmDescription(String realmDescription)
|
||||
{
|
||||
|
||||
@@ -30,10 +30,12 @@
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.i18n;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import sonia.scm.util.ClassLoaders;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
@@ -41,6 +43,7 @@ import sonia.scm.util.Util;
|
||||
import java.text.MessageFormat;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
@@ -81,7 +84,7 @@ public class Bundle
|
||||
*/
|
||||
public static Bundle getBundle(String path)
|
||||
{
|
||||
return new Bundle(ResourceBundle.getBundle(path));
|
||||
return getBundle(path, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,7 +98,35 @@ public class Bundle
|
||||
*/
|
||||
public static Bundle getBundle(String path, Locale locale)
|
||||
{
|
||||
return new Bundle(ResourceBundle.getBundle(path, locale));
|
||||
return getBundle(path, locale, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new bundle instance
|
||||
*
|
||||
*
|
||||
* @param path path to the properties file
|
||||
* @param locale locale for the properties file
|
||||
* @param classLoader classLoader to load
|
||||
*
|
||||
* @return new bundle instance
|
||||
*
|
||||
* @since 1.37
|
||||
*/
|
||||
public static Bundle getBundle(String path, Locale locale,
|
||||
ClassLoader classLoader)
|
||||
{
|
||||
if (locale == null)
|
||||
{
|
||||
locale = Locale.ENGLISH;
|
||||
}
|
||||
|
||||
if (classLoader == null)
|
||||
{
|
||||
classLoader = ClassLoaders.getContextClassLoader(Bundle.class);
|
||||
}
|
||||
|
||||
return new Bundle(ResourceBundle.getBundle(path, locale, classLoader));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,8 +165,33 @@ public class Bundle
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the key, formatted with {@link MessageFormat} or null
|
||||
* if the key is not present in the bundle.
|
||||
*
|
||||
*
|
||||
* @param key key in the properties file
|
||||
* @param args format arguments
|
||||
*
|
||||
* @return formated message or null
|
||||
*
|
||||
* @since 1.37
|
||||
*/
|
||||
public String getStringIfPresent(String key, Object... args)
|
||||
{
|
||||
String msg = null;
|
||||
|
||||
try
|
||||
{
|
||||
msg = getString(key, args);
|
||||
}
|
||||
catch (MissingResourceException ex) {}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private ResourceBundle bundle;
|
||||
/** resource bundle */
|
||||
private final ResourceBundle bundle;
|
||||
}
|
||||
|
||||
60
scm-core/src/main/java/sonia/scm/i18n/I18n.java
Normal file
60
scm-core/src/main/java/sonia/scm/i18n/I18n.java
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* 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.i18n;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* The I18n annotation is used by the {@link I18nMessages} class to define the
|
||||
* resource bundle key.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.37
|
||||
*/
|
||||
@Documented
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface I18n
|
||||
{
|
||||
/**
|
||||
* Returns the key for the resource bundle.
|
||||
*
|
||||
* @return resource bundle key
|
||||
*/
|
||||
String value();
|
||||
}
|
||||
85
scm-core/src/main/java/sonia/scm/i18n/I18nException.java
Normal file
85
scm-core/src/main/java/sonia/scm/i18n/I18nException.java
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* 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.i18n;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class I18nException extends RuntimeException
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final long serialVersionUID = 1845326427312983227L;
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
public I18nException() {}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
public I18nException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param cause
|
||||
*/
|
||||
public I18nException(Throwable cause)
|
||||
{
|
||||
super(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param message
|
||||
* @param cause
|
||||
*/
|
||||
public I18nException(String message, Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
288
scm-core/src/main/java/sonia/scm/i18n/I18nMessages.java
Normal file
288
scm-core/src/main/java/sonia/scm/i18n/I18nMessages.java
Normal file
@@ -0,0 +1,288 @@
|
||||
/**
|
||||
* 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.i18n;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
import sonia.scm.util.ClassLoaders;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* The I18nMessages class instantiates a class and initializes all {@link String}
|
||||
* fields with values from a resource bundle. The resource bundle must have the
|
||||
* same name as the class. Each field which should be initialized from the
|
||||
* bundle, must match a key in the resource bundle or is annotated with a
|
||||
* {@link I18n} annotation which holds the key. I18nMessages injects also the
|
||||
* locale and the bundle if it founds a field with the corresponding type.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.37
|
||||
*/
|
||||
public final class I18nMessages
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final Cache<CacheKey, Object> cache =
|
||||
CacheBuilder.newBuilder().build();
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
private I18nMessages() {}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Same as {@link #get(java.lang.Class, java.util.Locale)}, with locale
|
||||
* {@link Locale#ENGLISH}.
|
||||
*
|
||||
* @param msgClass message class
|
||||
* @param <T> type of message class
|
||||
*
|
||||
* @return instance of message class
|
||||
*/
|
||||
public static <T> T get(Class<T> msgClass)
|
||||
{
|
||||
return get(msgClass, Locale.ENGLISH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #get(java.lang.Class, java.util.Locale)}, with locale
|
||||
* from servlet request ({@link HttpServletRequest#getLocale()}).
|
||||
*
|
||||
*
|
||||
* @param msgClass message class
|
||||
* @param request servlet request
|
||||
* @param <T> type of message class
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static <T> T get(Class<T> msgClass, HttpServletRequest request)
|
||||
{
|
||||
return get(msgClass, request.getLocale());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a instance of the given message class with all message fields
|
||||
* initialized.
|
||||
*
|
||||
*
|
||||
* @param msgClass message class
|
||||
* @param locale locale
|
||||
* @param <T> type of the message class
|
||||
*
|
||||
* @return instance of message class
|
||||
*/
|
||||
public synchronized static <T> T get(Class<T> msgClass, Locale locale)
|
||||
{
|
||||
CacheKey ck = new CacheKey(locale, msgClass);
|
||||
T instance = (T) cache.getIfPresent(ck);
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
instance = createInstance(msgClass, locale);
|
||||
cache.put(ck, instance);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param msgClass
|
||||
* @param locale
|
||||
* @param <T>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static <T> T createInstance(Class<T> msgClass, Locale locale)
|
||||
{
|
||||
Bundle bundle = Bundle.getBundle(msgClass.getName(), locale,
|
||||
ClassLoaders.getContextClassLoader(msgClass));
|
||||
T instance = null;
|
||||
|
||||
try
|
||||
{
|
||||
instance = msgClass.newInstance();
|
||||
initializeInstance(bundle, locale, msgClass, instance);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new I18nException("could not instantiate/initialize class", ex);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param bundle
|
||||
* @param locale
|
||||
* @param msgClass
|
||||
* @param instance
|
||||
*
|
||||
* @throws IllegalAccessException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
private static void initializeInstance(Bundle bundle, Locale locale,
|
||||
Class msgClass, Object instance)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
for (Field field : msgClass.getDeclaredFields())
|
||||
{
|
||||
if (field.getType().isAssignableFrom(String.class))
|
||||
{
|
||||
String key = field.getName();
|
||||
I18n i18n = field.getAnnotation(I18n.class);
|
||||
|
||||
if (i18n != null)
|
||||
{
|
||||
key = i18n.value();
|
||||
}
|
||||
|
||||
String value = bundle.getString(key);
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
field.setAccessible(true);
|
||||
field.set(instance, value);
|
||||
}
|
||||
}
|
||||
else if (field.getType().isAssignableFrom(Bundle.class))
|
||||
{
|
||||
field.setAccessible(true);
|
||||
field.set(instance, bundle);
|
||||
}
|
||||
else if (field.getType().isAssignableFrom(Locale.class))
|
||||
{
|
||||
|
||||
field.setAccessible(true);
|
||||
field.set(instance, locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Class description
|
||||
*
|
||||
*
|
||||
* @version Enter version here..., 14/03/15
|
||||
* @author Enter your name here...
|
||||
*/
|
||||
private static class CacheKey
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param locale
|
||||
* @param msgClass
|
||||
*/
|
||||
public CacheKey(Locale locale, Class msgClass)
|
||||
{
|
||||
this.locale = locale;
|
||||
this.msgClass = msgClass;
|
||||
}
|
||||
|
||||
//~--- methods ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param obj
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final CacheKey other = (CacheKey) obj;
|
||||
|
||||
return Objects.equal(locale, other.locale)
|
||||
&& Objects.equal(msgClass, other.msgClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hashCode(locale, msgClass);
|
||||
}
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private final Locale locale;
|
||||
|
||||
/** Field description */
|
||||
private final Class msgClass;
|
||||
}
|
||||
}
|
||||
@@ -30,8 +30,13 @@
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.io;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.io.Closer;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -70,12 +75,15 @@ public final class DeepCopy
|
||||
{
|
||||
T obj = null;
|
||||
|
||||
Closer closer = Closer.create();
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Write the object out to a byte array
|
||||
FastByteArrayOutputStream fbos = new FastByteArrayOutputStream();
|
||||
ObjectOutputStream out = new ObjectOutputStream(fbos);
|
||||
FastByteArrayOutputStream fbos =
|
||||
closer.register(new FastByteArrayOutputStream());
|
||||
ObjectOutputStream out = closer.register(new ObjectOutputStream(fbos));
|
||||
|
||||
out.writeObject(orig);
|
||||
out.flush();
|
||||
@@ -83,7 +91,10 @@ public final class DeepCopy
|
||||
|
||||
// Retrieve an input stream from the byte array and read
|
||||
// a copy of the object back in.
|
||||
ObjectInputStream in = new ObjectInputStream(fbos.getInputStream());
|
||||
// use ScmObjectInputStream to solve ClassNotFoundException
|
||||
// for plugin classes
|
||||
ObjectInputStream in =
|
||||
closer.register(new ScmObjectInputStream(fbos.getInputStream()));
|
||||
|
||||
obj = (T) in.readObject();
|
||||
}
|
||||
@@ -91,6 +102,10 @@ public final class DeepCopy
|
||||
{
|
||||
throw new IOException("could not copy object", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
closer.close();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
124
scm-core/src/main/java/sonia/scm/io/ScmObjectInputStream.java
Normal file
124
scm-core/src/main/java/sonia/scm/io/ScmObjectInputStream.java
Normal file
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectStreamClass;
|
||||
|
||||
/**
|
||||
* {@link ObjectInputStream} implementation which uses the context class loader
|
||||
* to resolve classes.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.36
|
||||
*/
|
||||
public class ScmObjectInputStream extends ObjectInputStream
|
||||
{
|
||||
|
||||
/**
|
||||
* the logger for ScmObjectInputStream
|
||||
*/
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(ScmObjectInputStream.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public ScmObjectInputStream(InputStream stream) throws IOException
|
||||
{
|
||||
super(stream);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> resolveClass(ObjectStreamClass desc)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
Class<?> clazz = null;
|
||||
ClassLoader classLoader = getClassLoader();
|
||||
|
||||
try
|
||||
{
|
||||
clazz = classLoader.loadClass(desc.getName());
|
||||
}
|
||||
catch (ClassNotFoundException ex)
|
||||
{
|
||||
// do not log the exception, because the class
|
||||
// is mostly found by the parent method.
|
||||
}
|
||||
|
||||
if (clazz == null)
|
||||
{
|
||||
clazz = super.resolveClass(desc);
|
||||
}
|
||||
|
||||
return clazz;
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the context class loader if available. If the context class loader
|
||||
* is not available the method will fall back to the class loader which has
|
||||
* load this class.
|
||||
*
|
||||
*
|
||||
* @return context class loader or default class loader
|
||||
*/
|
||||
private ClassLoader getClassLoader()
|
||||
{
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
if (classLoader == null)
|
||||
{
|
||||
logger.debug("could not find context class loader, fall back to default");
|
||||
classLoader = ScmObjectInputStream.class.getClassLoader();
|
||||
}
|
||||
|
||||
return classLoader;
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,9 @@ package sonia.scm.search;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.TransformFilter;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
@@ -53,6 +56,14 @@ import java.util.Locale;
|
||||
public final class SearchUtil
|
||||
{
|
||||
|
||||
/**
|
||||
* the logger for SearchUtil
|
||||
*/
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(SearchUtil.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
@@ -180,6 +191,77 @@ public final class SearchUtil
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param pattern
|
||||
* @param c
|
||||
*/
|
||||
private static void appendChar(StringBuilder pattern, char c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '*' :
|
||||
pattern.append(".*");
|
||||
|
||||
break;
|
||||
|
||||
case '?' :
|
||||
pattern.append(".");
|
||||
|
||||
break;
|
||||
|
||||
case '(' :
|
||||
pattern.append("\\(");
|
||||
|
||||
break;
|
||||
|
||||
case ')' :
|
||||
pattern.append("\\)");
|
||||
|
||||
break;
|
||||
|
||||
case '{' :
|
||||
pattern.append("\\{");
|
||||
|
||||
break;
|
||||
|
||||
case '}' :
|
||||
pattern.append("\\}");
|
||||
|
||||
break;
|
||||
|
||||
case '[' :
|
||||
pattern.append("\\[");
|
||||
|
||||
break;
|
||||
|
||||
case ']' :
|
||||
pattern.append("\\]");
|
||||
|
||||
break;
|
||||
|
||||
case '|' :
|
||||
pattern.append("\\|");
|
||||
|
||||
break;
|
||||
|
||||
case '.' :
|
||||
pattern.append("\\.");
|
||||
|
||||
break;
|
||||
|
||||
case '\\' :
|
||||
pattern.append("\\\\");
|
||||
|
||||
break;
|
||||
|
||||
default :
|
||||
pattern.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -192,19 +274,26 @@ public final class SearchUtil
|
||||
{
|
||||
String query = request.getQuery().trim();
|
||||
|
||||
StringBuilder pattern = new StringBuilder();
|
||||
|
||||
if (request.isIgnoreCase())
|
||||
{
|
||||
pattern.append("(?i)");
|
||||
query = query.toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
query = query.replace("\\", "\\\\").replace("*", ".*").replace("?", ".");
|
||||
query = ".*".concat(query).concat(".*");
|
||||
pattern.append(".*");
|
||||
|
||||
if (request.isIgnoreCase())
|
||||
for (char c : query.toCharArray())
|
||||
{
|
||||
query = "(?i)".concat(query);
|
||||
appendChar(pattern, c);
|
||||
}
|
||||
|
||||
return query;
|
||||
pattern.append(".*");
|
||||
|
||||
logger.trace("converted query \"{}\" to regex pattern \"{}\"",
|
||||
request.getQuery(), pattern);
|
||||
|
||||
return pattern.toString();
|
||||
}
|
||||
}
|
||||
|
||||
72
scm-core/src/main/java/sonia/scm/util/ClassLoaders.java
Normal file
72
scm-core/src/main/java/sonia/scm/util/ClassLoaders.java
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 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.util;
|
||||
|
||||
/**
|
||||
* Util methods for {@link ClassLoader}s.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.37
|
||||
*/
|
||||
public final class ClassLoaders
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
private ClassLoaders() {}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the context {@link ClassLoader} from the current {@link Thread}, if
|
||||
* the context {@link ClassLoader} is not available the {@link ClassLoader},
|
||||
* which has load the given context class, is used.
|
||||
*
|
||||
*
|
||||
* @param contextClass context class
|
||||
*
|
||||
* @return context class loader
|
||||
*/
|
||||
public static ClassLoader getContextClassLoader(Class<?> contextClass)
|
||||
{
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
if (classLoader == null)
|
||||
{
|
||||
classLoader = contextClass.getClassLoader();
|
||||
}
|
||||
|
||||
return classLoader;
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,7 @@ package sonia.scm.util;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -46,11 +47,13 @@ import sonia.scm.config.ScmConfiguration;
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -77,6 +80,9 @@ public final class HttpUtil
|
||||
*/
|
||||
public static final String HEADER_SCM_CLIENT = "X-SCM-Client";
|
||||
|
||||
/** Field description */
|
||||
public static final String HEADER_USERAGENT = "User-Agent";
|
||||
|
||||
/** authentication header */
|
||||
public static final String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
|
||||
|
||||
@@ -158,6 +164,9 @@ public final class HttpUtil
|
||||
public static final String STATUS_UNAUTHORIZED_MESSAGE =
|
||||
"Authorization Required";
|
||||
|
||||
/** Field description */
|
||||
private static final int SKIP_SIZE = 4096;
|
||||
|
||||
/** the logger for HttpUtil */
|
||||
private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);
|
||||
|
||||
@@ -299,6 +308,38 @@ public final class HttpUtil
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips to complete body of a request.
|
||||
*
|
||||
*
|
||||
* @param request http request
|
||||
*
|
||||
* @since 1.37
|
||||
*/
|
||||
public static void drainBody(HttpServletRequest request)
|
||||
{
|
||||
if (isChunked(request) || (request.getContentLength() > 0))
|
||||
{
|
||||
InputStream in = null;
|
||||
|
||||
try
|
||||
{
|
||||
in = request.getInputStream();
|
||||
|
||||
while ((0 < in.skip(SKIP_SIZE)) || (0 <= in.read()))
|
||||
{
|
||||
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
catch (IOException e) {}
|
||||
finally
|
||||
{
|
||||
IOUtil.close(in);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -443,8 +484,11 @@ public final class HttpUtil
|
||||
* @param realmDescription - realm description
|
||||
*
|
||||
* @throws IOException
|
||||
*
|
||||
* @since 1.36
|
||||
*/
|
||||
public static void sendUnauthorized(HttpServletResponse response, String realmDescription)
|
||||
public static void sendUnauthorized(HttpServletResponse response,
|
||||
String realmDescription)
|
||||
throws IOException
|
||||
{
|
||||
sendUnauthorized(null, response, realmDescription);
|
||||
@@ -463,8 +507,7 @@ public final class HttpUtil
|
||||
* @since 1.19
|
||||
*/
|
||||
public static void sendUnauthorized(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
String realmDescription)
|
||||
HttpServletResponse response, String realmDescription)
|
||||
throws IOException
|
||||
{
|
||||
if ((request == null) ||!isWUIRequest(request))
|
||||
@@ -483,6 +526,26 @@ public final class HttpUtil
|
||||
STATUS_UNAUTHORIZED_MESSAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the User-Agent header of the current request starts with
|
||||
* the given string.
|
||||
*
|
||||
*
|
||||
* @param request http request
|
||||
* @param userAgent string to test against the header
|
||||
*
|
||||
* @return true if the header starts with the given string
|
||||
*
|
||||
* @since 1.37
|
||||
*/
|
||||
public static boolean userAgentStartsWith(HttpServletRequest request,
|
||||
String userAgent)
|
||||
{
|
||||
return Strings.nullToEmpty(request.getHeader(HEADER_USERAGENT)).toLowerCase(
|
||||
Locale.ENGLISH).startsWith(
|
||||
Strings.nullToEmpty(userAgent).toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -669,6 +732,21 @@ public final class HttpUtil
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the body of the request is chunked.
|
||||
*
|
||||
*
|
||||
* @param request http request
|
||||
*
|
||||
* @return true if the request is chunked
|
||||
*
|
||||
* @since 1.37
|
||||
*/
|
||||
public static boolean isChunked(HttpServletRequest request)
|
||||
{
|
||||
return "chunked".equals(request.getHeader("Transfer-Encoding"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the http request is send by the scm-manager web interface.
|
||||
*
|
||||
|
||||
@@ -35,7 +35,6 @@ package sonia.scm.web.filter;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
@@ -83,6 +82,9 @@ public class BasicAuthenticationFilter extends AutoLoginFilter
|
||||
/** Field description */
|
||||
public static final String HEADER_AUTHORIZATION = "Authorization";
|
||||
|
||||
/** marker for failed authentication */
|
||||
private static final String ATTRIBUTE_FAILED_AUTH = "sonia.scm.auth.failed";
|
||||
|
||||
/** the logger for BasicAuthenticationFilter */
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(BasicAuthenticationFilter.class);
|
||||
@@ -182,9 +184,8 @@ public class BasicAuthenticationFilter extends AutoLoginFilter
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends status code 401 back to client, if no authorization header was found,
|
||||
* if a authorization is present and the authentication failed the method will
|
||||
* send status code 403.
|
||||
* Sends status code 403 back to client, if the authentication has failed.
|
||||
* In all other cases the method will send status code 403 back to client.
|
||||
*
|
||||
* @param request servlet request
|
||||
* @param response servlet response
|
||||
@@ -199,18 +200,53 @@ public class BasicAuthenticationFilter extends AutoLoginFilter
|
||||
HttpServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
String authentication = request.getHeader(HEADER_AUTHORIZATION);
|
||||
|
||||
if (Strings.isNullOrEmpty(authentication))
|
||||
// send only forbidden, if the authentication has failed.
|
||||
// see https://bitbucket.org/sdorra/scm-manager/issue/545/git-clone-with-username-in-url-does-not
|
||||
if (Boolean.TRUE.equals(request.getAttribute(ATTRIBUTE_FAILED_AUTH)))
|
||||
{
|
||||
HttpUtil.sendUnauthorized(request, response, configuration.getRealmDescription());
|
||||
sendFailedAuthenticationError(request, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
sendUnauthorizedError(request, response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an error for a failed authentication back to client.
|
||||
*
|
||||
*
|
||||
* @param request http request
|
||||
* @param response http response
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void sendFailedAuthenticationError(HttpServletRequest request,
|
||||
HttpServletResponse response)
|
||||
throws IOException
|
||||
{
|
||||
HttpUtil.sendUnauthorized(request, response,
|
||||
configuration.getRealmDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an unauthorized error back to client.
|
||||
*
|
||||
*
|
||||
* @param request http request
|
||||
* @param response http response
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void sendUnauthorizedError(HttpServletRequest request,
|
||||
HttpServletResponse response)
|
||||
throws IOException
|
||||
{
|
||||
HttpUtil.sendUnauthorized(request, response,
|
||||
configuration.getRealmDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -254,6 +290,10 @@ public class BasicAuthenticationFilter extends AutoLoginFilter
|
||||
}
|
||||
catch (AuthenticationException ex)
|
||||
{
|
||||
|
||||
// add a marker to the request that the authentication has failed
|
||||
request.setAttribute(ATTRIBUTE_FAILED_AUTH, Boolean.TRUE);
|
||||
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("authentication failed for user ".concat(username),
|
||||
@@ -280,6 +320,6 @@ public class BasicAuthenticationFilter extends AutoLoginFilter
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private final ScmConfiguration configuration;
|
||||
/** scm main configuration */
|
||||
protected ScmConfiguration configuration;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.repository.PermissionType;
|
||||
import sonia.scm.repository.PermissionUtil;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.security.Role;
|
||||
import sonia.scm.security.ScmSecurityException;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
import sonia.scm.util.Util;
|
||||
@@ -63,7 +64,6 @@ import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import sonia.scm.security.Role;
|
||||
|
||||
/**
|
||||
* Abstract http filter to check repository permissions.
|
||||
@@ -162,7 +162,7 @@ public abstract class PermissionFilter extends HttpFilter
|
||||
getUserName(subject));
|
||||
}
|
||||
|
||||
sendAccessDenied(response, subject);
|
||||
sendAccessDenied(request, response, subject);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -199,11 +199,43 @@ public abstract class PermissionFilter extends HttpFilter
|
||||
subject.getPrincipal());
|
||||
}
|
||||
|
||||
sendAccessDenied(response, subject);
|
||||
sendAccessDenied(request, response, subject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a "not enough privileges" error back to client.
|
||||
*
|
||||
*
|
||||
* @param request http request
|
||||
* @param response http response
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void sendNotEnoughPrivilegesError(HttpServletRequest request,
|
||||
HttpServletResponse response)
|
||||
throws IOException
|
||||
{
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an unauthorized error back to client.
|
||||
*
|
||||
*
|
||||
* @param request http request
|
||||
* @param response http response
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void sendUnauthorizedError(HttpServletRequest request,
|
||||
HttpServletResponse response)
|
||||
throws IOException
|
||||
{
|
||||
HttpUtil.sendUnauthorized(response, configuration.getRealmDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the type of the repositroy from url.
|
||||
*
|
||||
@@ -230,22 +262,23 @@ public abstract class PermissionFilter extends HttpFilter
|
||||
/**
|
||||
* Send access denied to the servlet response.
|
||||
*
|
||||
*
|
||||
* @param request current http request object
|
||||
* @param response current http response object
|
||||
* @param subject user subject
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private void sendAccessDenied(HttpServletResponse response, Subject subject)
|
||||
private void sendAccessDenied(HttpServletRequest request,
|
||||
HttpServletResponse response, Subject subject)
|
||||
throws IOException
|
||||
{
|
||||
if (subject.hasRole(Role.USER))
|
||||
{
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
sendNotEnoughPrivilegesError(request, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
HttpUtil.sendUnauthorized(response, configuration.getRealmDescription());
|
||||
sendUnauthorizedError(request, response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,5 +367,5 @@ public abstract class PermissionFilter extends HttpFilter
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** scm-manager global configuration */
|
||||
private ScmConfiguration configuration;
|
||||
private final ScmConfiguration configuration;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# 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
|
||||
#
|
||||
|
||||
failedAuthentication = Invalid username or password.
|
||||
notEnoughPrivileges = You do not have enough access privileges for this operation.
|
||||
95
scm-core/src/test/java/sonia/scm/i18n/I18nMessagesTest.java
Normal file
95
scm-core/src/test/java/sonia/scm/i18n/I18nMessagesTest.java
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* 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.i18n;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import sonia.scm.repository.Changeset;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.MissingResourceException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class I18nMessagesTest
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testI18n()
|
||||
{
|
||||
TestMessages msg = I18nMessages.get(TestMessages.class);
|
||||
|
||||
assertEquals("Normal Key", msg.normalKey);
|
||||
assertEquals("Key with Annotation", msg.keyWithAnnotation);
|
||||
assertNull(msg.someObject);
|
||||
assertNotNull(msg.bundle);
|
||||
assertEquals(Locale.ENGLISH, msg.locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testI18nOtherLanguage()
|
||||
{
|
||||
TestMessages msg = I18nMessages.get(TestMessages.class, Locale.GERMANY);
|
||||
|
||||
assertEquals("Normaler Schlüssel", msg.normalKey);
|
||||
assertEquals("Schlüssel mit Annotation", msg.keyWithAnnotation);
|
||||
assertNull(msg.someObject);
|
||||
assertNotNull(msg.bundle);
|
||||
assertEquals(Locale.GERMANY, msg.locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test(expected = MissingResourceException.class)
|
||||
public void testMissingBundle()
|
||||
{
|
||||
Changeset msg = I18nMessages.get(Changeset.class);
|
||||
}
|
||||
}
|
||||
60
scm-core/src/test/java/sonia/scm/i18n/TestMessages.java
Normal file
60
scm-core/src/test/java/sonia/scm/i18n/TestMessages.java
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* 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.i18n;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class TestMessages
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
public Bundle bundle;
|
||||
|
||||
/** Field description */
|
||||
@I18n("key_with_annotation")
|
||||
public String keyWithAnnotation;
|
||||
|
||||
/** Field description */
|
||||
public Locale locale;
|
||||
|
||||
/** Field description */
|
||||
public String normalKey;
|
||||
|
||||
/** Field description */
|
||||
public Integer someObject;
|
||||
}
|
||||
328
scm-core/src/test/java/sonia/scm/io/DeepCopyTest.java
Normal file
328
scm-core/src/test/java/sonia/scm/io/DeepCopyTest.java
Normal file
@@ -0,0 +1,328 @@
|
||||
/**
|
||||
* 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 com.google.common.base.Objects;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class DeepCopyTest
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testDeepCopy() throws IOException
|
||||
{
|
||||
Person orig = new Person("Tricia", "McMillan",
|
||||
new Address("Magrathea", "Mainstreet 3"));
|
||||
Person copy = DeepCopy.copy(orig);
|
||||
|
||||
assertNotSame(orig, copy);
|
||||
assertEquals(orig, copy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test(expected = IOException.class)
|
||||
public void testDeepCopyNonSerializable() throws IOException
|
||||
{
|
||||
DeepCopy.copy(new NonSerializable());
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Class description
|
||||
*
|
||||
*
|
||||
* @version Enter version here..., 14/03/08
|
||||
* @author Enter your name here...
|
||||
*/
|
||||
private static class Address implements Serializable
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final long serialVersionUID = 3200816222378286310L;
|
||||
|
||||
//~--- constructors -------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
public Address() {}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param city
|
||||
* @param street
|
||||
*/
|
||||
public Address(String city, String street)
|
||||
{
|
||||
this.city = city;
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
//~--- methods ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param obj
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Address other = (Address) obj;
|
||||
|
||||
return Objects.equal(city, other.city)
|
||||
&& Objects.equal(street, other.street);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hashCode(city, street);
|
||||
}
|
||||
|
||||
//~--- get methods --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getCity()
|
||||
{
|
||||
return city;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getStreet()
|
||||
{
|
||||
return street;
|
||||
}
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private String city;
|
||||
|
||||
/** Field description */
|
||||
private String street;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class description
|
||||
*
|
||||
*
|
||||
* @version Enter version here..., 14/03/08
|
||||
* @author Enter your name here...
|
||||
*/
|
||||
private static class NonSerializable {}
|
||||
|
||||
|
||||
/**
|
||||
* Class description
|
||||
*
|
||||
*
|
||||
* @version Enter version here..., 14/03/08
|
||||
* @author Enter your name here...
|
||||
*/
|
||||
private static class Person implements Serializable
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final long serialVersionUID = -2098386757802626539L;
|
||||
|
||||
//~--- constructors -------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
public Person() {}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param firstname
|
||||
* @param lastname
|
||||
* @param address
|
||||
*/
|
||||
public Person(String firstname, String lastname, Address address)
|
||||
{
|
||||
this.firstname = firstname;
|
||||
this.lastname = lastname;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
//~--- methods ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param obj
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Person other = (Person) obj;
|
||||
|
||||
return Objects.equal(firstname, other.firstname)
|
||||
&& Objects.equal(lastname, other.lastname)
|
||||
&& Objects.equal(address, other.address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hashCode(firstname, lastname, address);
|
||||
}
|
||||
|
||||
//~--- get methods --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Address getAddress()
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getFirstname()
|
||||
{
|
||||
return firstname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getLastname()
|
||||
{
|
||||
return lastname;
|
||||
}
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private Address address;
|
||||
|
||||
/** Field description */
|
||||
private String firstname;
|
||||
|
||||
/** Field description */
|
||||
private String lastname;
|
||||
}
|
||||
}
|
||||
@@ -177,6 +177,12 @@ public class SearchUtilTest
|
||||
"testhansolo"));
|
||||
assertFalse(SearchUtil.matchesAll(new SearchRequest("test\\hansolo"),
|
||||
"test\\hnsolo"));
|
||||
assertTrue(SearchUtil.matchesAll(new SearchRequest("{test,hansolo} tst"),
|
||||
"{test,hansolo} tst"));
|
||||
assertTrue(SearchUtil.matchesAll(new SearchRequest("(test,hansolo) tst"),
|
||||
"(test,hansolo) tst"));
|
||||
assertTrue(SearchUtil.matchesAll(new SearchRequest("[test,hansolo] tst"),
|
||||
"[test,hansolo] tst"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -184,6 +184,23 @@ public class HttpUtilTest
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void userAgentStartsWithTest()
|
||||
{
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
|
||||
when(request.getHeader(HttpUtil.HEADER_USERAGENT)).thenReturn(
|
||||
"git/1.7.10.5997.gaa4aa");
|
||||
assertTrue(HttpUtil.userAgentStartsWith(request, "git/"));
|
||||
assertTrue(HttpUtil.userAgentStartsWith(request, "GIT/"));
|
||||
assertFalse(HttpUtil.userAgentStartsWith(request, "git/a"));
|
||||
assertFalse(HttpUtil.userAgentStartsWith(request, "sobbo/"));
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# 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
|
||||
#
|
||||
key_with_annotation = Key with Annotation
|
||||
normalKey = Normal Key
|
||||
@@ -0,0 +1,30 @@
|
||||
# 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
|
||||
#
|
||||
key_with_annotation = Schl\u00fcssel mit Annotation
|
||||
normalKey = Normaler Schl\u00fcssel
|
||||
@@ -409,7 +409,7 @@ public class JAXBConfigurationEntryStore<V>
|
||||
{
|
||||
//J-
|
||||
writer = new IndentXMLStreamWriter(
|
||||
XMLOutputFactory.newFactory().createXMLStreamWriter(
|
||||
XMLOutputFactory.newInstance().createXMLStreamWriter(
|
||||
createWriter()
|
||||
)
|
||||
);
|
||||
|
||||
@@ -36,6 +36,7 @@ package sonia.scm.repository;
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
@@ -59,6 +60,7 @@ import org.eclipse.jgit.util.FS;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.util.HttpUtil;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
@@ -66,9 +68,12 @@ import sonia.scm.util.Util;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -109,6 +114,9 @@ public final class GitUtil
|
||||
/** Field description */
|
||||
private static final int TIMEOUT = 5;
|
||||
|
||||
/** Field description */
|
||||
private static final String USERAGENT_GIT = "git/";
|
||||
|
||||
/** the logger for GitUtil */
|
||||
private static final Logger logger = LoggerFactory.getLogger(GitUtil.class);
|
||||
|
||||
@@ -652,6 +660,19 @@ public final class GitUtil
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the request comes from a git client.
|
||||
*
|
||||
*
|
||||
* @param request servlet request
|
||||
*
|
||||
* @return true if the client is git
|
||||
*/
|
||||
public static boolean isGitClient(HttpServletRequest request)
|
||||
{
|
||||
return HttpUtil.userAgentStartsWith(request, USERAGENT_GIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* 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 org.eclipse.jgit.http.server.GitSmartHttpTools;
|
||||
|
||||
import sonia.scm.ClientMessages;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.repository.GitUtil;
|
||||
import sonia.scm.web.filter.AutoLoginModule;
|
||||
import sonia.scm.web.filter.BasicAuthenticationFilter;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@Singleton
|
||||
public class GitBasicAuthenticationFilter extends BasicAuthenticationFilter
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param configuration
|
||||
* @param autoLoginModules
|
||||
*/
|
||||
@Inject
|
||||
public GitBasicAuthenticationFilter(ScmConfiguration configuration,
|
||||
Set<AutoLoginModule> autoLoginModules)
|
||||
{
|
||||
super(configuration, autoLoginModules);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
protected void sendFailedAuthenticationError(HttpServletRequest request,
|
||||
HttpServletResponse response)
|
||||
throws IOException
|
||||
{
|
||||
System.out.println(ClientMessages.get(request).failedAuthentication());
|
||||
if (GitUtil.isGitClient(request))
|
||||
{
|
||||
GitSmartHttpTools.sendError(request, response,
|
||||
HttpServletResponse.SC_FORBIDDEN,
|
||||
ClientMessages.get(request).failedAuthentication());
|
||||
}
|
||||
else
|
||||
{
|
||||
super.sendFailedAuthenticationError(request, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,13 +38,20 @@ package sonia.scm.web;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import org.eclipse.jgit.http.server.GitSmartHttpTools;
|
||||
|
||||
import sonia.scm.ClientMessages;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.repository.GitUtil;
|
||||
import sonia.scm.repository.RepositoryProvider;
|
||||
import sonia.scm.web.filter.ProviderPermissionFilter;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -71,19 +78,44 @@ public class GitPermissionFilter extends ProviderPermissionFilter
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param securityContextProvider
|
||||
* @param configuration
|
||||
* @param repositoryProvider
|
||||
*/
|
||||
@Inject
|
||||
public GitPermissionFilter(
|
||||
ScmConfiguration configuration,
|
||||
public GitPermissionFilter(ScmConfiguration configuration,
|
||||
RepositoryProvider repositoryProvider)
|
||||
{
|
||||
super(configuration, repositoryProvider);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
protected void sendNotEnoughPrivilegesError(HttpServletRequest request,
|
||||
HttpServletResponse response)
|
||||
throws IOException
|
||||
{
|
||||
if (GitUtil.isGitClient(request))
|
||||
{
|
||||
GitSmartHttpTools.sendError(request, response,
|
||||
HttpServletResponse.SC_FORBIDDEN,
|
||||
ClientMessages.get(request).notEnoughPrivileges());
|
||||
}
|
||||
else
|
||||
{
|
||||
super.sendNotEnoughPrivilegesError(request, response);
|
||||
}
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,7 +40,6 @@ import com.google.inject.servlet.ServletModule;
|
||||
import org.eclipse.jgit.transport.ScmTransportProtocol;
|
||||
|
||||
import sonia.scm.plugin.ext.Extension;
|
||||
import sonia.scm.web.filter.BasicAuthenticationFilter;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -68,7 +67,7 @@ public class GitServletModule extends ServletModule
|
||||
bind(ScmTransportProtocol.class);
|
||||
|
||||
// serlvelts and filters
|
||||
filter(PATTERN_GIT).through(BasicAuthenticationFilter.class);
|
||||
filter(PATTERN_GIT).through(GitBasicAuthenticationFilter.class);
|
||||
filter(PATTERN_GIT).through(GitPermissionFilter.class);
|
||||
serve(PATTERN_GIT).with(ScmGitServlet.class);
|
||||
}
|
||||
|
||||
@@ -37,8 +37,11 @@ package sonia.scm.repository;
|
||||
|
||||
import com.github.legman.Subscribe;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.OutOfScopeException;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.ProvisionException;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@@ -152,7 +155,7 @@ public class HgHookManager
|
||||
|
||||
if (url == null)
|
||||
{
|
||||
HttpServletRequest request = httpServletRequestProvider.get();
|
||||
HttpServletRequest request = getHttpServletRequest();
|
||||
|
||||
if (request != null)
|
||||
{
|
||||
@@ -160,10 +163,10 @@ public class HgHookManager
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn(
|
||||
"created hook url {} without request, in some cases this could cause problems",
|
||||
hookUrl);
|
||||
url = createConfiguredUrl();
|
||||
logger.warn(
|
||||
"created url {} without request, in some cases this could cause problems",
|
||||
url);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,8 +272,14 @@ public class HgHookManager
|
||||
*/
|
||||
private String createConfiguredUrl()
|
||||
{
|
||||
//J-
|
||||
return HttpUtil.getUriWithoutEndSeperator(
|
||||
configuration.getBaseUrl()).concat("/hook/hg/");
|
||||
Objects.firstNonNull(
|
||||
configuration.getBaseUrl(),
|
||||
"http://localhost:8080/scm"
|
||||
)
|
||||
).concat("/hook/hg/");
|
||||
//J+
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -309,6 +318,32 @@ public class HgHookManager
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private HttpServletRequest getHttpServletRequest()
|
||||
{
|
||||
HttpServletRequest request = null;
|
||||
|
||||
try
|
||||
{
|
||||
request = httpServletRequestProvider.get();
|
||||
}
|
||||
catch (ProvisionException ex)
|
||||
{
|
||||
logger.debug("http servlet request is not available");
|
||||
}
|
||||
catch (OutOfScopeException ex)
|
||||
{
|
||||
logger.debug("http servlet request is not available");
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* 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.config.ScmConfiguration;
|
||||
import sonia.scm.web.filter.AutoLoginModule;
|
||||
import sonia.scm.web.filter.BasicAuthenticationFilter;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@Singleton
|
||||
public class HgBasicAuthenticationFilter extends BasicAuthenticationFilter
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param configuration
|
||||
* @param autoLoginModules
|
||||
*/
|
||||
@Inject
|
||||
public HgBasicAuthenticationFilter(ScmConfiguration configuration,
|
||||
Set<AutoLoginModule> autoLoginModules)
|
||||
{
|
||||
super(configuration, autoLoginModules);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
protected void sendFailedAuthenticationError(HttpServletRequest request,
|
||||
HttpServletResponse response)
|
||||
throws IOException
|
||||
{
|
||||
if (HgUtil.isHgClient(request))
|
||||
{
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.sendFailedAuthenticationError(request, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,9 +57,6 @@ public class HgPermissionFilter extends ProviderPermissionFilter
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param securityContextProvider
|
||||
*
|
||||
* @param configuration
|
||||
* @param repositoryProvider
|
||||
*/
|
||||
|
||||
@@ -75,7 +75,7 @@ public class HgServletModule extends ServletModule
|
||||
serve(MAPPING_HOOK).with(HgHookCallbackServlet.class);
|
||||
|
||||
// register hg cgi servlet
|
||||
filter(MAPPING_HG).through(BasicAuthenticationFilter.class);
|
||||
filter(MAPPING_HG).through(HgBasicAuthenticationFilter.class);
|
||||
filter(MAPPING_HG).through(HgPermissionFilter.class);
|
||||
serve(MAPPING_HG).with(HgCGIServlet.class);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ import sonia.scm.repository.HgHookManager;
|
||||
import sonia.scm.repository.HgPythonScript;
|
||||
import sonia.scm.repository.HgRepositoryHandler;
|
||||
import sonia.scm.repository.spi.javahg.HgFileviewExtension;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
@@ -58,6 +59,8 @@ import java.io.File;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -68,6 +71,9 @@ public final class HgUtil
|
||||
/** Field description */
|
||||
public static final String REVISION_TIP = "tip";
|
||||
|
||||
/** Field description */
|
||||
private static final String USERAGENT_HG = "mercurial/";
|
||||
|
||||
/**
|
||||
* the logger for HgUtil
|
||||
*/
|
||||
@@ -180,4 +186,17 @@ public final class HgUtil
|
||||
? REVISION_TIP
|
||||
: revision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the request comes from a mercurial client.
|
||||
*
|
||||
*
|
||||
* @param request servlet request
|
||||
*
|
||||
* @return true if the client is mercurial
|
||||
*/
|
||||
public static boolean isHgClient(HttpServletRequest request)
|
||||
{
|
||||
return HttpUtil.userAgentStartsWith(request, USERAGENT_HG);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* 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.repository;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import org.tmatesoft.svn.core.SVNErrorCode;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public final class ScmSvnErrorCode extends SVNErrorCode
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final long serialVersionUID = -6864996390796610410L;
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param category
|
||||
* @param index
|
||||
* @param description
|
||||
*/
|
||||
protected ScmSvnErrorCode(int category, int index, String description)
|
||||
{
|
||||
super(category, index, description);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param description
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ScmSvnErrorCode authzNotEnoughPrivileges(String description)
|
||||
{
|
||||
return new ScmSvnErrorCode(AUTHZ_CATEGORY, 4, description);
|
||||
}
|
||||
}
|
||||
@@ -37,23 +37,36 @@ package sonia.scm.repository;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.io.Closeables;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.tmatesoft.svn.core.SVNErrorCode;
|
||||
import org.tmatesoft.svn.core.SVNLogEntry;
|
||||
import org.tmatesoft.svn.core.SVNLogEntryPath;
|
||||
import org.tmatesoft.svn.core.internal.io.dav.DAVElement;
|
||||
import org.tmatesoft.svn.core.internal.server.dav.DAVXMLUtil;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
|
||||
import org.tmatesoft.svn.core.internal.util.SVNXMLUtil;
|
||||
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
import org.tmatesoft.svn.core.wc.SVNClientManager;
|
||||
import org.tmatesoft.svn.core.wc.admin.SVNChangeEntry;
|
||||
|
||||
import sonia.scm.util.HttpUtil;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -61,6 +74,9 @@ import java.util.Map;
|
||||
public final class SvnUtil
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
public static final String XML_CONTENT_TYPE = "text/xml; charset=\"utf-8\"";
|
||||
|
||||
/** Field description */
|
||||
private static final String ID_TRANSACTION_PREFIX = "-1:";
|
||||
|
||||
@@ -70,6 +86,9 @@ public final class SvnUtil
|
||||
*/
|
||||
private static final char TYPE_UPDATED = 'U';
|
||||
|
||||
/** Field description */
|
||||
private static final String USERAGENT_SVN = "svn/";
|
||||
|
||||
/**
|
||||
* the logger for SvnUtil
|
||||
*/
|
||||
@@ -232,6 +251,39 @@ public final class SvnUtil
|
||||
return changesets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
* @param errorCode
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String createErrorBody(SVNErrorCode errorCode)
|
||||
{
|
||||
StringBuffer xmlBuffer = new StringBuffer();
|
||||
|
||||
SVNXMLUtil.addXMLHeader(xmlBuffer);
|
||||
|
||||
List<String> namespaces = Lists.newArrayList(DAVElement.DAV_NAMESPACE,
|
||||
DAVElement.SVN_APACHE_PROPERTY_NAMESPACE);
|
||||
|
||||
SVNXMLUtil.openNamespaceDeclarationTag(SVNXMLUtil.DAV_NAMESPACE_PREFIX,
|
||||
DAVXMLUtil.SVN_DAV_ERROR_TAG, namespaces, SVNXMLUtil.PREFIX_MAP,
|
||||
xmlBuffer);
|
||||
|
||||
SVNXMLUtil.openXMLTag(SVNXMLUtil.SVN_APACHE_PROPERTY_PREFIX,
|
||||
"human-readable", SVNXMLUtil.XML_STYLE_NORMAL, "errcode",
|
||||
String.valueOf(errorCode.getCode()), xmlBuffer);
|
||||
xmlBuffer.append(
|
||||
SVNEncodingUtil.xmlEncodeCDATA(errorCode.getDescription()));
|
||||
SVNXMLUtil.closeXMLTag(SVNXMLUtil.SVN_APACHE_PROPERTY_PREFIX,
|
||||
"human-readable", xmlBuffer);
|
||||
SVNXMLUtil.closeXMLTag(SVNXMLUtil.DAV_NAMESPACE_PREFIX,
|
||||
DAVXMLUtil.SVN_DAV_ERROR_TAG, xmlBuffer);
|
||||
|
||||
return xmlBuffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -266,6 +318,39 @@ public final class SvnUtil
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @param statusCode
|
||||
* @param errorCode
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void sendError(HttpServletRequest request,
|
||||
HttpServletResponse response, int statusCode, SVNErrorCode errorCode)
|
||||
throws IOException
|
||||
{
|
||||
HttpUtil.drainBody(request);
|
||||
|
||||
response.setStatus(statusCode);
|
||||
response.setContentType(XML_CONTENT_TYPE);
|
||||
|
||||
PrintWriter writer = null;
|
||||
|
||||
try
|
||||
{
|
||||
writer = response.getWriter();
|
||||
writer.println(createErrorBody(errorCode));
|
||||
}
|
||||
finally
|
||||
{
|
||||
Closeables.close(writer, true);
|
||||
}
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -311,6 +396,19 @@ public final class SvnUtil
|
||||
return id.substring(ID_TRANSACTION_PREFIX.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param request
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static boolean isSvnClient(HttpServletRequest request)
|
||||
{
|
||||
return HttpUtil.userAgentStartsWith(request, USERAGENT_SVN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* 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.config.ScmConfiguration;
|
||||
import sonia.scm.repository.SvnUtil;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
import sonia.scm.web.filter.AutoLoginModule;
|
||||
import sonia.scm.web.filter.BasicAuthenticationFilter;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@Singleton
|
||||
public class SvnBasicAuthenticationFilter extends BasicAuthenticationFilter
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param configuration
|
||||
* @param autoLoginModules
|
||||
*/
|
||||
@Inject
|
||||
public SvnBasicAuthenticationFilter(ScmConfiguration configuration,
|
||||
Set<AutoLoginModule> autoLoginModules)
|
||||
{
|
||||
super(configuration, autoLoginModules);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Sends unauthorized instead of forbidden for svn clients, because the
|
||||
* svn client prompts again for authentication.
|
||||
*
|
||||
*
|
||||
* @param request http request
|
||||
* @param response http response
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
protected void sendFailedAuthenticationError(HttpServletRequest request,
|
||||
HttpServletResponse response)
|
||||
throws IOException
|
||||
{
|
||||
if (SvnUtil.isSvnClient(request))
|
||||
{
|
||||
HttpUtil.sendUnauthorized(response, configuration.getRealmDescription());
|
||||
}
|
||||
else
|
||||
{
|
||||
super.sendFailedAuthenticationError(request, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,15 +39,21 @@ import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import sonia.scm.ClientMessages;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.repository.RepositoryProvider;
|
||||
import sonia.scm.repository.ScmSvnErrorCode;
|
||||
import sonia.scm.repository.SvnUtil;
|
||||
import sonia.scm.web.filter.ProviderPermissionFilter;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -58,22 +64,16 @@ public class SvnPermissionFilter extends ProviderPermissionFilter
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static Set<String> WRITEMETHOD_SET = ImmutableSet.of("MKACTIVITY",
|
||||
"PROPPATCH", "PUT",
|
||||
"CHECKOUT", "MKCOL", "MOVE",
|
||||
"COPY", "DELETE", "LOCK",
|
||||
"UNLOCK", "MERGE");
|
||||
private static final Set<String> WRITEMETHOD_SET =
|
||||
ImmutableSet.of("MKACTIVITY", "PROPPATCH", "PUT", "CHECKOUT", "MKCOL",
|
||||
"MOVE", "COPY", "DELETE", "LOCK", "UNLOCK", "MERGE");
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param configuration
|
||||
* @param securityContextProvider
|
||||
* @param repository
|
||||
*/
|
||||
@Inject
|
||||
@@ -83,6 +83,41 @@ public class SvnPermissionFilter extends ProviderPermissionFilter
|
||||
super(configuration, repository);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
protected void sendNotEnoughPrivilegesError(HttpServletRequest request,
|
||||
HttpServletResponse response)
|
||||
throws IOException
|
||||
{
|
||||
if (SvnUtil.isSvnClient(request))
|
||||
{
|
||||
//J-
|
||||
SvnUtil.sendError(
|
||||
request,
|
||||
response,
|
||||
HttpServletResponse.SC_FORBIDDEN,
|
||||
ScmSvnErrorCode.authzNotEnoughPrivileges(
|
||||
ClientMessages.get(request).notEnoughPrivileges()
|
||||
)
|
||||
);
|
||||
//J+
|
||||
}
|
||||
else
|
||||
{
|
||||
super.sendNotEnoughPrivilegesError(request, response);
|
||||
}
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
||||
@@ -69,7 +69,7 @@ public class SvnServletModule extends ServletModule
|
||||
protected void configureServlets()
|
||||
{
|
||||
filter(PATTERN_SVN).through(SvnGZipFilter.class);
|
||||
filter(PATTERN_SVN).through(BasicAuthenticationFilter.class);
|
||||
filter(PATTERN_SVN).through(SvnBasicAuthenticationFilter.class);
|
||||
filter(PATTERN_SVN).through(SvnPermissionFilter.class);
|
||||
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
|
||||
@@ -164,13 +164,7 @@
|
||||
<dependency>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
<version>1.8.3</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<version>1.9.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -179,6 +173,17 @@
|
||||
<version>3.2.1</version>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
fix installation of httpasswd-plugin
|
||||
https://groups.google.com/d/topic/scmmanager/eN7UtG8TwW8/discussion
|
||||
-->
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.9</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
@@ -300,12 +305,6 @@
|
||||
<artifactId>selenium-java</artifactId>
|
||||
<version>${selenium.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -327,12 +326,22 @@
|
||||
<artifactId>jersey-apache-client</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- global excludes -->
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<version>1.1.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.17</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
@@ -503,20 +512,6 @@
|
||||
|
||||
<profiles>
|
||||
|
||||
<profile>
|
||||
<id>cluster</id>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>sonia.scm</groupId>
|
||||
<artifactId>scm-dao-orientdb</artifactId>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>release</id>
|
||||
|
||||
|
||||
@@ -35,42 +35,47 @@ package sonia.scm.plugin;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.sonatype.aether.artifact.Artifact;
|
||||
import org.sonatype.aether.graph.DependencyFilter;
|
||||
import org.sonatype.aether.graph.DependencyNode;
|
||||
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class AetherDependencyFilter implements DependencyFilter
|
||||
public abstract class AbstractDependencyFilter implements DependencyFilter
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
public static final String EXCLUDE_LIST = "/config/dependencies.list";
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
* the logger for AbstractDependencyFilter
|
||||
*/
|
||||
public AetherDependencyFilter()
|
||||
{
|
||||
loadExcludes();
|
||||
}
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(AbstractDependencyFilter.class);
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
protected abstract Set<String> loadExcludeSet() throws IOException;
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -91,62 +96,44 @@ public class AetherDependencyFilter implements DependencyFilter
|
||||
|
||||
if (artifact != null)
|
||||
{
|
||||
result = !exludeSet.contains(getId(artifact));
|
||||
String id = getId(artifact);
|
||||
|
||||
result = !getExludeSet().contains(id);
|
||||
|
||||
if (!result && logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("exlcude dependency {} because it is blacklisted", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private void loadExcludes()
|
||||
private Set<String> getExludeSet()
|
||||
{
|
||||
if (exludeSet == null)
|
||||
{
|
||||
Scanner scanner = null;
|
||||
|
||||
try
|
||||
{
|
||||
scanner = new Scanner(
|
||||
AetherDependencyFilter.class.getResourceAsStream(EXCLUDE_LIST));
|
||||
|
||||
while (scanner.hasNextLine())
|
||||
{
|
||||
parseLine(scanner.nextLine());
|
||||
exludeSet = loadExcludeSet();
|
||||
}
|
||||
}
|
||||
finally
|
||||
catch (IOException ex)
|
||||
{
|
||||
if (scanner != null)
|
||||
{
|
||||
scanner.close();
|
||||
}
|
||||
throw Throwables.propagate(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param line
|
||||
*/
|
||||
private void parseLine(String line)
|
||||
{
|
||||
line = line.trim();
|
||||
|
||||
if (Util.isNotEmpty(line))
|
||||
{
|
||||
String[] parts = line.split(":");
|
||||
|
||||
if (parts.length >= 2)
|
||||
{
|
||||
exludeSet.add(parts[0].concat(":").concat(parts[1]));
|
||||
return exludeSet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
@@ -164,5 +151,5 @@ public class AetherDependencyFilter implements DependencyFilter
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private Set<String> exludeSet = new HashSet<String>();
|
||||
private Set<String> exludeSet;
|
||||
}
|
||||
@@ -57,6 +57,7 @@ import org.sonatype.aether.resolution.DependencyRequest;
|
||||
import org.sonatype.aether.resolution.DependencyResolutionException;
|
||||
import org.sonatype.aether.util.artifact.DefaultArtifact;
|
||||
import org.sonatype.aether.util.artifact.JavaScopes;
|
||||
import org.sonatype.aether.util.filter.AndDependencyFilter;
|
||||
import org.sonatype.aether.util.filter.DependencyFilterUtils;
|
||||
import org.sonatype.aether.util.graph.transformer
|
||||
.ChainedDependencyGraphTransformer;
|
||||
@@ -77,7 +78,11 @@ public final class Aether
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final DependencyFilter FILTER = new AetherDependencyFilter();
|
||||
private static final DependencyFilter FILTER =
|
||||
new AndDependencyFilter(
|
||||
new CoreDependencyFilter(),
|
||||
new BlacklistDependencyFilter()
|
||||
);
|
||||
|
||||
/**
|
||||
* the logger for Aether
|
||||
@@ -167,7 +172,6 @@ public final class Aether
|
||||
*
|
||||
*
|
||||
* @param system
|
||||
* @param repositoryManager
|
||||
* @param localRepository
|
||||
* @param configuration
|
||||
*
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.plugin;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
@@ -116,32 +117,17 @@ public class AetherDependencyResolver
|
||||
*
|
||||
*
|
||||
* @param dependency
|
||||
* @param dependencies
|
||||
*
|
||||
* @throws DependencyCollectionException
|
||||
* @throws DependencyResolutionException
|
||||
*/
|
||||
public void resolveLocalDependency(Dependency dependency)
|
||||
public void resolveDependencies(Dependency dependency,
|
||||
List<Dependency> dependencies)
|
||||
throws DependencyCollectionException, DependencyResolutionException
|
||||
{
|
||||
CollectRequest request = new CollectRequest();
|
||||
|
||||
request.setRoot(dependency);
|
||||
resolveDependency(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param dependency
|
||||
*
|
||||
* @throws DependencyCollectionException
|
||||
* @throws DependencyResolutionException
|
||||
*/
|
||||
public void resolveRemoteDependency(Dependency dependency)
|
||||
throws DependencyCollectionException, DependencyResolutionException
|
||||
{
|
||||
resolveDependency(new CollectRequest(dependency, remoteRepositories));
|
||||
resolveDependency(new CollectRequest(dependency, dependencies,
|
||||
remoteRepositories));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -199,12 +199,7 @@ public class AetherPluginHandler
|
||||
new AetherDependencyResolver(configuration, repositorySystem,
|
||||
localRepository, remoteRepositories);
|
||||
|
||||
resolver.resolveRemoteDependency(dependency);
|
||||
|
||||
for (Dependency localDependency : localDependencies)
|
||||
{
|
||||
resolver.resolveLocalDependency(localDependency);
|
||||
}
|
||||
resolver.resolveDependencies(dependency, localDependencies);
|
||||
|
||||
if (classpath == null)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class BlacklistDependencyFilter extends AbstractDependencyFilter
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final String BLACKLIST = "/config/blacklist.list";
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
protected Set<String> loadExcludeSet() throws IOException
|
||||
{
|
||||
return DependencyFilters.loadDependencySet(BLACKLIST);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class CoreDependencyFilter extends AbstractDependencyFilter
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final String CORE_DEPENDENCIES = "/config/dependencies.list";
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
protected Set<String> loadExcludeSet() throws IOException
|
||||
{
|
||||
return DependencyFilters.loadDependencySet(CORE_DEPENDENCIES);
|
||||
}
|
||||
}
|
||||
110
scm-webapp/src/main/java/sonia/scm/plugin/DependencyFilters.java
Normal file
110
scm-webapp/src/main/java/sonia/scm/plugin/DependencyFilters.java
Normal file
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* 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 com.google.common.base.Charsets;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSet.Builder;
|
||||
import com.google.common.io.Resources;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public final class DependencyFilters
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param path
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public static Set<String> loadDependencySet(String path) throws IOException
|
||||
{
|
||||
URL url = Resources.getResource(DependencyFilters.class, path);
|
||||
|
||||
if (url == null)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"could not find dependency set at ".concat(path));
|
||||
}
|
||||
|
||||
Builder<String> builder = ImmutableSet.builder();
|
||||
List<String> lines = Resources.readLines(url, Charsets.UTF_8);
|
||||
|
||||
for (String line : lines)
|
||||
{
|
||||
parseAndAppendLine(builder, line);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param builder
|
||||
* @param line
|
||||
*/
|
||||
private static void parseAndAppendLine(Builder<String> builder, String line)
|
||||
{
|
||||
line = line.trim();
|
||||
|
||||
if (!Strings.isNullOrEmpty(line))
|
||||
{
|
||||
String[] parts = line.split(":");
|
||||
|
||||
if (parts.length >= 2)
|
||||
{
|
||||
builder.add(parts[0].concat(":").concat(parts[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
scm-webapp/src/main/resources/config/blacklist.list
Normal file
10
scm-webapp/src/main/resources/config/blacklist.list
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
The following dependencies are blacklisted
|
||||
commons-logging:commons-logging
|
||||
log4j:log4j
|
||||
junit:junit
|
||||
org.mockito:mockito-core
|
||||
org.mockito:mockito-all
|
||||
org.mockito:mockito-junit
|
||||
org.testng:testng
|
||||
org.powermock:powermock
|
||||
@@ -64,9 +64,7 @@ Sonia.action.ChangePasswordWindow = Ext.extend(Ext.Window,{
|
||||
name: 'old-password',
|
||||
fieldLabel: this.oldPasswordText,
|
||||
inputType: 'password',
|
||||
allowBlank: false,
|
||||
minLength: 6,
|
||||
maxLength: 32
|
||||
allowBlank: false
|
||||
},{
|
||||
id: 'new-password',
|
||||
name: 'new-password',
|
||||
|
||||
@@ -75,7 +75,7 @@ Ext.apply(Ext.form.VTypes, {
|
||||
// username validator
|
||||
|
||||
username: function(val){
|
||||
return name(val);
|
||||
return this.name(val);
|
||||
},
|
||||
|
||||
usernameText: 'The username is invalid.'
|
||||
|
||||
Reference in New Issue
Block a user