basichttpdecoding

Change-Id: I94e7619ee623257911c035cbe0a911338803aeec
diff --git a/src/main/java/de/ids_mannheim/korap/config/Attributes.java b/src/main/java/de/ids_mannheim/korap/config/Attributes.java
index 77fa6e1..8775883 100644
--- a/src/main/java/de/ids_mannheim/korap/config/Attributes.java
+++ b/src/main/java/de/ids_mannheim/korap/config/Attributes.java
@@ -56,8 +56,9 @@
     /**
      * token context
      */
-    public static final String TOKEN = "authToken";
-    public static final String TOKEN_EXPIRATION = "tokenExpires";
+    public static final String TOKEN = "token";
+    public static final String TOKEN_TYPE = "token_type";
+    public static final String TOKEN_EXPIRATION = "expires";
     public static final String TOKEN_CREATION = "tokenCreated";
     public static final String USER_AGENT = "User-Agent";
     public static final String HOST = "userIP";
diff --git a/src/main/java/de/ids_mannheim/korap/config/JWTSigner.java b/src/main/java/de/ids_mannheim/korap/config/JWTSigner.java
index 447ca17..1881db8 100644
--- a/src/main/java/de/ids_mannheim/korap/config/JWTSigner.java
+++ b/src/main/java/de/ids_mannheim/korap/config/JWTSigner.java
@@ -31,11 +31,11 @@
     private final int defaultttl;
 
 
-    public JWTSigner (final byte[] secret, URL issuer, final int defaultttl) {
+    public JWTSigner (final byte[] secret, URL issuer, final int defaulttl) {
         this.issuer = issuer;
         this.signer = new MACSigner(secret);
         this.verifier = new MACVerifier(secret);
-        this.defaultttl = defaultttl;
+        this.defaultttl = defaulttl;
     }
 
 
diff --git a/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java b/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
index 9e025e4..1aed56c 100644
--- a/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
+++ b/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
@@ -62,7 +62,6 @@
     private int loginAttemptTTL;
     private long loginAttemptNum;
     private boolean allowMultiLogIn;
-    private int expiration;
     private int loadFactor;
     @Deprecated
     private int validationStringLength;
@@ -124,8 +123,6 @@
                 "opennlp");
 
         // security configuration
