package com.google.wallet.objects.utils;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.util.SecurityUtils;
import com.google.common.io.ByteStreams;
import java.io.*;
import java.security.GeneralSecurityException;
import java.security.interfaces.RSAPrivateKey;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Class to define Wallet Object related credentials. These credentials are used
* with WobUtils to simplify the OAuth token generation and JWT signing.
* <p/>
* If you're using a key file, specify the privateKeyPath using the first
* constructor. If you've defined the private key as a base 64 encoded string,
* convert it to an RSAPrivate Key with WobUtils.getRsaPrivateKey.
*
* @author pying
*/
public class WobCredentials {
String serviceAccountId;
String serviceAccountPrivateKeyPath;
String applicationName;
String issuerId;
private RSAPrivateKey serviceAccountPrivateKey;
public static final HttpTransport httpTransport = new NetHttpTransport();
public static final JsonFactory jsonFactory = new GsonFactory();
public static final List<String> scopes = Collections.unmodifiableList(Arrays.asList(
"https://www.googleapis.com/auth/wallet_object.issuer",
"https://www.googleapis.com/auth/wallet_object_sandbox.issuer"));
private GoogleCredential gCredential;
/**
* Constructor for defining a path to your key.p12 file.
*
* @param serviceAccountId
* @param privateKeyPath
* @param applicationName
* @param issuerId
*/
public WobCredentials(String serviceAccountId, String privateKeyPath,
String applicationName, String issuerId) throws IOException, GeneralSecurityException {
setServiceAccountId(serviceAccountId);
setServiceAccountPrivateKeyPath(privateKeyPath);
setApplicationName(applicationName);
setIssuerId(issuerId);
generateRsaKey();
generateGoogleCredential();
}
/**
* Constructor for a base64 encoded private key String.
*
* @param serviceAccountId
* @param privateKey
* @param applicationName
* @param issuerId
*/
public WobCredentials(String serviceAccountId, RSAPrivateKey privateKey,
String applicationName, String issuerId) {
setServiceAccountId(serviceAccountId);
setServiceAccountPrivateKey(privateKey);
setApplicationName(applicationName);
setIssuerId(issuerId);
generateGoogleCredential();
}
/**
* Helper function to generate the Google Credential
*
* @return
* @throws GeneralSecurityException
* @throws IOException
*/
private void generateGoogleCredential() {
gCredential = new GoogleCredential.Builder().setTransport(httpTransport).setJsonFactory(jsonFactory)
.setServiceAccountId(serviceAccountId).setServiceAccountScopes(scopes)
.setServiceAccountPrivateKey(serviceAccountPrivateKey).build();
}
private void generateRsaKey() throws IOException, GeneralSecurityException {
File file = new File(serviceAccountPrivateKeyPath);
System.out.println("Key Path: " + file.getAbsolutePath());
byte[] bytes = ByteStreams.toByteArray(new FileInputStream(file));
InputStream keyStream = new ByteArrayInputStream(bytes);
serviceAccountPrivateKey = (RSAPrivateKey) SecurityUtils.loadPrivateKeyFromKeyStore(
SecurityUtils.getPkcs12KeyStore(), keyStream, "notasecret",
"privatekey", "notasecret");
}
/**
* @return the serviceAccountPrivateKey
*/
public RSAPrivateKey getServiceAccountPrivateKey() {
return serviceAccountPrivateKey;
}
/**
* @param serviceAccountPrivateKey the serviceAccountPrivateKey to set
*/
public void setServiceAccountPrivateKey(RSAPrivateKey serviceAccountPrivateKey) {
this.serviceAccountPrivateKey = serviceAccountPrivateKey;
}
/**
* @return the serviceAccountId
*/
public String getServiceAccountId() {
return serviceAccountId;
}
/**
* @param serviceAccountId the serviceAccountId to set
*/
public void setServiceAccountId(String serviceAccountId) {
this.serviceAccountId = serviceAccountId;
}
/**
* @return the serviceAccountPrivateKey
*/
public String getServiceAccountPrivateKeyPath() {
return serviceAccountPrivateKeyPath;
}
/**
* @param serviceAccountPrivateKey the serviceAccountPrivateKey to set
*/
public void setServiceAccountPrivateKeyPath(String serviceAccountPrivateKey) {
this.serviceAccountPrivateKeyPath = serviceAccountPrivateKey;
}
/**
* @return the applicationName
*/
public String getApplicationName() {
return applicationName;
}
/**
* @param applicationName the applicationName to set
*/
public void setApplicationName(String applicationName) {
this.applicationName = applicationName;
}
/**
* @return the issuerId
*/
public String getIssuerId() {
return issuerId;
}
/**
* @param issuerId the issuerId to set
*/
public void setIssuerId(String issuerId) {
this.issuerId = issuerId;
}
public String toString() {
StringBuilder sb =
new StringBuilder().append(serviceAccountId).append(serviceAccountPrivateKeyPath).append(applicationName)
.append(issuerId).append(new String(serviceAccountPrivateKey.getEncoded()));
return sb.toString();
}
public GoogleCredential getGoogleCredential() {
return gCredential;
}
/**
* Refreshes the access token and returns it. You do not need to explicitly call this function.
* You should only call it for one offs, like a script to request access tokens.
*
* @return OAuth access token
* @throws GeneralSecurityException
* @throws IOException
*/
public String accessToken() throws GeneralSecurityException, IOException {
gCredential.refreshToken();
return gCredential.getAccessToken();
}
}