Repository: firebase/firebase-admin-go (go)

Issue:
Authentication emulator fails on clean environment to required default credentials
### [REQUIRED] Step 2: Describe your environment

  * Operating System version: WSL Unix
  * Firebase SDK version: 4.6.0
  * Library version: v4.6.0
  * Firebase Product: auth emulator

### [REQUIRED] Step 3: Describe the problem

Running auth emulator with the wanted env variable FIREBASE_AUTH_EMULATOR_HOST fails.

#### Steps to reproduce:

Start a project in a clean machine. Add env variable FIREBASE_AUTH_EMULATOR_HOST and make firebase auth app.
It gives error `google: could not find default credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.`

#### Relevant Code:

```go
conf := &firebase.Config{ProjectID: "demo-project"}
app, err := firebase.NewApp(ctx, conf)
auth, err := app.Auth(ctx)
if err != nil {
   log.Fatalf("making firebase auth failed: %v", err) // this line is hit
}
```

The problem was missing the option `firebase.NewApp(ctx, conf, option.WithoutAuthentication())`. This isn't documented anywhere. Took me an hour of searching google and trying all kinds of things.

I came across this as Github Action failed to it. Tested on a brand new EC2 ubuntu instance in Amazon and fails too. With `WithoutAuthentication()` option both work as expected.

Pull request:
fix: Skipping credential lookup in emulator mode
We currently perform a credential lookup in the emulator mode, which can result in errors if the developer hasn't specified any credentials during initialization. This PR attempts to solve this problem by defaulting to "owner" emulator credentials in the emulator mode. 

One downside of this solution is that it will cause all client options to get ignored in emulator mode. Ideally we should check if the developer has specified any credentials, and only replace that. But currently there's no clean way to implement such a replacement.

Also found a couple of existing unit tests that were taking 7 seconds each due to automatic retries. I've disabled retries for those tests thus saving 14 seconds from our unit test runs. 

Resolves #458 

Patch:
diff --git a/auth/auth.go b/auth/auth.go
index f035726..8ef7715 100644
--- a/auth/auth.go
+++ b/auth/auth.go
@@ -25,6 +25,8 @@ import (
 	"time"
 
 	"firebase.google.com/go/v4/internal"
+	"golang.org/x/oauth2"
+	"google.golang.org/api/option"
 	"google.golang.org/api/transport"
 )
 
@@ -47,6 +49,10 @@ var reservedClaims = []string{
 	"exp", "firebase", "iat", "iss", "jti", "nbf", "nonce", "sub",
 }
 
+var emulatorToken = &oauth2.Token{
+	AccessToken: "owner",
+}
+
 // Client is the interface for the Firebase auth service.
 //
 // Client facilitates generating custom JWT tokens for Firebase clients, and verifying ID tokens issued
@@ -114,7 +120,15 @@ func NewClient(ctx context.Context, conf *internal.AuthConfig) (*Client, error)
 		return nil, err
 	}
 
-	transport, _, err := transport.NewHTTPClient(ctx, conf.Opts...)
+	var opts []option.ClientOption
+	if isEmulator {
+		ts := oauth2.StaticTokenSource(emulatorToken)
+		opts = append(opts, option.WithTokenSource(ts))
+	} else {
+		opts = append(opts, conf.Opts...)
+	}
+
+	transport, _, err := transport.NewHTTPClient(ctx, opts...)
 	if err != nil {
 		return nil, err
 	}


Test patch:
diff --git a/auth/auth_test.go b/auth/auth_test.go
index 330c174..634345a 100644
--- a/auth/auth_test.go
+++ b/auth/auth_test.go
@@ -296,15 +296,11 @@ func TestNewClientEmulatorHostEnvVar(t *testing.T) {
 	os.Setenv(emulatorHostEnvVar, emulatorHost)
 	defer os.Unsetenv(emulatorHostEnvVar)
 
-	conf := &internal.AuthConfig{
-		Opts: []option.ClientOption{
-			option.WithoutAuthentication(),
-		},
-	}
-	client, err := NewClient(context.Background(), conf)
+	client, err := NewClient(context.Background(), &internal.AuthConfig{})
 	if err != nil {
 		t.Fatal(err)
 	}
+
 	baseClient := client.baseClient
 	if baseClient.userManagementEndpoint != idToolkitV1Endpoint {
 		t.Errorf("baseClient.userManagementEndpoint = %q; want = %q", baseClient.userManagementEndpoint, idToolkitV1Endpoint)
@@ -778,6 +774,7 @@ func TestEmulatorVerifyIDTokenUnreachableEmulator(t *testing.T) {
 		t.Fatal(err)
 	}
 	client.httpClient.Client.Transport = eConnRefusedTransport{}
+	client.httpClient.RetryConfig = nil
 	client.isEmulator = true
 
 	token := getEmulatedIDToken(nil)
@@ -1239,6 +1236,7 @@ func TestEmulatorVerifySessionCookieUnreachableEmulator(t *testing.T) {
 		t.Fatal(err)
 	}
 	client.httpClient.Client.Transport = eConnRefusedTransport{}
+	client.httpClient.RetryConfig = nil
 	client.isEmulator = true
 
 	token := getEmulatedSessionCookie(nil)