Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented in-memory TokenStore and added opportunity to save user credentials into file #129

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4fa1b0d
Created MemoryCredentialsStorage and implemented added opportunity to…
YuryBandarchuk16 Sep 14, 2017
9cfc14d
Moved TokenStore.java to another directory
YuryBandarchuk16 Sep 14, 2017
48ff167
Comments added
YuryBandarchuk16 Sep 14, 2017
dd03f9d
Tests for UserAuthorizer updated
YuryBandarchuk16 Sep 14, 2017
71adc52
Renamed MemoryCredentialsStorage to MemoryTokensStorage
YuryBandarchuk16 Sep 14, 2017
8208263
Tests for UserCredentials updated
YuryBandarchuk16 Sep 14, 2017
b44d07d
Java header added
YuryBandarchuk16 Sep 14, 2017
8adc97a
small fixes
YuryBandarchuk16 Sep 14, 2017
431453d
Used MemoryTokenStorage as default for UserAuthorizer
YuryBandarchuk16 Sep 14, 2017
c3feabc
Comments regrading credentials
YuryBandarchuk16 Sep 14, 2017
5fcddeb
Removed unnecessary test
YuryBandarchuk16 Sep 15, 2017
7bcfeab
Add apache.commons.io dependency and update the implementation of 'sa…
YuryBandarchuk16 Nov 2, 2017
b28a59b
Merge branch 'MemoryCrenetialsStorage' of https://github.com/YuryBand…
YuryBandarchuk16 Nov 2, 2017
32e098d
Merge branch 'master' into MemoryCrenetialsStorage
YuryBandarchuk16 Nov 2, 2017
46ea6af
Returned pom.xml to its previous state, used Guava 'ByteStreams.copy'…
YuryBandarchuk16 Nov 2, 2017
7845198
Move storage implementation to its original package.
YuryBandarchuk16 Nov 2, 2017
de94bcc
Update the implementation of saving user credentials, fix issues with…
YuryBandarchuk16 Nov 2, 2017
366e718
Merge branch 'master' into MemoryCrenetialsStorage
YuryBandarchuk16 Nov 2, 2017
8e59f30
Merge branch 'master' into MemoryCrenetialsStorage
YuryBandarchuk16 Nov 2, 2017
4026b3a
Use temporary files for tests, move generic implementation to 'OAuth2…
YuryBandarchuk16 Nov 2, 2017
e3d8020
Update method name to 'writeInputStreamToFile'.
YuryBandarchuk16 Nov 2, 2017
7f60405
Merge branch 'master' into MemoryCrenetialsStorage
YuryBandarchuk16 Nov 2, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

import java.io.IOException;
import java.io.InputStream;

import java.util.Collection;

/**
Expand Down
59 changes: 59 additions & 0 deletions oauth2_http/java/com/google/auth/oauth2/MemoryTokensStorage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2017, Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package com.google.auth.oauth2;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
* Represents an in-memory storage of tokens.
*/
public class MemoryTokensStorage implements TokenStore {
private final Map<String, String> tokensStorage = new HashMap<>();

@Override
public String load(String id) throws IOException {
return tokensStorage.get(id);
}

@Override
public void store(String id, String tokens) throws IOException {
tokensStorage.put(id, tokens);
}

@Override
public void delete(String id) throws IOException {
tokensStorage.remove(id);
}

}
20 changes: 20 additions & 0 deletions oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,14 @@
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.auth.http.AuthHttpConstants;
import com.google.auth.http.HttpTransportFactory;
import com.google.common.io.ByteStreams;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URI;
import java.nio.charset.Charset;
Expand Down Expand Up @@ -122,6 +126,22 @@ static String validateString(Map<String, Object> map, String key, String errorPr
return (String) value;
}

/**
* Saves the end user credentials into the given file path.
*
* @param credentials InputStream containing user credentials in JSON format
* @param filePath Path to file where to store the credentials
* @throws IOException An error saving the credentials.
*/
static void writeInputStreamToFile(InputStream credentials, String filePath) throws IOException {
final OutputStream outputStream = new FileOutputStream(new File(filePath));
try {
ByteStreams.copy(credentials, outputStream);
} finally {
outputStream.close();
}
}

