Deprecate API token (JWT) web-service.

Change-Id: I818bf5cbe81b078c1beaf24d8f81929c946c561c
diff --git a/full/Changes b/full/Changes
index 94a3963..f00ffc2 100644
--- a/full/Changes
+++ b/full/Changes
@@ -19,6 +19,10 @@
 2023-02-15
 - Moved user-group retrieval API to UserGroupAdminController 
   and changed the service path URL of UserGroupAdminController. 
+2023-02-20
+- Deprecate API token (JWT) web-service
+
+
 
 # version 0.69.1
 
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/APIAuthentication.java b/full/src/main/java/de/ids_mannheim/korap/authentication/APIAuthentication.java
index 2137ab8..9d66617 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/APIAuthentication.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/APIAuthentication.java
@@ -29,6 +29,7 @@
  * 
  * Created by hanl on 5/23/14.
  */
+@Deprecated
 public class APIAuthentication implements AuthenticationIface {
 
     private static Logger jlog = LogManager.getLogger(APIAuthentication.class);
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/AuthenticationController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/AuthenticationController.java
index e061644..597ae0e 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/AuthenticationController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/AuthenticationController.java
@@ -1,8 +1,6 @@
 package de.ids_mannheim.korap.web.controller;
 
-import java.util.Date;
 import java.util.HashMap;
-import java.util.Iterator; // 07.02.17/FB
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -17,18 +15,15 @@
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.SecurityContext;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
+import org.glassfish.jersey.server.ContainerRequest;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 
-import org.glassfish.jersey.server.ContainerRequest;
-import de.ids_mannheim.korap.web.utils.ResourceFilters;
-
 import de.ids_mannheim.korap.authentication.AuthenticationManager;
 import de.ids_mannheim.korap.authentication.http.AuthorizationData;
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
@@ -43,13 +38,13 @@
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.ServiceInfo;
-import de.ids_mannheim.korap.utils.TimeUtils;
 import de.ids_mannheim.korap.web.KustvaktResponseHandler;
 import de.ids_mannheim.korap.web.filter.APIVersionFilter;
 import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
 import de.ids_mannheim.korap.web.filter.BlockingFilter;
 import de.ids_mannheim.korap.web.filter.DemoUserFilter;
 import de.ids_mannheim.korap.web.filter.PiwikFilter;
+import de.ids_mannheim.korap.web.utils.ResourceFilters;
 
 // import com.sun.xml.internal.messaging.saaj.util.Base64;
 
@@ -76,7 +71,7 @@
     @Autowired
     private HttpAuthorizationHandler authorizationHandler;
 
-    private static Boolean DEBUG_LOG = false;
+    private static Boolean DEBUG_LOG = true;
 
     //todo: bootstrap function to transmit certain default configuration settings and examples (example user queries,
     // default usersettings, etc.)
@@ -172,6 +167,7 @@
 //    }
 
 
+    @Deprecated
     @GET
     @Path("apiToken")
     //@ResourceFilters({HeaderFilter.class})
@@ -183,117 +179,144 @@
             @QueryParam("scope") String scopes,
             //   @Context WebServiceContext wsContext, // FB
             @Context SecurityContext secCtx) {
-
-        List<String> auth =
-                headers.getRequestHeader(ContainerRequest.AUTHORIZATION);
-        if (auth == null || auth.isEmpty()) {
-            throw kustvaktResponseHandler
-                    .throwit(new KustvaktException(StatusCodes.MISSING_PARAMETER,
-                            "Authorization header is missing.",
-                            "Authorization header"));
-        }
         
-        AuthorizationData authorizationData;
-        try {
-            authorizationData = authorizationHandler.
-                    parseAuthorizationHeaderValue(auth.get(0));
-            if (authorizationData.getAuthenticationScheme().equals(AuthenticationScheme.BASIC)){
-                authorizationData = authorizationHandler.parseBasicToken(authorizationData);
-            }
-            else {
-                // EM: throw exception that auth scheme is not supported?
-            }
-           
-        }
-        catch (KustvaktException e) {
-            throw kustvaktResponseHandler.throwit(e);
-        }
-
         if (DEBUG_LOG == true) {
-            System.out.printf("Debug: AuthService.requestAPIToken...:\n");
-            System.out.printf("Debug: auth.size=%d\n", auth.size());
-            System.out.printf("auth.get(0)='%s'\n", auth.get(0));
-            /* hide password etc. - FB
-             if( auth.size() > 0 )
-            	{
-            	Iterator it = auth.iterator();
-            	while( it.hasNext() )
-            		System.out.printf(" header '%s'\n",  it.next());
-            	}
-            if( values.length > 0 )
-            	{
-            	for(int i=0; i< values.length; i++)
-            		{
-            		System.out.printf(" values[%d]='%s'\n",  i, values[i]);
-            		}
-            	}
-             */
-            MultivaluedMap<String, String> headerMap =
-                    headers.getRequestHeaders();
-            if (headerMap != null && headerMap.size() > 0) {
-                Iterator<String> it = headerMap.keySet().iterator();
-                while (it.hasNext()) {
-                    String key = (String) it.next();
-                    List<String> vals = headerMap.get(key);
-//                    System.out.printf("Debug: requestAPIToken: '%s' = '%s'\n",
-//                            key, vals);
-                }
-
-            }
-//            System.out.printf("Debug: requestAPIToken: isSecure = %s.\n",
-//                    secCtx.isSecure() ? "yes" : "no");
-        } // DEBUG_LOG        
-
-        if (authorizationData.getUsername() == null || 
-                authorizationData.getUsername().isEmpty() || 
-                authorizationData.getPassword()== null || 
-                authorizationData.getPassword().isEmpty())
-            // is actual an invalid request
-            throw kustvaktResponseHandler.throwit(StatusCodes.REQUEST_INVALID);
-
-        Map<String, Object> attr = new HashMap<>();
-        if (scopes != null && !scopes.isEmpty())
-            attr.put(Attributes.SCOPE, scopes);
-        attr.put(Attributes.HOST, host);
-        attr.put(Attributes.USER_AGENT, agent);
-
-        TokenContext context;
-        try {
-            // User user = controller.authenticate(0, values[0], values[1], attr); Implementation by Hanl
-            User user = controller.authenticate(AuthenticationMethod.LDAP,
-                    authorizationData.getUsername(), authorizationData.getPassword(), attr); // Implementation with IdM/LDAP
-            // Userdata data = this.controller.getUserData(user, UserDetails.class); // Implem. by Hanl
-            // todo: is this necessary?
-            //            attr.putAll(data.fields());
+            String warning = "Access to API token (JWT) web service";
             
-            // EM: add authentication time
-            Date authenticationTime = TimeUtils.getNow().toDate();
-            attr.put(Attributes.AUTHENTICATION_TIME, authenticationTime);
-            // -- EM
-            
-            controller.setAccessAndLocation(user, headers);
-            if (DEBUG_LOG == true) System.out.printf(
-                    "Debug: /apiToken/: location=%s, access='%s'.\n",
-                    user.locationtoString(), user.accesstoString());
-            attr.put(Attributes.LOCATION, user.getLocation());
-            attr.put(Attributes.CORPUS_ACCESS, user.getCorpusAccess());
-            context = controller.createTokenContext(user, attr,
-                  TokenType.API);
-//            context = controller.createTokenContext(user, attr,
-//                    Attributes.API_AUTHENTICATION);
+            List<String> auth =
+                  headers.getRequestHeader(ContainerRequest.AUTHORIZATION);
+          if (auth != null && !auth.isEmpty()) {
+              try {
+                  AuthorizationData authorizationData = authorizationHandler
+                          .parseAuthorizationHeaderValue(auth.get(0));
+                  if (authorizationData.getAuthenticationScheme()
+                          .equals(AuthenticationScheme.BASIC)) {
+                      authorizationData = authorizationHandler
+                              .parseBasicToken(authorizationData);
+                      jlog.warn(warning + " with username:"+authorizationData.getUsername());
+                  }
+              }
+              catch (KustvaktException e) {}
+          }
+          else {
+              jlog.warn(warning);
+          }
         }
-        catch (KustvaktException e) {
-            throw kustvaktResponseHandler.throwit(e);
-        }
-
-        try {
-            return Response.ok(context.toJson()).build();
-        }
-        catch (KustvaktException e) {
-            throw kustvaktResponseHandler.throwit(e);
-        }
+        throw kustvaktResponseHandler.throwit(new KustvaktException(
+                StatusCodes.DEPRECATED,
+                "API token is no longer supported. Please use OAuth2 procedure instead."));
     }
 