-        expiration = TimeUtils.convertTimeToSeconds(properties.getProperty(
-                "security.absoluteTimeoutDuration", "25M"));
         inactiveTime = TimeUtils.convertTimeToSeconds(properties.getProperty(
                 "security.idleTimeoutDuration", "10M"));
         allowMultiLogIn = Boolean.valueOf(properties
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationManagerIface.java b/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationManagerIface.java
index 1d77605..d5af729 100644
--- a/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationManagerIface.java
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationManagerIface.java
@@ -27,13 +27,13 @@
 
     public void setProviders (Set<AuthenticationIface> providers) {
         for (AuthenticationIface i : providers)
-            this.providers.put(i.getIdentifier().toUpperCase(), i);
+            this.providers.put(i.getIdentifier().toLowerCase(), i);
     }
 
 
     protected AuthenticationIface getProvider (String key, String default_iface) {
         AuthenticationIface iface = this.providers.get(key != null ? key
-                .toUpperCase() : "NONE");
+                .toLowerCase() : "none");
         // todo: configurable authentication schema
         if (iface == null)
             iface = this.providers.get(default_iface);
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/APIAuthentication.java b/src/main/java/de/ids_mannheim/korap/security/auth/APIAuthentication.java
index aed87d5..5e4cfc2 100644
--- a/src/main/java/de/ids_mannheim/korap/security/auth/APIAuthentication.java
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/APIAuthentication.java
@@ -43,7 +43,6 @@
         TokenContext context;
         //Element ein = invalided.get(authToken);
             try {
-                authToken = StringUtils.stripTokenType(authToken);
                 context = signedToken.getTokenContext(authToken);
                 context.setTokenType(Attributes.API_AUTHENTICATION);
             }
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/BasicHttpAuth.java b/src/main/java/de/ids_mannheim/korap/security/auth/BasicHttpAuth.java
index 0d828cb..82e2fb3 100644
--- a/src/main/java/de/ids_mannheim/korap/security/auth/BasicHttpAuth.java
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/BasicHttpAuth.java
@@ -1,5 +1,6 @@
 package de.ids_mannheim.korap.security.auth;
 
+import com.sun.org.apache.xpath.internal.SourceTree;
 import de.ids_mannheim.korap.config.BeansFactory;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.config.Scopes;
@@ -25,6 +26,7 @@
  * @author hanl
  * @date 28/04/2015
  */
+// todo: bean injection!
 public class BasicHttpAuth implements AuthenticationIface {
 
     private KustvaktConfiguration config;
@@ -39,7 +41,28 @@
 
 
     public static String[] decode (String token) {
-        return OAuthUtils.decodeClientAuthenticationHeader(token);
+        //return OAuthUtils.decodeClientAuthenticationHeader(token);
+        String[] tokens = token.split(" ");
+        String encodedCred = null;
+        if (!token.equals(tokens[0])) {
+            if (tokens[0] != null && !tokens[0].isEmpty()) {
+                if (!tokens[0].toLowerCase().equalsIgnoreCase("basic")) {
+                    return null;
+                }
+                encodedCred = tokens[1];
+            }
+        } else {
+            encodedCred = tokens[0];
+        }
+            if(encodedCred != null && !"".equals(encodedCred)) {
+                String decodedCreds = new String(Base64.decodeBase64(encodedCred));
+                if(decodedCreds.contains(":") && decodedCreds.split(":").length == 2) {
+                    String[] creds = decodedCreds.split(":");
+                    if ((creds[0] != null && !creds[0].isEmpty()) && (creds[1] != null && !creds[1].isEmpty()))
+                        return decodedCreds.split(":");
+                }
+            }
+        return null;
     }
 
 
@@ -53,7 +76,7 @@
     @Override
     public TokenContext getTokenContext(String authToken)
             throws KustvaktException {
-        //fixme: handled via constructor
+        //fixme: handle via constructor
         this.config = BeansFactory.getKustvaktContext().getConfiguration();
         EncryptionIface crypto = BeansFactory.getKustvaktContext()
                 .getEncryption();
@@ -71,7 +94,7 @@
                     return null;
             }
             c.setUsername(values[0]);
-            c.setExpirationTime(TimeUtils.plusSeconds(this.config.getExpiration()).getMillis());
+            c.setExpirationTime(TimeUtils.plusSeconds(this.config.getTokenTTL()).getMillis());
             c.setTokenType(Attributes.BASIC_AUTHENTICATION);
             // todo: for production mode, set true
             c.setSecureRequired(false);
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java b/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java
index 81fccf2..4f18a76 100644
--- a/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java
@@ -1,5 +1,6 @@
 package de.ids_mannheim.korap.security.auth;
 
+import com.sun.org.apache.xpath.internal.SourceTree;
 import de.ids_mannheim.korap.auditing.AuditRecord;
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.BeansFactory;
@@ -81,10 +82,12 @@
         if (token == null)
             throw new KustvaktException(StatusCodes.MISSING_ARGUMENT, "authorization header");
 
+        String token_type = StringUtils.getTokenType(token);
+        token = StringUtils.stripTokenType(token);
         jlog.info("getting session status of token type '{}'",
                 token.split(" ")[0]);
         AuthenticationIface provider = getProvider(
-                StringUtils.getTokenType(token), null);
+                token_type, null);
 
         if (provider == null)
             // throw exception for missing type parameter
@@ -529,7 +532,7 @@
         user.setAccountLocked(confirmation_required);
         if (confirmation_required) {
             URIParam param = new URIParam(crypto.createToken(), TimeUtils
-                    .plusSeconds(config.getExpiration()).getMillis());
+                    .plusSeconds(config.getTokenTTL()).getMillis());
             user.addField(param);
         }
         user.setPassword(hash);
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/OpenIDconnectAuthentication.java b/src/main/java/de/ids_mannheim/korap/security/auth/OpenIDconnectAuthentication.java
index 75a25f6..dad0ec1 100644
--- a/src/main/java/de/ids_mannheim/korap/security/auth/OpenIDconnectAuthentication.java
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/OpenIDconnectAuthentication.java
@@ -41,7 +41,6 @@
     @Override
     public TokenContext getTokenContext(String authToken)
             throws KustvaktException {
-        authToken = StringUtils.stripTokenType(authToken);
         return this.database.getContext(authToken);
     }
 
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/SessionAuthentication.java b/src/main/java/de/ids_mannheim/korap/security/auth/SessionAuthentication.java
index d7d2b75..6f42073 100644
--- a/src/main/java/de/ids_mannheim/korap/security/auth/SessionAuthentication.java
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/SessionAuthentication.java
@@ -26,7 +26,7 @@
  */
 public class SessionAuthentication implements AuthenticationIface {
 
-    private static Logger jlog = LoggerFactory
+    private static final Logger jlog = LoggerFactory
             .getLogger(SessionAuthentication.class);
     private SessionFactory sessions;
     private ScheduledThreadPoolExecutor scheduled;
@@ -61,7 +61,7 @@
             throws KustvaktException {
         DateTime now = TimeUtils.getNow();
         DateTime ex = TimeUtils.getExpiration(now.getMillis(),
-                config.getExpiration());
+                config.getShortTokenTTL());
         String token = crypto.createToken(true, user.getUsername(),
                 now.getMillis());
         TokenContext ctx = new TokenContext();
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/SessionFactory.java b/src/main/java/de/ids_mannheim/korap/security/auth/SessionFactory.java
index 03b9e6e..9cc270f 100644
--- a/src/main/java/de/ids_mannheim/korap/security/auth/SessionFactory.java
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/SessionFactory.java
@@ -13,6 +13,7 @@
 import org.springframework.cache.annotation.Cacheable;
 
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -53,11 +54,12 @@
     public boolean hasSession (TokenContext context) {
         if (context.getUsername().equalsIgnoreCase(DemoUser.DEMOUSER_NAME))
             return false;
-        return loggedInRecord.containsKey(context.getUsername())
-                && !loggedInRecord.get(context.getUsername()).isEmpty();
+
+        List<String> value = loggedInRecord.get(context.getUsername());
+        return value != null && !value.isEmpty();
     }
 
-
+    // todo: remove this!
     @Cacheable("session")
     public TokenContext getSession (String token) throws KustvaktException {
         jlog.debug("logged in users: {}", loggedInRecord);
diff --git a/src/main/java/de/ids_mannheim/korap/user/TokenContext.java b/src/main/java/de/ids_mannheim/korap/user/TokenContext.java
index a47978d..6a7f92e 100644
--- a/src/main/java/de/ids_mannheim/korap/user/TokenContext.java
+++ b/src/main/java/de/ids_mannheim/korap/user/TokenContext.java
@@ -54,8 +54,9 @@
         if (username != null && !username.isEmpty())
             m.put(Attributes.USERNAME, username);
         m.put(Attributes.TOKEN_EXPIRATION,
-                new DateTime(expirationTime).toString());
+                TimeUtils.format(this.expirationTime));
         m.put(Attributes.TOKEN, this.token);
+        m.put(Attributes.TOKEN_TYPE, this.tokenType);
         return m;
     }
 
