Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (C) 2015 Zalando SE (http://tech.zalando.com) Licensed 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.
 
 package org.zalando.stups.tokens;
 
 import java.util.Date;
 import java.util.List;
 
 
 
 
 class AccessTokenRefresher implements AccessTokensRunnable {
     private static final Logger LOG = LoggerFactory.getLogger(AccessTokenRefresher.class);
 
     private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
 
     private static final long ONE_YEAR_SECONDS = 3600 * 24 * 365;
     private static final String FIXED_TOKENS_ENV_VAR = "OAUTH2_ACCESS_TOKENS";
 
     private final AccessTokensBuilder configuration;
     private final ScheduledExecutorService scheduler;
 
 
     public AccessTokenRefresher(final AccessTokensBuilder configuration) {
         this. = configuration;
          = Executors.newSingleThreadScheduledExecutor();
     }
 
     protected void initializeFixedTokensFromEnvironment() {
         final String csv = getFixedToken();
         if (csv != null) {
             .info("Initializing fixed access tokens from {} environment variable..");
 
             final String[] tokens = csv.split(",");
             final long expiresInSeconds = ;
             final Date validUntil = new Date(System.currentTimeMillis() + (expiresInSeconds * 1000));
             for (String token : tokens) {
                 final String[] keyValue = token.split("=");
                 if (keyValue.length == 2) {
                     .info("Using fixed access token {}.."keyValue[0]);
                     .put(keyValue[0], new AccessToken(keyValue[1], "fixed"expiresInSecondsvalidUntil));
                 } else {
                     .error("Could not create access token from {}"token);
                 }
             }
         }
     }
 
     // visible for testing
     protected String getFixedToken() {
         return System.getenv();
     }
 
     void start() {
         .info("Starting to refresh tokens regularly...");
        .scheduleAtFixedRate(this, 1, 1, .);
    }
    static int percentLeft(final AccessToken token) {
        final long now = System.currentTimeMillis();
        final long validUntil = token.getValidUntil().getTime();
        final long hundredPercentSeconds = token.getInitialValidSeconds();
        final long secondsLeft = (validUntil - now) / 1000;
        return (int) ((doublesecondsLeft / (doublehundredPercentSeconds * (double) 100);
    }
    static boolean shouldRefresh(final AccessToken tokenfinal AccessTokensBuilder configuration) {
        return percentLeft(token) <= configuration.getRefreshPercentLeft();
    }
    static boolean shouldWarn(final AccessToken tokenfinal AccessTokensBuilder configuration) {
        return percentLeft(token) <= configuration.getWarnPercentLeft();
    }
    @Override
    public void run() {
        try {
            for (final AccessTokenConfiguration tokenConfig : .getAccessTokenConfigurations()) {
                final AccessToken oldToken = .get(tokenConfig.getTokenId());
                // TODO optionally check with tokeninfo endpoint regularly (every x% of time)
                if (oldToken == null || shouldRefresh(oldToken)) {
                    try {
                        .trace("Refreshing access token {}..."tokenConfig.getTokenId());
                        final AccessToken newToken = createToken(tokenConfig);
                        .put(tokenConfig.getTokenId(), newToken);
                        .info("Refreshed access token {}."tokenConfig.getTokenId());
                    } catch (final Throwable t) {
                        if (oldToken == null || shouldWarn(oldToken)) {
                            .warn("Cannot refresh access token {} because {}."tokenConfig.getTokenId(), t);
                        } else {
                            .info("Cannot refresh access token {} because {}."tokenConfig.getTokenId(), t);
                        }
                    }
                }
            }
        } catch (final Throwable t) {
            .error("Unexpected problem during token refresh run!"t);
        }
    }
    private static String joinScopes(final Collection<Objectscopes) {
        final Iterator<Objectiter = scopes.iterator();
        final StringBuilder scope = new StringBuilder(iter.next().toString());
        while (iter.hasNext()) {
            scope.append(' ');
            scope.append(iter.next().toString());
        }
        return scope.toString();
    }
    private AccessToken createToken(final AccessTokenConfiguration tokenConfig) {
        try {
            // collect credentials
            final ClientCredentials clientCredentials = .getClientCredentialsProvider().get();
            final UserCredentials userCredentials = .getUserCredentialsProvider().get();
            // prepare basic auth credentials
            final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(new AuthScope(.getAccessTokenUri().getHost(),
                    .getAccessTokenUri().getPort()),
                new UsernamePasswordCredentials(clientCredentials.getId(), clientCredentials.getSecret()));
            // create a new client that targets our host with basic auth enabled
            final CloseableHttpClient client = HttpClients.custom().setDefaultCredentialsProvider(credentialsProvider)
                                                          .build();
            final HttpHost host = new HttpHost(.getAccessTokenUri().getHost(),
                    .getAccessTokenUri().getPort(), .getAccessTokenUri().getScheme());
            final HttpPost request = new HttpPost(.getAccessTokenUri());
            // prepare the request body
            final List<NameValuePairvalues = new ArrayList<NameValuePair>() {
                {
                    add(new BasicNameValuePair("grant_type""password"));
                    add(new BasicNameValuePair("username"userCredentials.getUsername()));
                    add(new BasicNameValuePair("password"userCredentials.getPassword()));
                    add(new BasicNameValuePair("scope"joinScopes(tokenConfig.getScopes())));
                }
            };
            request.setEntity(new UrlEncodedFormEntity(values));
            // enable basic auth for the request
            final AuthCache authCache = new BasicAuthCache();
            final BasicScheme basicAuth = new BasicScheme();
            authCache.put(hostbasicAuth);
            final HttpClientContext localContext = HttpClientContext.create();
            localContext.setAuthCache(authCache);
            // execute!
            final CloseableHttpResponse response = client.execute(hostrequestlocalContext);
            try {
                // success status code?
                final int status = response.getStatusLine().getStatusCode();
                if (status < 200 || status >= 300) {
                    throw AccessTokenEndpointException.from(response);
                }
                // get json response
                final HttpEntity entity = response.getEntity();
                final AccessTokenResponse accessTokenResponse = .readValue(EntityUtils.toByteArray(entity),
                        AccessTokenResponse.class);
                // create new access token object
                final Date validUntil = new Date(System.currentTimeMillis()
                            + (accessTokenResponse.expiresInSeconds * 1000));
                return new AccessToken(accessTokenResponse.getAccessToken(), accessTokenResponse.getTokenType(),
                        accessTokenResponse.getExpiresInSeconds(), validUntil);
            } finally {
                response.close();
            }
        } catch (Throwable t) {
            throw new AccessTokenEndpointException(t.getMessage(), t);
        }
    }
    @Override
    public String get(final Object tokenIdthrows AccessTokenUnavailableException {
        return getAccessToken(tokenId).getToken();
    }
    @Override
    public AccessToken getAccessToken(final Object tokenIdthrows AccessTokenUnavailableException {
        final AccessToken token = .get(tokenId);
        if (token == null) {
            throw new AccessTokenUnavailableException("no token available");
        }
        if (token.isExpired()) {
            throw new AccessTokenUnavailableException("token expired");
        }
        return token;
    }
    @Override
    public void invalidate(final Object tokenId) {
        .remove(tokenId);
    }
    @Override
    public void stop() {
        .shutdown();
    }
    @JsonIgnoreProperties(ignoreUnknown = true)
    private static final class AccessTokenResponse {
        @JsonProperty("access_token")
        private String accessToken;
        @JsonProperty("token_type")
        private String tokenType;
        @JsonProperty("expires_in")
        private long expiresInSeconds;
        public String getAccessToken() {
            return ;
        }
        public String getTokenType() {
            return ;
        }
        public long getExpiresInSeconds() {
            return ;
        }
    }
New to GrepCode? Check out our FAQ X