diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ClientId.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ClientId.java index 2cf9f0c2e6d5..9e07fb5a7638 100644 --- a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ClientId.java +++ b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ClientId.java @@ -96,7 +96,7 @@ public static ClientId fromJson(Map json) throws IOException { @SuppressWarnings("unchecked") Map detail = (Map) rawDetail; String clientId = OAuth2Utils.validateString(detail, FIELD_CLIENT_ID, JSON_PARSE_ERROR); - if (clientId == null || clientId.length() == 0) { + if (clientId.isEmpty()) { throw new IOException( "Unable to parse ClientId. Field '" + FIELD_CLIENT_ID + "' is required."); } diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/UserAuthorizer.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/UserAuthorizer.java index 161eb36ef1db..bdab0d2c882b 100644 --- a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/UserAuthorizer.java +++ b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/UserAuthorizer.java @@ -40,8 +40,8 @@ import com.google.api.client.json.JsonObjectParser; import com.google.api.client.util.GenericData; import com.google.api.client.util.Joiner; -import com.google.api.client.util.Preconditions; import com.google.auth.http.HttpTransportFactory; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.io.IOException; @@ -76,8 +76,8 @@ public enum ClientAuthenticationType { static final URI DEFAULT_CALLBACK_URI = URI.create("/oauth2callback"); - private final String TOKEN_STORE_ERROR = "Error parsing stored token data."; - private final String FETCH_TOKEN_ERROR = "Error reading result of Token API:"; + private static final String TOKEN_STORE_ERROR = "Error parsing stored token data."; + private static final String FETCH_TOKEN_ERROR = "Error reading result of Token API:"; private final ClientId clientId; private final Collection scopes; @@ -249,7 +249,7 @@ public URL getAuthorizationUrl( GenericJson tokenJson = OAuth2Utils.parseJson(tokenData); String accessTokenValue = OAuth2Utils.validateString(tokenJson, "access_token", TOKEN_STORE_ERROR); - Long expirationMillis = + long expirationMillis = OAuth2Utils.validateLong(tokenJson, "expiration_time_millis", TOKEN_STORE_ERROR); Date expirationTime = new Date(expirationMillis); List scopes = @@ -414,21 +414,23 @@ public void revokeAuthorization(String userId) throws IOException { */ public void storeCredentials(String userId, UserCredentials credentials) throws IOException { AccessToken accessToken = credentials.getAccessToken(); - String acessTokenValue = null; + String accessTokenValue = null; Date expiresBy = null; List grantedScopes = new ArrayList<>(); if (accessToken != null) { - acessTokenValue = accessToken.getTokenValue(); + accessTokenValue = accessToken.getTokenValue(); expiresBy = accessToken.getExpirationTime(); grantedScopes = accessToken.getScopes(); } String refreshToken = credentials.getRefreshToken(); GenericJson tokenStateJson = new GenericJson(); tokenStateJson.setFactory(OAuth2Utils.JSON_FACTORY); - tokenStateJson.put("access_token", acessTokenValue); + tokenStateJson.put("access_token", accessTokenValue); tokenStateJson.put(OAuth2Utils.TOKEN_RESPONSE_SCOPE, grantedScopes); - tokenStateJson.put("expiration_time_millis", expiresBy.getTime()); + if (expiresBy != null) { + tokenStateJson.put("expiration_time_millis", expiresBy.getTime()); + } if (refreshToken != null) { tokenStateJson.put("refresh_token", refreshToken); } @@ -498,7 +500,7 @@ private TokenResponseWithConfig getCredentialsFromCodeInternal( String accessTokenValue = OAuth2Utils.validateString(parsedTokens, "access_token", FETCH_TOKEN_ERROR); int expiresInSecs = OAuth2Utils.validateInt32(parsedTokens, "expires_in", FETCH_TOKEN_ERROR); - Date expirationTime = new Date(new Date().getTime() + expiresInSecs * 1000); + Date expirationTime = new Date(new Date().getTime() + expiresInSecs * 1000L); String scopes = OAuth2Utils.validateOptionalString( parsedTokens, OAuth2Utils.TOKEN_RESPONSE_SCOPE, FETCH_TOKEN_ERROR); @@ -551,15 +553,15 @@ public Builder toBuilder() { public static class Builder { - private ClientId clientId; - private TokenStore tokenStore; - private URI callbackUri; - private URI tokenServerUri; - private URI userAuthUri; - private Collection scopes; - private HttpTransportFactory transportFactory; + private @Nullable ClientId clientId; + private @Nullable TokenStore tokenStore; + private @Nullable URI callbackUri; + private @Nullable URI tokenServerUri; + private @Nullable URI userAuthUri; + private @Nullable Collection scopes; + private @Nullable HttpTransportFactory transportFactory; private @Nullable PKCEProvider pkce; - private ClientAuthenticationType clientAuthenticationType; + private @Nullable ClientAuthenticationType clientAuthenticationType; protected Builder() {} @@ -674,7 +676,6 @@ public Builder setPKCEProvider(@Nullable PKCEProvider pkce) { if (pkce.getCodeChallenge() == null || pkce.getCodeVerifier() == null || pkce.getCodeChallengeMethod() == null) { - throw new IllegalArgumentException( "PKCE provider contained null implementations. PKCE object must implement all" + " PKCEProvider methods."); @@ -698,31 +699,31 @@ public Builder setClientAuthenticationType(ClientAuthenticationType clientAuthen return this; } - public ClientId getClientId() { + public @Nullable ClientId getClientId() { return clientId; } - public TokenStore getTokenStore() { + public @Nullable TokenStore getTokenStore() { return tokenStore; } - public Collection getScopes() { + public @Nullable Collection getScopes() { return scopes; } - public URI getTokenServerUri() { + public @Nullable URI getTokenServerUri() { return tokenServerUri; } - public URI getCallbackUri() { + public @Nullable URI getCallbackUri() { return callbackUri; } - public URI getUserAuthUri() { + public @Nullable URI getUserAuthUri() { return userAuthUri; } - public HttpTransportFactory getHttpTransportFactory() { + public @Nullable HttpTransportFactory getHttpTransportFactory() { return transportFactory; } @@ -730,7 +731,7 @@ public HttpTransportFactory getHttpTransportFactory() { return pkce; } - public ClientAuthenticationType getClientAuthenticationType() { + public @Nullable ClientAuthenticationType getClientAuthenticationType() { return clientAuthenticationType; } @@ -771,18 +772,18 @@ public UserAuthorizer build() { public static class TokenResponseWithConfig { private final String clientId; - private final String clientSecret; - private final String refreshToken; + private final @Nullable String clientSecret; + private final @Nullable String refreshToken; private final AccessToken accessToken; - private URI tokenServerUri; + private final URI tokenServerUri; private final HttpTransportFactory httpTransportFactory; private TokenResponseWithConfig(Builder builder) { - this.clientId = builder.clientId; + this.clientId = Preconditions.checkNotNull(builder.clientId); this.clientSecret = builder.clientSecret; - this.accessToken = builder.accessToken; - this.httpTransportFactory = builder.httpTransportFactory; - this.tokenServerUri = builder.tokenServerUri; + this.accessToken = Preconditions.checkNotNull(builder.accessToken); + this.httpTransportFactory = Preconditions.checkNotNull(builder.httpTransportFactory); + this.tokenServerUri = Preconditions.checkNotNull(builder.tokenServerUri); this.refreshToken = builder.refreshToken; } @@ -800,7 +801,7 @@ public String getClientId() { * * @return The client secret. */ - public String getClientSecret() { + public @Nullable String getClientSecret() { return clientSecret; } @@ -836,8 +837,7 @@ public URI getTokenServerUri() { * * @return The refresh token, or null if not granted. */ - @Nullable - public String getRefreshToken() { + public @Nullable String getRefreshToken() { return refreshToken; } @@ -846,12 +846,12 @@ static Builder newBuilder() { } static class Builder { - private String clientId; - private String clientSecret; - private String refreshToken; - private AccessToken accessToken; - private URI tokenServerUri; - private HttpTransportFactory httpTransportFactory; + private @Nullable String clientId; + private @Nullable String clientSecret; + private @Nullable String refreshToken; + private @Nullable AccessToken accessToken; + private @Nullable URI tokenServerUri; + private @Nullable HttpTransportFactory httpTransportFactory; @CanIgnoreReturnValue Builder setClientId(String clientId) { @@ -860,13 +860,13 @@ Builder setClientId(String clientId) { } @CanIgnoreReturnValue - Builder setClientSecret(String clientSecret) { + Builder setClientSecret(@Nullable String clientSecret) { this.clientSecret = clientSecret; return this; } @CanIgnoreReturnValue - Builder setRefreshToken(String refreshToken) { + Builder setRefreshToken(@Nullable String refreshToken) { this.refreshToken = refreshToken; return this; } diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java index 8e4618aba214..668dfda9b5ec 100644 --- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java +++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java @@ -946,4 +946,64 @@ void testTokenResponseWithConfig_noRefreshToken() { assertEquals(httpTransportFactory, tokenResponse.getHttpTransportFactory()); assertNull(tokenResponse.getRefreshToken()); } + + @Test + void testTokenResponseWithConfig_noClientSecret() { + String clientId = "testClientId"; + AccessToken accessToken = new AccessToken("token", new Date()); + URI tokenServerUri = URI.create("https://example.com/token"); + HttpTransportFactory httpTransportFactory = new MockTokenServerTransportFactory(); + + TokenResponseWithConfig tokenResponse = + TokenResponseWithConfig.newBuilder() + .setClientId(clientId) + .setClientSecret(null) + .setAccessToken(accessToken) + .setTokenServerUri(tokenServerUri) + .setHttpTransportFactory(httpTransportFactory) + .build(); + + assertEquals(clientId, tokenResponse.getClientId()); + assertNull(tokenResponse.getClientSecret()); + assertEquals(accessToken, tokenResponse.getAccessToken()); + assertEquals(tokenServerUri, tokenResponse.getTokenServerUri()); + assertEquals(httpTransportFactory, tokenResponse.getHttpTransportFactory()); + assertNull(tokenResponse.getRefreshToken()); + } + + @Test + void build_withDefaults() { + UserAuthorizer authorizer = + UserAuthorizer.newBuilder().setClientId(CLIENT_ID).setScopes(DUMMY_SCOPES).build(); + + assertNotNull(authorizer.getTokenStore()); + assertEquals(DUMMY_SCOPES, authorizer.getScopes()); + assertEquals(UserAuthorizer.DEFAULT_CALLBACK_URI, authorizer.getCallbackUri()); + assertEquals( + UserAuthorizer.ClientAuthenticationType.CLIENT_SECRET_POST, + authorizer.getClientAuthenticationType()); + } + + @Test + void storeCredentials_nullAccessToken() throws IOException { + TokenStore store = new MemoryTokensStorage(); + UserAuthorizer authorizer = + UserAuthorizer.newBuilder() + .setClientId(CLIENT_ID) + .setScopes(DUMMY_SCOPES) + .setTokenStore(store) + .build(); + + UserCredentials credentials = + UserCredentials.newBuilder() + .setClientId(CLIENT_ID_VALUE) + .setClientSecret(CLIENT_SECRET) + .setRefreshToken(REFRESH_TOKEN) + .build(); + + authorizer.storeCredentials(USER_ID, credentials); + String loaded = store.load(USER_ID); + assertNotNull(loaded); + assertTrue(loaded.contains(REFRESH_TOKEN)); + } }