+//        List<String> auth =
+//                headers.getRequestHeader(ContainerRequest.AUTHORIZATION);
+//        if (auth == null || auth.isEmpty()) {
+//            throw kustvaktResponseHandler
+//                    .throwit(new KustvaktException(StatusCodes.MISSING_PARAMETER,
+//                            "Authorization header is missing.",
+//                            "Authorization header"));
+//        }
+//        
+//        AuthorizationData authorizationData;
+//        try {
+//            authorizationData = authorizationHandler.
+//                    parseAuthorizationHeaderValue(auth.get(0));
+//            if (authorizationData.getAuthenticationScheme().equals(AuthenticationScheme.BASIC)){
+//                authorizationData = authorizationHandler.parseBasicToken(authorizationData);
+//            }
+//            else {
+//                // EM: throw exception that auth scheme is not supported?
+//            }
+//           
+//        }
+//        catch (KustvaktException e) {
+//            throw kustvaktResponseHandler.throwit(e);
+//        }
+//
+//        if (DEBUG_LOG == true) {
+//            System.out.printf("Debug: AuthService.requestAPIToken...:\n");
+//            System.out.printf("Debug: auth.size=%d\n", auth.size());
+//            System.out.printf("auth.get(0)='%s'\n", auth.get(0));
+//            /* hide password etc. - FB
+//             if( auth.size() > 0 )
+//            	{
+//            	Iterator it = auth.iterator();
+//            	while( it.hasNext() )
+//            		System.out.printf(" header '%s'\n",  it.next());
+//            	}
+//            if( values.length > 0 )
+//            	{
+//            	for(int i=0; i< values.length; i++)
+//            		{
+//            		System.out.printf(" values[%d]='%s'\n",  i, values[i]);
+//            		}
+//            	}
+//             */
+//            MultivaluedMap<String, String> headerMap =
+//                    headers.getRequestHeaders();
+//            if (headerMap != null && headerMap.size() > 0) {
+//                Iterator<String> it = headerMap.keySet().iterator();
+//                while (it.hasNext()) {
+//                    String key = (String) it.next();
+//                    List<String> vals = headerMap.get(key);
+////                    System.out.printf("Debug: requestAPIToken: '%s' = '%s'\n",
+////                            key, vals);
+//                }
+//
+//            }
+////            System.out.printf("Debug: requestAPIToken: isSecure = %s.\n",
+////                    secCtx.isSecure() ? "yes" : "no");
+//        } // DEBUG_LOG        
+//
+//        if (authorizationData.getUsername() == null || 
+//                authorizationData.getUsername().isEmpty() || 
+//                authorizationData.getPassword()== null || 
+//                authorizationData.getPassword().isEmpty())
+//            // is actual an invalid request
+//            throw kustvaktResponseHandler.throwit(StatusCodes.REQUEST_INVALID);
+//
+//        Map<String, Object> attr = new HashMap<>();
+//        if (scopes != null && !scopes.isEmpty())
+//            attr.put(Attributes.SCOPE, scopes);
+//        attr.put(Attributes.HOST, host);
+//        attr.put(Attributes.USER_AGENT, agent);
+//
+//        TokenContext context;
+//        try {
+//            // User user = controller.authenticate(0, values[0], values[1], attr); Implementation by Hanl
+//            User user = controller.authenticate(AuthenticationMethod.LDAP,
+//                    authorizationData.getUsername(), authorizationData.getPassword(), attr); // Implementation with IdM/LDAP
+//            // Userdata data = this.controller.getUserData(user, UserDetails.class); // Implem. by Hanl
+//            // todo: is this necessary?
+//            //            attr.putAll(data.fields());
+//            
+//            // EM: add authentication time
+//            Date authenticationTime = TimeUtils.getNow().toDate();
+//            attr.put(Attributes.AUTHENTICATION_TIME, authenticationTime);
+//            // -- EM
+//            
+//            controller.setAccessAndLocation(user, headers);
+//            if (DEBUG_LOG == true) System.out.printf(
+//                    "Debug: /apiToken/: location=%s, access='%s'.\n",
+//                    user.locationtoString(), user.accesstoString());
+//            attr.put(Attributes.LOCATION, user.getLocation());
+//            attr.put(Attributes.CORPUS_ACCESS, user.getCorpusAccess());
+//            context = controller.createTokenContext(user, attr,
+//                  TokenType.API);
+////            context = controller.createTokenContext(user, attr,
+////                    Attributes.API_AUTHENTICATION);
+//        }
+//        catch (KustvaktException e) {
+//            throw kustvaktResponseHandler.throwit(e);
+//        }
+//
+//        try {
+//            return Response.ok(context.toJson()).build();
+//        }
+//        catch (KustvaktException e) {
+//            throw kustvaktResponseHandler.throwit(e);
+//        }
+//    }
+
 
     // todo:
     @Deprecated
