Repository: archiva-redback-core
Updated Branches:
  refs/heads/feature/header_check [created] e9bc48188


Implementing Header verification for REST API calls

Implementing header verification techniques mentioned in:
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#Verifying_Same_Origin_with_Standard_Headers


Project: http://git-wip-us.apache.org/repos/asf/archiva-redback-core/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/archiva-redback-core/commit/95f1b3e4
Tree: http://git-wip-us.apache.org/repos/asf/archiva-redback-core/tree/95f1b3e4
Diff: http://git-wip-us.apache.org/repos/asf/archiva-redback-core/diff/95f1b3e4

Branch: refs/heads/feature/header_check
Commit: 95f1b3e4307fb7d407ad0cb83869af2564a1aae8
Parents: 78d822d
Author: Martin Stockhammer <marti...@apache.org>
Authored: Mon Jan 30 20:37:15 2017 +0100
Committer: Martin Stockhammer <marti...@apache.org>
Committed: Mon Jan 30 20:37:15 2017 +0100

----------------------------------------------------------------------
 .../archiva/redback/config-defaults.properties  |   6 +
 .../RequestValidationInterceptor.java           | 213 +++++++++++++++++++
 .../main/resources/META-INF/spring-context.xml  |   1 +
 .../rest/services/AbstractRestServicesTest.java |   5 +
 .../RequestValidationInterceptorTest.java       | 162 ++++++++++++++
 .../redback/rest/services/UserServiceTest.java  |   3 +
 .../mock/MockContainerRequestContext.java       | 175 +++++++++++++++
 .../services/mock/MockUserConfiguration.java    | 105 +++++++++
 8 files changed, 670 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/95f1b3e4/redback-configuration/src/main/resources/org/apache/archiva/redback/config-defaults.properties
----------------------------------------------------------------------
diff --git 
a/redback-configuration/src/main/resources/org/apache/archiva/redback/config-defaults.properties
 
b/redback-configuration/src/main/resources/org/apache/archiva/redback/config-defaults.properties
index 402aaf9..9fa02ce 100644
--- 
a/redback-configuration/src/main/resources/org/apache/archiva/redback/config-defaults.properties
+++ 
b/redback-configuration/src/main/resources/org/apache/archiva/redback/config-defaults.properties
@@ -133,4 +133,10 @@ ldap.bind.authenticator.enabled=false
 user.manager.impl=jdo
 
 
+# REST security settings
 