@@ -135,20 +136,10 @@
     }
 
 
-    @Deprecated
-    public String toJSON () {
+    public String toJson() {
         return JsonUtils.toJSON(this.statusMap());
     }
 
-    @Deprecated
-    public String toResponse () {
-        ObjectNode node = JsonUtils.createObjectNode();
-        node.put("token", this.getToken());
-        node.put("expires", TimeUtils.format(this.getExpirationTime()));
-        node.put("token_type", this.getTokenType());
-        return JsonUtils.toJSON(node);
-    }
-
 
     public boolean isDemo() {
         return User.UserFactory.isDemo(this.username);
diff --git a/src/main/java/de/ids_mannheim/korap/web/filter/AuthFilter.java b/src/main/java/de/ids_mannheim/korap/web/filter/AuthFilter.java
index b142a9b..b1c6146 100644
--- a/src/main/java/de/ids_mannheim/korap/web/filter/AuthFilter.java
+++ b/src/main/java/de/ids_mannheim/korap/web/filter/AuthFilter.java
@@ -43,7 +43,7 @@
                         ua);
             }
             catch (KustvaktException e) {
-                throw KustvaktResponseHandler.throwAuthenticationException("");
+                throw KustvaktResponseHandler.throwAuthenticationException(authentication);
             }
             // fixme: give reason why access is not granted?
             if (context != null
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/full/AuthService.java b/src/main/java/de/ids_mannheim/korap/web/service/full/AuthService.java
index d6e2c57..d10906f 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/full/AuthService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/full/AuthService.java
@@ -83,7 +83,7 @@
             @HeaderParam(ContainerRequest.HOST) String host,
             @Context Locale locale) {
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
-        return Response.ok(ctx.toJSON()).build();
+        return Response.ok(ctx.toJson()).build();
     }
 
 