diff --git a/full/src/main/resources/log4j2.properties b/full/src/main/resources/log4j2.properties
index 661aab6..c366776 100644
--- a/full/src/main/resources/log4j2.properties
+++ b/full/src/main/resources/log4j2.properties
@@ -21,3 +21,10 @@
 logger.file.appenderRefs = file
 logger.file.appenderRef.file.ref = MAINLOG
 logger.file.additivity=false
+
+loggers=file
+logger.console.name=de.ids_mannheim.korap.web.controller.AuthenticationController
+logger.console.level = warn
+logger.console.appenderRefs = file
+logger.console.appenderRef.file.ref = MAINLOG
+logger.console.additivity=false
\ No newline at end of file
diff --git a/full/src/test/java/de/ids_mannheim/korap/authentication/APIAuthenticationTest.java b/full/src/test/java/de/ids_mannheim/korap/authentication/APIAuthenticationTest.java
index 086169b..a36a27b 100644
--- a/full/src/test/java/de/ids_mannheim/korap/authentication/APIAuthenticationTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/authentication/APIAuthenticationTest.java
@@ -6,27 +6,54 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.net.HttpHeaders;
 import com.nimbusds.jose.JOSEException;
 
+import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.FullConfiguration;
-import de.ids_mannheim.korap.config.SpringJerseyTest;
 import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.KorAPUser;
 import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.TimeUtils;
