-
Notifications
You must be signed in to change notification settings - Fork 118
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
55c2d53
commit f710c18
Showing
14 changed files
with
257 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
test_runner/src/main/kotlin/com/google/api/client/http/GoogleApiLogger.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package com.google.api.client.http | ||
|
||
import com.google.auth.oauth2.ComputeEngineCredentials | ||
import java.util.logging.Level | ||
import java.util.logging.Logger | ||
import java.util.logging.SimpleFormatter | ||
import java.util.logging.StreamHandler | ||
|
||
// Used to enable cURL logging of the Java client API requests. | ||
// | ||
// Compare with gcloud sdk traffic by using the --log-http flag | ||
// | ||
// gcloud alpha firebase test ios models list --log-http | ||
// | ||
object GoogleApiLogger { | ||
fun logAllToStdout() { | ||
val logger = HttpTransport.LOGGER | ||
logger.level = Level.ALL | ||
|
||
val handler = StreamHandler(System.out, SimpleFormatter()) | ||
handler.level = Level.ALL | ||
logger.addHandler(handler) | ||
} | ||
|
||
fun silenceComputeEngine() { | ||
// Silence info log about "Failed to detect whether we are running on Google Compute Engine." | ||
Logger.getLogger(ComputeEngineCredentials::class.java.name).level = Level.OFF | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package ftl.cli | ||
|
||
import ftl.cli.auth.LoginCommand | ||
import picocli.CommandLine | ||
import picocli.CommandLine.Command | ||
|
||
@Command( | ||
name = "auth", | ||
synopsisHeading = "%n", | ||
header = ["Manage oauth2 credentials for Google Cloud"], | ||
subcommands = [ | ||
LoginCommand::class | ||
] | ||
) | ||
class AuthCommand : Runnable { | ||
override fun run() { | ||
CommandLine.usage(AuthCommand(), System.out) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package ftl.cli.auth | ||
|
||
import ftl.gc.GcAuth | ||
import picocli.CommandLine | ||
|
||
@CommandLine.Command( | ||
name = "login", | ||
sortOptions = false, | ||
headerHeading = "", | ||
synopsisHeading = "%n", | ||
descriptionHeading = "%n@|bold,underline Description:|@%n%n", | ||
parameterListHeading = "%n@|bold,underline Parameters:|@%n", | ||
optionListHeading = "%n@|bold,underline Options:|@%n", | ||
header = ["Obtains access credentials for your user account via a web-based authorization flow."], | ||
description = ["""Authenticates using your user account. For CI, a service account is recommended."""] | ||
) | ||
class LoginCommand : Runnable { | ||
override fun run() { | ||
GcAuth.authorizeUser() | ||
println("Saving credential to ${GcAuth.CRED.absolutePath}") | ||
} | ||
|
||
@CommandLine.Option( | ||
names = ["-h", "--help"], | ||
usageHelp = true, | ||
description = ["Prints this help message"] | ||
) | ||
var usageHelpRequested: Boolean = false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package ftl.gc | ||
|
||
import com.google.api.client.auth.oauth2.Credential | ||
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp | ||
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver | ||
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow | ||
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential | ||
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport | ||
import com.google.api.client.json.jackson2.JacksonFactory | ||
import com.google.api.client.util.store.FileDataStoreFactory | ||
import ftl.config.FtlConstants | ||
import java.io.File | ||
import java.io.IOException | ||
|
||
// https://github.com/googleapis/google-oauth-java-client | ||
// GoogleAuthorizationCodeFlow usage based on https://developers.google.com/sheets/api/quickstart/java | ||
object GcAuth { | ||
private val HOME = System.getProperty("user.home") | ||
private val CRED_FOLDER = File(HOME, ".flank/") | ||
val CRED = File(CRED_FOLDER, "StoredCredential") | ||
|
||
private val JSON_FACTORY = JacksonFactory.getDefaultInstance() | ||
private var HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport() | ||
private var DATA_STORE_FACTORY = FileDataStoreFactory(CRED_FOLDER) | ||
|
||
// https://github.com/bootstraponline/gcloud_cli/blob/40521a6e297830b9f652a9ab4d8002e309b4353a/google-cloud-sdk/platform/gsutil/gslib/utils/system_util.py#L177 | ||
private const val CLIENT_ID = "32555940559.apps.googleusercontent.com" | ||
private const val CLIENT_SECRET = "ZmssLNjJy2998hD4CTg2ejr2" | ||
|
||
fun hasUserAuth(): Boolean { | ||
return CRED.exists() | ||
} | ||
|
||
private fun Credential.toGoogleCredential(): GoogleCredential { | ||
return GoogleCredential.Builder() | ||
.setTransport(HTTP_TRANSPORT) | ||
.setJsonFactory(JSON_FACTORY) | ||
.setClientSecrets(CLIENT_ID, CLIENT_SECRET) | ||
.build() | ||
.setAccessToken(this.accessToken) | ||
} | ||
|
||
@Throws(IOException::class) | ||
fun authorizeUser(): GoogleCredential { | ||
if (FtlConstants.useMock) return GoogleCredential() | ||
// https://github.com/bootstraponline/gcloud_cli/blob/e4b5e01610abad2e31d8a6edb20b17b2f84c5395/google-cloud-sdk/lib/googlecloudsdk/core/config.py#L167 | ||
val scopes = listOf("https://www.googleapis.com/auth/cloud-platform") | ||
|
||
val flow = GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, CLIENT_ID, CLIENT_SECRET, scopes) | ||
.setDataStoreFactory(DATA_STORE_FACTORY) | ||
.setAccessType("offline") | ||
.build() | ||
|
||
val authCode = AuthorizationCodeInstalledApp(flow, LocalServerReceiver()) | ||
val dataStoreKey = "default" | ||
|
||
return authCode.authorize(dataStoreKey).toGoogleCredential() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 3 additions & 3 deletions
6
test_runner/src/main/kotlin/ftl/http/TimeoutHttpRequestInitializer.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package ftl.cli | ||
|
||
import com.google.common.truth.Truth.assertThat | ||
import ftl.test.util.FlankTestRunner | ||
import org.junit.Rule | ||
import org.junit.Test | ||
import org.junit.contrib.java.lang.system.SystemOutRule | ||
import org.junit.runner.RunWith | ||
|
||
@RunWith(FlankTestRunner::class) | ||
class AuthCommandTest { | ||
@Rule | ||
@JvmField | ||
val systemOutRule: SystemOutRule = SystemOutRule().enableLog().muteForSuccessfulTests() | ||
|
||
@Test | ||
fun firebaseCommandPrintsHelp() { | ||
AuthCommand().run() | ||
val output = systemOutRule.log | ||
assertThat(output).startsWith( | ||
"Manage oauth2 credentials for Google Cloud\n\n" + | ||
"auth [COMMAND]\n" + | ||
"Commands:\n" + | ||
" login" | ||
) | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
test_runner/src/test/kotlin/ftl/cli/auth/LoginCommandTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package ftl.cli.auth | ||
|
||
import com.google.common.truth.Truth | ||
import com.google.common.truth.Truth.assertThat | ||
import ftl.test.util.FlankTestRunner | ||
import org.junit.Rule | ||
import org.junit.Test | ||
import org.junit.contrib.java.lang.system.ExpectedSystemExit | ||
import org.junit.contrib.java.lang.system.SystemOutRule | ||
import org.junit.runner.RunWith | ||
import picocli.CommandLine | ||
|
||
@RunWith(FlankTestRunner::class) | ||
class LoginCommandTest { | ||
@Rule | ||
@JvmField | ||
val systemOutRule: SystemOutRule = SystemOutRule().enableLog().muteForSuccessfulTests() | ||
|
||
@get:Rule | ||
val exit = ExpectedSystemExit.none() | ||
|
||
@Test | ||
fun cancelCommandPrintsHelp() { | ||
val command = LoginCommand() | ||
assertThat(command.usageHelpRequested).isFalse() | ||
CommandLine.run<Runnable>(command, System.out, "-h") | ||
|
||
val output = systemOutRule.log | ||
Truth.assertThat(output).startsWith( | ||
"""Obtains access credentials for your user account via a web-based authorization | ||
flow. | ||
login [-h]""".trimIndent()) | ||
|
||
assertThat(command.usageHelpRequested).isTrue() | ||
} | ||
|
||
@Test | ||
fun commandRuns() { | ||
LoginCommand().run() | ||
} | ||
|
||
@Test | ||
fun cancelCommandOptions() { | ||
val cmd = LoginCommand() | ||
assertThat(cmd.usageHelpRequested).isFalse() | ||
cmd.usageHelpRequested = true | ||
assertThat(cmd.usageHelpRequested).isTrue() | ||
} | ||
} |