/**
* Return the specified optional string from JSON or throw a helpful error message.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public UserAuthorizer(ClientId clientId, Collection<String> scopes, TokenStore t
(transportFactory == null) ? OAuth2Utils.HTTP_TRANSPORT_FACTORY : transportFactory;
this.tokenServerUri = (tokenServerUri == null) ? OAuth2Utils.TOKEN_SERVER_URI : tokenServerUri;
this.userAuthUri = (userAuthUri == null) ? OAuth2Utils.USER_AUTH_URI : userAuthUri;
this.tokenStore = tokenStore;
this.tokenStore = (tokenStore == null) ? new MemoryTokensStorage() : tokenStore;
}


Expand Down
48 changes: 46 additions & 2 deletions oauth2_http/java/com/google/auth/oauth2/UserCredentials.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

package com.google.auth.oauth2;

import static com.google.auth.oauth2.OAuth2Utils.JSON_FACTORY;
import static com.google.auth.oauth2.OAuth2Utils.UTF_8;
import static com.google.common.base.MoreObjects.firstNonNull;

import com.google.api.client.http.GenericUrl;
Expand All @@ -45,6 +47,7 @@
import com.google.api.client.util.Preconditions;
import com.google.auth.http.HttpTransportFactory;

import java.io.ByteArrayInputStream;
import com.google.common.base.MoreObjects;
import java.io.IOException;
import java.io.InputStream;
Expand Down Expand Up @@ -184,7 +187,7 @@ public static UserCredentials fromStream(InputStream credentialsStream,
Preconditions.checkNotNull(credentialsStream);
Preconditions.checkNotNull(transportFactory);

JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY;
JsonFactory jsonFactory = JSON_FACTORY;
JsonObjectParser parser = new JsonObjectParser(jsonFactory);
GenericJson fileContents = parser.parseAndClose(
credentialsStream, OAuth2Utils.UTF_8, GenericJson.class);
Expand Down Expand Up @@ -220,7 +223,7 @@ public AccessToken refreshAccessToken() throws IOException {
HttpRequestFactory requestFactory = transportFactory.create().createRequestFactory();
HttpRequest request =
requestFactory.buildPostRequest(new GenericUrl(tokenServerUri), content);
request.setParser(new JsonObjectParser(OAuth2Utils.JSON_FACTORY));
request.setParser(new JsonObjectParser(JSON_FACTORY));
HttpResponse response = request.execute();
GenericData responseData = response.parseAs(GenericData.class);
String accessToken =
Expand Down Expand Up @@ -258,6 +261,47 @@ public final String getRefreshToken() {
return refreshToken;
}


/**
* Returns the instance of InputStream containing the following user credentials in JSON format:
* - RefreshToken
* - ClientId
* - ClientSecret
* - ServerTokenUri
*
* @return user credentials stream
*/
private InputStream getUserCredentialsStream() throws IOException {
GenericJson json = new GenericJson();
json.put("type", GoogleCredentials.USER_FILE_TYPE);
if (refreshToken != null) {
json.put("refresh_token", refreshToken);
}
if (tokenServerUri != null) {
json.put("token_server_uri", tokenServerUri);
}
if (clientId != null) {
json.put("client_id", clientId);
}
if (clientSecret != null) {
json.put("client_secret", clientSecret);
}
json.setFactory(JSON_FACTORY);
String text = json.toPrettyString();
return new ByteArrayInputStream(text.getBytes(UTF_8));
}

/**
* Saves the end user credentials into the given file path.
*
* @param filePath Path to file where to store the credentials
*
* @throws IOException An error storing the credentials.
*/
public void save(String filePath) throws IOException {
OAuth2Utils.writeInputStreamToFile(getUserCredentialsStream(), filePath);
}