@@ -99,10 +99,6 @@
         List<String> auth = headers
                 .getRequestHeader(ContainerRequest.AUTHORIZATION);
 
-
-       // if (auth == null)
-        //    throw KustvaktResponseHandler
-        //            .throwit(StatusCodes.ACCESS_DENIED);
         String[] values = BasicHttpAuth.decode(auth.get(0));
 
         // "Invalid syntax for username and password"
@@ -134,7 +130,7 @@
             throw KustvaktResponseHandler.throwit(e);
         }
 
-        return Response.ok(context.toResponse()).build();
+        return Response.ok(context.toJson()).build();
     }
 
 
@@ -160,6 +156,7 @@
 
     @GET
     @Path("sessionToken")
+    @ResourceFilters({HeaderFilter.class})
     public Response requestSession (@Context HttpHeaders headers,
             @Context Locale locale,
             @HeaderParam(ContainerRequest.USER_AGENT) String agent,
@@ -167,10 +164,6 @@
         List<String> auth = headers
                 .getRequestHeader(ContainerRequest.AUTHORIZATION);
 
-        if (auth == null)
-            throw KustvaktResponseHandler
-                    .throwit(StatusCodes.ACCESS_DENIED);
-
         String[] values = BasicHttpAuth.decode(auth.get(0));
         //        authentication = StringUtils.stripTokenType(authentication);
         //        String[] values = new String(
@@ -198,7 +191,7 @@
         catch (KustvaktException e) {
             throw KustvaktResponseHandler.throwit(e);
         }
-        return Response.ok().entity(context.toJSON()).build();
+        return Response.ok().entity(context.toJson()).build();
     }
 
 
@@ -231,7 +224,7 @@
         catch (KustvaktException e) {
             throw KustvaktResponseHandler.throwit(e);
         }
-        return Response.ok().entity(context.toJSON()).build();
+        return Response.ok().entity(context.toJson()).build();
     }
 
 
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/full/UserService.java b/src/main/java/de/ids_mannheim/korap/web/service/full/UserService.java
index 03a9baa..84f5901 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/full/UserService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/full/UserService.java
@@ -408,13 +408,13 @@
 
 
     @DELETE