+# REST base url is for avoiding CSRF attacks
+# If it is not set or empty it tries to determine the base url automatically
+rest.baseUrl=
+# If true, requests without Origin or Referer Header are denied
+rest.csrf.absentorigin.deny=true
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/95f1b3e4/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/RequestValidationInterceptor.java
----------------------------------------------------------------------
diff --git 
a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/RequestValidationInterceptor.java
 
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/RequestValidationInterceptor.java
new file mode 100644
index 0000000..4300baf
--- /dev/null
+++ 
b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/RequestValidationInterceptor.java
@@ -0,0 +1,213 @@
+package org.apache.archiva.redback.rest.services.interceptors;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import org.apache.archiva.redback.configuration.UserConfiguration;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.Provider;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * Created by Martin Stockhammer on 19.01.17.
+ *
+ * This interceptor tries to check if requests come from a valid origin and
+ * are not generated by another site on behalf of the real client.
+ *
+ * We are using some of the techniques mentioned in
+ * 
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet
+ *
+ * Try to find Origin and Referer of the request.
+ * Match them to the target address, that may be either statically configured 
or is determined
+ * by the Host/X-Forwarded-For Header.
+ *
+ *
+ */
+@Provider
+@Service( "requestValidationInterceptor#rest" )
+public class RequestValidationInterceptor extends AbstractInterceptor 
implements ContainerRequestFilter {
+
+
+    private static final String X_FORWARDED_PROTO = "X-Forwarded-Proto";
+    private static final String X_FORWARDED_HOST = "X-Forwarded-Host";
+    private static final String ORIGIN = "Origin";
+    private static final String REFERER = "Referer";
+    private static final String CFG_REST_BASE_URL = "rest.baseUrl";
+    private static final String CFG_REST_CSRF_ABSENTORIGIN_DENY = 
"rest.csrffilter.absentorigin.deny";
+    private static final String CFG_REST_CSRF_ENABLED = 
"rest.csrffilter.enabled";
+
+    private final Logger log = LoggerFactory.getLogger( getClass() );
+
+    private boolean enabled = true;
+    private boolean useStaticUrl = false;
+    private boolean denyAbsentHeaders = true;
+    private URL baseUrl;
+    private HttpServletRequest httpRequest = null;
+
+    private UserConfiguration config;
+
+    @Inject
+    public RequestValidationInterceptor(@Named( value = 
"userConfiguration#default" )
+                                                        UserConfiguration 
config) {
+        this.config = config;
+    }
+
+    @PostConstruct
+    public void init() {
+        String baseUrlStr = config.getString(CFG_REST_BASE_URL, "");
+        if (!"".equals(baseUrlStr.trim())) {
+            try {
+                baseUrl = new URL(baseUrlStr);
+                useStaticUrl = true;
+            } catch (MalformedURLException ex) {
+                log.error("Configured baseUrl (rest.baseUrl={}) is invalid. 
Message: {}", baseUrlStr, ex.getMessage());
+            }
+        } else {
+            useStaticUrl = false;
+        }
+        denyAbsentHeaders = 
config.getBoolean(CFG_REST_CSRF_ABSENTORIGIN_DENY,true);
+        enabled = config.getBoolean(CFG_REST_CSRF_ENABLED,true);
+        if (!enabled) {
+            log.info("CSRF Filter is disabled by configuration");
+        }
+    }
+
+    @Override
+    public void filter(ContainerRequestContext containerRequestContext) throws 
IOException {
+        if (enabled) {
+            HttpServletRequest request = getRequest();
+            URL targetUrl = getTargetUrl(request);
+            if (targetUrl == null) {
+                log.error("Could not verify target URL.");
+                
containerRequestContext.abortWith(Response.status(Response.Status.FORBIDDEN).build());
+            }
+            if (!checkSourceRequestHeader(targetUrl, request)) {
+                log.warn("HTTP Header check failed. Assuming CSRF attack.");
+                
containerRequestContext.abortWith(Response.status(Response.Status.FORBIDDEN).build());
+            }
+        }
+    }
+
+    private HttpServletRequest getRequest() {
+        if (httpRequest!=null) {
+            return httpRequest;
+        }  else {
+            Message message = JAXRSUtils.getCurrentMessage();
+            return getHttpServletRequest(message);
+        }
+    }
+
+    private URL getTargetUrl(HttpServletRequest request) {
+        if (useStaticUrl) {
+            return baseUrl;
+        } else {
+            URL requestUrl;
+            try {
+                requestUrl = new URL(request.getRequestURL().toString());
+            } catch (MalformedURLException ex) {
+                log.error("Bad Request URL {}, Message: {}", 
request.getRequestURL(), ex.getMessage());
+                return null;
+            }
+            String xforwarded = request.getHeader(X_FORWARDED_HOST);
+            String xforwardedProto = request.getHeader(X_FORWARDED_PROTO);
+            if (xforwardedProto==null) {
+                xforwardedProto=requestUrl.getProtocol();
+            }
+            if (xforwarded!=null) {
+                try {
+                    return new URL(xforwardedProto+"://"+xforwarded);
+                } catch (MalformedURLException ex) {
+                    log.warn("X-Forwarded-Host Header is malformed: {}", 
ex.getMessage());
+                }
+            }
+            return requestUrl;
+        }
+    }
+
+    private int getPort(final URL url) {
+        return url.getPort() > 0 ? url.getPort() : url.getDefaultPort();
+    }
+
+    private boolean checkSourceRequestHeader(final URL targetUrl, final 
HttpServletRequest request) {
+        boolean headerFound=false;
+        String origin = request.getHeader(ORIGIN);
+        if (origin!=null) {
+            try {
+                URL originUrl = new URL(origin);
+                headerFound=true;
+                log.debug("Origin Header URL found: {}", originUrl);
+                if (!targetUrl.getProtocol().equals(originUrl.getProtocol())) {
+                    log.warn("Origin Header Protocol does not match 
originUrl={}, targetUrl={}",  originUrl, targetUrl);
+                    return false;
+                }
+                if (!targetUrl.getHost().equals(originUrl.getHost())) {
+                    log.warn("Origin Header Host does not match originUrl={}, 
targetUrl={}",originUrl,targetUrl);
+                    return false;
+                }
+                int originPort = getPort(originUrl);
+                int targetPort = getPort(targetUrl);
+                if (targetPort != originPort) {
+                    log.warn("Origin Header Port does not match originUrl={}, 
targetUrl={}",originUrl,targetUrl);
+                    return false;
+                }
+            } catch (MalformedURLException ex) {
+                log.warn("Bad URL in Origin HTTP-Header: {}. Message: 
{}",origin, ex.getMessage());
+                return false;
+            }
+        }
+        String referer = request.getHeader(REFERER);
+        if (referer!=null) {
+            try {
+                URL refererUrl = new URL(referer);
+                headerFound=true;
+                log.debug("Referer Header URL found: {}",refererUrl);
+                if (!targetUrl.getHost().equals(refererUrl.getHost())) {
+                    log.warn("Referer Header Host does not match 
refererUrl={}, targetUrl={}",refererUrl,targetUrl);
+                    return false;
+                }
+            } catch (MalformedURLException ex) {
+                log.warn("Bad URL in Referer HTTP-Header: {}, Message: {}", 
referer, ex.getMessage());
+                return false;
+            }
+        }
+        if (!headerFound && denyAbsentHeaders) {
+            log.warn("Neither Origin nor Referer header found. Request is 
denied.");
+            return false;
+        }
+        return true;
+    }
+
+    public void setHttpRequest(HttpServletRequest request) {
+        this.httpRequest = request;
+    }
+}

http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/95f1b3e4/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml
----------------------------------------------------------------------
diff --git 
a/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml
 
b/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml
index 98188f4..4e7b815 100644
--- 
a/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml
+++ 
b/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml
@@ -65,6 +65,7 @@
       <ref bean="permissionInterceptor#rest"/>
       <ref bean="redbackServiceExceptionMapper"/>
       <ref bean="passwordRuleViolationExceptionMapper"/>
+      <ref bean="requestValidationInterceptor#rest" />
     </jaxrs:providers>
    </jaxrs:server>
 

http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/95f1b3e4/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/AbstractRestServicesTest.java
----------------------------------------------------------------------
diff --git 
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/AbstractRestServicesTest.java
 
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/AbstractRestServicesTest.java
index 806f322..0cab072 100644
--- 
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/AbstractRestServicesTest.java
+++ 
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/AbstractRestServicesTest.java
@@ -175,6 +175,7 @@ public abstract class AbstractRestServicesTest
         {
             WebClient.client( service ).header( "Authorization", authzHeader );
         }
+        WebClient.client(service).header("Referer","http://localhost";);
         WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE );
         WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE );
 
@@ -196,6 +197,8 @@ public abstract class AbstractRestServicesTest
         {
             WebClient.client( service ).header( "Authorization", authzHeader );
         }
+        WebClient.client( service ).header("Referer","http://localhost/";);
+
 
         WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE );
         WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE );
@@ -216,6 +219,7 @@ public abstract class AbstractRestServicesTest
         {
             WebClient.client( service ).header( "Authorization", authzHeader );
         }
+        WebClient.client( service ).header("Referer","http://localhost/";);
 
         WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE );
         WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE );
@@ -238,6 +242,7 @@ public abstract class AbstractRestServicesTest
         {
             WebClient.client( service ).header( "Authorization", authzHeader );
         }
+        WebClient.client( service ).header("Referer","http://localhost/";);
 
         WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE );
         WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE );

http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/95f1b3e4/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/RequestValidationInterceptorTest.java
----------------------------------------------------------------------
diff --git 
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/RequestValidationInterceptorTest.java
 
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/RequestValidationInterceptorTest.java
new file mode 100644
index 0000000..c88492a
--- /dev/null
+++ 
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/RequestValidationInterceptorTest.java
@@ -0,0 +1,162 @@
+package org.apache.archiva.redback.rest.services;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import junit.framework.TestCase;
+import org.apache.archiva.redback.configuration.UserConfigurationException;
+import 
org.apache.archiva.redback.rest.services.interceptors.RequestValidationInterceptor;
+import 
org.apache.archiva.redback.rest.services.mock.MockContainerRequestContext;
+import org.apache.archiva.redback.rest.services.mock.MockUserConfiguration;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.springframework.mock.web.MockHttpServletRequest;
+
+import java.io.IOException;
+
+
+
+/**
+ * Created by Martin Stockhammer on 21.01.17.
+ *
+ * Unit Test for RequestValidationInterceptor.
+ *
+ */
+@RunWith(JUnit4.class)
+public class RequestValidationInterceptorTest extends TestCase {
+
+
+
+    @Test
+    public void validateRequestWithoutHeader() throws 
UserConfigurationException, IOException {
+        MockUserConfiguration cfg = new MockUserConfiguration();
+        RequestValidationInterceptor interceptor = new 
RequestValidationInterceptor(cfg);
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        interceptor.setHttpRequest(request);
+        interceptor.init();
+        MockContainerRequestContext ctx = new MockContainerRequestContext();
+        interceptor.filter(ctx);
+        assertTrue(ctx.isAborted());
+    }
+
+    @Test
+    public void validateRequestWithOrigin() throws UserConfigurationException, 
IOException {
+        MockUserConfiguration cfg = new MockUserConfiguration();
+        RequestValidationInterceptor interceptor = new 
RequestValidationInterceptor(cfg);
+        MockHttpServletRequest request = new 
MockHttpServletRequest("GET","/api/v1/userService");
+        request.setServerName("test.archiva.org");
+        request.addHeader("Origin","http://test.archiva.org/myservlet";);
+        interceptor.setHttpRequest(request);
+        interceptor.init();
+        MockContainerRequestContext ctx = new MockContainerRequestContext();
+        interceptor.filter(ctx);
+        assertFalse(ctx.isAborted());
+    }
+
+    @Test
+    public void validateRequestWithBadOrigin() throws 
UserConfigurationException, IOException {
+        MockUserConfiguration cfg = new MockUserConfiguration();
+        RequestValidationInterceptor interceptor = new 
RequestValidationInterceptor(cfg);
+        MockHttpServletRequest request = new 
MockHttpServletRequest("GET","/api/v1/userService");
+        request.setServerName("test.archiva.org");
+        request.addHeader("Origin","http://test2.archiva.org/myservlet";);
+        interceptor.setHttpRequest(request);
+        interceptor.init();
+        MockContainerRequestContext ctx = new MockContainerRequestContext();
+        interceptor.filter(ctx);
+        assertTrue(ctx.isAborted());
+    }
+
+    @Test
+    public void validateRequestWithReferer() throws 
UserConfigurationException, IOException {
+        MockUserConfiguration cfg = new MockUserConfiguration();
+        RequestValidationInterceptor interceptor = new 
RequestValidationInterceptor(cfg);
+        MockHttpServletRequest request = new 
MockHttpServletRequest("GET","/api/v1/userService");
+        request.setServerName("test.archiva.org");
+        request.addHeader("Referer","http://test.archiva.org/myservlet2";);
+        interceptor.setHttpRequest(request);
+        interceptor.init();
+        MockContainerRequestContext ctx = new MockContainerRequestContext();
+        interceptor.filter(ctx);
+        assertFalse(ctx.isAborted());
+    }
+
+    @Test
+    public void validateRequestWithBadReferer() throws 
UserConfigurationException, IOException {
+        MockUserConfiguration cfg = new MockUserConfiguration();
+        RequestValidationInterceptor interceptor = new 
RequestValidationInterceptor(cfg);
+        MockHttpServletRequest request = new 
MockHttpServletRequest("GET","/api/v1/userService");
+        request.setServerName("test.archiva.org");
+        request.addHeader("Referer","http://test3.archiva.org/myservlet2";);
+        interceptor.setHttpRequest(request);
+        interceptor.init();
+        MockContainerRequestContext ctx = new MockContainerRequestContext();
+        interceptor.filter(ctx);
+        assertTrue(ctx.isAborted());
+    }
+
+    @Test
+    public void validateRequestWithOriginAndReferer() throws 
UserConfigurationException, IOException {
+        MockUserConfiguration cfg = new MockUserConfiguration();
+        RequestValidationInterceptor interceptor = new 
RequestValidationInterceptor(cfg);
+        MockHttpServletRequest request = new 
MockHttpServletRequest("GET","/api/v1/userService");
+        request.setServerName("test.archiva.org");
+        request.addHeader("Origin","http://test.archiva.org/myservlet";);
+        request.addHeader("Referer","http://test.archiva.org/myservlet2";);
+        interceptor.setHttpRequest(request);
+        interceptor.init();
+        MockContainerRequestContext ctx = new MockContainerRequestContext();
+        interceptor.filter(ctx);
+        assertFalse(ctx.isAborted());
+    }
+
+
+    @Test
+    public void validateRequestWithOriginAndStaticUrl() throws 
UserConfigurationException, IOException {
+        MockUserConfiguration cfg = new MockUserConfiguration();
+        cfg.addValue("rest.baseUrl","http://test.archiva.org";);
+        RequestValidationInterceptor interceptor = new 
RequestValidationInterceptor(cfg);
+        MockHttpServletRequest request = new 
MockHttpServletRequest("GET","/api/v1/userService");
+        request.setServerName("test4.archiva.org");
+        request.addHeader("Origin","http://test.archiva.org/myservlet";);
+        interceptor.setHttpRequest(request);
+        interceptor.init();
+        MockContainerRequestContext ctx = new MockContainerRequestContext();
+        interceptor.filter(ctx);
+        assertFalse(ctx.isAborted());
+    }
+
+    @Test
+    public void validateRequestWithBadOriginAndStaticUrl() throws 
UserConfigurationException, IOException {
+        MockUserConfiguration cfg = new MockUserConfiguration();
+        cfg.addValue("rest.baseUrl","http://mytest.archiva.org";);
+        RequestValidationInterceptor interceptor = new 
RequestValidationInterceptor(cfg);
+        MockHttpServletRequest request = new 
MockHttpServletRequest("GET","/api/v1/userService");
+        request.setServerName("mytest.archiva.org");
+        request.addHeader("Origin","http://test.archiva.org/myservlet";);
+        interceptor.setHttpRequest(request);
+        interceptor.init();
+        MockContainerRequestContext ctx = new MockContainerRequestContext();
+        interceptor.filter(ctx);
+        assertTrue(ctx.isAborted());
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/95f1b3e4/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/UserServiceTest.java
----------------------------------------------------------------------
diff --git 
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/UserServiceTest.java
 
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/UserServiceTest.java
index b5a80d2..a1d6f57 100644
--- 
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/UserServiceTest.java
+++ 
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/UserServiceTest.java
@@ -93,6 +93,9 @@ public class UserServiceTest
         throws Exception
     {
 
+        UserService userService = getUserService();
+        WebClient.client( userService ).header( "Origin", 
"http://localhost/myrequest";);
+
         try
         {
             getFakeCreateAdminService().testAuthzWithoutKarmasNeededButAuthz();

http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/95f1b3e4/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/mock/MockContainerRequestContext.java
----------------------------------------------------------------------
diff --git 
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/mock/MockContainerRequestContext.java
 
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/mock/MockContainerRequestContext.java
new file mode 100644
index 0000000..ae98a8f
--- /dev/null
+++ 
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/mock/MockContainerRequestContext.java
@@ -0,0 +1,175 @@
+package org.apache.archiva.redback.rest.services.mock;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.core.Cookie;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.core.UriInfo;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Created by Martin Stockhammer on 21.01.17.
+ *
+ * RequestContext used in unit tests.
+ */
+public class MockContainerRequestContext implements ContainerRequestContext {
+
+    private boolean aborted = false;
+
+    @Override
+    public Object getProperty(String s) {
+        return null;
+    }
+
+    @Override
+    public Collection<String> getPropertyNames() {
+        return null;
+    }
+
+    @Override
+    public void setProperty(String s, Object o) {
+
+    }
+
+    @Override
+    public void removeProperty(String s) {
+
+    }
+
+    @Override
+    public UriInfo getUriInfo() {
+        return null;
+    }
+
+    @Override
+    public void setRequestUri(URI uri) {
+
+    }
+
+    @Override
+    public void setRequestUri(URI uri, URI uri1) {
+
+    }
+
+    @Override
+    public Request getRequest() {
+        return null;
+    }
+
+
+    @Override
+    public String getMethod() {
+        return null;
+    }
+
+    @Override
+    public void setMethod(String s) {
+
+    }
+
+    @Override
+    public MultivaluedMap<String, String> getHeaders() {
+        return null;
+    }
+
+    @Override
+    public String getHeaderString(String s) {
+        return null;
+    }
+
+    @Override
+    public Date getDate() {
+        return null;
+    }
+
+    @Override
+    public Locale getLanguage() {
+        return null;
+    }
+
+    @Override
+    public int getLength() {
+        return 0;
+    }
+
+    @Override
+    public MediaType getMediaType() {
+        return null;
+    }
+
+    @Override
+    public List<MediaType> getAcceptableMediaTypes() {
+        return null;
+    }
+
+    @Override
+    public List<Locale> getAcceptableLanguages() {
+        return null;
+    }
+
+    @Override
+    public Map<String, Cookie> getCookies() {
+        return null;
+    }
+
+    @Override
+    public boolean hasEntity() {
+        return false;
+    }
+
+    @Override
+    public InputStream getEntityStream() {
+        return null;
+    }
+
+    @Override
+    public void setEntityStream(InputStream inputStream) {
+
+    }
+
+    @Override
+    public SecurityContext getSecurityContext() {
+        return null;
+    }
+
+    @Override
+    public void setSecurityContext(SecurityContext securityContext) {
+
+    }
+
+    @Override
+    public void abortWith(Response response) {
+        this.aborted=true;
+    }
+
+    public boolean isAborted() {
+        return aborted;
+    }
+}

http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/95f1b3e4/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/mock/MockUserConfiguration.java
----------------------------------------------------------------------
diff --git 
a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/mock/MockUserConfiguration.java
 
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/mock/MockUserConfiguration.java
new file mode 100644
index 0000000..6eaaed8
--- /dev/null
+++ 
b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/mock/MockUserConfiguration.java
@@ -0,0 +1,105 @@
+package org.apache.archiva.redback.rest.services.mock;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import org.apache.archiva.redback.configuration.UserConfiguration;
+import org.apache.archiva.redback.configuration.UserConfigurationException;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by Martin Stockhammer on 21.01.17.
+ *
+ * User configuration implementation to be used in unit tests.
+ *
+ */
+public class MockUserConfiguration implements UserConfiguration {
+
+    private Map<String, String> values = new 
java.util.HashMap<String,String>();
+
+    @SuppressWarnings("SameParameterValue")
+    public void addValue(String key, String value) {
+        values.put(key,value);
+    }
+
+    @Override
+    public void initialize() throws UserConfigurationException {
+
+    }
+
+    @Override
+    public String getString(String key) {
+        return values.get(key);
+    }
+
+    @Override
+    public String getString(String key, String defaultValue) {
+        if (values.containsKey(key)) {
+            return values.get(key);
+        } else {
+            return defaultValue;
+        }
+    }
+
+    @Override
+    public int getInt(String key) {
+        return getInt(key, -1);
+    }
+
+    @Override
+    public int getInt(String key, int defaultValue) {
+        if (values.containsKey(key)) {
+            return Integer.parseInt(values.get(key));
+        } else {
+            return defaultValue;
+        }
+    }
+
+    @Override
+    public boolean getBoolean(String key) {
+        return getBoolean(key, false);
+    }
+
+    @Override
+    public boolean getBoolean(String key, boolean defaultValue) {
+        if (values.containsKey(key)) {
+            return Boolean.parseBoolean(values.get(key));
+        } else {
+            return defaultValue;
+        }
+    }
+
+    @Override
+    public List<String> getList(String key) {
+        return null;
+    }
+
+    @Override
+    public String getConcatenatedList(String key, String defaultValue) {
+        return null;
+    }
+
+    @Override
+    public Collection<String> getKeys() {
+        return values.keySet();
+    }
+}

Reply via email to