@Override
public int hashCode() {
return Objects.hash(super.hashCode(), clientId, clientSecret, refreshToken, tokenServerUri,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
Expand All @@ -75,7 +74,7 @@ public class UserAuthorizerTest {

@Test
public void constructorMinimum() {
TestTokenStore store = new TestTokenStore();
TokenStore store = new MemoryTokensStorage();

UserAuthorizer authorizer = UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
Expand All @@ -91,7 +90,7 @@ public void constructorMinimum() {

@Test
public void constructorCommon() {
TestTokenStore store = new TestTokenStore();
TokenStore store = new MemoryTokensStorage();

UserAuthorizer authorizer = UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
Expand Down Expand Up @@ -172,7 +171,7 @@ public void getCredentials_noCredentials_returnsNull() throws IOException {
UserAuthorizer authorizer = UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
.setScopes(SCOPES)
.setTokenStore(new TestTokenStore())
.setTokenStore(new MemoryTokensStorage())
.build();

UserCredentials credentials = authorizer.getCredentials(USER_ID);
Expand All @@ -182,7 +181,7 @@ public void getCredentials_noCredentials_returnsNull() throws IOException {

@Test
public void getCredentials_storedCredentials_returnsStored() throws IOException {
TestTokenStore tokenStore = new TestTokenStore();
TokenStore tokenStore = new MemoryTokensStorage();

UserCredentials initialCredentials = UserCredentials.newBuilder()
.setClientId(CLIENT_ID_VALUE)
Expand All @@ -207,7 +206,7 @@ public void getCredentials_storedCredentials_returnsStored() throws IOException

@Test(expected = NullPointerException.class)
public void getCredentials_nullUserId_throws() throws IOException {
TestTokenStore tokenStore = new TestTokenStore();
TokenStore tokenStore = new MemoryTokensStorage();
UserAuthorizer authorizer = UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
.setScopes(SCOPES)
Expand All @@ -217,16 +216,6 @@ public void getCredentials_nullUserId_throws() throws IOException {
authorizer.getCredentials(null);
}

@Test(expected = IllegalStateException.class)
public void getCredentials_nullTokenStore_throws() throws IOException {
UserAuthorizer authorizer = UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
.setScopes(SCOPES)
.build();

authorizer.getCredentials(USER_ID);
}

@Test
public void getCredentials_refreshedToken_stored() throws IOException {
final String accessTokenValue1 = "1/MkSJoj1xsli0AccessToken_NKPY2";
Expand All @@ -236,7 +225,7 @@ public void getCredentials_refreshedToken_stored() throws IOException {
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET);
transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessTokenValue2);
TestTokenStore tokenStore = new TestTokenStore();
TokenStore tokenStore = new MemoryTokensStorage();
UserAuthorizer authorizer = UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
.setScopes(SCOPES)
Expand Down Expand Up @@ -277,7 +266,7 @@ public void getCredentialsFromCode_conevertsCodeToTokens() throws IOException {
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET);
transportFactory.transport.addAuthorizationCode(CODE, REFRESH_TOKEN, ACCESS_TOKEN_VALUE);
TestTokenStore tokenStore = new TestTokenStore();
TokenStore tokenStore = new MemoryTokensStorage();
UserAuthorizer authorizer = UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
.setScopes(SCOPES)
Expand All @@ -296,7 +285,7 @@ public void getCredentialsFromCode_nullCode_throws() throws IOException {
UserAuthorizer authorizer = UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
.setScopes(SCOPES)
.setTokenStore(new TestTokenStore())
.setTokenStore(new MemoryTokensStorage())
.build();

authorizer.getCredentialsFromCode(null, BASE_URI);
Expand All @@ -309,7 +298,7 @@ public void getAndStoreCredentialsFromCode_getAndStoresCredentials() throws IOEx
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET);
transportFactory.transport.addAuthorizationCode(CODE, REFRESH_TOKEN, accessTokenValue1);
TestTokenStore tokenStore = new TestTokenStore();
TokenStore tokenStore = new MemoryTokensStorage();
UserAuthorizer authorizer = UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
.setScopes(SCOPES)
Expand Down Expand Up @@ -342,7 +331,7 @@ public void getAndStoreCredentialsFromCode_nullCode_throws() throws IOException
UserAuthorizer authorizer = UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
.setScopes(SCOPES)
.setTokenStore(new TestTokenStore())
.setTokenStore(new MemoryTokensStorage())
.build();

authorizer.getAndStoreCredentialsFromCode(USER_ID, null, BASE_URI);
Expand All @@ -353,15 +342,15 @@ public void getAndStoreCredentialsFromCode_nullUserId_throws() throws IOExceptio
UserAuthorizer authorizer = UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
.setScopes(SCOPES)
.setTokenStore(new TestTokenStore())
.setTokenStore(new MemoryTokensStorage())
.build();

authorizer.getAndStoreCredentialsFromCode(null, CODE, BASE_URI);
}

@Test
public void revokeAuthorization_revokesAndClears() throws IOException {
TestTokenStore tokenStore = new TestTokenStore();
TokenStore tokenStore = new MemoryTokensStorage();
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET);
transportFactory.transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN_VALUE);
Expand Down Expand Up @@ -398,24 +387,4 @@ public void revokeAuthorization_revokesAndClears() throws IOException {
UserCredentials credentials2 = authorizer.getCredentials(USER_ID);
assertNull(credentials2);
}

private static class TestTokenStore implements TokenStore {

private final Map<String, String> map = new HashMap<>();

@Override
public String load(String id) throws IOException {
return map.get(id);
}

@Override
public void store(String id, String tokens) throws IOException {
map.put(id, tokens);
}

@Override
public void delete(String id) throws IOException {
map.remove(id);
}
}
}
Loading