-    @ResourceFilters({ AuthFilter.class, DemoUserFilter.class,
+    @ResourceFilters({ AuthFilter.class,
             PiwikFilter.class, BlockingFilter.class })
     public Response deleteUser (@Context SecurityContext context) {
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
         try {
             User user = controller.getUser(ctx.getUsername());
-            if (User.UserFactory.isDemo(ctx.getUsername()))
+            if (ctx.isDemo())
                 return Response.notModified().build();
             controller.deleteAccount(user);
         }
diff --git a/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java b/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java
index 85b0f46..df5cd42 100644
--- a/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java
+++ b/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java
@@ -69,6 +69,7 @@
     }
 
 
+    //todo:  if exception, make exception message and error code available if not masked!
     public static WebApplicationException throwAuthenticationException (String username) {
         return new WebApplicationException(Response
                 .status(Response.Status.UNAUTHORIZED)
@@ -79,6 +80,7 @@
     }
 
 
+
     private static Response.Status getStatus (int code) {
         Response.Status status = Response.Status.BAD_REQUEST;
         switch (code) {
diff --git a/src/test/java/de/ids_mannheim/korap/config/StringUtilsTest.java b/src/test/java/de/ids_mannheim/korap/config/StringUtilsTest.java
index c77184c..ac7cc25 100644
--- a/src/test/java/de/ids_mannheim/korap/config/StringUtilsTest.java
+++ b/src/test/java/de/ids_mannheim/korap/config/StringUtilsTest.java
@@ -1,9 +1,15 @@
 package de.ids_mannheim.korap.config;
 
+import de.ids_mannheim.korap.security.auth.BasicHttpAuth;
 import de.ids_mannheim.korap.utils.StringUtils;
+import org.apache.commons.codec.binary.Base64;
 import org.junit.Test;
 
+import java.util.Arrays;
+
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 
 /**
  * Created by hanl on 29.05.16.
@@ -20,7 +26,17 @@
 
 
     @Test
-    public void testSQLRegexBuild () {
-
+    public void testBasicHttpSplit() {
+            String s1 = "basic " + new String(Base64.encodeBase64("test:testPass".getBytes()));
+            String s2 = new String(Base64.encodeBase64("test:testPass".getBytes()));
+            String[] f1 = BasicHttpAuth.decode(s1);
+            String[] f2 = BasicHttpAuth.decode(s2);
+            assertNotNull(f1);
+            assertNotNull(f2);
+            assertEquals("test", f1[0]);
+            assertEquals("testPass", f1[1]);
+            assertEquals("test", f2[0]);
+            assertEquals("testPass", f2[1]);
     }
+
 }
diff --git a/src/test/java/de/ids_mannheim/korap/config/TestHelper.java b/src/test/java/de/ids_mannheim/korap/config/TestHelper.java
index 0a9131e..9788eeb 100644
--- a/src/test/java/de/ids_mannheim/korap/config/TestHelper.java
+++ b/src/test/java/de/ids_mannheim/korap/config/TestHelper.java
@@ -10,9 +10,7 @@
 import de.ids_mannheim.korap.interfaces.defaults.KustvaktEncryption;
 import de.ids_mannheim.korap.resources.KustvaktResource;
 import de.ids_mannheim.korap.security.ac.PolicyDao;
-import de.ids_mannheim.korap.security.auth.APIAuthentication;
-import de.ids_mannheim.korap.security.auth.BasicHttpAuth;
-import de.ids_mannheim.korap.security.auth.KustvaktAuthenticationManager;
+import de.ids_mannheim.korap.security.auth.*;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.TimeUtils;
 import de.ids_mannheim.korap.web.service.BootableBeanInterface;
@@ -475,6 +473,8 @@
             Set<AuthenticationIface> pro = new HashSet<>();
             pro.add(new BasicHttpAuth());
             pro.add(new APIAuthentication(getConfig()));
+            pro.add(new SessionAuthentication(getConfig(), getCrypto()));
+            pro.add(new OpenIDconnectAuthentication(getConfig(), getDataSource()));
             manager.setProviders(pro);
             return manager;
         }
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/AuthServiceTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/AuthServiceTest.java
index 6da2bb5..fd648d6 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/AuthServiceTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/AuthServiceTest.java
@@ -1,23 +1,39 @@
 package de.ids_mannheim.korap.web.service.full;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.json.JSONUnmarshaller;
+import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.TestHelper;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.security.auth.BasicHttpAuth;
 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.service.FastJerseyTest;
+import org.joda.time.DateTime;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
+import static org.junit.Assert.*;
+
 /**
  * @author hanl
  * @date 24/09/2015
  */
 public class AuthServiceTest extends FastJerseyTest {
 
+    private static String[] credentials;
+
     @BeforeClass
     public static void configure () throws Exception {
-        FastJerseyTest.setPackages("de.ids_mannheim.korap.web.service",
+        FastJerseyTest.setPackages("de.ids_mannheim.korap.web.service.full",
                 "de.ids_mannheim.korap.web.filter",
                 "de.ids_mannheim.korap.web.utils");
+        credentials = new String[2];
+        credentials[0] = (String) TestHelper.getUserCredentials().get(Attributes.USERNAME);
+        credentials[1] = (String) TestHelper.getUserCredentials().get(Attributes.PASSWORD);
     }
 
 
@@ -30,10 +46,74 @@
     @Test
     public void testBasicHttp () {
         User user = helper().getUser();
-
     }
 
     @Test
+    public void testSessionToken() {
+        String auth = BasicHttpAuth.encode(credentials[0], credentials[1]);
+        ClientResponse response = resource().path(getAPIVersion()).path("auth")
+                .path("sessionToken").header(Attributes.AUTHORIZATION, auth)
+                .get(ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String en = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(en);
+        assertNotNull(node);
+
+        String token = node.path("token").asText();
+        String token_type = node.path("token_type").asText();
+        String expiration = node.path("expires").asText();
+        DateTime ex = TimeUtils.getTime(expiration);
+        assertNotEquals("", token);
+        assertNotEquals("", token_type);
+        assertFalse(TimeUtils.isExpired(ex.getMillis()));
+
+        response = resource().path(getAPIVersion()).path("user")
+                .path("info").header(Attributes.AUTHORIZATION, token_type + " "+ token)
+                .get(ClientResponse.class);
+        en = response.getEntity(String.class);
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+    }
+
+    @Test
+    public void testSessionTokenExpire() {
+        String auth = BasicHttpAuth.encode(credentials[0], credentials[1]);
+        ClientResponse response = resource().path(getAPIVersion()).path("auth")
+                .path("sessionToken").header(Attributes.AUTHORIZATION, auth)
+                .get(ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String en = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(en);
+        assertNotNull(node);
+
+        String token = node.path("token").asText();
+        String token_type = node.path("token_type").asText();
+        String expiration = node.path("expires").asText();
+        DateTime ex = TimeUtils.getTime(expiration);
+        assertNotEquals("", token);
+        assertNotEquals("", token_type);
+
+        while (true) {
+            if (TimeUtils.isExpired(ex.getMillis()))
+                break;
+        }
+        response = resource().path(getAPIVersion()).path("user")
+                .path("info").header(Attributes.AUTHORIZATION, token_type + " "+ token)
+                .get(ClientResponse.class);
+        en = response.getEntity(String.class);
+        node = JsonUtils.readTree(en);
+        assertNotNull(node);
+
+        assertEquals(StatusCodes.BAD_CREDENTIALS, node.at("/errors/0/0").asInt());
+        assertEquals(ClientResponse.Status.UNAUTHORIZED.getStatusCode(),
+                response.getStatus());
+    }
+
+
+    @Test
     public void testBlockingFilterFail() {
 
     }