Added port checking in test suite.

Change-Id: Ia246f5f35364f6b7b93548dbb34d0a40b595ae56
diff --git a/full/Changes b/full/Changes
index 9753b9e..98b84e8 100644
--- a/full/Changes
+++ b/full/Changes
@@ -22,6 +22,8 @@
     - Added support for unrestricted corpus statistics (ndiewald)
     - updated paths of user-group deletion-controllers (margaretha)
     - Do not pass broken queries to Krill (diewald)
+    - added OAuth2 token request with client authentication via Authorization header (margaretha)
+    - added port checking in test suite (margaretha)
     
 version 0.60.3
 06/06/2018
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2AuthorizationService.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2AuthorizationService.java
index ed47976..f70ce8e 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2AuthorizationService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2AuthorizationService.java
@@ -45,13 +45,14 @@
      * @param code
      * @param authenticationTime
      *            user authentication time
-     * @param nonce 
+     * @param nonce
      * @return
      * @throws KustvaktException
      */
     public String createAuthorization (String username, String clientId,
             String redirectUri, Set<String> scopeSet, String code,
-            ZonedDateTime authenticationTime, String nonce) throws KustvaktException {
+            ZonedDateTime authenticationTime, String nonce)
+            throws KustvaktException {
 
         if (scopeSet == null || scopeSet.isEmpty()) {
             scopeSet = config.getDefaultAccessScopes();
@@ -102,15 +103,14 @@
         String registeredUri = client.getRedirectURI();
         if (redirectUri != null && !redirectUri.isEmpty()) {
             // check if the redirect URI the same as that in DB
-            if (!redirectUri.equals(registeredUri)) {
+            if (registeredUri != null && !registeredUri.isEmpty()
+                    && !redirectUri.equals(registeredUri)) {
                 throw new KustvaktException(StatusCodes.INVALID_REDIRECT_URI,
                         "Invalid redirect URI", OAuth2Error.INVALID_REQUEST);
             }
         }
         else {
-            // check if there is a redirect URI in the DB
-            // This should not happened as it is required in client
-            // registration!
+            // redirect_uri is not required in client registration!
             if (registeredUri != null && !registeredUri.isEmpty()) {
                 redirectUri = registeredUri;
             }
diff --git a/full/src/test/java/de/ids_mannheim/korap/config/SpringJerseyTest.java b/full/src/test/java/de/ids_mannheim/korap/config/SpringJerseyTest.java
index 246e14e..f60cad1 100644
--- a/full/src/test/java/de/ids_mannheim/korap/config/SpringJerseyTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/config/SpringJerseyTest.java
@@ -1,6 +1,9 @@
 package de.ids_mannheim.korap.config;
 
 import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
 import java.util.concurrent.ThreadLocalRandom;
 
 import org.junit.runner.RunWith;
@@ -11,7 +14,6 @@
 import org.springframework.context.support.GenericApplicationContext;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.web.context.ContextLoaderListener;
 import org.springframework.web.context.support.AbstractRefreshableWebApplicationContext;
 
 import com.sun.jersey.spi.spring.container.servlet.SpringServlet;
@@ -73,15 +75,24 @@
         return new WebAppDescriptor.Builder(classPackages)
                 .servletClass(SpringServlet.class)
                 .contextListenerClass(StaticContextLoaderListener.class)
-//                .contextListenerClass(ContextLoaderListener.class)
-//                                .contextParam("contextConfigLocation",
-//                                        "classpath:test-config.xml")
+                // .contextListenerClass(ContextLoaderListener.class)
+                // .contextParam("contextConfigLocation",
+                // "classpath:test-config.xml")
                 .build();
     }
-
+    
     @Override
     protected int getPort (int defaultPort) {
-        return ThreadLocalRandom.current().nextInt(5000, 8000 + 1);
+        int port = ThreadLocalRandom.current().nextInt(5000, 8000 + 1);
+        try {
+            ServerSocket socket = new ServerSocket(port);
+            socket.close();
+        }
+        catch (IOException e) {
+            e.printStackTrace();
+            port = getPort(port);
+        }
+        return port;
     }
 
 }
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java
index 497218c..93666ea 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java
@@ -123,7 +123,7 @@
         MultivaluedMap<String, String> form = new MultivaluedMapImpl();
         form.add("response_type", "string");
         form.add("state", "thisIsMyState");
-        
+
         ClientResponse response = requestAuthorizationConfidentialClient(form);
         assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
 
@@ -143,7 +143,7 @@
         form.add("client_id", "fCBbQkAyYzI4NzUxMg");
         form.add("scope", "read_address");
         form.add("state", "thisIsMyState");
-        
+
         ClientResponse response = requestAuthorizationConfidentialClient(form);
         assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
 
@@ -151,7 +151,8 @@
         MultiValueMap<String, String> params =
                 UriComponentsBuilder.fromUri(location).build().getQueryParams();
         assertEquals(OAuth2Error.INVALID_SCOPE, params.getFirst("error"));
-        assertEquals("read_address+is+an+invalid+scope", params.getFirst("error_description"));
+        assertEquals("read_address+is+an+invalid+scope",
+                params.getFirst("error_description"));
         assertEquals("thisIsMyState", params.getFirst("state"));
     }
 
@@ -326,6 +327,31 @@
     }
 
     @Test
+    public void testRequestTokenPasswordGrantAuthorizationHeader ()
+            throws KustvaktException {
+        MultivaluedMap<String, String> form = new MultivaluedMapImpl();
+        form.add("grant_type", "password");
+        form.add("client_id", "fCBbQkAyYzI4NzUxMg");
+        form.add("username", "dory");
+        form.add("password", "password");
+
+        ClientResponse response = resource().path("oauth2").path("token")
+                .header(HttpHeaders.AUTHORIZATION,
+                        "Basic ZkNCYlFrQXlZekk0TnpVeE1nOnNlY3JldA==")
+                .header(HttpHeaders.CONTENT_TYPE,
+                        ContentType.APPLICATION_FORM_URLENCODED)
+                .entity(form).post(ClientResponse.class);
+        String entity = response.getEntity(String.class);
+        System.out.println(entity);
+        JsonNode node = JsonUtils.readTree(entity);
+        assertNotNull(node.at("/access_token").asText());
+        assertNotNull(node.at("/refresh_token").asText());
+        assertEquals(TokenType.BEARER.toString(),
+                node.at("/token_type").asText());
+        assertNotNull(node.at("/expires_in").asText());
+    }
+
+    @Test
     public void testRequestTokenPasswordGrantMissingClientSecret ()
             throws KustvaktException {
 
diff --git a/full/src/test/resources/log4j2-test.properties b/full/src/test/resources/log4j2-test.properties
index 909a154..58a30cf 100644
--- a/full/src/test/resources/log4j2-test.properties
+++ b/full/src/test/resources/log4j2-test.properties
@@ -10,10 +10,16 @@
 #appender.file.layout.type=PatternLayout
 #appender.file.layout.pattern= %d{yyyy-MM-dd, HH:mm:ss} %C{6} - %M%n %-5p: %m%n
 
-rootLogger.level = info
+rootLogger.level = error
 rootLogger.appenderRefs = stdout
 rootLogger.appenderRef.stdout.ref = STDOUT
 
+loggers=console
+logger.console.name=com.sun.jersey.test.framework.spi.container
+logger.console.level = info
+logger.console.appenderRefs = stdout
+logger.console.appenderRef.file.ref = STDOUT
+
 #loggers=file
 #logger.file.name=com.sun.jersey.test.framework.spi.container
 #logger.file.level = info