Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 16 additions & 1 deletion java-spanner/google-cloud-spanner/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,19 @@
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:4.33.2:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.64.0:exe:${os.detected.classifier}</pluginArtifact>
<additionalProtoPathElements>
<additionalProtoPathElement>${project.basedir}/../proto-google-cloud-spanner-v1/src/main/proto</additionalProtoPathElement>
<additionalProtoPathElement>${project.basedir}/../google-cloud-spanner/src/main/proto</additionalProtoPathElement>
</additionalProtoPathElements>
</configuration>
<executions>
<execution>
<id>test-compile</id>
<id>compile</id>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
<goal>test-compile</goal>
</goals>
</execution>
Expand Down Expand Up @@ -544,6 +549,16 @@
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>1.78</version>
</dependency>
<dependency>
<groupId>com.google.crypto.tink</groupId>
<artifactId>tink</artifactId>
<version>1.13.0</version>
</dependency>
</dependencies>
</profile>
<profile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Duration;
Expand Down Expand Up @@ -1817,6 +1818,84 @@ public Builder setExperimentalHost(String host) {
return this;
}


/**
* Authenticates to Spanner Omni using the provided username and password file, and configures
* the resulting token for use in subsequent Spanner API calls. The endpoint must be set on the
* builder before calling this method.
*
* @param username The username for login.
* @param passwordFile The path to a file containing the password.
* @return this builder
*/
public Builder login(String username, String passwordFile) {
return login(username, passwordFile, true);
}

/**
* Authenticates to Spanner Omni using the provided username and password file, and configures
* the resulting token for use in subsequent Spanner API calls. The endpoint must be set on the
* builder before calling this method.
*
* @param username The username for login.
* @param passwordFile The path to a file containing the password.
* @param backgroundRefresh Whether to proactively refresh the token in a background thread before it expires. If false, GAX still triggers a synchronous inline refresh upon UNAUTHENTICATED error.
* @return this builder
*/
public Builder login(String username, String passwordFile, boolean backgroundRefresh) {
try {
byte[] rawBytes = Files.readAllBytes(Paths.get(passwordFile));
int len = rawBytes.length;
while (len > 0 && (rawBytes[len - 1] == '\n' || rawBytes[len - 1] == '\r')) {
len--;
}
byte[] passwordBytes = java.util.Arrays.copyOf(rawBytes, len);
return loginWithPasswordBytes(username, passwordBytes, backgroundRefresh);
} catch (IOException e) {
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.NOT_FOUND, "Could not read password file: " + passwordFile, e);
}
}

/**
* Authenticates to Spanner Omni using the provided username and password, and configures the
* resulting token for use in subsequent Spanner API calls. The endpoint must be set on the
* builder before calling this method.
*
* @param username The username for login.
* @param password The password for login.
* @return this builder
*/
public Builder loginWithPassword(String username, String password) {
return loginWithPassword(username, password, true);
}

/**
* Authenticates to Spanner Omni using the provided username and password, and configures the
* resulting token for use in subsequent Spanner API calls. The endpoint must be set on the
* builder before calling this method.
*
* @param username The username for login.
* @param password The password for login.
* @param backgroundRefresh Whether to proactively refresh the token in a background thread before it expires. If false, GAX still triggers a synchronous inline refresh upon UNAUTHENTICATED error.
* @return this builder
*/
public Builder loginWithPassword(String username, String password, boolean backgroundRefresh) {
return loginWithPasswordBytes(username, password.getBytes(StandardCharsets.UTF_8), backgroundRefresh);
}

private Builder loginWithPasswordBytes(String username, byte[] password, boolean backgroundRefresh) {
if (this.experimentalHost == null) {
throw new IllegalStateException("Endpoint must be set before calling login.");
}
String target = this.experimentalHost.replaceFirst("^https?://", "");
com.google.crypto.tink.util.SecretBytes secretBytes = com.google.crypto.tink.util.SecretBytes.copyFrom(
password, com.google.crypto.tink.InsecureSecretKeyAccess.get());
java.util.Arrays.fill(password, (byte) 0);
super.setCredentials(new com.google.cloud.spanner.omni.SpannerOmniCredentials(username, secretBytes, target, backgroundRefresh));
return this;
}

/** Enables gRPC-GCP extension with the default settings. This option is enabled by default. */
public Builder enableGrpcGcpExtension() {
return this.enableGrpcGcpExtension(null);
Expand Down
Loading
Loading