From ff95c79ef5b6a192ad84d43359e79625e8a023ca Mon Sep 17 00:00:00 2001 From: Maks Plys Date: Mon, 15 May 2017 15:57:54 +0300 Subject: [PATCH 1/2] Added automatic token refresh functionality --- pom.xml | 19 ++++++-- .../config/AuthenticationParameters.java | 21 ++++++++- .../DefaultSequencingFileMetadataApi.java | 8 +++- .../core/DefaultSequencingOAuth2Client.java | 45 +++++++------------ .../oauth/core/SequencingFileMetadataApi.java | 6 +++ .../java/com/sequencing/oauth/core/Token.java | 13 +++++- .../sequencing/oauth/helper/JsonHelper.java | 17 +++++++ 7 files changed, 94 insertions(+), 35 deletions(-) diff --git a/pom.xml b/pom.xml index 7ffdbc2..ce3c0a0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.sequencing oauth2-core jar - 1.0 + 1.9 Sequencing oAuth API Module provides API access to sequencing.com backend @@ -35,10 +35,10 @@ UTF-8 - 1.6 + 1.7 4.4.1 2.5 - 1.7.12 + 1.7.18 @@ -133,6 +133,19 @@ true + + + org.apache.maven.plugins + maven-release-plugin + 2.5 + + true + false + release + deploy + + + \ No newline at end of file diff --git a/src/main/java/com/sequencing/oauth/config/AuthenticationParameters.java b/src/main/java/com/sequencing/oauth/config/AuthenticationParameters.java index 65f6d0f..c9d1f0d 100644 --- a/src/main/java/com/sequencing/oauth/config/AuthenticationParameters.java +++ b/src/main/java/com/sequencing/oauth/config/AuthenticationParameters.java @@ -20,9 +20,10 @@ public class AuthenticationParameters implements Serializable public static final String DEFAULT_TOKEN_URI = "https://sequencing.com/oauth2/token"; public static final String DEFAULT_API_URI = "https://api.sequencing.com"; public static final String DEFAULT_RESPONSE_TYPE = "code"; - public static final String DEFAULT_SCOPE = "demo"; + public static final String DEFAULT_SCOPE = "demo,external"; public static final String DEFAULT_GRANT_TYPE = "authorization_code"; public static final String DEFAULT_GRANT_TYPE_REFRESH = "refresh_token"; + public static final String DEFAULT_MOBILE_MODE = "0"; private static final Logger log = LoggerFactory.getLogger(AuthenticationParameters.class); @@ -89,6 +90,11 @@ public class AuthenticationParameters implements Serializable * token. */ private final String grantTypeRefreshToken; + + /** + * Sequencing login page mode. 1 - mobile mode, 0 - web mode. + */ + private final String mobileMode; private AuthenticationParameters(ConfigurationBuilder builder) { oAuthAuthorizationUri = builder.oAuthAuthorizationUri; @@ -102,6 +108,8 @@ private AuthenticationParameters(ConfigurationBuilder builder) { scope = builder.scope; grantType = builder.grantType; grantTypeRefreshToken = builder.grantTypeRefreshToken; + mobileMode = builder.mobileMode; + } public static class ConfigurationBuilder { @@ -117,6 +125,7 @@ public static class ConfigurationBuilder { private String scope; private String grantType; private String grantTypeRefreshToken; + private String mobileMode; public ConfigurationBuilder() { @@ -128,6 +137,7 @@ public ConfigurationBuilder() .withScope(DEFAULT_SCOPE) .withGrantType(DEFAULT_GRANT_TYPE) .withGrantTypeRefreshToken(DEFAULT_GRANT_TYPE_REFRESH) + .withMobileMode(DEFAULT_MOBILE_MODE) .withState(nextState()); } @@ -185,6 +195,11 @@ public ConfigurationBuilder withGrantTypeRefreshToken(String grantTypeRefreshTok this.grantTypeRefreshToken = grantTypeRefreshToken; return this; } + + public ConfigurationBuilder withMobileMode(String mobileMode) { + this.mobileMode = mobileMode; + return this; + } public AuthenticationParameters build() { return new AuthenticationParameters(this); @@ -255,4 +270,8 @@ public String getGrantType() { public String getGrantTypeRefreshToken() { return grantTypeRefreshToken; } + + public String getMobileMode() { + return mobileMode; + } } diff --git a/src/main/java/com/sequencing/oauth/core/DefaultSequencingFileMetadataApi.java b/src/main/java/com/sequencing/oauth/core/DefaultSequencingFileMetadataApi.java index edfe833..4368286 100644 --- a/src/main/java/com/sequencing/oauth/core/DefaultSequencingFileMetadataApi.java +++ b/src/main/java/com/sequencing/oauth/core/DefaultSequencingFileMetadataApi.java @@ -26,6 +26,12 @@ public String getOwnFiles() throws NonAuthorizedException return getFilesByType("uploaded"); } + @Override + public String getFiles() throws NonAuthorizedException + { + return getFilesByType("all"); + } + /** * Returns files depending on file type */ @@ -35,7 +41,7 @@ private String getFilesByType(String fileType) throws NonAuthorizedException throw new NonAuthorizedException(); } - String uri = String.format("%s/DataSourceList?%s=true&shared=true", + String uri = String.format("%s/DataSourceList?%s=true", client.getAuthenticationParameters().getApiUri(), fileType); return HttpHelper.doOauthSecureGet(uri, client.getToken()); diff --git a/src/main/java/com/sequencing/oauth/core/DefaultSequencingOAuth2Client.java b/src/main/java/com/sequencing/oauth/core/DefaultSequencingOAuth2Client.java index f6de101..1cce66c 100644 --- a/src/main/java/com/sequencing/oauth/core/DefaultSequencingOAuth2Client.java +++ b/src/main/java/com/sequencing/oauth/core/DefaultSequencingOAuth2Client.java @@ -2,13 +2,11 @@ import java.io.Serializable; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,7 +21,7 @@ */ public class DefaultSequencingOAuth2Client implements SequencingOAuth2Client, Serializable { - private static final long serialVersionUID = 367801346184616920L; + private static final long serialVersionUID = -1085956585099205527L; private AuthenticationParameters parameters; private volatile Token token; @@ -83,9 +81,9 @@ public class DefaultSequencingOAuth2Client implements SequencingOAuth2Client, Se private static final String ATTR_EXPRIES_IN = "expires_in"; /** - * Executor that handles token refresh + * Attribute for value mobile mode */ - private ScheduledExecutorService tokenUpdateExecutor = Executors.newSingleThreadScheduledExecutor(); + private static final String ATTR_MOBILE_MODE = "mobile"; public DefaultSequencingOAuth2Client(AuthenticationParameters parameters){ this.parameters = parameters; @@ -99,6 +97,7 @@ public Map getHttpParametersForRedirect() { attribures.put(ATTR_STATE, parameters.getState()); attribures.put(ATTR_CLIENT_ID, parameters.getClientId()); attribures.put(ATTR_SCOPE, parameters.getScope()); + attribures.put(ATTR_MOBILE_MODE, parameters.getMobileMode()); return attribures; } @@ -134,9 +133,7 @@ public Token authorize(String responseCode, String responseState) throws Illegal String refreshToken = JsonHelper.getField(result, ATTR_REFRESH_TOKEN); long timelife = Long.parseLong(JsonHelper.getField(result, ATTR_EXPRIES_IN)); - token = new Token(accessToken, refreshToken, timelife); - - runRefreshTokenExecutor(); + token = new Token(accessToken, refreshToken, timelife, new Date()); return token; } @@ -154,6 +151,14 @@ public AuthenticationParameters getAuthenticationParameters() { @Override public Token getToken() { + if(System.currentTimeMillis() >= (token.getLastRefreshDate().getTime() + (token.getLifeTime() * 1000) - 30000) && isAuthorized()){ + try { + refreshToken(); + } catch (BasicAuthenticationFailedException e) { + log.debug("Error occured during refresh token", e.getMessage()); + } + } + return token; } @@ -176,26 +181,8 @@ protected void refreshToken() throws BasicAuthenticationFailedException String accessToken = JsonHelper.getField(result, ATTR_ACCESS_TOKEN); long timelife = Long.parseLong(JsonHelper.getField(result, ATTR_EXPRIES_IN)); - token = new Token(accessToken, token.getRefreshToken(), timelife); - log.debug("Token has been refreshed. New token value " + token.getAccessToken()); - } - - /** - * Runs executor for refreshing token - */ - private void runRefreshTokenExecutor() { - tokenUpdateExecutor.scheduleWithFixedDelay(new TokenRefreshTask(), 0, token.getLifeTime() - 60, TimeUnit.SECONDS); - } - - class TokenRefreshTask implements Runnable - { - public void run() { - try { - refreshToken(); - } catch (BasicAuthenticationFailedException e) { - log.debug("Error occured during refresh token", e.getMessage()); - } - } + token = new Token(accessToken, token.getRefreshToken(), timelife, new Date()); + log.info("Token has been refreshed. New token value " + token.getAccessToken()); } private List getAttributesForRedirectAsList() { diff --git a/src/main/java/com/sequencing/oauth/core/SequencingFileMetadataApi.java b/src/main/java/com/sequencing/oauth/core/SequencingFileMetadataApi.java index 6ddd7f9..5427d0a 100644 --- a/src/main/java/com/sequencing/oauth/core/SequencingFileMetadataApi.java +++ b/src/main/java/com/sequencing/oauth/core/SequencingFileMetadataApi.java @@ -18,4 +18,10 @@ public interface SequencingFileMetadataApi { * @return String json of file content */ public String getOwnFiles() throws NonAuthorizedException; + + /** + * Returns all files from sequencing.com + * @return String json of file content + */ + public String getFiles() throws NonAuthorizedException; } diff --git a/src/main/java/com/sequencing/oauth/core/Token.java b/src/main/java/com/sequencing/oauth/core/Token.java index 8b8c7c6..eb45b26 100644 --- a/src/main/java/com/sequencing/oauth/core/Token.java +++ b/src/main/java/com/sequencing/oauth/core/Token.java @@ -1,6 +1,7 @@ package com.sequencing.oauth.core; import java.io.Serializable; +import java.util.Date; /** * Class that defines token attributes needed for making data @@ -24,11 +25,17 @@ public class Token implements Serializable * Access token lifetime */ private long lifetime = 0; + + /** + * Last date of token refreshing + */ + private Date lastRefreshDate; - public Token(String accessToken, String refreshToken, long lifetime) { + public Token(String accessToken, String refreshToken, long lifetime, Date lastRefreshDate) { this.accessToken = accessToken; this.refreshToken = refreshToken; this.lifetime = lifetime; + this.lastRefreshDate = lastRefreshDate; } public String getAccessToken() { @@ -42,4 +49,8 @@ public String getRefreshToken() { public long getLifeTime() { return lifetime; } + + public Date getLastRefreshDate() { + return lastRefreshDate; + } } diff --git a/src/main/java/com/sequencing/oauth/helper/JsonHelper.java b/src/main/java/com/sequencing/oauth/helper/JsonHelper.java index e79c3be..0bd6a68 100644 --- a/src/main/java/com/sequencing/oauth/helper/JsonHelper.java +++ b/src/main/java/com/sequencing/oauth/helper/JsonHelper.java @@ -4,6 +4,7 @@ import java.util.Iterator; import java.util.List; +import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -49,4 +50,20 @@ public static String[] parseJsonArrayToStringArray(JsonArray jsonArray){ list.toArray(resultStringArray); return resultStringArray; } + + /** + * Convert json to java object + */ + public static T convertToJavaObject(String json, Class classOf){ + Gson gson = new Gson(); + T object = gson.fromJson(json, classOf); + return object; + } + + /** + * Convert java object to json format + */ + public static String convertToJson(T object){ + return new Gson().toJson(object); + } } From 530d221d5d96a5e59b1e99776ebb9faf9f2483c5 Mon Sep 17 00:00:00 2001 From: Maks Plys Date: Mon, 15 May 2017 16:00:52 +0300 Subject: [PATCH 2/2] Changed oauth2-core dependency version in the documentation --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6061eab..0ae2013 100644 --- a/README.md +++ b/README.md @@ -25,14 +25,14 @@ Integration as simple as adding following snippet to your pom.xml if you use Mav com.sequencing oauth2-core - 1.2 + 1.9 ``` or following line to the "dependencies" section of your build.gradle ``` -compile 'com.sequencing:oauth2-core:1.2' +compile 'com.sequencing:oauth2-core:1.9' ``` Resources