Skip to content

Commit

Permalink
Rename SigningCredentials to ServiceAccountSigner
Browse files Browse the repository at this point in the history
  • Loading branch information
mziccard committed Apr 5, 2016
1 parent de3c47f commit 08e23ff
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ public abstract class AuthCredentials implements Restorable<AuthCredentials> {
* Represents built-in credentials when running in Google App Engine.
*/
public static class AppEngineAuthCredentials extends AuthCredentials
implements SigningAuthCredentials {
implements ServiceAccountSigner {

private static final AuthCredentials INSTANCE = new AppEngineAuthCredentials();
private static final AppEngineAuthCredentialsState STATE = new AppEngineAuthCredentialsState();

private AppEngineCredentials credentials;

private static class AppEngineCredentials extends GoogleCredentials
implements SigningAuthCredentials {
implements ServiceAccountSigner {

private final Object appIdentityService;
private final String account;
Expand Down Expand Up @@ -191,7 +191,7 @@ public byte[] sign(byte[] toSign) {
* User accounts and service accounts</a>
*/
public static class ServiceAccountAuthCredentials extends AuthCredentials
implements SigningAuthCredentials {
implements ServiceAccountSigner {

private final ServiceAccountCredentials credentials;
private final String account;
Expand Down Expand Up @@ -232,15 +232,13 @@ public boolean equals(Object obj) {
}

ServiceAccountAuthCredentials(String account, PrivateKey privateKey) {
this.account = checkNotNull(account);
this.privateKey = checkNotNull(privateKey);
this.credentials = new ServiceAccountCredentials(null, account, privateKey, null, null);
this(new ServiceAccountCredentials(null, account, privateKey, null, null));
}

ServiceAccountAuthCredentials(ServiceAccountCredentials credentials) {
this.credentials = checkNotNull(credentials);
this.account = credentials.getClientEmail();
this.privateKey = credentials.getPrivateKey();
this.account = checkNotNull(credentials.getClientEmail());
this.privateKey = checkNotNull(credentials.getPrivateKey());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,48 @@

package com.google.gcloud;

import java.util.Objects;

/**
* Interface for authentication credentials that support signing.
* Interface for a service account signer. A signer for a service account is capable of signing
* bytes using the private key associated with its service account.
*/
public interface SigningAuthCredentials {
public interface ServiceAccountSigner {

class SigningException extends RuntimeException {

private static final long serialVersionUID = 8962780757822799255L;

SigningException(String message, Exception cause) {
super(message, cause);
}

@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof SigningException)) {
return false;
}
SigningException other = (SigningException) obj;
return Objects.equals(getCause(), other.getCause())
&& Objects.equals(getMessage(), other.getMessage());
}

@Override
public int hashCode() {
return Objects.hash(getMessage(), getCause());
}
}

/**
* Returns the service account associated with the auth credentials.
* Returns the service account associated with the signer.
*/
String account();

/**
* Signs the provided bytes using the private key associated with the credentials.
* Signs the provided bytes using the private key associated with the service account.
*
* @param toSign bytes to sign
* @return signed bytes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.google.gcloud;

import com.google.common.collect.ImmutableList;
import com.google.gcloud.ServiceAccountSigner.SigningException;

import java.io.ByteArrayInputStream;
import java.io.IOException;
Expand Down Expand Up @@ -52,6 +53,8 @@ public Builder toBuilder() {
private static final Identity IDENTITY = Identity.allAuthenticatedUsers();
private static final PageImpl<String> PAGE =
new PageImpl<>(null, "cursor", ImmutableList.of("string1", "string2"));
private static final SigningException SIGNING_EXCEPTION =
new SigningException("message", BASE_SERVICE_EXCEPTION);
private static final RetryParams RETRY_PARAMS = RetryParams.defaultInstance();
private static final SomeIamPolicy SOME_IAM_POLICY = new SomeIamPolicy.Builder().build();
private static final String JSON_KEY = "{\n"
Expand Down Expand Up @@ -84,7 +87,7 @@ public Builder toBuilder() {
@Override
protected Serializable[] serializableObjects() {
return new Serializable[]{BASE_SERVICE_EXCEPTION, EXCEPTION_HANDLER, IDENTITY, PAGE,
RETRY_PARAMS, SOME_IAM_POLICY};
RETRY_PARAMS, SOME_IAM_POLICY, SIGNING_EXCEPTION};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ public void run(Storage storage, Tuple<ServiceAccountAuthCredentials, BlobInfo>
private void run(Storage storage, ServiceAccountAuthCredentials cred, BlobInfo blobInfo) {
Blob blob = storage.get(blobInfo.blobId());
System.out.println("Signed URL: "
+ blob.signUrl(1, TimeUnit.DAYS, SignUrlOption.serviceAccount(cred)));
+ blob.signUrl(1, TimeUnit.DAYS, SignUrlOption.signer(cred)));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
import com.google.gcloud.AuthCredentials.AppEngineAuthCredentials;
import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials;
import com.google.gcloud.ReadChannel;
import com.google.gcloud.SigningAuthCredentials;
import com.google.gcloud.SigningAuthCredentials.SigningException;
import com.google.gcloud.ServiceAccountSigner;
import com.google.gcloud.ServiceAccountSigner.SigningException;
import com.google.gcloud.WriteChannel;
import com.google.gcloud.storage.Storage.BlobTargetOption;
import com.google.gcloud.storage.Storage.BlobWriteOption;
Expand Down Expand Up @@ -462,17 +462,16 @@ public WriteChannel writer(BlobWriteOption... options) {
* this blob, you can use this method to generate a URL that is only valid within a certain time
* period. This is particularly useful if you don't want publicly accessible blobs, but also don't
* want to require users to explicitly log in. Signing a URL requires
* authentication credentials capable of signing. If a {@link ServiceAccountAuthCredentials} or an
* a service account signer. If a {@link ServiceAccountAuthCredentials} or an
* {@link AppEngineAuthCredentials} was passed to
* {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default credentials
* are being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} is set, then
* {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default credentials are

This comment has been minimized.

Copy link
@aozarov

aozarov Apr 5, 2016

Contributor

I think we can make this javadoc more clear with the order of a signer lookup (provided, given credentials, default credentials) and exception otherwise.

Also, I wonder if we should change the exception to IllegalStateException as if signer argument is provided it will never throw that exception, so such exception is only thrown when argument is not provided...

* being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} is set, then
* {@code signUrl} will use that credentials to sign the URL. If the credentials passed to
* {@link StorageOptions} do not implement {@link SigningAuthCredentials}
* (this is the case for Compute Engine credentials and Google Cloud SDK credentials) then
* {@code signUrl} will throw an {@link IllegalArgumentException} unless an implementation of
* {@link SigningAuthCredentials} is passed using the {@code SignUrlOption.serviceAccount()}
* option. The service account and private key passed with {@code SignUrlOption.serviceAccount()}
* have priority over any credentials set with
* {@link StorageOptions} do not implement {@link ServiceAccountSigner} (this is the case for
* Compute Engine credentials and Google Cloud SDK credentials) then {@code signUrl} will throw an
* {@link IllegalArgumentException} unless an implementation of {@link ServiceAccountSigner} is
* passed using the {@code SignUrlOption.signer()} option. The signer passed with
* {@code SignUrlOption.signer()} has priority over any credentials set with
* {@link StorageOptions.Builder#authCredentials(AuthCredentials)}.
*
* <p>Example usage of creating a signed URL that is valid for 2 weeks, using the default
Expand All @@ -481,10 +480,10 @@ public WriteChannel writer(BlobWriteOption... options) {
* blob.signUrl(14, TimeUnit.DAYS);
* }</pre>
*
* <p>Example usage of creating a signed URL passing the {@code SignUrlOption.serviceAccount()}
* option, that will be used for signing the URL:
* <p>Example usage of creating a signed URL passing the {@code SignUrlOption.signer()} option,
* that will be used for signing the URL:
* <pre> {@code
* blob.signUrl(14, TimeUnit.DAYS, SignUrlOption.serviceAccount(
* blob.signUrl(14, TimeUnit.DAYS, SignUrlOption.signer(
* AuthCredentials.createForJson(new FileInputStream("/path/to/key.json"))));
* }</pre>
*
Expand All @@ -493,8 +492,8 @@ public WriteChannel writer(BlobWriteOption... options) {
* @param unit time unit of the {@code duration} parameter
* @param options optional URL signing options
* @return a signed URL for this blob and the specified options
* @throws IllegalArgumentException if {@code SignUrlOption.serviceAccount()} was not used and no
* implementation of {@link SigningAuthCredentials} was provided to {@link StorageOptions}
* @throws IllegalArgumentException if {@code SignUrlOption.signer()} was not used and no
* implementation of {@link ServiceAccountSigner} was provided to {@link StorageOptions}
* @throws IllegalArgumentException if {@code SignUrlOption.withMd5()} option is used and
* {@code blobInfo.md5()} is {@code null}
* @throws IllegalArgumentException if {@code SignUrlOption.withContentType()} option is used and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
import com.google.gcloud.Page;
import com.google.gcloud.ReadChannel;
import com.google.gcloud.Service;
import com.google.gcloud.SigningAuthCredentials;
import com.google.gcloud.SigningAuthCredentials.SigningException;
import com.google.gcloud.ServiceAccountSigner;
import com.google.gcloud.ServiceAccountSigner.SigningException;
import com.google.gcloud.WriteChannel;
import com.google.gcloud.storage.spi.StorageRpc;
import com.google.gcloud.storage.spi.StorageRpc.Tuple;
Expand Down Expand Up @@ -768,13 +768,13 @@ public static SignUrlOption withMd5() {
}

/**
* Signing credentials which should be used to sign the URL. If not provided an attempt will be
* made to get it from the environment.
* Provides a service account signer to sign the URL. If not provided an attempt will be made to
* get it from the environment.
*
* @see <a href="https://cloud.google.com/storage/docs/authentication#service_accounts">Service
* account</a>
*/
public static SignUrlOption serviceAccount(SigningAuthCredentials credentials) {
public static SignUrlOption signer(ServiceAccountSigner credentials) {

This comment has been minimized.

Copy link
@aozarov

aozarov Apr 5, 2016

Contributor

signer -> signWith ? Also s/credentials/signer/

return new SignUrlOption(Option.SERVICE_ACCOUNT_CRED, credentials);
}
}
Expand Down Expand Up @@ -1474,17 +1474,16 @@ public static Builder builder() {
* fixed amount of time, you can use this method to generate a URL that is only valid within a
* certain time period. This is particularly useful if you don't want publicly accessible blobs,
* but also don't want to require users to explicitly log in. Signing a URL requires
* authentication credentials capable of signing. If a {@link ServiceAccountAuthCredentials} or an
* a service account signer. If a {@link ServiceAccountAuthCredentials} or an
* {@link AppEngineAuthCredentials} was passed to
* {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default credentials
* are being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} is set, then
* {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default credentials are
* being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} is set, then
* {@code signUrl} will use that credentials to sign the URL. If the credentials passed to
* {@link StorageOptions} do not implement {@link SigningAuthCredentials}
* (this is the case for Compute Engine credentials and Google Cloud SDK credentials) then
* {@code signUrl} will throw an {@link IllegalArgumentException} unless an implementation of
* {@link SigningAuthCredentials} is passed using the {@code SignUrlOption.serviceAccount()}
* option. The service account and private key passed with {@code SignUrlOption.serviceAccount()}
* have priority over any credentials set with
* {@link StorageOptions} do not implement {@link ServiceAccountSigner} (this is the case for
* Compute Engine credentials and Google Cloud SDK credentials) then {@code signUrl} will throw an
* {@link IllegalArgumentException} unless an implementation of {@link ServiceAccountSigner} is
* passed using the {@code SignUrlOption.signer()} option. The signer passed with
* {@code SignUrlOption.signer()} has priority over any credentials set with
* {@link StorageOptions.Builder#authCredentials(AuthCredentials)}.
*
* <p>Example usage of creating a signed URL that is valid for 2 weeks, using the default
Expand All @@ -1493,11 +1492,11 @@ public static Builder builder() {
* service.signUrl(BlobInfo.builder("bucket", "name").build(), 14, TimeUnit.DAYS);
* }</pre>
*
* <p>Example usage of creating a signed URL passing the {@code SignUrlOption.serviceAccount()}
* option, that will be used for signing the URL:
* <p>Example usage of creating a signed URL passing the {@code SignUrlOption.signer()} option,
* that will be used for signing the URL:
* <pre> {@code
* service.signUrl(BlobInfo.builder("bucket", "name").build(), 14, TimeUnit.DAYS,
* SignUrlOption.serviceAccount(
* SignUrlOption.signer(
* AuthCredentials.createForJson(new FileInputStream("/path/to/key.json"))));
* }</pre>
*
Expand All @@ -1506,8 +1505,8 @@ public static Builder builder() {
* granularity supported is 1 second, finer granularities will be truncated
* @param unit time unit of the {@code duration} parameter
* @param options optional URL signing options
* @throws IllegalArgumentException if {@code SignUrlOption.serviceAccount()} was not used and no
* implementation of {@link SigningAuthCredentials} was provided to {@link StorageOptions}
* @throws IllegalArgumentException if {@code SignUrlOption.signer()} was not used and no
* implementation of {@link ServiceAccountSigner} was provided to {@link StorageOptions}
* @throws IllegalArgumentException if {@code SignUrlOption.withMd5()} option is used and
* {@code blobInfo.md5()} is {@code null}
* @throws IllegalArgumentException if {@code SignUrlOption.withContentType()} option is used and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
import com.google.gcloud.PageImpl.NextPageFetcher;
import com.google.gcloud.ReadChannel;
import com.google.gcloud.RetryHelper.RetryHelperException;
import com.google.gcloud.SigningAuthCredentials;
import com.google.gcloud.ServiceAccountSigner;
import com.google.gcloud.storage.spi.StorageRpc;
import com.google.gcloud.storage.spi.StorageRpc.RewriteResponse;
import com.google.gcloud.storage.spi.StorageRpc.Tuple;
Expand Down Expand Up @@ -533,13 +533,12 @@ public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOptio
for (SignUrlOption option : options) {
optionMap.put(option.option(), option.value());
}
SigningAuthCredentials authCredentials =
(SigningAuthCredentials) optionMap.get(SignUrlOption.Option.SERVICE_ACCOUNT_CRED);
ServiceAccountSigner authCredentials =
(ServiceAccountSigner) optionMap.get(SignUrlOption.Option.SERVICE_ACCOUNT_CRED);
if (authCredentials == null) {
checkArgument(this.options().authCredentials() != null
&& this.options().authCredentials() instanceof SigningAuthCredentials,
checkArgument(this.options().authCredentials() instanceof ServiceAccountSigner,

This comment has been minimized.

Copy link
@aozarov

aozarov Apr 5, 2016

Contributor

see my comment above about considering the use of checkState instead.

"Signing key was not provided and could not be derived");
authCredentials = (SigningAuthCredentials) this.options().authCredentials();
authCredentials = (ServiceAccountSigner) this.options().authCredentials();
}
// construct signature - see https://cloud.google.com/storage/docs/access-control#Signed-URLs
StringBuilder stBuilder = new StringBuilder();
Expand Down

0 comments on commit 08e23ff

Please sign in to comment.