+import de.ids_mannheim.korap.web.controller.OAuth2TestBase;
 
-public class APIAuthenticationTest extends SpringJerseyTest {
+public class APIAuthenticationTest extends OAuth2TestBase {
 
     @Autowired
     private FullConfiguration config;
 
     @Test
+    public void testDeprecatedService () throws KustvaktException {
+
+        String userAuthHeader = HttpAuthorizationHandler
+                .createBasicAuthorizationHeaderValue("dory", "password");
+
+        Response response = target().path(API_VERSION).path("auth")
+                .path("apiToken").request()
+                .header(Attributes.AUTHORIZATION, userAuthHeader)
+                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32").get();
+
+        assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+
+        String entity = response.readEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+        
+        assertEquals(StatusCodes.DEPRECATED, node.at("/errors/0/0").asInt());
+    }
+
+    @Test
     public void testCreateGetTokenContext () throws KustvaktException,
             IOException, InterruptedException, JOSEException {
         User user = new KorAPUser();
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/MultipleCorpusQueryTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/MultipleCorpusQueryTest.java
index 911e716..f44c1c8 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/MultipleCorpusQueryTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/MultipleCorpusQueryTest.java
@@ -81,7 +81,7 @@
         assertEquals(19387, node.at("/sentences").asInt());
         assertEquals(514, node.at("/paragraphs").asInt());
 
-        assertEquals(StatusCodes.DEPRECATED_PARAMETER,
+        assertEquals(StatusCodes.DEPRECATED,
                 node.at("/warnings/0/0").asInt());
         assertEquals("Parameter corpusQuery is deprecated in favor of cq.",
                 node.at("/warnings/0/1").asText());
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java
index 29471a0..e2d36c6 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java
@@ -105,7 +105,7 @@
         assertEquals(node.get("documents").asInt(),11);
         assertEquals(node.get("tokens").asInt(),665842);
         
-        assertEquals(StatusCodes.DEPRECATED_PARAMETER,
+        assertEquals(StatusCodes.DEPRECATED,
                 node.at("/warnings/0/0").asInt());
         assertEquals("Parameter corpusQuery is deprecated in favor of cq.",
                 node.at("/warnings/0/1").asText());
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/TokenExpiryTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/TokenExpiryTest.java
index 3b1d086..4518d1d 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/TokenExpiryTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/TokenExpiryTest.java
@@ -6,15 +6,16 @@
 
 import javax.ws.rs.client.Entity;
 import javax.ws.rs.core.Form;
+import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
 import org.apache.http.HttpStatus;
 import org.apache.http.entity.ContentType;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.google.common.net.HttpHeaders;
-import javax.ws.rs.core.Response;
 
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.SpringJerseyTest;
@@ -31,7 +32,8 @@
  *
  */
 public class TokenExpiryTest extends SpringJerseyTest {
-
+    
+    @Ignore
     @Test
     public void requestToken ()
             throws KustvaktException, InterruptedException, IOException {
diff --git a/full/src/test/resources/log4j2-test.properties b/full/src/test/resources/log4j2-test.properties
index 2810e0c..872b150 100644
--- a/full/src/test/resources/log4j2-test.properties
+++ b/full/src/test/resources/log4j2-test.properties
@@ -35,9 +35,9 @@
 logger.console.appenderRef.file.ref = STDOUT
 logger.console.additivity=false
 
-#loggers=console
-#logger.console.name=de.ids_mannheim.korap
-#logger.console.level = info
-#logger.console.appenderRefs = stdout
-#logger.console.appenderRef.file.ref = STDOUT
-#logger.console.additivity=false
+loggers=console
+logger.console.name=de.ids_mannheim.korap.web.controller.AuthenticationController
+logger.console.level = warn
+logger.console.appenderRefs = stdout
+logger.console.appenderRef.file.ref = STDOUT
+logger.console.additivity=false