/** * Returns user credentials defined by JSON contents using the format supported by the Cloud SDK. * * @param json a map from the JSON representing the credentials. * @param transportFactory HTTP transport factory, creates the transport used to get access * tokens. * @return the credentials defined by the JSON. * @throws IOException if the credential cannot be created from the JSON. **/ static UserCredentials fromJson(Map<String, Object> json, HttpTransportFactory transportFactory) throws IOException { String clientId = (String) json.get("client_id"); String clientSecret = (String) json.get("client_secret"); String refreshToken = (String) json.get("refresh_token"); if (clientId == null || clientSecret == null || refreshToken == null) { throw new IOException("Error reading user credential from JSON, " + " expecting 'client_id', 'client_secret' and 'refresh_token'."); } return UserCredentials.newBuilder() .setClientId(clientId) .setClientSecret(clientSecret) .setRefreshToken(refreshToken) .setAccessToken(null) .setHttpTransportFactory(transportFactory) .setTokenServerUri(null) .build(); }
/** * Returns user credentials defined by JSON contents using the format supported by the Cloud SDK. * * @param json a map from the JSON representing the credentials. * @param transportFactory HTTP transport factory, creates the transport used to get access * tokens. * @return the credentials defined by the JSON. * @throws IOException if the credential cannot be created from the JSON. **/ static UserCredentials fromJson(Map<String, Object> json, HttpTransportFactory transportFactory) throws IOException { String clientId = (String) json.get("client_id"); String clientSecret = (String) json.get("client_secret"); String refreshToken = (String) json.get("refresh_token"); if (clientId == null || clientSecret == null || refreshToken == null) { throw new IOException("Error reading user credential from JSON, " + " expecting 'client_id', 'client_secret' and 'refresh_token'."); } return UserCredentials.newBuilder() .setClientId(clientId) .setClientSecret(clientSecret) .setRefreshToken(refreshToken) .setAccessToken(null) .setHttpTransportFactory(transportFactory) .setTokenServerUri(null) .build(); }
@Test public void toString_containsFields() throws IOException { AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null); final URI tokenServer = URI.create("https://foo.com/bar"); MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); UserCredentials credentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(transportFactory) .setTokenServerUri(tokenServer) .build(); String expectedToString = String.format( "UserCredentials{requestMetadata=%s, temporaryAccess=%s, clientId=%s, refreshToken=%s, " + "tokenServerUri=%s, transportFactoryClassName=%s}", ImmutableMap.of(AuthHttpConstants.AUTHORIZATION, ImmutableList.of(OAuth2Utils.BEARER_PREFIX + accessToken.getTokenValue())), accessToken.toString(), CLIENT_ID, REFRESH_TOKEN, tokenServer, MockTokenServerTransportFactory.class.getName()); assertEquals(expectedToString, credentials.toString()); }
@Test public void refresh_refreshesToken() throws IOException { final String accessToken1 = "1/MkSJoj1xsli0AccessToken_NKPY2"; final String accessToken2 = "2/MkSJoj1xsli0AccessToken_NKPY2"; MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET); transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken1); OAuth2Credentials userCredentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setHttpTransportFactory(transportFactory) .build(); // Use a fixed clock so tokens don't expire userCredentials.clock = new TestClock(); // Get a first token Map<String, List<String>> metadata = userCredentials.getRequestMetadata(CALL_URI); TestUtils.assertContainsBearerToken(metadata, accessToken1); assertEquals(1, transportFactory.transport.buildRequestCount--); // Change server to a different token transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken2); // Confirm token being cached TestUtils.assertContainsBearerToken(metadata, accessToken1); assertEquals(0, transportFactory.transport.buildRequestCount); // Refresh to force getting next token userCredentials.refresh(); metadata = userCredentials.getRequestMetadata(CALL_URI); TestUtils.assertContainsBearerToken(metadata, accessToken2); assertEquals(1, transportFactory.transport.buildRequestCount--); }
@Test public void getRequestMetadata_async_refreshRace() throws IOException { final String accessToken1 = "1/MkSJoj1xsli0AccessToken_NKPY2"; MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET); transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken1); TestClock clock = new TestClock(); OAuth2Credentials credentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setHttpTransportFactory(transportFactory) .build(); credentials.clock = clock; MockExecutor executor = new MockExecutor(); MockRequestMetadataCallback callback = new MockRequestMetadataCallback(); // Getting the first token, which uses the transport and calls the callback in the executor. credentials.getRequestMetadata(CALL_URI, executor, callback); assertEquals(0, transportFactory.transport.buildRequestCount); assertNull(callback.metadata); // Asynchronous task is scheduled, but beaten by another blocking get call. assertEquals(1, executor.numTasks()); Map<String, List<String>> metadata = credentials.getRequestMetadata(CALL_URI); assertEquals(1, transportFactory.transport.buildRequestCount--); TestUtils.assertContainsBearerToken(metadata, accessToken1); // When the task is run, the cached data is used. assertEquals(1, executor.runTasksExhaustively()); assertEquals(0, transportFactory.transport.buildRequestCount); assertSame(metadata, callback.metadata); }
@Test public void equals_false_transportFactory() throws IOException { final URI tokenServer1 = URI.create("https://foo1.com/bar"); AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null); MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory(); MockTokenServerTransportFactory serverTransportFactory = new MockTokenServerTransportFactory(); UserCredentials credentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(httpTransportFactory) .setTokenServerUri(tokenServer1) .build(); UserCredentials otherCredentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(serverTransportFactory) .setTokenServerUri(tokenServer1) .build(); assertFalse(credentials.equals(otherCredentials)); assertFalse(otherCredentials.equals(credentials)); }
@Test public void equals_false_clientSecret() throws IOException { final URI tokenServer1 = URI.create("https://foo1.com/bar"); AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null); MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory(); UserCredentials credentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(httpTransportFactory) .setTokenServerUri(tokenServer1) .build(); UserCredentials otherCredentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret("other client secret") .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(httpTransportFactory) .setTokenServerUri(tokenServer1) .build(); assertFalse(credentials.equals(otherCredentials)); assertFalse(otherCredentials.equals(credentials)); }
@Test public void equals_false_tokenServer() throws IOException { final URI tokenServer1 = URI.create("https://foo1.com/bar"); final URI tokenServer2 = URI.create("https://foo2.com/bar"); AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null); MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory(); UserCredentials credentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(httpTransportFactory) .setTokenServerUri(tokenServer1) .build(); UserCredentials otherCredentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(httpTransportFactory) .setTokenServerUri(tokenServer2) .build(); assertFalse(credentials.equals(otherCredentials)); assertFalse(otherCredentials.equals(credentials)); }
@Test public void equals_false_accessToken() throws IOException { final URI tokenServer1 = URI.create("https://foo1.com/bar"); AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null); AccessToken otherAccessToken = new AccessToken("otherAccessToken", null); MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory(); UserCredentials credentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(httpTransportFactory) .setTokenServerUri(tokenServer1) .build(); UserCredentials otherCredentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(otherAccessToken) .setHttpTransportFactory(httpTransportFactory) .setTokenServerUri(tokenServer1) .build(); assertFalse(credentials.equals(otherCredentials)); assertFalse(otherCredentials.equals(credentials)); }
@Test public void equals_true() throws IOException { final URI tokenServer = URI.create("https://foo.com/bar"); MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null); UserCredentials credentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(transportFactory) .setTokenServerUri(tokenServer) .build(); UserCredentials otherCredentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(transportFactory) .setTokenServerUri(tokenServer) .build(); assertTrue(credentials.equals(otherCredentials)); assertTrue(otherCredentials.equals(credentials)); }
@Test public void equals_false_refreshToken() throws IOException { final URI tokenServer1 = URI.create("https://foo1.com/bar"); AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null); MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory(); OAuth2Credentials credentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(httpTransportFactory) .setTokenServerUri(tokenServer1) .build(); OAuth2Credentials otherCredentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken("otherRefreshToken") .setAccessToken(accessToken) .setHttpTransportFactory(httpTransportFactory) .setTokenServerUri(tokenServer1) .build(); assertFalse(credentials.equals(otherCredentials)); assertFalse(otherCredentials.equals(credentials)); }
@Test public void hashCode_equals() throws IOException { final URI tokenServer = URI.create("https://foo.com/bar"); MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null); UserCredentials credentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(transportFactory) .setTokenServerUri(tokenServer) .build(); UserCredentials otherCredentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(transportFactory) .setTokenServerUri(tokenServer) .build(); assertEquals(credentials.hashCode(), otherCredentials.hashCode()); }
@Test public void equals_false_clientId() throws IOException { final URI tokenServer1 = URI.create("https://foo1.com/bar"); AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null); MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory(); UserCredentials credentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(httpTransportFactory) .setTokenServerUri(tokenServer1) .build(); UserCredentials otherCredentials = UserCredentials.newBuilder() .setClientId("other client id") .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(httpTransportFactory) .setTokenServerUri(tokenServer1) .build(); assertFalse(credentials.equals(otherCredentials)); assertFalse(otherCredentials.equals(credentials)); }
@Test public void initialize_noURI() throws IOException { final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2"; final String expectedAuthorization = InternalAuthHttpConstants.BEARER_PREFIX + accessToken; MockTokenServerTransportFactory tokenServerTransportFactory = new MockTokenServerTransportFactory(); tokenServerTransportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET); tokenServerTransportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken); OAuth2Credentials credentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setHttpTransportFactory(tokenServerTransportFactory) .build(); HttpCredentialsAdapter adapter = new HttpCredentialsAdapter(credentials); HttpRequestFactory requestFactory = tokenServerTransportFactory.transport.createRequestFactory(); HttpRequest request = requestFactory.buildGetRequest(null); adapter.initialize(request); HttpHeaders requestHeaders = request.getHeaders(); String authorizationHeader = requestHeaders.getAuthorization(); assertEquals(authorizationHeader, expectedAuthorization); } }
@Test public void initialize_populatesOAuth2Credentials() throws IOException { final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2"; final String expectedAuthorization = InternalAuthHttpConstants.BEARER_PREFIX + accessToken; MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET); transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken); OAuth2Credentials credentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setHttpTransportFactory(transportFactory) .build(); HttpCredentialsAdapter adapter = new HttpCredentialsAdapter(credentials); HttpRequestFactory requestFactory = transportFactory.transport.createRequestFactory(); HttpRequest request = requestFactory.buildGetRequest(new GenericUrl("http://foo")); adapter.initialize(request); HttpHeaders requestHeaders = request.getHeaders(); String authorizationHeader = requestHeaders.getAuthorization(); assertEquals(authorizationHeader, expectedAuthorization); }
@Test public void getRequestMetadata_customTokenServer_hasAccessToken() throws IOException { final URI TOKEN_SERVER = URI.create("https://foo.com/bar"); MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET); transportFactory.transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN); transportFactory.transport.setTokenServerUri(TOKEN_SERVER); UserCredentials userCredentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setHttpTransportFactory(transportFactory) .setTokenServerUri(TOKEN_SERVER) .build(); Map<String, List<String>> metadata = userCredentials.getRequestMetadata(CALL_URI); TestUtils.assertContainsBearerToken(metadata, ACCESS_TOKEN); }
@Test public void serialize() throws IOException, ClassNotFoundException { final URI tokenServer = URI.create("https://foo.com/bar"); MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null); UserCredentials credentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setAccessToken(accessToken) .setHttpTransportFactory(transportFactory) .setTokenServerUri(tokenServer) .build(); UserCredentials deserializedCredentials = serializeAndDeserialize(credentials); assertEquals(credentials, deserializedCredentials); assertEquals(credentials.hashCode(), deserializedCredentials.hashCode()); assertEquals(credentials.toString(), deserializedCredentials.toString()); assertSame(deserializedCredentials.clock, Clock.SYSTEM); }
@Test public void getRequestMetadata_initialTokenRefreshed_throws() throws IOException { MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET); AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null); UserCredentials userCredentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setAccessToken(accessToken) .setHttpTransportFactory(transportFactory) .build(); try { userCredentials.refresh(); fail("Should not be able to refresh without refresh token."); } catch (IllegalStateException expected) { // Expected } }
@Test public void getRequestMetadata_fromRefreshToken_hasAccessToken() throws IOException { MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET); transportFactory.transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN); UserCredentials userCredentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setRefreshToken(REFRESH_TOKEN) .setHttpTransportFactory(transportFactory) .build(); Map<String, List<String>> metadata = userCredentials.getRequestMetadata(CALL_URI); TestUtils.assertContainsBearerToken(metadata, ACCESS_TOKEN); }
@Test public void getRequestMetadata_initialToken_hasAccessToken() throws IOException { MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET); AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null); UserCredentials userCredentials = UserCredentials.newBuilder() .setClientId(CLIENT_ID) .setClientSecret(CLIENT_SECRET) .setAccessToken(accessToken) .setHttpTransportFactory(transportFactory) .build(); Map<String, List<String>> metadata = userCredentials.getRequestMetadata(CALL_URI); TestUtils.assertContainsBearerToken(metadata, ACCESS_TOKEN); }