merge with branch issue-627

This commit is contained in:
Sebastian Sdorra
2015-02-10 20:50:06 +01:00
18 changed files with 1556 additions and 13 deletions

View File

@@ -0,0 +1,270 @@
/**
* 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.common.base.Charsets;
import com.google.common.base.Objects;
import static com.google.common.base.Preconditions.*;
//~--- JDK imports ------------------------------------------------------------
import java.nio.charset.Charset;
/**
*
* @author Sebastian Sdorra <s.sdorra@gmail.com>
* @since 1.45
*/
public final class UserAgent
{
/**
* Constructs ...
*
*
* @param name
* @param browser
* @param basicAuthenticationCharset
*/
private UserAgent(String name, boolean browser,
Charset basicAuthenticationCharset)
{
this.name = checkNotNull(name);
this.browser = browser;
this.basicAuthenticationCharset = checkNotNull(basicAuthenticationCharset);
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param name
*
* @return
*/
public static Builder builder(String name)
{
return new Builder(name);
}
/**
* Method description
*
*
* @param obj
*
* @return
*/
@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final UserAgent other = (UserAgent) obj;
return Objects.equal(name, other.name)
&& Objects.equal(browser, other.browser)
&& Objects.equal(basicAuthenticationCharset, basicAuthenticationCharset);
}
/**
* Method description
*
*
* @return
*/
@Override
public int hashCode()
{
return Objects.hashCode(name, browser, basicAuthenticationCharset);
}
/**
* Method description
*
*
* @return
*/
@Override
public String toString()
{
//J-
return Objects.toStringHelper(this)
.add("name", name)
.add("browser", browser)
.add("basicAuthenticationCharset", basicAuthenticationCharset)
.toString();
//J+
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public Charset getBasicAuthenticationCharset()
{
return basicAuthenticationCharset;
}
/**
* Method description
*
*
* @return
*/
public String getName()
{
return name;
}
/**
* Method description
*
*
* @return
*/
public boolean isBrowser()
{
return browser;
}
//~--- inner classes --------------------------------------------------------
/**
* Class description
*
*
* @version Enter version here..., 14/10/15
* @author Enter your name here...
*/
public static class Builder
{
/**
* Constructs ...
*
*
* @param name
*/
public Builder(String name)
{
this.name = name;
}
//~--- methods ------------------------------------------------------------
/**
* Method description
*
*
* @param basicAuthenticationCharset
*
* @return
*/
public Builder basicAuthenticationCharset(
Charset basicAuthenticationCharset)
{
this.basicAuthenticationCharset =
checkNotNull(basicAuthenticationCharset);
return this;
}
/**
* Method description
*
*
* @param browser
*
* @return
*/
public Builder browser(boolean browser)
{
this.browser = browser;
return this;
}
/**
* Method description
*
*
* @return
*/
public UserAgent build()
{
return new UserAgent(name, browser, basicAuthenticationCharset);
}
//~--- fields -------------------------------------------------------------
/** Field description */
private final String name;
/** Field description */
private boolean browser = true;
/** Field description */
private Charset basicAuthenticationCharset = Charsets.ISO_8859_1;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private final Charset basicAuthenticationCharset;
/** Field description */
private final boolean browser;
/** Field description */
private final String name;
}

View File

@@ -0,0 +1,156 @@
/**
* 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.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.cache.Cache;
import sonia.scm.cache.CacheManager;
import sonia.scm.util.HttpUtil;
//~--- JDK imports ------------------------------------------------------------
import java.util.Locale;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
/**
*
* @author Sebastian Sdorra <s.sdorra@gmail.com>
* @since 1.45
*/
@Singleton
public final class UserAgentParser
{
/** Field description */
@VisibleForTesting
static final String CACHE_NAME = "sonia.scm.user-agent";
/** Field description */
@VisibleForTesting
static final UserAgent UNKNOWN = UserAgent.builder("UNKNOWN").build();
/** Field description */
private static final Logger logger =
LoggerFactory.getLogger(UserAgentParser.class);
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*
* @param providers
* @param cacheManager
*/
@Inject
public UserAgentParser(Set<UserAgentProvider> providers,
CacheManager cacheManager)
{
this.providers = providers;
this.cache = cacheManager.getCache(String.class, UserAgent.class,
CACHE_NAME);
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param request
*
* @return
*/
public UserAgent parse(HttpServletRequest request)
{
return parse(request.getHeader(HttpUtil.HEADER_USERAGENT));
}
/**
* Method description
*
*
* @param userAgent
*
* @return
*/
public UserAgent parse(String userAgent)
{
String uas = Strings.nullToEmpty(userAgent).toLowerCase(Locale.ENGLISH);
UserAgent ua = cache.get(uas);
if (ua == null)
{
for (UserAgentProvider provider : providers)
{
ua = provider.parseUserAgent(uas);
if (ua != null)
{
break;
}
}
if (ua == null)
{
ua = UNKNOWN;
}
// cache.put(uas, ua);
}
logger.trace("return user-agent {} for {}", ua, userAgent);
return ua;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private final Cache<String, UserAgent> cache;
/** Field description */
private final Set<UserAgentProvider> providers;
}

View File

@@ -0,0 +1,56 @@
/**
* 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;
import sonia.scm.plugin.ExtensionPoint;
/**
*
* @author Sebastian Sdorra <sebastian.sdorra@gmail.com>
* @since 1.45
*/
@ExtensionPoint(multi = true)
public interface UserAgentProvider
{
/**
* Method description
*
*
* @param userAgentString
*
* @return
*/
public UserAgent parseUserAgent(String userAgentString);
}

View File

@@ -35,6 +35,7 @@ package sonia.scm.web.filter;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.base.Charsets;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@@ -51,6 +52,7 @@ import sonia.scm.SCMContext;
import sonia.scm.config.ScmConfiguration;
import sonia.scm.user.User;
import sonia.scm.util.HttpUtil;
import sonia.scm.web.UserAgentParser;
import sonia.scm.util.Util;
import sonia.scm.web.security.WebSecurityContext;
@@ -59,6 +61,9 @@ import sonia.scm.web.security.WebSecurityContext;
import com.sun.jersey.core.util.Base64;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Set;
@@ -66,6 +71,7 @@ import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import sonia.scm.web.UserAgent;
/**
*
@@ -87,6 +93,9 @@ public class BasicAuthenticationFilter extends AutoLoginFilter
/** marker for failed authentication */
private static final String ATTRIBUTE_FAILED_AUTH = "sonia.scm.auth.failed";
/** default encoding to decode basic authentication header */
public static final Charset DEFAULT_ENCODING = Charsets.ISO_8859_1;
/** the logger for BasicAuthenticationFilter */
private static final Logger logger =
LoggerFactory.getLogger(BasicAuthenticationFilter.class);
@@ -94,11 +103,13 @@ public class BasicAuthenticationFilter extends AutoLoginFilter
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
* Constructs a new basic authenticaton filter
*
*
* @param securityContextProvider
* @deprecated use the constructor with out arguments instead.
* @deprecated use
* {@link #BasicAuthenticationFilter(ScmConfiguration, Set, UserAgentParser)
* instead
*/
@Deprecated
public BasicAuthenticationFilter(
@@ -111,17 +122,68 @@ public class BasicAuthenticationFilter extends AutoLoginFilter
* @param autoLoginModules auto login modules
*
* @since 1.21
*
* @deprecated use
* {@link #BasicAuthenticationFilter(ScmConfiguration, Set, UserAgentParser)
* instead
*/
@Inject
@Deprecated
public BasicAuthenticationFilter(ScmConfiguration configuration,
Set<AutoLoginModule> autoLoginModules)
{
this(configuration, autoLoginModules, null);
}
/**
* Constructs a new basic authentication filter
*
* @param configuration scm-manager global configuration
* @param autoLoginModules auto login modules
* @param userAgentParser parser for user-agent header
*
* @since 1.42
*/
@Inject
public BasicAuthenticationFilter(ScmConfiguration configuration,
Set<AutoLoginModule> autoLoginModules, UserAgentParser userAgentParser)
{
super(autoLoginModules);
this.configuration = configuration;
this.userAgentParser = userAgentParser;
}
//~--- methods --------------------------------------------------------------
/**
* Decode base64 of the basic authentication header. The method will use
* the charset provided by the {@link UserAgent}, if the
* {@link UserAgentParser} is not available the method will be fall back to
* ISO-8859-1.
*
* @param request http request
* @param authentication base64 encoded basic authentication string
*
* @return decoded basic authentication header
*
* @see <a href="http://goo.gl/tZEBS3">issue 627</a>
* @see <a href="http://goo.gl/NhbZ2F">Stackoverflow Basic Authentication</a>
*
* @throws UnsupportedEncodingException
*/
protected String decodeAuthenticationHeader(HttpServletRequest request,
String authentication)
throws UnsupportedEncodingException
{
Charset encoding = DEFAULT_ENCODING;
if (userAgentParser != null)
{
encoding = userAgentParser.parse(request).getBasicAuthenticationCharset();
}
return new String(Base64.decode(authentication), encoding);
}
/**
* Method description
*
@@ -228,13 +290,15 @@ public class BasicAuthenticationFilter extends AutoLoginFilter
* @param authentication
*
* @return
*
* @throws IOException
*/
private User authenticate(HttpServletRequest request,
HttpServletResponse response, Subject subject, String authentication)
throws IOException
{
String token = authentication.substring(6);
token = new String(Base64.decode(token.getBytes()));
String token = decodeAuthenticationHeader(request,
authentication.substring(6));
int index = token.indexOf(CREDENTIAL_SEPARATOR);
User user = null;
@@ -365,4 +429,7 @@ public class BasicAuthenticationFilter extends AutoLoginFilter
/** scm main configuration */
protected ScmConfiguration configuration;
/** Field description */
protected UserAgentParser userAgentParser;
}

View File

@@ -0,0 +1,188 @@
/**
* 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.common.base.Charsets;
import com.google.common.collect.Sets;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import sonia.scm.cache.Cache;
import sonia.scm.cache.CacheManager;
import sonia.scm.util.HttpUtil;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
//~--- JDK imports ------------------------------------------------------------
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
/**
*
* @author Sebastian Sdorra <sebastian.sdorra@triology.de>
*/
@RunWith(MockitoJUnitRunner.class)
public class UserAgentParserTest
{
/** Field description */
private static final String UA_1 = "mozilla/5.0";
/** Field description */
private static final String UA_2 = "wget/1.5.3";
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*/
@Before
public void prepare()
{
Set<UserAgentProvider> providers = Sets.newHashSet(provider1, provider2);
when(cacheManager.getCache(String.class, UserAgent.class,
UserAgentParser.CACHE_NAME)).thenReturn(cache);
parser = new UserAgentParser(providers, cacheManager);
}
/**
* Method description
*
*/
@Test
public void testDefaultValues()
{
UserAgent ua = parser.parse(UA_1);
assertEquals(Charsets.ISO_8859_1, ua.getBasicAuthenticationCharset());
assertTrue(ua.isBrowser());
}
/**
* Method description
*
*/
@Test
public void testParse()
{
UserAgent ua = UserAgent.builder("UA1").build();
when(provider1.parseUserAgent(UA_1)).thenReturn(ua);
UserAgent ua2 = UserAgent.builder("UA2").build();
when(provider2.parseUserAgent(UA_2)).thenReturn(ua2);
assertEquals(ua, parser.parse(UA_1));
assertEquals(ua2, parser.parse(UA_2));
}
/**
* Method description
*
*/
@Test
public void testParseHttpServletRequest()
{
when(request.getHeader(HttpUtil.HEADER_USERAGENT)).thenReturn(UA_2);
UserAgent ua = UserAgent.builder("UA2").build();
when(provider1.parseUserAgent(UA_2)).thenReturn(ua);
assertEquals(ua, parser.parse(request));
}
/**
* Method description
*
*/
@Test
public void testParseNotFound()
{
assertEquals(UserAgentParser.UNKNOWN, parser.parse(UA_1));
assertEquals(UserAgentParser.UNKNOWN, parser.parse(UA_2));
}
/**
* Method description
*
*/
@Test
public void testParseWithCache()
{
UserAgent ua = UserAgent.builder("UA").build();
when(cache.get(UA_1)).thenReturn(ua);
assertEquals(ua, parser.parse(UA_1));
assertEquals(UserAgentParser.UNKNOWN, parser.parse(UA_2));
}
//~--- fields ---------------------------------------------------------------
/** Field description */
@Mock
private Cache<String, UserAgent> cache;
/** Field description */
@Mock
private CacheManager cacheManager;
/** Field description */
private UserAgentParser parser;
/** Field description */
@Mock
private UserAgentProvider provider1;
/** Field description */
@Mock
private UserAgentProvider provider2;
/** Field description */
@Mock
private HttpServletRequest request;
}

View File

@@ -67,12 +67,13 @@ public class GitBasicAuthenticationFilter extends BasicAuthenticationFilter
*
* @param configuration
* @param autoLoginModules
* @param userAgentParser
*/
@Inject
public GitBasicAuthenticationFilter(ScmConfiguration configuration,
Set<AutoLoginModule> autoLoginModules)
Set<AutoLoginModule> autoLoginModules, UserAgentParser userAgentParser)
{
super(configuration, autoLoginModules);
super(configuration, autoLoginModules, userAgentParser);
}
//~--- methods --------------------------------------------------------------

View File

@@ -0,0 +1,97 @@
/**
* 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.common.annotations.VisibleForTesting;
import com.google.common.base.Charsets;
import sonia.scm.plugin.ext.Extension;
/**
*
* @author Sebastian Sdorra <sebastian.sdorra@gmail.com>
* @since 1.45
*/
@Extension
public class GitUserAgentProvider implements UserAgentProvider
{
/** Field description */
@VisibleForTesting
static final UserAgent GIT = UserAgent.builder("Git").browser(
false).basicAuthenticationCharset(
Charsets.UTF_8).build();
/** Field description */
@VisibleForTesting
static final UserAgent MSYSGIT = UserAgent.builder("msysGit").browser(
false).basicAuthenticationCharset(
Charsets.UTF_8).build();
/** Field description */
private static final String PREFIX = "git/";
/** Field description */
private static final String SUFFIX = "msysgit";
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param userAgentString
*
* @return
*/
@Override
public UserAgent parseUserAgent(String userAgentString)
{
UserAgent ua = null;
if (userAgentString.startsWith(PREFIX))
{
if (userAgentString.contains(SUFFIX))
{
ua = MSYSGIT;
}
else
{
ua = GIT;
}
}
return ua;
}
}

View File

@@ -0,0 +1,83 @@
/**
* 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.common.base.Strings;
import org.junit.Test;
import static org.junit.Assert.*;
//~--- JDK imports ------------------------------------------------------------
import java.util.Locale;
/**
*
* @author Sebastian Sdorra <sebastian.sdorra@triology.de>
*/
public class GitUserAgentProviderTest
{
/**
* Method description
*
*/
@Test
public void testParseUserAgent()
{
assertEquals(GitUserAgentProvider.GIT, parse("git/1.7.9.5"));
assertEquals(GitUserAgentProvider.MSYSGIT, parse("git/1.8.3.msysgit.0"));
assertNull(parse("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36"));
}
/**
* Method description
*
*
* @param v
*
* @return
*/
private UserAgent parse(String v)
{
return provider.parseUserAgent(
Strings.nullToEmpty(v).toLowerCase(Locale.ENGLISH));
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private final GitUserAgentProvider provider = new GitUserAgentProvider();
}

View File

@@ -63,12 +63,13 @@ public class HgBasicAuthenticationFilter extends BasicAuthenticationFilter
*
* @param configuration
* @param autoLoginModules
* @param userAgentParser
*/
@Inject
public HgBasicAuthenticationFilter(ScmConfiguration configuration,
Set<AutoLoginModule> autoLoginModules)
Set<AutoLoginModule> autoLoginModules, UserAgentParser userAgentParser)
{
super(configuration, autoLoginModules);
super(configuration, autoLoginModules, userAgentParser);
}
//~--- methods --------------------------------------------------------------

View File

@@ -0,0 +1,84 @@
/**
* 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.common.annotations.VisibleForTesting;
import sonia.scm.plugin.ext.Extension;
//~--- JDK imports ------------------------------------------------------------
import java.nio.charset.Charset;
/**
*
* @author Sebastian Sdorra <s.sdorra@gmail.com>
* @since 1.45
*/
@Extension
public class HgUserAgentProvider implements UserAgentProvider
{
/** mercurial seems to use system encoding */
@VisibleForTesting
static UserAgent HG = UserAgent.builder("Mercurial").browser(
false).basicAuthenticationCharset(
Charset.defaultCharset()).build();
/** Field description */
private static final String PREFIX = "mercurial";
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param userAgentString
*
* @return
*/
@Override
public UserAgent parseUserAgent(String userAgentString)
{
UserAgent ua = null;
if (userAgentString.startsWith(PREFIX))
{
ua = HG;
}
return ua;
}
}

View File

@@ -0,0 +1,91 @@
/**
* 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.common.base.Strings;
import org.junit.Test;
import static org.junit.Assert.*;
//~--- JDK imports ------------------------------------------------------------
import java.util.Locale;
/**
*
* @author Sebastian Sdorra <sebastian.sdorra@triology.de>
*/
public class HgUserAgentProviderTest
{
/** Field description */
private static final String UA_1 = "mercurial/proto-1.0";
/** Field description */
private static final String UA_2 =
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36";
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*/
@Test
public void testParseUserAgent()
{
assertEquals(HgUserAgentProvider.HG, parse(UA_1));
assertNull(parse(UA_2));
}
/**
* Method description
*
*
* @param v
*
* @return
*/
private UserAgent parse(String v)
{
return provider.parseUserAgent(
Strings.nullToEmpty(v).toLowerCase(Locale.ENGLISH));
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private final HgUserAgentProvider provider = new HgUserAgentProvider();
}

View File

@@ -65,12 +65,13 @@ public class SvnBasicAuthenticationFilter extends BasicAuthenticationFilter
*
* @param configuration
* @param autoLoginModules
* @param userAgentParser
*/
@Inject
public SvnBasicAuthenticationFilter(ScmConfiguration configuration,
Set<AutoLoginModule> autoLoginModules)
Set<AutoLoginModule> autoLoginModules, UserAgentParser userAgentParser)
{
super(configuration, autoLoginModules);
super(configuration, autoLoginModules, userAgentParser);
}
//~--- methods --------------------------------------------------------------

View File

@@ -0,0 +1,97 @@
/**
* 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.common.annotations.VisibleForTesting;
import com.google.common.base.Charsets;
import sonia.scm.plugin.ext.Extension;
/**
*
* @author Sebastian Sdorra <s.sdorra@gmail.com>
* @since 1.45
*/
@Extension
public final class SvnUserAgentProvider implements UserAgentProvider
{
/** ua prefix */
private static final String PREFIX = "svn";
/** ua suffix */
private static final String SUFFIX = "tortoisesvn";
/** TortoiseSVN */
@VisibleForTesting
static final UserAgent TORTOISE_SVN =
UserAgent.builder("TortoiseSVN").browser(false)
.basicAuthenticationCharset(Charsets.UTF_8).build();
/** Subversion cli client */
@VisibleForTesting
static final UserAgent SVN =
UserAgent.builder("Subversion").browser(false)
.basicAuthenticationCharset(Charsets.UTF_8).build();
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param userAgentString
*
* @return
*/
@Override
public UserAgent parseUserAgent(String userAgentString)
{
UserAgent ua = null;
if (userAgentString.startsWith(PREFIX))
{
if (userAgentString.contains(SUFFIX))
{
ua = TORTOISE_SVN;
}
else
{
ua = SVN;
}
}
return ua;
}
}

View File

@@ -0,0 +1,98 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import org.junit.Test;
import static org.junit.Assert.*;
//~--- JDK imports ------------------------------------------------------------
import java.util.Locale;
/**
*
* @author Sebastian Sdorra <sebastian.sdorra@triology.de>
*/
public class SvnUserAgentProviderTest
{
/** Field description */
private static final String UA_1 =
"SVN/1.8.8 (x64-microsoft-windows) serf/1.3.4 TortoiseSVN-1.8.6.25419";
/** Field description */
private static final String UA_2 = "SVN/1.5.4 (r33841) neon/0.28.3";
/** Field description */
private static final String UA_3 = "SVN/1.6.3 (r38063) neon/0.28.4";
/** Field description */
private static final String UA_4 =
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0;Google Wireless Transcoder;)";
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*/
@Test
public void testParseUserAgent()
{
assertEquals(SvnUserAgentProvider.TORTOISE_SVN, parse(UA_1));
assertEquals(SvnUserAgentProvider.SVN, parse(UA_2));
assertEquals(SvnUserAgentProvider.SVN, parse(UA_3));
assertNull(parse(UA_4));
}
/**
* Method description
*
*
* @param ua
*
* @return
*/
private UserAgent parse(String ua)
{
return suap.parseUserAgent(ua.toLowerCase(Locale.ENGLISH));
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private final SvnUserAgentProvider suap = new SvnUserAgentProvider();
}

View File

@@ -157,6 +157,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import sonia.scm.web.UserAgentParser;
/**
*
@@ -343,6 +344,9 @@ public class ScmServletModule extends ServletModule
bind(HookContextFactory.class);
bind(HookEventFacade.class);
// bind user-agent parser
bind(UserAgentParser.class);
// bind debug logging filter
if ("true".equalsIgnoreCase(System.getProperty(SYSTEM_PROPERTY_DEBUG_HTTP)))
{

View File

@@ -80,6 +80,7 @@ import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionListener;
import javax.xml.bind.JAXB;
import sonia.scm.web.BrowserUserAgentProvider;
/**
*
@@ -586,6 +587,12 @@ public class DefaultPluginLoader implements PluginLoader
DefaultAuthenticationHandler.class
)
);
extensions.add(
new AnnotatedClass<Extension>(
Extensions.createExtension(),
BrowserUserAgentProvider.class
)
);
//J+
}

View File

@@ -0,0 +1,128 @@
/**
* 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.common.annotations.VisibleForTesting;
import com.google.common.base.Charsets;
import sonia.scm.plugin.ext.Extension;
/**
*
* @author Sebastian Sdorra <s.sdorra@gmail.com>
*/
@Extension
public class BrowserUserAgentProvider implements UserAgentProvider
{
/** Field description */
@VisibleForTesting
static final UserAgent CHROME = UserAgent.builder(
"Chrome").basicAuthenticationCharset(
Charsets.UTF_8).build();
/** Field description */
private static final String CHROME_PATTERN = "chrome";
/** Field description */
@VisibleForTesting
static final UserAgent FIREFOX = UserAgent.builder("Firefox").build();
/** Field description */
private static final String FIREFOX_PATTERN = "firefox";
/** Field description */
@VisibleForTesting
static final UserAgent MSIE = UserAgent.builder("Internet Explorer").build();
/** Field description */
private static final String MSIE_PATTERN = "msie";
/** Field description */
@VisibleForTesting // todo check charset
static final UserAgent SAFARI = UserAgent.builder("Safari").build();
/** Field description */
private static final String OPERA_PATTERN = "opera";
/** Field description */
private static final String SAFARI_PATTERN = "safari";
/** Field description */
@VisibleForTesting // todo check charset
static final UserAgent OPERA = UserAgent.builder(
"Opera").basicAuthenticationCharset(
Charsets.UTF_8).build();
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param userAgentString
*
* @return
*/
@Override
public UserAgent parseUserAgent(String userAgentString)
{
UserAgent ua = null;
if (userAgentString.contains(CHROME_PATTERN))
{
ua = CHROME;
}
else if (userAgentString.contains(FIREFOX_PATTERN))
{
ua = FIREFOX;
}
else if (userAgentString.contains(OPERA_PATTERN))
{
ua = OPERA;
}
else if (userAgentString.contains(MSIE_PATTERN))
{
ua = MSIE;
}
else if (userAgentString.contains(SAFARI_PATTERN))
{
ua = SAFARI;
}
return ua;
}
}

View File

@@ -0,0 +1,114 @@
/**
* 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.common.base.Strings;
import org.junit.Test;
import static org.junit.Assert.*;
//~--- JDK imports ------------------------------------------------------------
import java.util.Locale;
/**
*
* @author Sebastian Sdorra <sebastian.sdorra@triology.de>
*/
public class BrowserUserAgentProviderTest
{
/** Field description */
private static final String CHROME =
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36";
/** Field description */
private static final String FIREFOX =
"Mozilla/5.0 (Windows; U; Windows NT 5.2; en-GB; rv:1.8.1.18) Gecko/20081029 Firefox/2.0.0.18";
/** Field description */
private static final String MSIE =
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; )";
/** Field description */
private static final String OPERA =
"Opera/9.80 (Windows NT 5.1; U; cs) Presto/2.2.15 Version/10.00";
/** Field description */
private static final String SAFARI =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/6.1.3 Safari/537.75.14";
/** Field description */
private static final String WGET = "Wget/1.5.3";
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*/
@Test
public void testParseUserAgent()
{
assertEquals(BrowserUserAgentProvider.MSIE, parse(MSIE));
assertEquals(BrowserUserAgentProvider.FIREFOX, parse(FIREFOX));
assertEquals(BrowserUserAgentProvider.OPERA, parse(OPERA));
assertEquals(BrowserUserAgentProvider.CHROME, parse(CHROME));
assertEquals(BrowserUserAgentProvider.SAFARI, parse(SAFARI));
assertNull(parse(WGET));
}
/**
* Method description
*
*
* @param v
*
* @return
*/
private UserAgent parse(String v)
{
return provider.parseUserAgent(
Strings.nullToEmpty(v).toLowerCase(Locale.ENGLISH));
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private final BrowserUserAgentProvider provider =
new BrowserUserAgentProvider();
}