package com.github.scribejava.core.extractors; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.github.scribejava.core.exceptions.OAuthException; import com.github.scribejava.core.model.OAuth2AccessToken; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.utils.OAuthEncoder; import com.github.scribejava.core.utils.Preconditions; /** * Custom implementation of {@link TokenExtractor} for OAuth 2.0 */ public class OAuth2AccessTokenExtractor implements TokenExtractor<OAuth2AccessToken> { private static final Pattern ACCESS_TOKEN_REGEX_PATTERN = Pattern.compile("access_token=([^&]+)"); private static final Pattern TOKEN_TYPE_REGEX_PATTERN = Pattern.compile("token_type=([^&]+)"); private static final Pattern EXPIRES_IN_REGEX_PATTERN = Pattern.compile("expires_in=([^&]+)"); private static final Pattern REFRESH_TOKEN_REGEX_PATTERN = Pattern.compile("refresh_token=([^&]+)"); private static final Pattern SCOPE_REGEX_PATTERN = Pattern.compile("scope=([^&]+)"); protected OAuth2AccessTokenExtractor() { } private static class InstanceHolder { private static final OAuth2AccessTokenExtractor INSTANCE = new OAuth2AccessTokenExtractor(); } public static OAuth2AccessTokenExtractor instance() { return InstanceHolder.INSTANCE; } /** * {@inheritDoc} */ @Override public OAuth2AccessToken extract(Response response) throws IOException { final String body = response.getBody(); Preconditions.checkEmptyString(body, "Response body is incorrect. Can't extract a token from an empty string"); final String accessToken = extractParameter(body, ACCESS_TOKEN_REGEX_PATTERN, true); final String tokenType = extractParameter(body, TOKEN_TYPE_REGEX_PATTERN, false); final String expiresInString = extractParameter(body, EXPIRES_IN_REGEX_PATTERN, false); Integer expiresIn; try { expiresIn = expiresInString == null ? null : Integer.valueOf(expiresInString); } catch (NumberFormatException nfe) { expiresIn = null; } final String refreshToken = extractParameter(body, REFRESH_TOKEN_REGEX_PATTERN, false); final String scope = extractParameter(body, SCOPE_REGEX_PATTERN, false); return new OAuth2AccessToken(accessToken, tokenType, expiresIn, refreshToken, scope, body); } private static String extractParameter(String response, Pattern regexPattern, boolean required) throws OAuthException { final Matcher matcher = regexPattern.matcher(response); if (matcher.find()) { return OAuthEncoder.decode(matcher.group(1)); } else if (required) { throw new OAuthException("Response body is incorrect. Can't extract a '" + regexPattern.pattern() + "' from this: '" + response + "'", null); } else { return null; } } }